summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/stagefright/record.cpp39
-rw-r--r--include/media/stagefright/OMXCodec.h2
-rw-r--r--media/libstagefright/OMXCodec.cpp123
3 files changed, 151 insertions, 13 deletions
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 176dab0..0025c5e 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -32,8 +32,10 @@
using namespace android;
-#if 0
+#if 1
class DummySource : public MediaSource {
+ static const int32_t kFramerate = 24; // fps
+
public:
DummySource(int width, int height)
: mWidth(width),
@@ -52,6 +54,7 @@ public:
}
virtual status_t start(MetaData *params) {
+ mNumFramesOutput = 0;
return OK;
}
@@ -61,6 +64,12 @@ public:
virtual status_t read(
MediaBuffer **buffer, const MediaSource::ReadOptions *options) {
+ if (mNumFramesOutput == kFramerate * 10) {
+ // Stop returning data after 10 secs.
+ return ERROR_END_OF_STREAM;
+ }
+
+ // printf("DummySource::read\n");
status_t err = mGroup.acquire_buffer(buffer);
if (err != OK) {
return err;
@@ -69,7 +78,13 @@ public:
char x = (char)((double)rand() / RAND_MAX * 255);
memset((*buffer)->data(), x, mSize);
(*buffer)->set_range(0, mSize);
+ (*buffer)->meta_data()->clear();
+ (*buffer)->meta_data()->setInt64(
+ kKeyTime, (mNumFramesOutput * 1000000) / kFramerate);
+ ++mNumFramesOutput;
+ // printf("DummySource::read - returning buffer\n");
+ // LOGI("DummySource::read - returning buffer");
return OK;
}
@@ -80,6 +95,7 @@ private:
MediaBufferGroup mGroup;
int mWidth, mHeight;
size_t mSize;
+ int64_t mNumFramesOutput;;
DummySource(const DummySource &);
DummySource &operator=(const DummySource &);
@@ -144,8 +160,8 @@ int main(int argc, char **argv) {
success = success && meta->findInt32(kKeyHeight, &height);
CHECK(success);
#else
- int width = 320;
- int height = 240;
+ int width = 800;
+ int height = 480;
sp<MediaSource> decoder = new DummySource(width, height);
#endif
@@ -159,19 +175,26 @@ int main(int argc, char **argv) {
OMXCodec::Create(
client.interface(), enc_meta, true /* createEncoder */, decoder);
-#if 0
+#if 1
sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4");
- writer->addSource(enc_meta, encoder);
+ writer->addSource(encoder);
writer->start();
- sleep(20);
- printf("stopping now.\n");
+ while (!writer->reachedEOS()) {
+ usleep(100000);
+ }
writer->stop();
#else
encoder->start();
MediaBuffer *buffer;
while (encoder->read(&buffer) == OK) {
- printf("got an output frame of size %d\n", buffer->range_length());
+ int32_t isSync;
+ if (!buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)) {
+ isSync = false;
+ }
+
+ printf("got an output frame of size %d%s\n", buffer->range_length(),
+ isSync ? " (SYNC)" : "");
buffer->release();
buffer = NULL;
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index d0f4f17..7890883 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -158,6 +158,8 @@ private:
void setVideoInputFormat(
const char *mime, OMX_U32 width, OMX_U32 height);
+ status_t setupMPEG4EncoderParameters();
+
void setVideoOutputFormat(
const char *mime, OMX_U32 width, OMX_U32 height);
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 01ec973..41a9fe9 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -214,6 +214,7 @@ uint32_t OMXCodec::getComponentQuirks(const char *componentName) {
if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
quirks |= kRequiresLoadedToIdleAfterAllocation;
quirks |= kRequiresAllocateBufferOnInputPorts;
+ quirks |= kRequiresAllocateBufferOnOutputPorts;
}
if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
// XXX Required on P....on only.
@@ -562,6 +563,22 @@ status_t OMXCodec::setVideoPortFormatType(
return err;
}
+static size_t getFrameSize(
+ OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
+ switch (colorFormat) {
+ case OMX_COLOR_FormatYCbYCr:
+ case OMX_COLOR_FormatCbYCrY:
+ return width * height * 2;
+
+ case OMX_COLOR_FormatYUV420SemiPlanar:
+ return (width * height * 3) / 2;
+
+ default:
+ CHECK(!"Should not be here. Unsupported color format.");
+ break;
+ }
+}
+
void OMXCodec::setVideoInputFormat(
const char *mime, OMX_U32 width, OMX_U32 height) {
CODEC_LOGV("setVideoInputFormat width=%ld, height=%ld", width, height);
@@ -585,12 +602,13 @@ void OMXCodec::setVideoInputFormat(
colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
}
- setVideoPortFormatType(
+ CHECK_EQ(setVideoPortFormatType(
kPortIndexInput, OMX_VIDEO_CodingUnused,
- colorFormat);
+ colorFormat), OK);
- setVideoPortFormatType(
- kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
+ CHECK_EQ(setVideoPortFormatType(
+ kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
+ OK);
OMX_PARAM_PORTDEFINITIONTYPE def;
InitOMXParams(&def);
@@ -623,7 +641,7 @@ void OMXCodec::setVideoInputFormat(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
- def.nBufferSize = (width * height * 2); // (width * height * 3) / 2;
+ def.nBufferSize = getFrameSize(colorFormat, width, height);
CODEC_LOGV("Setting nBufferSize = %ld", def.nBufferSize);
CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
@@ -633,9 +651,103 @@ void OMXCodec::setVideoInputFormat(
video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
video_def->eColorFormat = colorFormat;
+ video_def->xFramerate = 24 << 16; // XXX crucial!
+
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
+
+ switch (compressionFormat) {
+ case OMX_VIDEO_CodingMPEG4:
+ {
+ CHECK_EQ(setupMPEG4EncoderParameters(), OK);
+ break;
+ }
+
+ case OMX_VIDEO_CodingH263:
+ break;
+
+ default:
+ CHECK(!"Support for this compressionFormat to be implemented.");
+ break;
+ }
+}
+
+status_t OMXCodec::setupMPEG4EncoderParameters() {
+ OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
+ InitOMXParams(&mpeg4type);
+ mpeg4type.nPortIndex = kPortIndexOutput;
+
+ status_t err = mOMX->getParameter(
+ mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
+ CHECK_EQ(err, OK);
+
+ mpeg4type.nSliceHeaderSpacing = 0;
+ mpeg4type.bSVH = OMX_FALSE;
+ mpeg4type.bGov = OMX_FALSE;
+
+ mpeg4type.nAllowedPictureTypes =
+ OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
+
+ mpeg4type.nPFrames = 23;
+ mpeg4type.nBFrames = 0;
+
+ mpeg4type.nIDCVLCThreshold = 0;
+ mpeg4type.bACPred = OMX_TRUE;
+ mpeg4type.nMaxPacketSize = 256;
+ mpeg4type.nTimeIncRes = 1000;
+ mpeg4type.nHeaderExtension = 0;
+ mpeg4type.bReversibleVLC = OMX_FALSE;
+
+ mpeg4type.eProfile = OMX_VIDEO_MPEG4ProfileCore;
+ mpeg4type.eLevel = OMX_VIDEO_MPEG4Level2;
+
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
+ CHECK_EQ(err, OK);
+
+ // ----------------
+
+ OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
+ InitOMXParams(&bitrateType);
+ bitrateType.nPortIndex = kPortIndexOutput;
+
+ err = mOMX->getParameter(
+ mNode, OMX_IndexParamVideoBitrate,
+ &bitrateType, sizeof(bitrateType));
+ CHECK_EQ(err, OK);
+
+ bitrateType.eControlRate = OMX_Video_ControlRateVariable;
+ bitrateType.nTargetBitrate = 1000000;
+
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamVideoBitrate,
+ &bitrateType, sizeof(bitrateType));
+ CHECK_EQ(err, OK);
+
+ // ----------------
+
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
+ InitOMXParams(&errorCorrectionType);
+ errorCorrectionType.nPortIndex = kPortIndexOutput;
+
+ err = mOMX->getParameter(
+ mNode, OMX_IndexParamVideoErrorCorrection,
+ &errorCorrectionType, sizeof(errorCorrectionType));
+ CHECK_EQ(err, OK);
+
+ errorCorrectionType.bEnableHEC = OMX_FALSE;
+ errorCorrectionType.bEnableResync = OMX_TRUE;
+ errorCorrectionType.nResynchMarkerSpacing = 256;
+ errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
+ errorCorrectionType.bEnableRVLC = OMX_FALSE;
+
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamVideoErrorCorrection,
+ &errorCorrectionType, sizeof(errorCorrectionType));
+ CHECK_EQ(err, OK);
+
+ return OK;
}
void OMXCodec::setVideoOutputFormat(
@@ -708,6 +820,7 @@ void OMXCodec::setVideoOutputFormat(
video_def->nFrameWidth = width;
video_def->nFrameHeight = height;
+ video_def->eCompressionFormat = compressionFormat;
video_def->eColorFormat = OMX_COLOR_FormatUnused;
err = mOMX->setParameter(