diff options
-rw-r--r-- | cmds/stagefright/record.cpp | 7 | ||||
-rw-r--r-- | include/media/stagefright/OMXDecoder.h | 4 | ||||
-rw-r--r-- | media/libstagefright/MPEG4Writer.cpp | 7 | ||||
-rw-r--r-- | media/libstagefright/OMXDecoder.cpp | 282 |
4 files changed, 126 insertions, 174 deletions
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp index d8db8b3..cd54958 100644 --- a/cmds/stagefright/record.cpp +++ b/cmds/stagefright/record.cpp @@ -114,8 +114,8 @@ int main(int argc, char **argv) { assert(success); sp<MetaData> enc_meta = new MetaData; - // enc_meta->setCString(kKeyMIMEType, "video/3gpp"); - enc_meta->setCString(kKeyMIMEType, "video/mp4v-es"); + enc_meta->setCString(kKeyMIMEType, "video/3gpp"); + // enc_meta->setCString(kKeyMIMEType, "video/mp4v-es"); enc_meta->setInt32(kKeyWidth, width); enc_meta->setInt32(kKeyHeight, height); @@ -129,7 +129,8 @@ int main(int argc, char **argv) { MPEG4Writer writer("/sdcard/output.mp4"); writer.addSource(enc_meta, encoder); writer.start(); - sleep(120); + sleep(20); + printf("stopping now.\n"); writer.stop(); #else encoder->start(); diff --git a/include/media/stagefright/OMXDecoder.h b/include/media/stagefright/OMXDecoder.h index e76fd4c..c6b7cb3 100644 --- a/include/media/stagefright/OMXDecoder.h +++ b/include/media/stagefright/OMXDecoder.h @@ -91,8 +91,10 @@ private: sp<IOMX> mOMX; IOMX::node_id mNode; char *mComponentName; + char *mMIME; bool mIsMP3; bool mIsAVC; + bool mIsEncoder; uint32_t mQuirks; MediaSource *mSource; @@ -132,6 +134,7 @@ private: OMXDecoder(OMXClient *client, IOMX::node_id node, const char *mime, const char *codec, + bool is_encoder, uint32_t quirks); void setPortStatus(OMX_U32 port_index, PortStatus status); @@ -148,6 +151,7 @@ private: OMX_COLOR_FORMATTYPE colorFormat); void setVideoOutputFormat(const char *mime, OMX_U32 width, OMX_U32 height); + void setVideoInputFormat(const char *mime, OMX_U32 width, OMX_U32 height); void setup(); void dumpPortDefinition(OMX_U32 port_index); diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index 6bdf282..b53bb29 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -342,7 +342,12 @@ void MPEG4Writer::Track::threadEntry() { ++offset; } - assert(offset + 3 < size); + // assert(offset + 3 < size); + if (offset + 3 >= size) { + // XXX assume the entire first chunk of data is the codec specific + // data. + offset = size; + } mCodecSpecificDataSize = offset; mCodecSpecificData = malloc(offset); diff --git a/media/libstagefright/OMXDecoder.cpp b/media/libstagefright/OMXDecoder.cpp index 780cd2e..3ea3d01 100644 --- a/media/libstagefright/OMXDecoder.cpp +++ b/media/libstagefright/OMXDecoder.cpp @@ -76,9 +76,12 @@ static const CodecInfo kEncoderInfo[] = { { "audio/3gpp", "OMX.PV.amrencnb" }, { "audio/mp4a-latm", "OMX.PV.aacenc" }, { "video/mp4v-es", "OMX.qcom.video.encoder.mpeg4" }, + { "video/mp4v-es", "OMX.TI.Video.encoder" }, { "video/mp4v-es", "OMX.PV.mpeg4enc" }, { "video/3gpp", "OMX.qcom.video.encoder.h263" }, + { "video/3gpp", "OMX.TI.Video.encoder" }, { "video/3gpp", "OMX.PV.h263enc" }, + { "video/avc", "OMX.TI.Video.encoder" }, { "video/avc", "OMX.PV.avcenc" }, }; @@ -158,7 +161,8 @@ OMXDecoder *OMXDecoder::Create( quirks |= kMeasuresTimeInMilliseconds; } - OMXDecoder *decoder = new OMXDecoder(client, node, mime, codec, quirks); + OMXDecoder *decoder = new OMXDecoder( + client, node, mime, codec, createEncoder, quirks); uint32_t type; const void *data; @@ -166,7 +170,7 @@ OMXDecoder *OMXDecoder::Create( if (meta->findData(kKeyESDS, &type, &data, &size)) { ESDS esds((const char *)data, size); assert(esds.InitCheck() == OK); - + const void *codec_specific_data; size_t codec_specific_data_size; esds.getCodecSpecificInfo( @@ -211,13 +215,16 @@ OMXDecoder *OMXDecoder::Create( OMXDecoder::OMXDecoder(OMXClient *client, IOMX::node_id node, const char *mime, const char *codec, + bool is_encoder, uint32_t quirks) : mClient(client), mOMX(mClient->interface()), mNode(node), mComponentName(strdup(codec)), + mMIME(strdup(mime)), mIsMP3(!strcasecmp(mime, "audio/mpeg")), mIsAVC(!strcasecmp(mime, "video/avc")), + mIsEncoder(is_encoder), mQuirks(quirks), mSource(NULL), mCodecSpecificDataIterator(mCodecSpecificData.begin()), @@ -252,6 +259,9 @@ OMXDecoder::~OMXDecoder() { assert(err == OK); mNode = 0; + free(mMIME); + mMIME = NULL; + free(mComponentName); mComponentName = NULL; } @@ -512,6 +522,27 @@ status_t OMXDecoder::setVideoPortFormatType( // The following assertion is violated by TI's video decoder. // assert(format.nIndex == index); +#if 1 + LOGI("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d", + portIndex, + index, format.eCompressionFormat, format.eColorFormat); +#endif + + if (!strcmp("OMX.TI.Video.encoder", mComponentName)) { + if (portIndex == kPortIndexInput + && colorFormat == format.eColorFormat) { + // eCompressionFormat does not seem right. + found = true; + break; + } + if (portIndex == kPortIndexOutput + && compressionFormat == format.eCompressionFormat) { + // eColorFormat does not seem right. + found = true; + break; + } + } + if (format.eCompressionFormat == compressionFormat && format.eColorFormat == colorFormat) { found = true; @@ -525,6 +556,7 @@ status_t OMXDecoder::setVideoPortFormatType( return UNKNOWN_ERROR; } + LOGI("found a match."); status_t err = mOMX->set_parameter( mNode, OMX_IndexParamVideoPortFormat, &format, sizeof(format)); @@ -532,103 +564,51 @@ status_t OMXDecoder::setVideoPortFormatType( return err; } -#if 1 -void OMXDecoder::setVideoOutputFormat( +void OMXDecoder::setVideoInputFormat( const char *mime, OMX_U32 width, OMX_U32 height) { - LOGI("setVideoOutputFormat width=%ld, height=%ld", width, height); - -#if 1 - // Enabling this code appears to be the right thing(tm), but,... - // the TI decoder then loses the ability to output YUV420 and only outputs - // YCbYCr (16bit) - if (!strcasecmp("video/avc", mime)) { - OMX_PARAM_COMPONENTROLETYPE role; - role.nSize = sizeof(role); - role.nVersion.s.nVersionMajor = 1; - role.nVersion.s.nVersionMinor = 1; - strncpy((char *)role.cRole, "video_decoder.avc", - OMX_MAX_STRINGNAME_SIZE - 1); - role.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; - - status_t err = mOMX->set_parameter( - mNode, OMX_IndexParamStandardComponentRole, - &role, sizeof(role)); - assert(err == OK); - } -#endif + LOGI("setVideoInputFormat width=%ld, height=%ld", width, height); OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; - if (!strcasecmp("video/avc", mime)) { + if (!strcasecmp("video/avc", mMIME)) { compressionFormat = OMX_VIDEO_CodingAVC; - } else if (!strcasecmp("video/mp4v-es", mime)) { + } else if (!strcasecmp("video/mp4v-es", mMIME)) { compressionFormat = OMX_VIDEO_CodingMPEG4; - } else if (!strcasecmp("video/3gpp", mime)) { + } else if (!strcasecmp("video/3gpp", mMIME)) { compressionFormat = OMX_VIDEO_CodingH263; } else { + LOGE("Not a supported video mime type: %s", mime); assert(!"Should not be here. Not a supported video mime type."); } - setVideoPortFormatType( - kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); - -#if 1 - { - OMX_VIDEO_PARAM_PORTFORMATTYPE format; - format.nSize = sizeof(format); - format.nVersion.s.nVersionMajor = 1; - format.nVersion.s.nVersionMinor = 1; - format.nPortIndex = kPortIndexOutput; - format.nIndex = 0; - - status_t err = mOMX->get_parameter( - mNode, OMX_IndexParamVideoPortFormat, - &format, sizeof(format)); - assert(err == OK); - - assert(format.eCompressionFormat == OMX_VIDEO_CodingUnused); - - static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; + OMX_COLOR_FORMATTYPE colorFormat = + 0 ? OMX_COLOR_FormatYCbYCr : OMX_COLOR_FormatCbYCrY; - assert(format.eColorFormat == OMX_COLOR_FormatYUV420Planar - || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar - || format.eColorFormat == OMX_COLOR_FormatCbYCrY - || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar); + setVideoPortFormatType( + kPortIndexInput, OMX_VIDEO_CodingUnused, + colorFormat); - err = mOMX->set_parameter( - mNode, OMX_IndexParamVideoPortFormat, - &format, sizeof(format)); - assert(err == OK); - } -#endif + setVideoPortFormatType( + kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused); OMX_PARAM_PORTDEFINITIONTYPE def; OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; - bool is_encoder = strstr(mComponentName, ".encoder.") != NULL; // XXX - def.nSize = sizeof(def); def.nVersion.s.nVersionMajor = 1; def.nVersion.s.nVersionMinor = 1; - def.nPortIndex = is_encoder ? kPortIndexOutput : kPortIndexInput; + def.nPortIndex = kPortIndexOutput; status_t err = mOMX->get_parameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); assert(err == NO_ERROR); -#if 1 - // XXX Need a (much) better heuristic to compute input buffer sizes. - const size_t X = 64 * 1024; - if (def.nBufferSize < X) { - def.nBufferSize = X; - } -#endif - assert(def.eDomain == OMX_PortDomainVideo); - + video_def->nFrameWidth = width; video_def->nFrameHeight = height; + video_def->eCompressionFormat = compressionFormat; video_def->eColorFormat = OMX_COLOR_FormatUnused; err = mOMX->set_parameter( @@ -640,96 +620,37 @@ void OMXDecoder::setVideoOutputFormat( def.nSize = sizeof(def); def.nVersion.s.nVersionMajor = 1; def.nVersion.s.nVersionMinor = 1; - def.nPortIndex = is_encoder ? kPortIndexInput : kPortIndexOutput; + def.nPortIndex = kPortIndexInput; err = mOMX->get_parameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); assert(err == NO_ERROR); + def.nBufferSize = (width * height * 2); // (width * height * 3) / 2; + LOGI("setting nBufferSize = %ld", def.nBufferSize); + assert(def.eDomain == OMX_PortDomainVideo); - -#if 0 - def.nBufferSize = - (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420 -#endif video_def->nFrameWidth = width; video_def->nFrameHeight = height; + video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; + video_def->eColorFormat = colorFormat; err = mOMX->set_parameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); assert(err == NO_ERROR); } -#else -static void hexdump(const void *_data, size_t size) { - char line[256]; - char tmp[16]; - - const uint8_t *data = (const uint8_t *)_data; - size_t offset = 0; - while (offset < size) { - sprintf(line, "0x%04x ", offset); - - size_t n = size - offset; - if (n > 16) { - n = 16; - } - - for (size_t i = 0; i < 16; ++i) { - if (i == 8) { - strcat(line, " "); - } - - if (offset + i < size) { - sprintf(tmp, "%02x ", data[offset + i]); - strcat(line, tmp); - } else { - strcat(line, " "); - } - } - - strcat(line, " "); - - for (size_t i = 0; i < n; ++i) { - if (isprint(data[offset + i])) { - sprintf(tmp, "%c", data[offset + i]); - strcat(line, tmp); - } else { - strcat(line, "."); - } - } - - LOGI(line); - - offset += 16; - } -} - -static void DumpPortDefinitionType(const void *_param) { - OMX_PARAM_PORTDEFINITIONTYPE *param = (OMX_PARAM_PORTDEFINITIONTYPE *)_param; - - LOGI("nPortIndex=%ld eDir=%s nBufferCountActual=%ld nBufferCountMin=%ld nBufferSize=%ld", param->nPortIndex, param->eDir == OMX_DirInput ? "input" : "output", - param->nBufferCountActual, param->nBufferCountMin, param->nBufferSize); - - if (param->eDomain == OMX_PortDomainVideo) { - OMX_VIDEO_PORTDEFINITIONTYPE *video = ¶m->format.video; - LOGI("nFrameWidth=%ld nFrameHeight=%ld nStride=%ld nSliceHeight=%ld nBitrate=%ld xFramerate=%ld eCompressionFormat=%d eColorFormat=%d", - video->nFrameWidth, video->nFrameHeight, video->nStride, video->nSliceHeight, video->nBitrate, video->xFramerate, video->eCompressionFormat, video->eColorFormat); - } else { - hexdump(param, param->nSize); - } -} - void OMXDecoder::setVideoOutputFormat( const char *mime, OMX_U32 width, OMX_U32 height) { LOGI("setVideoOutputFormat width=%ld, height=%ld", width, height); -#if 0 +#if 1 // Enabling this code appears to be the right thing(tm), but,... - // the decoder then loses the ability to output YUV420 and only outputs + // the TI decoder then loses the ability to output YUV420 and only outputs // YCbYCr (16bit) - { + if (!strcmp("OMX.TI.Video.Decoder", mComponentName) + && !strcasecmp("video/avc", mime)) { OMX_PARAM_COMPONENTROLETYPE role; role.nSize = sizeof(role); role.nVersion.s.nVersionMajor = 1; @@ -745,8 +666,20 @@ void OMXDecoder::setVideoOutputFormat( } #endif + OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; + if (!strcasecmp("video/avc", mime)) { + compressionFormat = OMX_VIDEO_CodingAVC; + } else if (!strcasecmp("video/mp4v-es", mime)) { + compressionFormat = OMX_VIDEO_CodingMPEG4; + } else if (!strcasecmp("video/3gpp", mime)) { + compressionFormat = OMX_VIDEO_CodingH263; + } else { + LOGE("Not a supported video mime type: %s", mime); + assert(!"Should not be here. Not a supported video mime type."); + } + setVideoPortFormatType( - kPortIndexInput, OMX_VIDEO_CodingAVC, OMX_COLOR_FormatUnused); + kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); #if 1 { @@ -762,13 +695,14 @@ void OMXDecoder::setVideoOutputFormat( &format, sizeof(format)); assert(err == OK); - LOGI("XXX MyOMX_GetParameter OMX_IndexParamVideoPortFormat"); - hexdump(&format, format.nSize); - assert(format.eCompressionFormat == OMX_VIDEO_CodingUnused); + + static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; + assert(format.eColorFormat == OMX_COLOR_FormatYUV420Planar || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar - || format.eColorFormat == OMX_COLOR_FormatCbYCrY); + || format.eColorFormat == OMX_COLOR_FormatCbYCrY + || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar); err = mOMX->set_parameter( mNode, OMX_IndexParamVideoPortFormat, @@ -777,60 +711,64 @@ void OMXDecoder::setVideoOutputFormat( } #endif - OMX_PORT_PARAM_TYPE ptype; - ptype.nSize = sizeof(ptype); - ptype.nVersion.s.nVersionMajor = 1; - ptype.nVersion.s.nVersionMinor = 1; - - status_t err = mOMX->get_parameter( - mNode, OMX_IndexParamVideoInit, &ptype, sizeof(ptype)); - assert(err == OK); - - LOGI("XXX MyOMX_GetParameter OMX_IndexParamVideoInit"); - hexdump(&ptype, ptype.nSize); - OMX_PARAM_PORTDEFINITIONTYPE def; + OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; + def.nSize = sizeof(def); def.nVersion.s.nVersionMajor = 1; def.nVersion.s.nVersionMinor = 1; def.nPortIndex = kPortIndexInput; - err = mOMX->get_parameter( + status_t err = mOMX->get_parameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - assert(err == OK); - LOGI("XXX MyOMX_GetParameter OMX_IndexParamPortDefinition"); - DumpPortDefinitionType(&def); + assert(err == NO_ERROR); + +#if 1 + // XXX Need a (much) better heuristic to compute input buffer sizes. + const size_t X = 64 * 1024; + if (def.nBufferSize < X) { + def.nBufferSize = X; + } +#endif + + assert(def.eDomain == OMX_PortDomainVideo); - OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; video_def->nFrameWidth = width; video_def->nFrameHeight = height; + video_def->eColorFormat = OMX_COLOR_FormatUnused; + err = mOMX->set_parameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - assert(err == OK); + assert(err == NO_ERROR); //////////////////////////////////////////////////////////////////////////// + def.nSize = sizeof(def); + def.nVersion.s.nVersionMajor = 1; + def.nVersion.s.nVersionMinor = 1; def.nPortIndex = kPortIndexOutput; err = mOMX->get_parameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - assert(err == OK); + assert(err == NO_ERROR); + + assert(def.eDomain == OMX_PortDomainVideo); - LOGI("XXX MyOMX_GetParameter OMX_IndexParamPortDefinition"); - DumpPortDefinitionType(&def); +#if 0 + def.nBufferSize = + (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420 +#endif video_def->nFrameWidth = width; video_def->nFrameHeight = height; err = mOMX->set_parameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - assert(err == OK); + assert(err == NO_ERROR); } -#endif - void OMXDecoder::setup() { const sp<MetaData> &meta = mSource->getFormat(); @@ -848,7 +786,11 @@ void OMXDecoder::setup() { success = success && meta->findInt32(kKeyHeight, &height); assert(success); - setVideoOutputFormat(mime, width, height); + if (mIsEncoder) { + setVideoInputFormat(mime, width, height); + } else { + setVideoOutputFormat(mime, width, height); + } } // dumpPortDefinition(0); @@ -1253,7 +1195,7 @@ void OMXDecoder::initiateShutdown() { if (mShutdownInitiated) { return; } - + if (mState == OMX_StateLoaded) { return; } |