summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/stagefright/record.cpp7
-rw-r--r--include/media/stagefright/OMXDecoder.h4
-rw-r--r--media/libstagefright/MPEG4Writer.cpp7
-rw-r--r--media/libstagefright/OMXDecoder.cpp282
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 = &param->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;
}