summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2014-10-10 17:15:17 -0700
committerLajos Molnar <lajos@google.com>2014-10-13 23:16:20 -0700
commit2edda09a2ad1d112c52acd37d323f63f0a492d67 (patch)
treeef7d3fbbf888e258fb12b24ddf23a04dac3e54c5 /media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
parent512e979284de984427e5b2f73b9054ae1b5e2b0a (diff)
downloadframeworks_av-2edda09a2ad1d112c52acd37d323f63f0a492d67.zip
frameworks_av-2edda09a2ad1d112c52acd37d323f63f0a492d67.tar.gz
frameworks_av-2edda09a2ad1d112c52acd37d323f63f0a492d67.tar.bz2
stagefright: fix surface input handling of software encoders
- added SoftVideoEncoder for common color conversion and extension handling logic - fix YUV420 SemiPlanar handling that should be NV12 not NV21 Bug: 17935149 Change-Id: I9b8d05678b1862dd37bf349ea83d67bdf1bb5560
Diffstat (limited to 'media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp')
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp122
1 files changed, 29 insertions, 93 deletions
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index 42c9956..c87d19c 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -46,42 +46,12 @@ static void InitOMXParams(T *params) {
params->nVersion.s.nStep = 0;
}
-inline static void ConvertYUV420SemiPlanarToYUV420Planar(
- uint8_t *inyuv, uint8_t* outyuv,
- int32_t width, int32_t height) {
-
- int32_t outYsize = width * height;
- uint32_t *outy = (uint32_t *) outyuv;
- uint16_t *outcb = (uint16_t *) (outyuv + outYsize);
- uint16_t *outcr = (uint16_t *) (outyuv + outYsize + (outYsize >> 2));
-
- /* Y copying */
- memcpy(outy, inyuv, outYsize);
-
- /* U & V copying */
- uint32_t *inyuv_4 = (uint32_t *) (inyuv + outYsize);
- for (int32_t i = height >> 1; i > 0; --i) {
- for (int32_t j = width >> 2; j > 0; --j) {
- uint32_t temp = *inyuv_4++;
- uint32_t tempU = temp & 0xFF;
- tempU = tempU | ((temp >> 8) & 0xFF00);
-
- uint32_t tempV = (temp >> 8) & 0xFF;
- tempV = tempV | ((temp >> 16) & 0xFF00);
-
- // Flip U and V
- *outcb++ = tempV;
- *outcr++ = tempU;
- }
- }
-}
-
SoftMPEG4Encoder::SoftMPEG4Encoder(
const char *name,
const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData,
OMX_COMPONENTTYPE **component)
- : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ : SoftVideoEncoderOMXComponent(name, callbacks, appData, component),
mEncodeMode(COMBINE_MODE_WITH_ERR_RES),
mVideoWidth(176),
mVideoHeight(144),
@@ -149,9 +119,10 @@ OMX_ERRORTYPE SoftMPEG4Encoder::initEncParams() {
mEncParams->quantType[0] = 0;
mEncParams->noFrameSkipped = PV_OFF;
- if (mVideoColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
+ if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar
+ || mStoreMetaDataInBuffers) {
// Color conversion is needed.
- CHECK(mInputFrameData == NULL);
+ free(mInputFrameData);
mInputFrameData =
(uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1);
CHECK(mInputFrameData != NULL);
@@ -216,7 +187,7 @@ OMX_ERRORTYPE SoftMPEG4Encoder::releaseEncoder() {
PVCleanUpVideoEncoder(mHandle);
- delete mInputFrameData;
+ free(mInputFrameData);
mInputFrameData = NULL;
delete mEncParams;
@@ -486,6 +457,17 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter(
mVideoHeight = def->format.video.nFrameHeight;
mVideoFrameRate = def->format.video.xFramerate >> 16;
mVideoColorFormat = def->format.video.eColorFormat;
+
+ OMX_PARAM_PORTDEFINITIONTYPE *portDef =
+ &editPortInfo(0)->mDef;
+ portDef->format.video.nFrameWidth = mVideoWidth;
+ portDef->format.video.nFrameHeight = mVideoHeight;
+ portDef->format.video.xFramerate = def->format.video.xFramerate;
+ portDef->format.video.eColorFormat =
+ (OMX_COLOR_FORMATTYPE) mVideoColorFormat;
+ portDef = &editPortInfo(1)->mDef;
+ portDef->format.video.nFrameWidth = mVideoWidth;
+ portDef->format.video.nFrameHeight = mVideoHeight;
} else {
mVideoBitRate = def->format.video.nBitrate;
}
@@ -607,11 +589,7 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter(
mStoreMetaDataInBuffers ? " true" : "false");
if (mStoreMetaDataInBuffers) {
- mVideoColorFormat == OMX_COLOR_FormatYUV420SemiPlanar;
- if (mInputFrameData == NULL) {
- mInputFrameData =
- (uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1);
- }
+ mVideoColorFormat = OMX_COLOR_FormatAndroidOpaque;
}
return OMX_ErrorNone;
@@ -679,9 +657,8 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {
mSawInputEOS = true;
}
- buffer_handle_t srcBuffer = NULL; // for MetaDataMode only
if (inHeader->nFilledLen > 0) {
- uint8_t *inputData = NULL;
+ const uint8_t *inputData = NULL;
if (mStoreMetaDataInBuffers) {
if (inHeader->nFilledLen != 8) {
ALOGE("MetaData buffer is wrong size! "
@@ -691,24 +668,25 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {
return;
}
inputData =
- extractGrallocData(inHeader->pBuffer + inHeader->nOffset,
- &srcBuffer);
+ extractGraphicBuffer(
+ mInputFrameData, (mVideoWidth * mVideoHeight * 3) >> 1,
+ inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen,
+ mVideoWidth, mVideoHeight);
if (inputData == NULL) {
ALOGE("Unable to extract gralloc buffer in metadata mode");
mSignalledError = true;
notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
return;
}
- // TODO: Verify/convert pixel format enum
} else {
- inputData = (uint8_t *)inHeader->pBuffer + inHeader->nOffset;
+ inputData = (const uint8_t *)inHeader->pBuffer + inHeader->nOffset;
+ if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar) {
+ ConvertYUV420SemiPlanarToYUV420Planar(
+ inputData, mInputFrameData, mVideoWidth, mVideoHeight);
+ inputData = mInputFrameData;
+ }
}
- if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar) {
- ConvertYUV420SemiPlanarToYUV420Planar(
- inputData, mInputFrameData, mVideoWidth, mVideoHeight);
- inputData = mInputFrameData;
- }
CHECK(inputData != NULL);
VideoEncFrameIO vin, vout;
@@ -717,7 +695,7 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {
vin.height = ((mVideoHeight + 15) >> 4) << 4;
vin.pitch = ((mVideoWidth + 15) >> 4) << 4;
vin.timestamp = (inHeader->nTimeStamp + 500) / 1000; // in ms
- vin.yChan = inputData;
+ vin.yChan = (uint8_t *)inputData;
vin.uChan = vin.yChan + vin.height * vin.pitch;
vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2);
@@ -744,7 +722,6 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {
inQueue.erase(inQueue.begin());
inInfo->mOwnedByUs = false;
- releaseGrallocData(srcBuffer);
notifyEmptyBufferDone(inHeader);
outQueue.erase(outQueue.begin());
@@ -759,47 +736,6 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {
}
}
-OMX_ERRORTYPE SoftMPEG4Encoder::getExtensionIndex(
- const char *name, OMX_INDEXTYPE *index) {
- if (!strcmp(name, "OMX.google.android.index.storeMetaDataInBuffers")) {
- *(int32_t*)index = kStoreMetaDataExtensionIndex;
- return OMX_ErrorNone;
- }
- return OMX_ErrorUndefined;
-}
-
-uint8_t *SoftMPEG4Encoder::extractGrallocData(void *data, buffer_handle_t *buffer) {
- OMX_U32 type = *(OMX_U32*)data;
- status_t res;
- if (type != kMetadataBufferTypeGrallocSource) {
- ALOGE("Data passed in with metadata mode does not have type "
- "kMetadataBufferTypeGrallocSource (%d), has type %d instead",
- kMetadataBufferTypeGrallocSource, type);
- return NULL;
- }
- buffer_handle_t imgBuffer = *(buffer_handle_t*)((uint8_t*)data + 4);
-
- const Rect rect(mVideoWidth, mVideoHeight);
- uint8_t *img;
- res = GraphicBufferMapper::get().lock(imgBuffer,
- GRALLOC_USAGE_HW_VIDEO_ENCODER,
- rect, (void**)&img);
- if (res != OK) {
- ALOGE("%s: Unable to lock image buffer %p for access", __FUNCTION__,
- imgBuffer);
- return NULL;
- }
-
- *buffer = imgBuffer;
- return img;
-}
-
-void SoftMPEG4Encoder::releaseGrallocData(buffer_handle_t buffer) {
- if (mStoreMetaDataInBuffers) {
- GraphicBufferMapper::get().unlock(buffer);
- }
-}
-
} // namespace android
android::SoftOMXComponent *createSoftOMXComponent(