diff options
Diffstat (limited to 'media/libstagefright/MediaCodecSource.cpp')
-rw-r--r-- | media/libstagefright/MediaCodecSource.cpp | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp index 7f9f824..14a3c0d 100644 --- a/media/libstagefright/MediaCodecSource.cpp +++ b/media/libstagefright/MediaCodecSource.cpp @@ -36,6 +36,9 @@ #include <media/stagefright/MetaData.h> #include <media/stagefright/PersistentSurface.h> #include <media/stagefright/Utils.h> +#include <OMX_Core.h> +#include <stagefright/AVExtensions.h> +#include <cutils/properties.h> namespace android { @@ -214,7 +217,7 @@ void MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) { status_t err = mSource->read(&mbuf); if (mPaused) { - if (err == OK) { + if (err == OK && (NULL != mbuf)) { mbuf->release(); mbuf = NULL; } @@ -399,10 +402,14 @@ status_t MediaCodecSource::initEncoder() { } AString outputMIME; + AString role; CHECK(mOutputFormat->findString("mime", &outputMIME)); - - mEncoder = MediaCodec::CreateByType( + if (AVUtils::get()->useQCHWEncoder(mOutputFormat, role)) { + mEncoder = MediaCodec::CreateByComponentName(mCodecLooper, role.c_str()); + } else { + mEncoder = MediaCodec::CreateByType( mCodecLooper, outputMIME.c_str(), true /* encoder */); + } if (mEncoder == NULL) { return NO_INIT; @@ -423,9 +430,14 @@ status_t MediaCodecSource::initEncoder() { return err; } + int32_t hfrRatio = 0; + mOutputFormat->findInt32("hfr-ratio", &hfrRatio); + mEncoder->getOutputFormat(&mOutputFormat); convertMessageToMetaData(mOutputFormat, mMeta); + AVUtils::get()->HFRUtils().setHFRRatio(mMeta, hfrRatio); + if (mFlags & FLAG_USE_SURFACE_INPUT) { CHECK(mIsVideo); @@ -514,6 +526,9 @@ void MediaCodecSource::signalEOS(status_t err) { mOutputBufferQueue.clear(); mEncoderReachedEOS = true; mErrorCode = err; + if (err == OMX_ErrorHardware) { + mErrorCode = ERROR_IO; + } mOutputBufferCond.signal(); } @@ -572,6 +587,9 @@ status_t MediaCodecSource::feedEncoderInputBuffers() { // push decoding time for video, or drift time for audio if (mIsVideo) { mDecodingTimeQueue.push_back(timeUs); + if (mFlags & FLAG_USE_METADATA_INPUT) { + AVUtils::get()->addDecodingTimesFromBatch(mbuf, mDecodingTimeQueue); + } } else { #if DEBUG_DRIFT_TIME if (mFirstSampleTimeUs < 0ll) { @@ -591,7 +609,7 @@ status_t MediaCodecSource::feedEncoderInputBuffers() { status_t err = mEncoder->getInputBuffer(bufferIndex, &inbuf); if (err != OK || inbuf == NULL) { mbuf->release(); - signalEOS(); + signalEOS(err); break; } @@ -633,6 +651,9 @@ status_t MediaCodecSource::onStart(MetaData *params) { resume(); } else { CHECK(mPuller != NULL); + if (mIsVideo) { + mEncoder->requestIDRFrame(); + } mPuller->resume(); } return OK; @@ -643,8 +664,13 @@ status_t MediaCodecSource::onStart(MetaData *params) { status_t err = OK; if (mFlags & FLAG_USE_SURFACE_INPUT) { + auto key = kKeyTime; + if (!property_get_bool("media.camera.ts.monotonic", true)) { + key = kKeyTimeBoot; + } + int64_t startTimeUs; - if (!params || !params->findInt64(kKeyTime, &startTimeUs)) { + if (!params || !params->findInt64(key, &startTimeUs)) { startTimeUs = -1ll; } resume(startTimeUs); @@ -738,12 +764,14 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) { sp<ABuffer> outbuf; status_t err = mEncoder->getOutputBuffer(index, &outbuf); if (err != OK || outbuf == NULL) { - signalEOS(); + signalEOS(err); break; } MediaBuffer *mbuf = new MediaBuffer(outbuf->size()); memcpy(mbuf->data(), outbuf->data(), outbuf->size()); + sp<MetaData> meta = mbuf->meta_data(); + AVUtils::get()->setDeferRelease(meta); if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) { if (mIsVideo) { @@ -799,7 +827,7 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) { CHECK(msg->findInt32("err", &err)); ALOGE("Encoder (%s) reported error : 0x%x", mIsVideo ? "video" : "audio", err); - signalEOS(); + signalEOS(err); } break; } @@ -852,7 +880,7 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) { } case kWhatPause: { - if (mFlags && FLAG_USE_SURFACE_INPUT) { + if (mFlags & FLAG_USE_SURFACE_INPUT) { suspend(); } else { CHECK(mPuller != NULL); |