OSDN Git Service

add support for ape decoder
authorMichael Chen <omxcodec@gmail.com>
Thu, 4 Apr 2013 11:50:21 +0000 (19:50 +0800)
committerMichael Chen <omxcodec@gmail.com>
Thu, 4 Apr 2013 11:50:21 +0000 (19:50 +0800)
libstagefright/FFmpegExtractor/FFmpegExtractor.cpp
libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp

index ed4c838..314316b 100644 (file)
@@ -491,6 +491,7 @@ int FFmpegExtractor::stream_component_open(int stream_index)
     case CODEC_ID_WMALOSSLESS:
     case CODEC_ID_RV40:
     case CODEC_ID_COOK:
+    case CODEC_ID_APE:
         supported = true;
         break;
     default:
@@ -646,7 +647,8 @@ int FFmpegExtractor::stream_component_open(int stream_index)
             break;
         }
 
-        LOGI("width: %d, height: %d, bit_rate: %d", avctx->width, avctx->height, avctx->bit_rate);
+        LOGI("width: %d, height: %d, bit_rate: %d",
+             avctx->width, avctx->height, avctx->bit_rate);
 
         meta->setInt32(kKeyWidth, avctx->width);
         meta->setInt32(kKeyHeight, avctx->height);
@@ -780,15 +782,23 @@ int FFmpegExtractor::stream_component_open(int stream_index)
             meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RA);
             meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size);
             break;
+        case CODEC_ID_APE:
+            LOGV("APE");
+            meta = new MetaData;
+            meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_APE);
+            meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size);
+            break;
         default:
             CHECK(!"Should not be here. Unsupported codec.");
             break;
         }
 
-        LOGI("bit_rate: %d, sample_rate: %d, channels: %d", avctx->bit_rate, avctx->sample_rate, avctx->channels);
+        LOGI("bit_rate: %d, sample_rate: %d, channels: %d, bits_per_coded_sample: %d",
+             avctx->bit_rate, avctx->sample_rate, avctx->channels, avctx->bits_per_coded_sample);
 
         meta->setInt32(kKeySampleRate, avctx->sample_rate);
         meta->setInt32(kKeyChannelCount, avctx->channels);
+        meta->setInt32(kKeyBitspersample, avctx->bits_per_coded_sample);
         meta->setInt32(kKeyBitRate, avctx->bit_rate);
         meta->setInt32(kKeyBlockAlign, avctx->block_align);
         if (mAudioStream->duration != AV_NOPTS_VALUE) {
@@ -1658,6 +1668,7 @@ static formatmap FILE_FORMATS[] = {
         {"rm",                      MEDIA_MIMETYPE_CONTAINER_RM  },
         {"flv",                     MEDIA_MIMETYPE_CONTAINER_FLV },
         {"avi",                     MEDIA_MIMETYPE_CONTAINER_AVI },
+        {"ape",                     MEDIA_MIMETYPE_CONTAINER_APE },
 };
 
 const char *BetterSniffFFMPEG(const char * uri)
index beaccaa..7445edb 100644 (file)
@@ -94,9 +94,12 @@ SoftFFmpegAudio::SoftFFmpegAudio(
         mMode = MODE_DTS;
     } else if (!strcmp(name, "OMX.ffmpeg.ra.decoder")) {
         mMode = MODE_RA;
-    } else {
-        CHECK(!strcmp(name, "OMX.ffmpeg.ac3.decoder"));
+    } else if (strcmp(name, "OMX.ffmpeg.ac3.decoder")) {
         mMode = MODE_AC3;
+    } else if (!strcmp(name, "OMX.ffmpeg.ape.decoder")) {
+        mMode = MODE_APE;
+    } else {
+        TRESPASS();
     }
 
     LOGV("SoftFFmpegAudio component: %s", name);
@@ -121,6 +124,8 @@ void SoftFFmpegAudio::initPorts() {
     def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
     def.nBufferSize = 8192;
+    if (mMode == MODE_APE)
+        def.nBufferSize = 200000; // large!
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainAudio;
@@ -158,6 +163,10 @@ void SoftFFmpegAudio::initPorts() {
         def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_RA);
         def.format.audio.eEncoding = OMX_AUDIO_CodingRA;
         break;
+    case MODE_APE:
+        def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_APE);
+        def.format.audio.eEncoding = OMX_AUDIO_CodingAPE;
+        break;
     default:
         CHECK(!"Should not be here. Unsupported mime type and compression format");
         break;
@@ -246,6 +255,9 @@ status_t SoftFFmpegAudio::initDecoder() {
     case MODE_RA:
         mCtx->codec_id = CODEC_ID_COOK; // FIXME
         break;
+    case MODE_APE:
+        mCtx->codec_id = CODEC_ID_APE;
+        break;
     default:
         CHECK(!"Should not be here. Unsupported codec");
         break;
@@ -355,6 +367,20 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalGetParameter(
 
             return OMX_ErrorNone;
         }
+        case OMX_IndexParamAudioApe:
+        {
+            OMX_AUDIO_PARAM_APETYPE *apeParams =
+                (OMX_AUDIO_PARAM_APETYPE *)params;
+
+            if (apeParams->nPortIndex != 0) {
+                return OMX_ErrorUndefined;
+            }
+
+            apeParams->nChannels = 0;
+            apeParams->nSamplingRate = 0;
+
+            return OMX_ErrorNone;
+        }
         case OMX_IndexParamAudioPcm:
         {
             OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
@@ -448,6 +474,11 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
                         "audio_decoder.ra", OMX_MAX_STRINGNAME_SIZE - 1))
                     supported =  false;
                 break;
+            case MODE_APE:
+                if (strncmp((const char *)roleParams->cRole,
+                        "audio_decoder.ape", OMX_MAX_STRINGNAME_SIZE - 1))
+                    supported =  false;
+                break;
             default:
                 CHECK(!"Should not be here. Unsupported role.");
                 break;
@@ -578,6 +609,43 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
 
             return OMX_ErrorNone;
         }
