Android视频录制-MediaRecorder

MediaRecorder流程如下:

Android视频录制-MediaRecorder_第1张图片

当使用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的操作。

 

大概流程如下:

Android视频录制-MediaRecorder_第2张图片

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。

大概流程如下:

Android视频录制-MediaRecorder_第3张图片

 

此处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

你可能感兴趣的:(安卓基础)