[Android N]MediaRecorder系列之StagefrightRecorder录制TS流flow(四)

MPEG2TSWriter::readMore()

回到MPEG2TSWriter里面,调用完start()函数之后,会call readMore(),

这里写图片描述

MediaCodecSource::read

mBufferQueue里面存放则encoder好的数据,通过流程图来看下,camera的raw数据是怎么送到OMX中encoder好,再送出来到这个mBufferQueue中。

status_t MediaCodecSource::read(
        MediaBuffer** buffer, const ReadOptions* /* options */) {
    Mutexed<Output>::Locked output(mOutput);

    *buffer = NULL;
    while (output->mBufferQueue.size() == 0 && !output->mEncoderReachedEOS) {
        output.waitForCondition(output->mCond);
    }
    if (!output->mEncoderReachedEOS) {
        *buffer = *output->mBufferQueue.begin();
        output->mBufferQueue.erase(output->mBufferQueue.begin());
        return OK;
    }
    return output->mErrorCode;
}

再puller函数中对kWhatStart的处理,mSource->start之后会调用schedulePull();,

void MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatStart:
        {
            sp<RefBase> obj;
            CHECK(msg->findObject("meta", &obj));

            {
                Mutexed<Queue>::Locked queue(mQueue);
                queue->mPulling = true;
            }

            status_t err = mSource->start(static_cast<MetaData *>(obj.get()));

            if (err == OK) {
                //这开始去拉数据
                schedulePull();
            }
        ....
        }
}


void MediaCodecSource::Puller::schedulePull() {
    (new AMessage(kWhatPull, this))->post();
}

这里写图片描述

void MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) {
        case kWhatPull:
        {
            Mutexed<Queue>::Locked queue(mQueue);
            queue->mReadPendingSince = ALooper::GetNowUs();
            if (!queue->mPulling) {
                handleEOS();
                break;
            }

            queue.unlock();
            MediaBuffer *mbuf = NULL;
            status_t err = mSource->read(&mbuf);
            queue.lock();

            queue->mReadPendingSince = 0;
            // if we need to discard buffer
            if (!queue->mPulling || queue->mPaused || err != OK) {
                if (mbuf != NULL) {
                    mbuf->release();
                    mbuf = NULL;
                }
                if (queue->mPulling && err == OK) {
                    msg->post(); // if simply paused, keep pulling source
                    break;
                } else if (err == ERROR_END_OF_STREAM) {
                    ALOGV("stream ended, mbuf %p", mbuf);
                } else if (err != OK) {
                    ALOGE("error %d reading stream.", err);
                }
            }

            if (mbuf != NULL) {
                queue->pushBuffer(mbuf);
            }

            queue.unlock();

            //mNotify存放的就是kWhatPullerNotify,pull到了数据之后,就抛出去
            if (mbuf != NULL) {
                mNotify->post();
                msg->post();
            } else {
                handleEOS();
            }
            break;
        }

这里audioSource和CameraSource都是走的同样的flow,那么encoder是在哪里做选择的?
我们最后是从这里去拿到数据的,找这个mEncoder可以很快找到答案,这个放在后面的文章讲
status_t err = mEncoder->getOutputBuffer(index, &outbuf);

发布了14 篇原创文章 · 获赞 5 · 访问量 5万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览