0. setDataSource时序图
1. MediaExtractor(java)
file: frameworks/base/media/java/android/mediaf/MediaExtractor.java
目前Android 5.0仅支持本地视频
public final void setDataSource(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++)