Android MediaExtractor setDataSource

1. MediaExtractor(java)

file: frameworks/base/media/java/android/mediaf/MediaExtractor.java 目前Android 5.0仅支持本地视频

(FileDescriptor fd) throws IOException {setDataSource(fd, 0, 0x7ffffffffffffffL);}

这会调用JNI setDataSource

2. android_media_MediaExtractor(native)

file: frameworks/base/media/jni/android_media_MediaExtractor.cpp native的setDataSource是调用NuMediaExtractor的setDataSource

status_t JMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) {return mImpl->setDataSource(fd, offset, size);}3. NuMediaExtractor

file:frameworks/av/media/libstagefright/NuMediaExtractor.cpp NuMediaExtractor先创建FileSource 然后根据FileSource创建相应的Extractor

status_t NuMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) {…sp<FileSource> fileSource = new FileSource(dup(fd), offset, size);mImpl = MediaExtractor::Create(fileSource);…mDataSource = fileSource;updateDurationAndBitrate();return OK;}4. New FileSource

FileSource继承于DataSource。 FileSource初始化函数执行操作有:打开文件,获取文件FD,Seek文件

FileSource::FileSource(const char *filename): mFd(-1),mOffset(0),mLength(-1),mDecryptHandle(NULL),mDrmManagerClient(NULL),mDrmBufOffset(0),mDrmBufSize(0),mDrmBuf(NULL){mFd = open(filename, O_LARGEFILE | O_RDONLY);if (mFd >= 0) {mLength = lseek64(mFd, 0, SEEK_END);} else {ALOGE(“Failed to open file ‘%s’. (%s)”, filename, strerror(errno));}}

DataSource初始化函数执行操作有:new Sniffer

DataSource() : mSniffer(new Sniffer()) {}

Sniffer构造过程:注册各个Extractor的Sniffer函数 registerDefaultSniffers

void Sniffer::registerDefaultSniffers() {Mutex::Autolock autoLock(mSnifferMutex);registerSniffer_l(SniffMPEG4);registerSniffer_l(SniffMatroska);registerSniffer_l(SniffOgg);registerSniffer_l(SniffWAV);registerSniffer_l(SniffFLAC);registerSniffer_l(SniffAMR);registerSniffer_l(SniffMPEG2TS);registerSniffer_l(SniffMP3);registerSniffer_l(SniffAAC);registerSniffer_l(SniffMPEG2PS);registerSniffer_l(SniffWVM);registerSniffer_l(ExtendedExtractor::Sniff);char value[PROPERTY_VALUE_MAX];if (property_get(“drm.service.enabled”, value, NULL)&& (!strcmp(value, “1”) || !strcasecmp(value, “true”))) {registerSniffer_l(SniffDRM);}}5. MediaExtractor::Create

file:frameworks/av/media/libstagefright/MediaExtractor.cpp MediaExtractor(C++)是MediaExtractor体系中核心,是各个extractor(eg.MPEG4Extractor)的父类,管理者. Create它根据文件的MIME信息创建对应的Extractor,具体逻辑如下: (1)sniff : 获取文件meta信息 (2)根据meta中的MIME创建对应的Extractor (3)ExtendedUtils判断创建默认Extractor还是扩展Extractor

sp<MediaExtractor> MediaExtractor::Create(const sp<DataSource> &source, const char *mime) {sp<AMessage> meta;String8 tmp;if (mime == NULL) {float confidence;if (!source->sniff(&tmp, &confidence, &meta)) {ALOGV(“FAILED to autodetect media content.”);return NULL;}mime = tmp.string();ALOGV(“Autodetected media content as ‘%s’ with confidence %.2f”,mime, confidence);}bool isDrm = false;(!strncmp(mime, “drm+”, 4)) {const char *originalMime = strchr(mime+4, ‘+’);if (originalMime == NULL) {;}++originalMime;if (!strncmp(mime, “drm+es_based+”, 13)) {DRMExtractor(source, originalMime);} else if (!strncmp(mime, “drm+container_based+”, 20)) {mime = originalMime;isDrm = true;} else {return NULL;}}MediaExtractor *ret = NULL;if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)|| !strcasecmp(mime, “audio/mp4”)) {ret = new MPEG4Extractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {ret = new MP3Extractor(source, meta);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)|| !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {ret = new AMRExtractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {ret = new FLACExtractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) {ret = new WAVExtractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)) {ret = new OggExtractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) {ret = new MatroskaExtractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {ret = new MPEG2TSExtractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) {WVMExtractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) {ret = new AACExtractor(source, meta);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)) {ret = new MPEG2PSExtractor(source);}if (ret != NULL) {if (isDrm) {ret->setDrmFlag(true);} else {ret->setDrmFlag(false);}}return ExtendedUtils::MediaExtractor_CreateIfNeeded(ret, source, mime);}6. ExtendedUtils::MediaExtractor_CreateIfNeeded,再回头,便生出无限羁绊。那是彼此的刺在对方心里留下的痕迹,

Android MediaExtractor setDataSource

相关文章:

你感兴趣的文章:

标签云: