“Android MediaCodec trace”的版本间的差异
来自个人维基
free6d1823(讨论 | 贡献) |
free6d1823(讨论 | 贡献) |
||
第41行: | 第41行: | ||
} | } | ||
} | } | ||
+ | |||
+ | </source> | ||
+ | |||
+ | 3. prepare | ||
+ | <source lang="c"> | ||
+ | NuPlayer::GenericSource::onPrepareAsync(){ | ||
+ | dataSource = DataSourceFactory::CreateFromURI(uri) or new FileSource(mFd, mOffset, mLength); | ||
+ | <IMediaExtractor> ex = mediaExService->makeExtractor() => | ||
+ | MediaExtractorFactory::CreateFromService(localSource, mime); => | ||
+ | creator = sniff(source, &confidence, &meta, &freeMeta, plugin, &creatorVersion);==> | ||
+ | find best creator from ExtractorPlugin gPlugins list. | ||
+ | |||
+ | </source> | ||
+ | 4. start | ||
+ | <source lang="c"> | ||
+ | void NuPlayer::start()==> (new AMessage(kWhatStart, this))->post(); | ||
+ | NuPlayer::onMessageReceived(const sp<AMessage> &msg) { case kWhatStart: onStart();} | ||
+ | => NuPlayer::onStart(int64_t startPositionUs, MediaPlayerSeekMode mode) | ||
+ | => mSource->start(); | ||
+ | hasVideo = (mSource->getFormat(false /* audio */) != NULL); | ||
+ | mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags); | ||
+ | mRendererLooper = new ALooper; | ||
+ | mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO); | ||
+ | mRenderer->setPlaybackSettings(mPlaybackSettings); | ||
+ | mRendererLooper->registerHandler(mRenderer); | ||
+ | mRenderer->setVideoFrameRate(rate); | ||
+ | postScanSources()=> (new AMessage(kWhatScanSources, this))->post(); => NuPlayer::onMessageReceived( kWhatScanSources) { | ||
+ | instantiateDecoder(false, &mVideoDecoder) | ||
+ | { | ||
+ | notify = new AMessage(kWhatVideoNotify, this); | ||
+ | *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer, mSurface, mCCDecoder); | ||
+ | format->setInt32("auto-frc", 1);// enable FRC if high-quality AV sync is requested | ||
+ | (*decoder)->init(); | ||
+ | (*decoder)->configure(format); | ||
+ | //buffer | ||
+ | <ABuffer> inputBufs = (*decoder)->getInputBuffers(); | ||
+ | for each buffer in inputBufs[i], | ||
+ | mbuf = new MediaBuffer(buffer->data(), buffer->size()); | ||
+ | mediaBufs.push(mbuf); | ||
+ | mSource->setBuffers(audio, mediaBufs); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) | ||
+ | { | ||
+ | mComponentName = format->findString("mime")="audio/ video/xxx"+"decoder"; | ||
+ | mCodec = MediaCodec::CreateByType(mCodecLooper, mime, false /* encoder */, NULL /* err */, mPid); | ||
+ | // disconnect from surface as MediaCodec will reconnect | ||
+ | mCodec->configure(format, mSurface, NULL /* crypto */, 0 /* flags */); | ||
+ | rememberCodecSpecificData(format); | ||
+ | mCodec->getOutputFormat(&mOutputFormat); | ||
+ | mCodec->getInputFormat(&mInputFormat)); | ||
+ | //find width and height from mOutputFormat() | ||
+ | mCodec->setCallback(reply); | ||
+ | mCodec->start(); | ||
+ | releaseAndResetMediaBuffers(); | ||
+ | } | ||
+ | mCodec->initiateAllocateComponent(format);=> msg->setWhat(kWhatAllocateComponent);=> msg->setWhat(kWhatAllocateComponent); | ||
+ | ACodec::UninitializedState::onAllocateComponent(msg) { | ||
+ | OMXClient client; | ||
+ | client.connect(); | ||
+ | <IOMX> omx = client.interface(); | ||
+ | OMXCodec::findMatchingCodecs(mime, encoder, &matchingCodecs); | ||
+ | omx->allocateNode(componentName.c_str(), observer, &node); | ||
+ | mCodec->mNotify->("CodecBase::kWhatComponentAllocated") | ||
+ | } | ||
+ | |||
+ | |||
+ | </source> | ||
+ | |||
+ | 5. Decoder input: | ||
+ | <source lang="c"> | ||
+ | MediaCodec::onInputBufferAvailable() | ||
+ | NuPlayer::Decoder::handleAnInputBuffer(…) | ||
+ | NuPlayer::Decoder::onInputBufferFetched(…) | ||
+ | OMX::emptyBuffer(…), | ||
+ | //decode | ||
+ | SoftOMXComponent::notifyEmptyBufferDone(…) | ||
+ | OMX::OnEmptyBufferDone(…) | ||
+ | ACodec::BaseState::onOMXEmptyBufferDone(…) | ||
+ | |||
+ | </source> | ||
+ | 6. Decoder output | ||
+ | <source lang="c"> | ||
+ | ACodec::ExecutingState::submitOutputBuffers() | ||
+ | ACodec::BaseState::postFillThisBuffer(…) | ||
+ | OMX:: fillBuffer (…) | ||
+ | SimpleSoftOMXComponent::fillThisBuffer(…) | ||
+ | //write decoded output | ||
+ | SoftOMXComponent::notifyFillBufferDone(…) | ||
+ | OMX:: OnFillBufferDone (…) | ||
+ | ACodec::BaseState:: onOMXFillBufferDone (…); | ||
+ | NuPlayer::Decoder::handleAnOutputBuffer(…) | ||
+ | |||
</source> | </source> |
2020年6月9日 (二) 21:45的版本
- MediaPlayer calling flow
MediaPlayer mp = new MediaPlayer(); 1. mp.setDataSource(filePath); 2. mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 3. mp.prepare(); //获取和解码媒体数据 4. mp.start(); 5. FillBuffer 6. EmptyBuffer
1. setDataSource(filePath)
<MediaPlayerBase> mPlayer = Create form (playerType of source); // => new NuPlayerDriver(pid) { mLooper->setName("NuPlayerDriver Looper")->start(PRIORITY_AUDIO); mPlayer = new NuPlayer(pid); } //绑定Extractor、omx、codec2服务的death监听, //mPlayer->setDataSource(dataSource)
2. setDisplay(SurfaceHolder sh)
{ mSurfaceHolder = sh; _setVideoSurface(sh.getSurface());--> { MediaPlayer.cpp { sp<IGraphicBufferProducer> new_st = surface->getIGraphicBufferProducer(); MediaPlayerService mp->setVideoSurfaceTexture(new_st); } MediaPlayerService::Client::setVideoSurfaceTexture(<IGraphicBufferProducer>& bufferProducer) sp<ANativeWindow> anw; if (bufferProducer != NULL) { anw = new Surface(bufferProducer, true /* controlledByApp */); status_t err = native_window_api_connect(anw.get(), NATIVE_WINDOW_API_MEDIA); p->setVideoSurfaceTexture(bufferProducer); mConnectedWindow = anw; //decoder } }
3. prepare
NuPlayer::GenericSource::onPrepareAsync(){ dataSource = DataSourceFactory::CreateFromURI(uri) or new FileSource(mFd, mOffset, mLength); <IMediaExtractor> ex = mediaExService->makeExtractor() => MediaExtractorFactory::CreateFromService(localSource, mime); => creator = sniff(source, &confidence, &meta, &freeMeta, plugin, &creatorVersion);==> find best creator from ExtractorPlugin gPlugins list.
4. start
void NuPlayer::start()==> (new AMessage(kWhatStart, this))->post(); NuPlayer::onMessageReceived(const sp<AMessage> &msg) { case kWhatStart: onStart();} => NuPlayer::onStart(int64_t startPositionUs, MediaPlayerSeekMode mode) => mSource->start(); hasVideo = (mSource->getFormat(false /* audio */) != NULL); mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags); mRendererLooper = new ALooper; mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO); mRenderer->setPlaybackSettings(mPlaybackSettings); mRendererLooper->registerHandler(mRenderer); mRenderer->setVideoFrameRate(rate); postScanSources()=> (new AMessage(kWhatScanSources, this))->post(); => NuPlayer::onMessageReceived( kWhatScanSources) { instantiateDecoder(false, &mVideoDecoder) { notify = new AMessage(kWhatVideoNotify, this); *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer, mSurface, mCCDecoder); format->setInt32("auto-frc", 1);// enable FRC if high-quality AV sync is requested (*decoder)->init(); (*decoder)->configure(format); //buffer <ABuffer> inputBufs = (*decoder)->getInputBuffers(); for each buffer in inputBufs[i], mbuf = new MediaBuffer(buffer->data(), buffer->size()); mediaBufs.push(mbuf); mSource->setBuffers(audio, mediaBufs); } } NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { mComponentName = format->findString("mime")="audio/ video/xxx"+"decoder"; mCodec = MediaCodec::CreateByType(mCodecLooper, mime, false /* encoder */, NULL /* err */, mPid); // disconnect from surface as MediaCodec will reconnect mCodec->configure(format, mSurface, NULL /* crypto */, 0 /* flags */); rememberCodecSpecificData(format); mCodec->getOutputFormat(&mOutputFormat); mCodec->getInputFormat(&mInputFormat)); //find width and height from mOutputFormat() mCodec->setCallback(reply); mCodec->start(); releaseAndResetMediaBuffers(); } mCodec->initiateAllocateComponent(format);=> msg->setWhat(kWhatAllocateComponent);=> msg->setWhat(kWhatAllocateComponent); ACodec::UninitializedState::onAllocateComponent(msg) { OMXClient client; client.connect(); <IOMX> omx = client.interface(); OMXCodec::findMatchingCodecs(mime, encoder, &matchingCodecs); omx->allocateNode(componentName.c_str(), observer, &node); mCodec->mNotify->("CodecBase::kWhatComponentAllocated") }
5. Decoder input:
MediaCodec::onInputBufferAvailable() NuPlayer::Decoder::handleAnInputBuffer(…) NuPlayer::Decoder::onInputBufferFetched(…) OMX::emptyBuffer(…), //decode SoftOMXComponent::notifyEmptyBufferDone(…) OMX::OnEmptyBufferDone(…) ACodec::BaseState::onOMXEmptyBufferDone(…)
6. Decoder output
ACodec::ExecutingState::submitOutputBuffers() ACodec::BaseState::postFillThisBuffer(…) OMX:: fillBuffer (…) SimpleSoftOMXComponent::fillThisBuffer(…) //write decoded output SoftOMXComponent::notifyFillBufferDone(…) OMX:: OnFillBufferDone (…) ACodec::BaseState:: onOMXFillBufferDone (…); NuPlayer::Decoder::handleAnOutputBuffer(…)