summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/MediaCodecSource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/MediaCodecSource.cpp')
-rw-r--r--media/libstagefright/MediaCodecSource.cpp44
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);