MediaRecorder流程如下:
当使用CameraSource的时候MediaCodecSource会从CameraSource中取数据。
当使用Surface的时候不用CameraSource。
实际实现都是生产者消费者模型,由camera生产数据,由codec消费数据。只是具体实现过程不一样,camerasource录制使用的是puller,surface录制使用的是BufferQueue.
CameraSource:
在MediaCodecSource::Create中创建MediaCodecSource对象,此处会判断当前对否是FLAG_USE_SURFACE_INPUT,若不是,则: mPuller = new Puller(source);
MediaCodecSource::Puller中有存放数据的Queue,并且响应各种对Queue的操作。
大概流程如下:
Puller中readbuffer的调用过程:
- MediaCodecSource::onMessageReceived收到消息kWhatPullerNotify或者kWhatEncoderActivity, kWhatPullerNotify是由MediaCodecSource::onStart发出,kWhatPullerNotify是由MediaCodec::onInputBufferAvailable()发出的。
- MediaCodecSource::feedEncoderInputBuffers()在此函数中把数据取出来,并调用mediacodec的queueInputBuffer,最终调用acodec的ETB.
- mPuller->readBuffer(&mbuf)
(此处是从queue里面取走数据)
Puller中pushBuffer的调用过程:
- MediaCodecSource::Puller::onMessageReceived 收到 kWhatPull ,kWhatPull是由schedulePull发出的消息,在收到kWhatStart之后就会调用schedulePull。
- queue->pushBuffer(mbuf);
(此处就是从camerasource取到数据,然后把数据push到queue里面)
编码完的数据会送给mpeg4writer去写入文件。解码后的数据会送给disaplay去render。
Surface:
Surface录制没有puller。
大概流程如下:
此处listener负责监听,防止consumer需要一直查看bufferqueue是否有数据,listener发现有数据会通知consumer。
MediaCodecSource::initEncoder()
如果是APP提供provider则调用mEncoder->setInputSurface,否则调用mEncoder->createInputSurface
MediaCodec::createInputSurface 发送 kWhatCreateInputSurface,并返回bufferProducer给APP
ACodec::initiateCreateInputSurface 发送 kWhatCreateInputSurface
ACodec::LoadedState::onCreateInputSurface 在此函数中mCodec->mOMX->createInputSurface(&bufferProducer, &mCodec->mGraphicBufferSource);会创建bufferProducer和mGraphicBufferSource。ACodec拿到的是mGraphicBufferSource,只能做一些参数设置,具体的数据写入读出不在ACodec中做。
IOMX.h的createInputSurface Bn
LWOmx::createInputSurface Bp *bufferProducer = new H2BGraphicBufferProducer(tProducer); *bufferSource = new LWGraphicBufferSource(tSource);
ACodec::LoadedState::setupInputSurface() 在此函数中mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace),将mGraphicBufferSource和omx关联起来。
LWGraphicBufferSource::configure
IGraphicBufferSource::configure 接口类,在TWGraphicBufferSource被实现
TWGraphicBufferSource::configure omxNode->setInputSurface(mOmxBufferSource) 和 mBase->configure(new TWOmxNodeWrapper(omxNode),toRawDataspace
(dataspace),def.nBufferCountActual,def.format.video.nFrameWidth,def.format.video.nFrameHeight,consumerUsage)
LWOmxNode::setInputSurface 在此函数中mBase->setInputSurface(new TWOmxBufferSource(bufferSource))
OmxGraphicBufferSource::configure
GraphicBufferSource::configure GraphicBufferSource::GraphicBufferSource()中BufferQueue::createBufferQueue(&mProducer, &mConsumer); 在mConsumer就会调用acquireBuffer、releaseBuffer等函数,实现数据的写入读出。
设置完成之后上层可以通过调用getIGraphicBufferProducer获取mProducer并返回给APP。mConsumer会调用mConsumer->consumerConnect连接到listener。
BufferQueueProducer调用queueBuffer、requestBuffer、dequeueBuffer等函数实现数据的写入读出。BufferQueueProducer在调用dequeueBuffer中会通知frameAvailableListener->onFrameAvailable。然后会调用到GraphicBufferSource::onFrameAvailable,然后调用过程如下:
GraphicBufferSource::onFrameAvailable
GraphicBufferSource::onBufferAcquired_l
GraphicBufferSource::fillCodecBuffer_l
GraphicBufferSource::submitBuffer_l
OmxGraphicBufferSource.cpp中submitBuffer 调用 mOmxNode->emptyBuffer