diff options
Diffstat (limited to 'media/libstagefright/ACodec.cpp')
-rw-r--r-- | media/libstagefright/ACodec.cpp | 120 |
1 files changed, 101 insertions, 19 deletions
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 4aecb80..0a3a3b6 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -17,6 +17,8 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "ACodec" +#include <utils/Trace.h> + #include <media/stagefright/ACodec.h> #include <binder/MemoryDealer.h> @@ -36,6 +38,7 @@ #include <media/hardware/HardwareAPI.h> #include <OMX_AudioExt.h> +#include <OMX_VideoExt.h> #include <OMX_Component.h> #include <OMX_IndexExt.h> @@ -97,12 +100,6 @@ struct CodecObserver : public BnOMXObserver { msg->setInt64( "timestamp", omx_msg.u.extended_buffer_data.timestamp); - msg->setPointer( - "platform_private", - omx_msg.u.extended_buffer_data.platform_private); - msg->setPointer( - "data_ptr", - omx_msg.u.extended_buffer_data.data_ptr); break; } @@ -157,9 +154,7 @@ private: IOMX::buffer_id bufferID, size_t rangeOffset, size_t rangeLength, OMX_U32 flags, - int64_t timeUs, - void *platformPrivate, - void *dataPtr); + int64_t timeUs); void getMoreInputDataIfPossible(); @@ -2370,12 +2365,81 @@ status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) { status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) { int32_t bitrate; + int32_t iFrameInterval = 0; + size_t tsLayers = 0; + OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern = + OMX_VIDEO_VPXTemporalLayerPatternNone; + static const uint32_t kVp8LayerRateAlloction + [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] + [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = { + {100, 100, 100}, // 1 layer + { 60, 100, 100}, // 2 layers {60%, 40%} + { 40, 60, 100}, // 3 layers {40%, 20%, 40%} + }; if (!msg->findInt32("bitrate", &bitrate)) { return INVALID_OPERATION; } + msg->findInt32("i-frame-interval", &iFrameInterval); OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); + float frameRate; + if (!msg->findFloat("frame-rate", &frameRate)) { + int32_t tmp; + if (!msg->findInt32("frame-rate", &tmp)) { + return INVALID_OPERATION; + } + frameRate = (float)tmp; + } + + AString tsSchema; + if (msg->findString("ts-schema", &tsSchema)) { + if (tsSchema == "webrtc.vp8.1-layer") { + pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; + tsLayers = 1; + } else if (tsSchema == "webrtc.vp8.2-layer") { + pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; + tsLayers = 2; + } else if (tsSchema == "webrtc.vp8.3-layer") { + pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; + tsLayers = 3; + } else { + ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str()); + } + } + + OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; + InitOMXParams(&vp8type); + vp8type.nPortIndex = kPortIndexOutput; + status_t err = mOMX->getParameter( + mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, + &vp8type, sizeof(vp8type)); + + if (err == OK) { + if (iFrameInterval > 0) { + vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate); + } + vp8type.eTemporalPattern = pattern; + vp8type.nTemporalLayerCount = tsLayers; + if (tsLayers > 0) { + for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) { + vp8type.nTemporalLayerBitrateRatio[i] = + kVp8LayerRateAlloction[tsLayers - 1][i]; + } + } + if (bitrateMode == OMX_Video_ControlRateConstant) { + vp8type.nMinQuantizer = 2; + vp8type.nMaxQuantizer = 63; + } + + err = mOMX->setParameter( + mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, + &vp8type, sizeof(vp8type)); + if (err != OK) { + ALOGW("Extended VP8 parameters set failed: %d", err); + } + } + return configureBitrate(bitrate, bitrateMode); } @@ -3156,23 +3220,17 @@ bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { int32_t rangeOffset, rangeLength, flags; int64_t timeUs; - void *platformPrivate; - void *dataPtr; CHECK(msg->findInt32("range_offset", &rangeOffset)); CHECK(msg->findInt32("range_length", &rangeLength)); CHECK(msg->findInt32("flags", &flags)); CHECK(msg->findInt64("timestamp", &timeUs)); - CHECK(msg->findPointer("platform_private", &platformPrivate)); - CHECK(msg->findPointer("data_ptr", &dataPtr)); return onOMXFillBufferDone( bufferID, (size_t)rangeOffset, (size_t)rangeLength, (OMX_U32)flags, - timeUs, - platformPrivate, - dataPtr); + timeUs); } default: @@ -3471,9 +3529,7 @@ bool ACodec::BaseState::onOMXFillBufferDone( IOMX::buffer_id bufferID, size_t rangeOffset, size_t rangeLength, OMX_U32 flags, - int64_t timeUs, - void * /* platformPrivate */, - void * /* dataPtr */) { + int64_t timeUs) { ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx", mCodec->mComponentName.c_str(), bufferID, timeUs, flags); @@ -3611,9 +3667,31 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { if (mCodec->mNativeWindow != NULL && msg->findInt32("render", &render) && render != 0 && info->mData != NULL && info->mData->size() != 0) { + ATRACE_NAME("render"); // The client wants this buffer to be rendered. + int64_t timestampNs = 0; + if (!msg->findInt64("timestampNs", ×tampNs)) { + // TODO: it seems like we should use the timestamp + // in the (media)buffer as it potentially came from + // an input surface, but we did not propagate it prior to + // API 20. Perhaps check for target SDK version. +#if 0 + if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { + ALOGI("using buffer PTS of %" PRId64, timestampNs); + timestampNs *= 1000; + } +#endif + } + status_t err; + err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs); + if (err != OK) { + ALOGW("failed to set buffer timestamp: %d", err); + } else { + ALOGI("set PTS to %" PRId64, timestampNs); + } + if ((err = mCodec->mNativeWindow->queueBuffer( mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), -1)) == OK) { @@ -3623,6 +3701,10 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { info->mStatus = BufferInfo::OWNED_BY_US; } } else { + if (mCodec->mNativeWindow != NULL && + (info->mData == NULL || info->mData->size() != 0)) { + ATRACE_NAME("frame-drop"); + } info->mStatus = BufferInfo::OWNED_BY_US; } |