X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=libstagefright%2FFFmpegExtractor%2FFFmpegExtractor.cpp;h=08fa7a2b78e74d28227f188d0eff4750f170562e;hb=4fcb5f072bf1232475a99b428ad543d8342449aa;hp=28cbeede31745358be7bcc2223558a708bac9e2b;hpb=ff31be5c5bd5864434d98159569534b327ef129a;p=android-x86%2Fexternal-stagefright-plugins.git diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp index 28cbeed..08fa7a2 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp @@ -375,7 +375,7 @@ static uint32_t get_sample_rate(const uint8_t sf_index) int FFmpegExtractor::check_extradata(AVCodecContext *avctx) { - enum AVCodecID codec_id = CODEC_ID_NONE; + enum AVCodecID codec_id = AV_CODEC_ID_NONE; const char *name = NULL; bool *defersToCreateTrack = NULL; AVBitStreamFilterContext **bsfc = NULL; @@ -392,16 +392,16 @@ int FFmpegExtractor::check_extradata(AVCodecContext *avctx) codec_id = avctx->codec_id; // ignore extradata - if (codec_id != CODEC_ID_H264 - && codec_id != CODEC_ID_MPEG4 - && codec_id != CODEC_ID_MPEG1VIDEO - && codec_id != CODEC_ID_MPEG2VIDEO - && codec_id != CODEC_ID_AAC) { + if (codec_id != AV_CODEC_ID_H264 + && codec_id != AV_CODEC_ID_MPEG4 + && codec_id != AV_CODEC_ID_MPEG1VIDEO + && codec_id != AV_CODEC_ID_MPEG2VIDEO + && codec_id != AV_CODEC_ID_AAC) { return 1; } // is extradata compatible with android? - if (codec_id != CODEC_ID_AAC) { + if (codec_id != AV_CODEC_ID_AAC) { int is_compatible = is_extradata_compatible_with_android(avctx); if (!is_compatible) { ALOGI("%s extradata is not compatible with android, should to extract it from bitstream", @@ -413,7 +413,7 @@ int FFmpegExtractor::check_extradata(AVCodecContext *avctx) return 1; } - if (codec_id == CODEC_ID_AAC) { + if (codec_id == AV_CODEC_ID_AAC) { name = "aac_adtstoasc"; } @@ -461,38 +461,41 @@ bool FFmpegExtractor::is_codec_supported(enum AVCodecID codec_id) bool supported = false; switch(codec_id) { - case CODEC_ID_H264: - case CODEC_ID_MPEG4: - case CODEC_ID_H263: - case CODEC_ID_H263P: - case CODEC_ID_H263I: - case CODEC_ID_AAC: - case CODEC_ID_AC3: - case CODEC_ID_MP1: - case CODEC_ID_MP2: - case CODEC_ID_MP3: - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - case CODEC_ID_WMV1: - case CODEC_ID_WMV2: - case CODEC_ID_WMV3: - case CODEC_ID_VC1: - case CODEC_ID_WMAV1: - case CODEC_ID_WMAV2: - case CODEC_ID_WMAPRO: - case CODEC_ID_WMALOSSLESS: - case CODEC_ID_RV20: - case CODEC_ID_RV30: - case CODEC_ID_RV40: - case CODEC_ID_COOK: - case CODEC_ID_APE: - case CODEC_ID_DTS: - case CODEC_ID_FLAC: - case CODEC_ID_FLV1: + case AV_CODEC_ID_H264: + case AV_CODEC_ID_MPEG4: + case AV_CODEC_ID_H263: + case AV_CODEC_ID_H263P: + case AV_CODEC_ID_H263I: + case AV_CODEC_ID_AAC: + case AV_CODEC_ID_AC3: + case AV_CODEC_ID_MP2: + case AV_CODEC_ID_MP3: + case AV_CODEC_ID_MPEG1VIDEO: + case AV_CODEC_ID_MPEG2VIDEO: + case AV_CODEC_ID_WMV1: + case AV_CODEC_ID_WMV2: + case AV_CODEC_ID_WMV3: + case AV_CODEC_ID_VC1: + case AV_CODEC_ID_WMAV1: + case AV_CODEC_ID_WMAV2: + case AV_CODEC_ID_WMAPRO: + case AV_CODEC_ID_WMALOSSLESS: + case AV_CODEC_ID_RV20: + case AV_CODEC_ID_RV30: + case AV_CODEC_ID_RV40: + case AV_CODEC_ID_COOK: + case AV_CODEC_ID_APE: + case AV_CODEC_ID_DTS: + case AV_CODEC_ID_FLAC: + case AV_CODEC_ID_FLV1: + case AV_CODEC_ID_VORBIS: + case AV_CODEC_ID_HEVC: + supported = true; break; default: - ALOGD("unsuppoted codec(id:0x%0x), but give it a chance", codec_id); + ALOGD("unsuppoted codec(%s), but give it a chance", + avcodec_get_name(codec_id)); //Won't promise that the following codec id can be supported. //Just give these codecs a chance. supported = true; @@ -521,10 +524,10 @@ int FFmpegExtractor::stream_component_open(int stream_index) supported = is_codec_supported(avctx->codec_id); if (!supported) { - ALOGE("unsupport the codec, id: 0x%0x", avctx->codec_id); + ALOGE("unsupport the codec(%s)", avcodec_get_name(avctx->codec_id)); return -1; } - ALOGV("support the codec"); + ALOGI("support the codec(%s)", avcodec_get_name(avctx->codec_id)); unsigned streamType; ssize_t index = mTracks.indexOfKey(stream_index); @@ -538,7 +541,7 @@ int FFmpegExtractor::stream_component_open(int stream_index) char tagbuf[32]; av_get_codec_tag_string(tagbuf, sizeof(tagbuf), avctx->codec_tag); - ALOGV("Tag %s/0x%08x with codec id '%d'\n", tagbuf, avctx->codec_tag, avctx->codec_id); + ALOGV("Tag %s/0x%08x with codec(%s)\n", tagbuf, avctx->codec_tag, avcodec_get_name(avctx->codec_id)); switch (avctx->codec_type) { case AVMEDIA_TYPE_VIDEO: @@ -574,7 +577,7 @@ int FFmpegExtractor::stream_component_open(int stream_index) meta = new MetaData; switch(avctx->codec_id) { - case CODEC_ID_H264: + case AV_CODEC_ID_H264: /** * H.264 Video Types * http://msdn.microsoft.com/en-us/library/dd757808(v=vs.85).aspx @@ -610,7 +613,7 @@ int FFmpegExtractor::stream_component_open(int stream_index) meta = MakeAVCCodecSpecificData(buffer); } break; - case CODEC_ID_MPEG4: + case AV_CODEC_ID_MPEG4: ALOGV("MPEG4"); meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); { @@ -620,15 +623,15 @@ int FFmpegExtractor::stream_component_open(int stream_index) meta->setData(kKeyESDS, kTypeESDS, esds->data(), esds->size()); } break; - case CODEC_ID_H263: - case CODEC_ID_H263P: - case CODEC_ID_H263I: + case AV_CODEC_ID_H263: + case AV_CODEC_ID_H263P: + case AV_CODEC_ID_H263I: ALOGV("H263"); meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); break; - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - ALOGV("MPEG%dVIDEO", avctx->codec_id == CODEC_ID_MPEG2VIDEO ? 2 : 1); + case AV_CODEC_ID_MPEG1VIDEO: + case AV_CODEC_ID_MPEG2VIDEO: + ALOGV("MPEG%dVIDEO", avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO ? 2 : 1); meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2); { sp csd = new ABuffer(avctx->extradata_size); @@ -637,50 +640,55 @@ int FFmpegExtractor::stream_component_open(int stream_index) meta->setData(kKeyESDS, kTypeESDS, esds->data(), esds->size()); } break; - case CODEC_ID_VC1: + case AV_CODEC_ID_VC1: ALOGV("VC1"); meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VC1); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); break; - case CODEC_ID_WMV1: + case AV_CODEC_ID_WMV1: ALOGV("WMV1"); meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_WMV); meta->setInt32(kKeyWMVVersion, kTypeWMVVer_7); break; - case CODEC_ID_WMV2: + case AV_CODEC_ID_WMV2: ALOGV("WMV2"); meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_WMV); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); meta->setInt32(kKeyWMVVersion, kTypeWMVVer_8); break; - case CODEC_ID_WMV3: + case AV_CODEC_ID_WMV3: ALOGV("WMV3"); meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_WMV); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); meta->setInt32(kKeyWMVVersion, kTypeWMVVer_9); break; - case CODEC_ID_RV20: + case AV_CODEC_ID_RV20: ALOGV("RV30"); meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RV); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); meta->setInt32(kKeyRVVersion, kTypeRVVer_G2); //http://en.wikipedia.org/wiki/RealVideo - case CODEC_ID_RV30: + case AV_CODEC_ID_RV30: ALOGV("RV30"); meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RV); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); meta->setInt32(kKeyRVVersion, kTypeRVVer_8); //http://en.wikipedia.org/wiki/RealVideo break; - case CODEC_ID_RV40: + case AV_CODEC_ID_RV40: ALOGV("RV40"); meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RV); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); meta->setInt32(kKeyRVVersion, kTypeRVVer_9); //http://en.wikipedia.org/wiki/RealVideo break; - case CODEC_ID_FLV1: + case AV_CODEC_ID_FLV1: ALOGV("FLV1"); meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_FLV1); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); break; + case AV_CODEC_ID_HEVC: + ALOGV("HEVC"); + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + break; default: ALOGD("unsuppoted video codec(id:%d, name:%s), but give it a chance", avctx->codec_id, avcodec_get_name(avctx->codec_id)); @@ -747,34 +755,35 @@ int FFmpegExtractor::stream_component_open(int stream_index) } if (avctx->extradata) { - ALOGV("audio stream extradata:"); + ALOGV("audio stream extradata(%d):", avctx->extradata_size); hexdump(avctx->extradata, avctx->extradata_size); } else { ALOGV("audio stream no extradata, but we can ignore it."); } switch(avctx->codec_id) { - case CODEC_ID_MP1: - ALOGV("MP1"); - meta = new MetaData; - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I); - break; - case CODEC_ID_MP2: + case AV_CODEC_ID_MP2: ALOGV("MP2"); meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II); break; - case CODEC_ID_MP3: + case AV_CODEC_ID_MP3: ALOGV("MP3"); meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); break; - case CODEC_ID_AC3: + case AV_CODEC_ID_VORBIS: + ALOGV("VORBIS"); + meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + break; + case AV_CODEC_ID_AC3: ALOGV("AC3"); meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3); break; - case CODEC_ID_AAC: + case AV_CODEC_ID_AAC: ALOGV("AAC"); uint32_t sr; const uint8_t *header; @@ -801,52 +810,52 @@ int FFmpegExtractor::stream_component_open(int stream_index) meta = MakeAACCodecSpecificData(profile, sf_index, channel); meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); break; - case CODEC_ID_WMAV1: // TODO, version? + case AV_CODEC_ID_WMAV1: // TODO, version? ALOGV("WMAV1"); meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_WMA); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); break; - case CODEC_ID_WMAV2: + case AV_CODEC_ID_WMAV2: ALOGV("WMAV2"); meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_WMA); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); meta->setInt32(kKeyWMAVersion, kTypeWMA); break; - case CODEC_ID_WMAPRO: + case AV_CODEC_ID_WMAPRO: ALOGV("WMAPRO"); meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_WMA); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); meta->setInt32(kKeyWMAVersion, kTypeWMAPro); break; - case CODEC_ID_WMALOSSLESS: + case AV_CODEC_ID_WMALOSSLESS: ALOGV("WMALOSSLESS"); meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_WMA); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); meta->setInt32(kKeyWMAVersion, kTypeWMALossLess); break; - case CODEC_ID_COOK: // audio codec in RMVB + case AV_CODEC_ID_COOK: // audio codec in RMVB ALOGV("COOK"); meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RA); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); break; - case CODEC_ID_APE: + case AV_CODEC_ID_APE: ALOGV("APE"); meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_APE); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); break; - case CODEC_ID_DTS: + case AV_CODEC_ID_DTS: ALOGV("DTS"); meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_DTS); meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); break; - case CODEC_ID_FLAC: + case AV_CODEC_ID_FLAC: ALOGV("FLAC"); meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC); @@ -1012,16 +1021,6 @@ int FFmpegExtractor::decode_interrupt_cb(void *ctx) return extrator->mAbortRequest; } -void FFmpegExtractor::print_error_ex(const char *filename, int err) -{ - char errbuf[128]; - const char *errbuf_ptr = errbuf; - - if (av_strerror(err, errbuf, sizeof(errbuf)) < 0) - errbuf_ptr = strerror(AVUNERROR(err)); - ALOGI("%s: %s\n", filename, errbuf_ptr); -} - void FFmpegExtractor::buildFileName(const sp &source) { #if 1 @@ -1129,7 +1128,7 @@ int FFmpegExtractor::initStreams() ALOGV("mFilename: %s", mFilename); err = avformat_open_input(&mFormatCtx, mFilename, NULL, &format_opts); if (err < 0) { - print_error_ex(mFilename, err); + ALOGE("%s: avformat_open_input failed, err:%s", mFilename, av_err2str(err)); ret = -1; goto fail; } @@ -1148,7 +1147,7 @@ int FFmpegExtractor::initStreams() err = avformat_find_stream_info(mFormatCtx, opts); if (err < 0) { - ALOGE("%s: could not find codec parameters\n", mFilename); + ALOGE("%s: could not find stream info, err:%s", mFilename, av_err2str(err)); ret = -1; goto fail; } @@ -1607,13 +1606,21 @@ retry: key = pkt.flags & AV_PKT_FLAG_KEY ? 1 : 0; pktTS = pkt.pts; //FIXME AV_NOPTS_VALUE?? - // use dts when AVI + + //use dts when AVI if (pkt.pts == AV_NOPTS_VALUE) pktTS = pkt.dts; + //FIXME, drop, omxcodec requires a positive timestamp! e.g. vorbis + if (pktTS != AV_NOPTS_VALUE && pktTS < 0) { + ALOGW("drop the packet with negative timestamp(pts:%lld)", pktTS); + av_free_packet(&pkt); + goto retry; + } + if (waitKeyPkt) { if (!key) { - ALOGV("drop the no key packet"); + ALOGV("drop the non-key packet"); av_free_packet(&pkt); goto retry; } else { @@ -1731,6 +1738,8 @@ static formatmap FILE_FORMATS[] = { {"flac", MEDIA_MIMETYPE_CONTAINER_FLAC }, {"ac3", MEDIA_MIMETYPE_AUDIO_AC3 }, {"wav", MEDIA_MIMETYPE_CONTAINER_WAV }, + {"ogg", MEDIA_MIMETYPE_CONTAINER_OGG }, + {"hevc", MEDIA_MIMETYPE_CONTAINER_HEVC }, }; static void adjustMPEG4Confidence(AVFormatContext *ic, float *confidence) @@ -1775,12 +1784,12 @@ static void adjustAudioCodecConfidence(AVFormatContext *ic, enum AVCodecID codec_id, float *confidence) { switch (codec_id) { - case CODEC_ID_AC3: + case AV_CODEC_ID_AC3: ALOGI("ffmpeg can demux ac3 only"); *confidence = 0.88f; break; - case CODEC_ID_MP1: - case CODEC_ID_MP2: + case AV_CODEC_ID_MP1: + case AV_CODEC_ID_MP2: //TODO. if the other stream(e.g. mp3) is supported by stagefright ALOGI("ffmpeg can demux mp1 and mp2 only"); *confidence = 0.88f; @@ -1811,7 +1820,7 @@ static void adjustCodecConfidence(AVFormatContext *ic, float *confidence) } else if (codec_type == AVMEDIA_TYPE_AUDIO) { haveAudio = true; adjustAudioCodecConfidence(ic, codec_id, confidence); - if (codec_id == CODEC_ID_MP3) + if (codec_id == AV_CODEC_ID_MP3) haveMP3 = true; } } @@ -1882,7 +1891,7 @@ static const char *SniffFFMPEGCommon(const char *url, float *confidence) err = avformat_open_input(&ic, url, NULL, NULL); if (err < 0) { - ALOGE("avformat_open_input faild, url: %s err: %d", url, err); + ALOGE("%s: avformat_open_input failed, err:%s", url, av_err2str(err)); goto fail; } @@ -1890,7 +1899,7 @@ static const char *SniffFFMPEGCommon(const char *url, float *confidence) orig_nb_streams = ic->nb_streams; err = avformat_find_stream_info(ic, opts); if (err < 0) { - ALOGE("%s: could not find codec parameters", url); + ALOGE("%s: could not find stream info, err:%s", url, av_err2str(err)); goto fail; } for (i = 0; i < orig_nb_streams; i++) { @@ -1993,7 +2002,7 @@ bool SniffFFMPEG( *confidence = 0.88f; } - if (*confidence == 0.88f) { + if (*confidence > 0.08f) { (*meta)->setString("extended-extractor-use", "ffmpegextractor"); } @@ -2025,6 +2034,8 @@ MediaExtractor *CreateFFmpegExtractor(const sp &source, const char * !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_DTS) || !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MP2) || !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_RA) || + !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG) || + !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_HEVC) || !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WMA))) { ret = new FFmpegExtractor(source); }