From 94705aff3c9eef58cbb72ec6fe5d2dcfd9481646 Mon Sep 17 00:00:00 2001 From: hkuang Date: Mon, 24 Jun 2013 11:21:17 -0700 Subject: Adds VP9 decoding support for stagefright. Also change the VP8 encoder role name from video_encoder.vpx to video_encoder.vp8 for future VP9 encoder support. Requires the change in frameworks/native and media_codecs.xml corresponding to the device. VP9 decoding test will be added to cts repo later. --- cmds/stagefright/stagefright.cpp | 2 +- include/media/stagefright/MediaDefs.h | 3 ++- media/libstagefright/ACodec.cpp | 9 +++++--- media/libstagefright/MediaDefs.cpp | 3 ++- media/libstagefright/OMXCodec.cpp | 12 +++++++---- media/libstagefright/codecs/on2/dec/SoftVPX.cpp | 25 +++++++++++++++++----- media/libstagefright/codecs/on2/dec/SoftVPX.h | 7 ++++++ .../codecs/on2/enc/SoftVPXEncoder.cpp | 10 ++++----- .../libstagefright/codecs/on2/enc/SoftVPXEncoder.h | 2 +- .../libstagefright/matroska/MatroskaExtractor.cpp | 4 +++- media/libstagefright/omx/SoftOMXPlugin.cpp | 5 +++-- media/libstagefright/omx/tests/OMXHarness.cpp | 3 ++- 12 files changed, 60 insertions(+), 25 deletions(-) diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp index 924cf6d..f8fc8ed 100644 --- a/cmds/stagefright/stagefright.cpp +++ b/cmds/stagefright/stagefright.cpp @@ -616,7 +616,7 @@ static void dumpCodecProfiles(const sp& omx, bool queryDecoders) { MEDIA_MIMETYPE_AUDIO_AMR_NB, MEDIA_MIMETYPE_AUDIO_AMR_WB, MEDIA_MIMETYPE_AUDIO_MPEG, MEDIA_MIMETYPE_AUDIO_G711_MLAW, MEDIA_MIMETYPE_AUDIO_G711_ALAW, MEDIA_MIMETYPE_AUDIO_VORBIS, - MEDIA_MIMETYPE_VIDEO_VPX + MEDIA_MIMETYPE_VIDEO_VP8, MEDIA_MIMETYPE_VIDEO_VP9 }; const char *codecType = queryDecoders? "decoder" : "encoder"; diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h index 81de6e4..85693d4 100644 --- a/include/media/stagefright/MediaDefs.h +++ b/include/media/stagefright/MediaDefs.h @@ -22,7 +22,8 @@ namespace android { extern const char *MEDIA_MIMETYPE_IMAGE_JPEG; -extern const char *MEDIA_MIMETYPE_VIDEO_VPX; +extern const char *MEDIA_MIMETYPE_VIDEO_VP8; +extern const char *MEDIA_MIMETYPE_VIDEO_VP9; extern const char *MEDIA_MIMETYPE_VIDEO_AVC; extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4; extern const char *MEDIA_MIMETYPE_VIDEO_H263; diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index bf650b4..2466a6b 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -836,8 +836,10 @@ status_t ACodec::setComponentRole( "video_decoder.mpeg4", "video_encoder.mpeg4" }, { MEDIA_MIMETYPE_VIDEO_H263, "video_decoder.h263", "video_encoder.h263" }, - { MEDIA_MIMETYPE_VIDEO_VPX, - "video_decoder.vpx", "video_encoder.vpx" }, + { MEDIA_MIMETYPE_VIDEO_VP8, + "video_decoder.vp8", "video_encoder.vp8" }, + { MEDIA_MIMETYPE_VIDEO_VP9, + "video_decoder.vp9", "video_encoder.vp9" }, { MEDIA_MIMETYPE_AUDIO_RAW, "audio_decoder.raw", "audio_encoder.raw" }, { MEDIA_MIMETYPE_AUDIO_FLAC, @@ -1501,7 +1503,8 @@ static const struct VideoCodingMapEntry { { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 }, { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 }, { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 }, - { MEDIA_MIMETYPE_VIDEO_VPX, OMX_VIDEO_CodingVPX }, + { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 }, + { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 }, }; static status_t GetVideoCodingTypeFromMime( diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp index 5d8029c..b5d4e44 100644 --- a/media/libstagefright/MediaDefs.cpp +++ b/media/libstagefright/MediaDefs.cpp @@ -20,7 +20,8 @@ namespace android { const char *MEDIA_MIMETYPE_IMAGE_JPEG = "image/jpeg"; -const char *MEDIA_MIMETYPE_VIDEO_VPX = "video/x-vnd.on2.vp8"; +const char *MEDIA_MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8"; +const char *MEDIA_MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9"; const char *MEDIA_MIMETYPE_VIDEO_AVC = "video/avc"; const char *MEDIA_MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es"; const char *MEDIA_MIMETYPE_VIDEO_H263 = "video/3gpp"; diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 9d349a1..3de3c28 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -1195,8 +1195,10 @@ status_t OMXCodec::setVideoOutputFormat( compressionFormat = OMX_VIDEO_CodingMPEG4; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { compressionFormat = OMX_VIDEO_CodingH263; - } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) { - compressionFormat = OMX_VIDEO_CodingVPX; + } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VP8, mime)) { + compressionFormat = OMX_VIDEO_CodingVP8; + } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VP9, mime)) { + compressionFormat = OMX_VIDEO_CodingVP9; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) { compressionFormat = OMX_VIDEO_CodingMPEG2; } else { @@ -1388,8 +1390,10 @@ void OMXCodec::setComponentRole( "video_decoder.mpeg4", "video_encoder.mpeg4" }, { MEDIA_MIMETYPE_VIDEO_H263, "video_decoder.h263", "video_encoder.h263" }, - { MEDIA_MIMETYPE_VIDEO_VPX, - "video_decoder.vpx", "video_encoder.vpx" }, + { MEDIA_MIMETYPE_VIDEO_VP8, + "video_decoder.vp8", "video_encoder.vp8" }, + { MEDIA_MIMETYPE_VIDEO_VP9, + "video_decoder.vp9", "video_encoder.vp9" }, { MEDIA_MIMETYPE_AUDIO_RAW, "audio_decoder.raw", "audio_encoder.raw" }, { MEDIA_MIMETYPE_AUDIO_FLAC, diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp index 43d0263..476e986 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp @@ -31,16 +31,20 @@ namespace android { SoftVPX::SoftVPX( const char *name, + const char *componentRole, + OMX_VIDEO_CODINGTYPE codingType, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, OMX_COMPONENTTYPE **component) : SoftVideoDecoderOMXComponent( - name, "video_decoder.vpx", OMX_VIDEO_CodingVPX, + name, componentRole, codingType, NULL /* profileLevels */, 0 /* numProfileLevels */, 320 /* width */, 240 /* height */, callbacks, appData, component), + mMode(codingType == OMX_VIDEO_CodingVP8 ? MODE_VP8 : MODE_VP9), mCtx(NULL) { initPorts(kNumBuffers, 768 * 1024 /* inputBufferSize */, - kNumBuffers, MEDIA_MIMETYPE_VIDEO_VPX); + kNumBuffers, + codingType == OMX_VIDEO_CodingVP8 ? MEDIA_MIMETYPE_VIDEO_VP8 : MEDIA_MIMETYPE_VIDEO_VP9); CHECK_EQ(initDecoder(), (status_t)OK); } @@ -71,7 +75,9 @@ status_t SoftVPX::initDecoder() { memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t)); cfg.threads = GetCPUCoreCount(); if ((vpx_err = vpx_codec_dec_init( - (vpx_codec_ctx_t *)mCtx, &vpx_codec_vp8_dx_algo, &cfg, 0))) { + (vpx_codec_ctx_t *)mCtx, + mMode == MODE_VP8 ? &vpx_codec_vp8_dx_algo : &vpx_codec_vp9_dx_algo, + &cfg, 0))) { ALOGE("on2 decoder failed to initialize. (%d)", vpx_err); return UNKNOWN_ERROR; } @@ -194,6 +200,15 @@ void SoftVPX::onQueueFilled(OMX_U32 portIndex) { android::SoftOMXComponent *createSoftOMXComponent( const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, OMX_COMPONENTTYPE **component) { - return new android::SoftVPX(name, callbacks, appData, component); + if (!strcmp(name, "OMX.google.vp8.decoder")) { + return new android::SoftVPX( + name, "video_decoder.vp8", OMX_VIDEO_CodingVP8, + callbacks, appData, component); + } else if (!strcmp(name, "OMX.google.vp9.decoder")) { + return new android::SoftVPX( + name, "video_decoder.vp9", OMX_VIDEO_CodingVP9, + callbacks, appData, component); + } else { + CHECK(!"Unknown component"); + } } - diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.h b/media/libstagefright/codecs/on2/dec/SoftVPX.h index 626307b..cd5eb28 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.h +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.h @@ -24,6 +24,8 @@ namespace android { struct SoftVPX : public SoftVideoDecoderOMXComponent { SoftVPX(const char *name, + const char *componentRole, + OMX_VIDEO_CODINGTYPE codingType, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, OMX_COMPONENTTYPE **component); @@ -38,6 +40,11 @@ private: kNumBuffers = 4 }; + enum { + MODE_VP8, + MODE_VP9 + } mMode; + void *mCtx; status_t initDecoder(); diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp index e25637a..74d6df5 100644 --- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp +++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp @@ -165,8 +165,8 @@ void SoftVPXEncoder::initPorts() { outputPort.eDir = OMX_DirOutput; outputPort.nBufferAlignment = kOutputBufferAlignment; outputPort.format.video.cMIMEType = - const_cast(MEDIA_MIMETYPE_VIDEO_VPX); - outputPort.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; + const_cast(MEDIA_MIMETYPE_VIDEO_VP8); + outputPort.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8; outputPort.format.video.eColorFormat = OMX_COLOR_FormatUnused; outputPort.format.video.pNativeWindow = NULL; outputPort.nBufferSize = 256 * 1024; // arbitrary @@ -315,7 +315,7 @@ OMX_ERRORTYPE SoftVPXEncoder::internalGetParameter(OMX_INDEXTYPE index, formatParams->xFramerate = (1000000/mFrameDurationUs) << 16; return OMX_ErrorNone; } else if (formatParams->nPortIndex == kOutputPortIndex) { - formatParams->eCompressionFormat = OMX_VIDEO_CodingVPX; + formatParams->eCompressionFormat = OMX_VIDEO_CodingVP8; formatParams->eColorFormat = OMX_COLOR_FormatUnused; formatParams->xFramerate = 0; return OMX_ErrorNone; @@ -513,7 +513,7 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetFormatParams( return OMX_ErrorUnsupportedSetting; } } else if (format->nPortIndex == kOutputPortIndex) { - if (format->eCompressionFormat == OMX_VIDEO_CodingVPX) { + if (format->eCompressionFormat == OMX_VIDEO_CodingVP8) { return OMX_ErrorNone; } else { return OMX_ErrorUnsupportedSetting; @@ -529,7 +529,7 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetRoleParams( const char* roleText = (const char*)role->cRole; const size_t roleTextMaxSize = OMX_MAX_STRINGNAME_SIZE - 1; - if (strncmp(roleText, "video_encoder.vpx", roleTextMaxSize)) { + if (strncmp(roleText, "video_encoder.vp8", roleTextMaxSize)) { ALOGE("Unsupported component role"); return OMX_ErrorBadParameter; } diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h index 3bc05c0..a0a8ee6 100644 --- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h +++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h @@ -175,7 +175,7 @@ class SoftVPXEncoder : public SimpleSoftOMXComponent { const OMX_VIDEO_PARAM_PORTFORMATTYPE* format); // Verifies the component role tried to be set to this OMX component is - // strictly video_encoder.vpx + // strictly video_encoder.vp8 OMX_ERRORTYPE internalSetRoleParams( const OMX_PARAM_COMPONENTROLETYPE* role); diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp index b304749..d260d0f 100644 --- a/media/libstagefright/matroska/MatroskaExtractor.cpp +++ b/media/libstagefright/matroska/MatroskaExtractor.cpp @@ -870,7 +870,9 @@ void MatroskaExtractor::addTracks() { continue; } } else if (!strcmp("V_VP8", codecID)) { - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX); + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP8); + } else if (!strcmp("V_VP9", codecID)) { + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP9); } else { ALOGW("%s is not supported.", codecID); continue; diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp index b3fe98e..d6cde73 100644 --- a/media/libstagefright/omx/SoftOMXPlugin.cpp +++ b/media/libstagefright/omx/SoftOMXPlugin.cpp @@ -50,8 +50,9 @@ static const struct { { "OMX.google.mpeg4.encoder", "mpeg4enc", "video_encoder.mpeg4" }, { "OMX.google.mp3.decoder", "mp3dec", "audio_decoder.mp3" }, { "OMX.google.vorbis.decoder", "vorbisdec", "audio_decoder.vorbis" }, - { "OMX.google.vpx.decoder", "vpxdec", "video_decoder.vpx" }, - { "OMX.google.vpx.encoder", "vpxenc", "video_encoder.vpx" }, + { "OMX.google.vp8.decoder", "vpxdec", "video_decoder.vp8" }, + { "OMX.google.vp9.decoder", "vpxdec", "video_decoder.vp9" }, + { "OMX.google.vp8.encoder", "vpxenc", "video_encoder.vp8" }, { "OMX.google.raw.decoder", "rawdec", "audio_decoder.raw" }, { "OMX.google.flac.encoder", "flacenc", "audio_encoder.flac" }, { "OMX.google.gsm.decoder", "gsmdec", "audio_decoder.gsm" }, diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp index 6cca8da..4bee808 100644 --- a/media/libstagefright/omx/tests/OMXHarness.cpp +++ b/media/libstagefright/omx/tests/OMXHarness.cpp @@ -449,7 +449,8 @@ static const char *GetMimeFromComponentRole(const char *componentRole) { { "video_decoder.avc", "video/avc" }, { "video_decoder.mpeg4", "video/mp4v-es" }, { "video_decoder.h263", "video/3gpp" }, - { "video_decoder.vpx", "video/x-vnd.on2.vp8" }, + { "video_decoder.vp8", "video/x-vnd.on2.vp8" }, + { "video_decoder.vp9", "video/x-vnd.on2.vp9" }, // we appear to use this as a synonym to amrnb. { "audio_decoder.amr", "audio/3gpp" }, -- cgit v1.1