+        case OMX_IndexParamAudioApe:
+        {
+            OMX_AUDIO_PARAM_APETYPE *apeParams =
+                (OMX_AUDIO_PARAM_APETYPE *)params;
+
+            if (apeParams->nPortIndex != 0) {
+                return OMX_ErrorUndefined;
+            }
+
+            mCtx->codec_id = CODEC_ID_APE;
+
+            mNumChannels = apeParams->nChannels;
+            mSamplingRate = apeParams->nSamplingRate;
+
+            // ape decoder need bits_per_coded_sample
+            mCtx->bits_per_coded_sample = apeParams->nBitsPerSample;
+
+            channels = mNumChannels >= 2 ? 2 : 1;
+            sampling_rate = mSamplingRate;
+            // 4000 <= nSamplingRate <= 48000
+            if (mSamplingRate < 4000) {
+                sampling_rate = 4000;
+            } else if (mSamplingRate > 48000) {
+                sampling_rate = 48000;
+            }
+
+            // update src and target(only wma), only once!
+            mAudioSrcChannels = mAudioTgtChannels = channels;
+            mAudioSrcFreq = mAudioTgtFreq = sampling_rate;
+            mAudioSrcFmt = mAudioTgtFmt = AV_SAMPLE_FMT_S16;
+            mAudioSrcChannelLayout = mAudioTgtChannelLayout = av_get_default_channel_layout(channels);
+
+            LOGV("got OMX_IndexParamAudioApe, mNumChannels: %d, mSamplingRate: %d, nBitsPerSample: %d",
+                mNumChannels, mSamplingRate, apeParams->nBitsPerSample);
+
+            return OMX_ErrorNone;
+        }
         default:
             LOGI("internalSetParameter, index: 0x%x", index);
             return SimpleSoftOMXComponent::internalSetParameter(index, params);
@@ -690,6 +758,7 @@ void SoftFFmpegAudio::onQueueFilled(OMX_U32 portIndex) {
             LOGI("open ffmpeg decoder now");
             err = avcodec_open2(mCtx, mCtx->codec, NULL);
             if (err < 0) {
+                print_error("avcodec_open2", err);
                 LOGE("ffmpeg audio decoder failed to initialize. (%d)", err);
                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
                 mSignalledError = true;