Loading cmds/stagefright/record.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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(); Loading include/media/stagefright/OMXDecoder.h +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); Loading media/libstagefright/MPEG4Writer.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -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); Loading media/libstagefright/OMXDecoder.cpp +112 −170 Original line number Diff line number Diff line Loading @@ -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" }, }; Loading Loading @@ -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; Loading Loading @@ -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()), Loading Loading @@ -252,6 +259,9 @@ OMXDecoder::~OMXDecoder() { assert(err == OK); mNode = 0; free(mMIME); mMIME = NULL; free(mComponentName); mComponentName = NULL; } Loading Loading @@ -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; Loading @@ -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)); Loading @@ -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); OMX_COLOR_FORMATTYPE colorFormat = 0 ? OMX_COLOR_FormatYCbYCr : OMX_COLOR_FormatCbYCrY; #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; 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( Loading @@ -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); assert(def.eDomain == OMX_PortDomainVideo); def.nBufferSize = (width * height * 2); // (width * height * 3) / 2; LOGI("setting nBufferSize = %ld", def.nBufferSize); #if 0 def.nBufferSize = (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420 #endif assert(def.eDomain == OMX_PortDomainVideo); 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; Loading @@ -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 { Loading @@ -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, Loading @@ -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(); Loading @@ -848,8 +786,12 @@ void OMXDecoder::setup() { success = success && meta->findInt32(kKeyHeight, &height); assert(success); if (mIsEncoder) { setVideoInputFormat(mime, width, height); } else { setVideoOutputFormat(mime, width, height); } } // dumpPortDefinition(0); // dumpPortDefinition(1); Loading Loading
cmds/stagefright/record.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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(); Loading
include/media/stagefright/OMXDecoder.h +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); Loading
media/libstagefright/MPEG4Writer.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
media/libstagefright/OMXDecoder.cpp +112 −170 Original line number Diff line number Diff line Loading @@ -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" }, }; Loading Loading @@ -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; Loading Loading @@ -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()), Loading Loading @@ -252,6 +259,9 @@ OMXDecoder::~OMXDecoder() { assert(err == OK); mNode = 0; free(mMIME); mMIME = NULL; free(mComponentName); mComponentName = NULL; } Loading Loading @@ -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; Loading @@ -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)); Loading @@ -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); OMX_COLOR_FORMATTYPE colorFormat = 0 ? OMX_COLOR_FormatYCbYCr : OMX_COLOR_FormatCbYCrY; #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; 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( Loading @@ -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); assert(def.eDomain == OMX_PortDomainVideo); def.nBufferSize = (width * height * 2); // (width * height * 3) / 2; LOGI("setting nBufferSize = %ld", def.nBufferSize); #if 0 def.nBufferSize = (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420 #endif assert(def.eDomain == OMX_PortDomainVideo); 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; Loading @@ -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 { Loading @@ -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, Loading @@ -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(); Loading @@ -848,8 +786,12 @@ void OMXDecoder::setup() { success = success && meta->findInt32(kKeyHeight, &height); assert(success); if (mIsEncoder) { setVideoInputFormat(mime, width, height); } else { setVideoOutputFormat(mime, width, height); } } // dumpPortDefinition(0); // dumpPortDefinition(1); Loading