From bf71712153a98d1ff1c2650ba7790ee2693ad4b7 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Fri, 1 Nov 2013 19:51:11 +0800 Subject: [PATCH 01/16] fix crash when ffmpeg video port notify setting change event. We don't notify event until "outQueue.size() == kNumOutputBuffers" test sample- http://samples.mplayerhq.hu/V-codecs/WVC1/rtvc1.vc1 crash log: I/SoftFFmpegVideo( 4196): ffmpeg video port setting change event(352x144)->(352x288). F/OMXCodec( 4196): frameworks/av/media/libstagefright/OMXCodec.cpp:3285 CHECK(info->mStatus == OWNED_BY_US || info->mStatus == OWNED_BY_NATIVE_WINDOW) failed. F/libc ( 4196): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 4241 (OMXCallbackDisp) --- libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp | 9 +++++---- libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp index ff6d988..4de59a6 100644 --- a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp +++ b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp @@ -918,7 +918,7 @@ int32_t SoftFFmpegVideo::drainOneOutputBuffer() { int sws_flags = SWS_BICUBIC; mImgConvertCtx = sws_getCachedContext(mImgConvertCtx, - mWidth, mHeight, mCtx->pix_fmt, mWidth, mHeight, + mWidth, mHeight, (AVPixelFormat)mFrame->format, mWidth, mHeight, PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL); if (mImgConvertCtx == NULL) { ALOGE("Cannot initialize the conversion context"); @@ -948,7 +948,7 @@ int32_t SoftFFmpegVideo::drainOneOutputBuffer() { if (pts == AV_NOPTS_VALUE) { pts = 0; } - outHeader->nTimeStamp = pts; + outHeader->nTimeStamp = pts; //FIXME pts is right??? #if DEBUG_FRM ALOGV("mFrame pts: %lld", pts); @@ -1041,7 +1041,7 @@ void SoftFFmpegVideo::onQueueFilled(OMX_U32 portIndex) { } while (((mEOSStatus != INPUT_DATA_AVAILABLE) || !inQueue.empty()) - && !outQueue.empty()) { + && outQueue.size() == kNumOutputBuffers) { if (mEOSStatus == INPUT_EOS_SEEN) { drainAllOutputBuffers(); return; @@ -1148,7 +1148,8 @@ void SoftFFmpegVideo::updatePortDefinitions() { def->format.video.nStride = def->format.video.nFrameWidth; def->format.video.nSliceHeight = def->format.video.nFrameHeight; def->nBufferSize = - def->format.video.nFrameWidth * def->format.video.nFrameHeight; + (def->format.video.nFrameWidth + * def->format.video.nFrameHeight * 3) / 2; def = &editPortInfo(1)->mDef; def->format.video.nFrameWidth = mWidth; diff --git a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h index cfb3d53..930948b 100644 --- a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h +++ b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h @@ -112,7 +112,7 @@ private: }; bool mFFmpegAlreadyInited; - bool mCodecAlreadyOpened; + bool mCodecAlreadyOpened; bool mPendingFrameAsSettingChanged; AVCodecContext *mCtx; struct SwsContext *mImgConvertCtx; -- 2.11.0 From 10528dbd0c45e225a37da2341c82915fee0b7a45 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Sat, 2 Nov 2013 20:56:05 +0800 Subject: [PATCH 02/16] add isPortSettingChanged func to check setting changed --- .../codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp | 30 ++++++++++++---- .../codecs/ffmpegdec/vdec/SoftFFmpegVideo.h | 40 ++++++++++++---------- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp index 4de59a6..3634dcb 100644 --- a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp +++ b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp @@ -81,6 +81,7 @@ SoftFFmpegVideo::SoftFFmpegVideo( mMode(MODE_NONE), mFFmpegAlreadyInited(false), mCodecAlreadyOpened(false), + mPendingSettingChangeEvent(false), mPendingFrameAsSettingChanged(false), mCtx(NULL), mImgConvertCtx(NULL), @@ -676,6 +677,10 @@ OMX_ERRORTYPE SoftFFmpegVideo::internalSetParameter( } } +bool SoftFFmpegVideo::isPortSettingChanged() { + return (mCtx->width != mWidth || mCtx->height != mHeight); +} + bool SoftFFmpegVideo::handlePortSettingChangeEvent() { if (mCtx->width != mWidth || mCtx->height != mHeight) { ALOGI("ffmpeg video port setting change event(%dx%d)->(%dx%d).", @@ -827,6 +832,8 @@ int32_t SoftFFmpegVideo::decodeVideo() { //don't send error to OMXCodec, skip! ret = ERR_NO_FRM; } else { + mPendingSettingChangeEvent = isPortSettingChanged(); + if (!gotPic) { ALOGI("ffmpeg video decoder failed to get frame."); //stop sending empty packets if the decoder is finished @@ -836,7 +843,7 @@ int32_t SoftFFmpegVideo::decodeVideo() { ret = ERR_NO_FRM; } } else { - if (handlePortSettingChangeEvent()) { + if (mPendingSettingChangeEvent) { mPendingFrameAsSettingChanged = true; } ret = ERR_OK; @@ -1008,8 +1015,8 @@ void SoftFFmpegVideo::drainAllOutputBuffers() { return; } else { CHECK_EQ(err, ERR_OK); - if (mPendingFrameAsSettingChanged) { - return; + if (mPendingSettingChangeEvent) { + return; } } } @@ -1041,10 +1048,19 @@ void SoftFFmpegVideo::onQueueFilled(OMX_U32 portIndex) { } while (((mEOSStatus != INPUT_DATA_AVAILABLE) || !inQueue.empty()) - && outQueue.size() == kNumOutputBuffers) { + && !outQueue.empty()) { + if (mPendingSettingChangeEvent) { + //fix crash! We don't notify event until wait for all output buffers + if (outQueue.size() == kNumOutputBuffers) { + CHECK(handlePortSettingChangeEvent() == true); + mPendingSettingChangeEvent = false; + } + return; + } + if (mEOSStatus == INPUT_EOS_SEEN) { drainAllOutputBuffers(); - return; + continue; } inInfo = *inQueue.begin(); @@ -1085,8 +1101,8 @@ void SoftFFmpegVideo::onQueueFilled(OMX_U32 portIndex) { continue; } else { CHECK_EQ(err, ERR_OK); - if (mPendingFrameAsSettingChanged) { - return; + if (mPendingSettingChangeEvent) { + continue; } } } diff --git a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h index 930948b..8371fa1 100644 --- a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h +++ b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h @@ -113,7 +113,8 @@ private: bool mFFmpegAlreadyInited; bool mCodecAlreadyOpened; - bool mPendingFrameAsSettingChanged; + bool mPendingSettingChangeEvent; + bool mPendingFrameAsSettingChanged; AVCodecContext *mCtx; struct SwsContext *mImgConvertCtx; AVFrame *mFrame; @@ -132,27 +133,28 @@ private: AWAITING_ENABLED } mOutputPortSettingsChange; - void setMode(const char *name); - void initInputFormat(uint32_t mode, OMX_PARAM_PORTDEFINITIONTYPE &def); - void getInputFormat(uint32_t mode, OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams); - void setDefaultCtx(AVCodecContext *avctx, const AVCodec *codec); + void setMode(const char *name); + void initInputFormat(uint32_t mode, OMX_PARAM_PORTDEFINITIONTYPE &def); + void getInputFormat(uint32_t mode, OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams); + void setDefaultCtx(AVCodecContext *avctx, const AVCodec *codec); OMX_ERRORTYPE isRoleSupported(const OMX_PARAM_COMPONENTROLETYPE *roleParams); - void initPorts(); + void initPorts(); status_t initDecoder(); - void deInitDecoder(); - - bool handlePortSettingChangeEvent(); - int32_t handleExtradata(); - int32_t openDecoder(); - void initPacket(AVPacket *pkt, OMX_BUFFERHEADERTYPE *inHeader); - int32_t decodeVideo(); - int32_t preProcessVideoFrame(AVPicture *picture, void **bufp); - int32_t drainOneOutputBuffer(); - void drainEOSOutputBuffer(); - void drainAllOutputBuffers(); - - void updatePortDefinitions(); + void deInitDecoder(); + + bool isPortSettingChanged(); + bool handlePortSettingChangeEvent(); + int32_t handleExtradata(); + int32_t openDecoder(); + void initPacket(AVPacket *pkt, OMX_BUFFERHEADERTYPE *inHeader); + int32_t decodeVideo(); + int32_t preProcessVideoFrame(AVPicture *picture, void **bufp); + int32_t drainOneOutputBuffer(); + void drainEOSOutputBuffer(); + void drainAllOutputBuffers(); + + void updatePortDefinitions(); DISALLOW_EVIL_CONSTRUCTORS(SoftFFmpegVideo); }; -- 2.11.0 From 3cc6e558f8df56d46b705f8094f5f1b051a8ce4b Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Sun, 3 Nov 2013 20:41:53 +0800 Subject: [PATCH 03/16] fix the rtvc1.vc1 file can't be played somtimes --- libstagefright/FFmpegExtractor/FFmpegExtractor.cpp | 41 +++++++++++----------- libstagefright/FFmpegExtractor/FFmpegExtractor.h | 3 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp index b65b745..e7c278a 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp @@ -215,6 +215,13 @@ void FFmpegExtractor::packet_queue_init(PacketQueue *q) packet_queue_put(q, &flush_pkt); } +void FFmpegExtractor::packet_queue_destroy(PacketQueue *q) +{ + packet_queue_flush(q); + pthread_mutex_destroy(&q->mutex); + pthread_cond_destroy(&q->cond); +} + void FFmpegExtractor::packet_queue_flush(PacketQueue *q) { AVPacketList *pkt, *pkt1; @@ -549,10 +556,6 @@ int FFmpegExtractor::stream_component_open(int stream_index) mVideoStreamIdx = stream_index; if (mVideoStream == NULL) mVideoStream = mFormatCtx->streams[stream_index]; - if (!mVideoQInited) { - packet_queue_init(&mVideoQ); - mVideoQInited = true; - } ret = check_extradata(avctx); if (ret != 1) { @@ -561,7 +564,6 @@ int FFmpegExtractor::stream_component_open(int stream_index) mVideoStreamIdx = -1; mVideoStream = NULL; packet_queue_end(&mVideoQ); - mVideoQInited = false; mFormatCtx->streams[stream_index]->discard = AVDISCARD_ALL; } return ret; @@ -736,10 +738,6 @@ int FFmpegExtractor::stream_component_open(int stream_index) mAudioStreamIdx = stream_index; if (mAudioStream == NULL) mAudioStream = mFormatCtx->streams[stream_index]; - if (!mAudioQInited) { - packet_queue_init(&mAudioQ); - mAudioQInited = true; - } ret = check_extradata(avctx); if (ret != 1) { @@ -748,7 +746,6 @@ int FFmpegExtractor::stream_component_open(int stream_index) mAudioStreamIdx = -1; mAudioStream = NULL; packet_queue_end(&mAudioQ); - mAudioQInited = false; mFormatCtx->streams[stream_index]->discard = AVDISCARD_ALL; } return ret; @@ -994,10 +991,10 @@ int FFmpegExtractor::stream_seek(int64_t pos, enum AVMediaType media_type) { Mutex::Autolock autoLock(mLock); - if (mVideoStreamIdx >= 0 && - mAudioStreamIdx >= 0 && - media_type == AVMEDIA_TYPE_AUDIO && - !mVideoEOSReceived) { + if (mVideoStreamIdx >= 0 + && mAudioStreamIdx >= 0 + && media_type == AVMEDIA_TYPE_AUDIO + && !mVideoEOSReceived) { return NO_SEEK; } @@ -1059,8 +1056,6 @@ void FFmpegExtractor::setFFmpegDefaultOpts() mAudioStreamIdx = -1; mVideoStream = NULL; mAudioStream = NULL; - mVideoQInited = false; - mAudioQInited = false; mDefersToCreateVideoTrack = false; mDefersToCreateAudioTrack = false; mVideoBsfc = NULL; @@ -1191,6 +1186,9 @@ int FFmpegExtractor::initStreams() hours, mins, secs, (100 * us) / AV_TIME_BASE); } + packet_queue_init(&mVideoQ); + packet_queue_init(&mAudioQ); + if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) { audio_ret = stream_component_open(st_index[AVMEDIA_TYPE_AUDIO]); } @@ -1213,6 +1211,9 @@ fail: void FFmpegExtractor::deInitStreams() { + packet_queue_destroy(&mVideoQ); + packet_queue_destroy(&mAudioQ); + if (mFormatCtx) { avformat_close_input(&mFormatCtx); } @@ -1321,7 +1322,8 @@ void FFmpegExtractor::readerEntry() { || ( (mAudioQ .size > MIN_AUDIOQ_SIZE || mAudioStreamIdx < 0) && (mVideoQ .nb_packets > MIN_FRAMES || mVideoStreamIdx < 0))) { #if DEBUG_READ_ENTRY - ALOGV("readerEntry, is full, fuck"); + ALOGV("readerEntry, full(wtf!!!), mVideoQ.size: %d, mVideoQ.nb_packets: %d, mAudioQ.size: %d, mAudioQ.nb_packets: %d", + mVideoQ.size, mVideoQ.nb_packets, mAudioQ.size, mAudioQ.nb_packets); #endif /* wait 10 ms */ usleep(10000); @@ -1364,10 +1366,10 @@ void FFmpegExtractor::readerEntry() { if (ret == AVERROR_EOF || url_feof(mFormatCtx->pb)) if (ret == AVERROR_EOF) { //ALOGV("ret == AVERROR_EOF"); - } + } if (url_feof(mFormatCtx->pb)) { //ALOGV("url_feof(mFormatCtx->pb)"); - } + } eof = 1; mEOF = true; @@ -1958,7 +1960,6 @@ static const char *SniffFFMPEGCommon(const char *url, float *confidence) fail: if (ic) { avformat_close_input(&ic); - av_free(ic); } if (status == OK) { deInitFFmpeg(); diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.h b/libstagefright/FFmpegExtractor/FFmpegExtractor.h index c0a1ab7..f7a7e32 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.h +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.h @@ -126,8 +126,6 @@ private: int mAudioStreamIdx; AVStream *mVideoStream; AVStream *mAudioStream; - bool mVideoQInited; - bool mAudioQInited; bool mDefersToCreateVideoTrack; bool mDefersToCreateAudioTrack; AVBitStreamFilterContext *mVideoBsfc; @@ -143,6 +141,7 @@ private: int stream_component_open(int stream_index); void stream_component_close(int stream_index); void packet_queue_init(PacketQueue *q); + void packet_queue_destroy(PacketQueue *q); void packet_queue_flush(PacketQueue *q); void packet_queue_end(PacketQueue *q); void packet_queue_abort(PacketQueue *q); -- 2.11.0 From 63611d5f2de13ca449857bc92d562585fb10ca98 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Mon, 4 Nov 2013 00:13:54 +0800 Subject: [PATCH 04/16] add support for vorbis parser in FFmpegExtractor --- libstagefright/FFmpegExtractor/FFmpegExtractor.cpp | 26 ++++++++++++++++++++-- libstagefright/FFmpegExtractor/FFmpegExtractor.h | 2 ++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp index e7c278a..303958c 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp @@ -446,6 +446,26 @@ int FFmpegExtractor::check_extradata(AVCodecContext *avctx) return 1; } +bool FFmpegExtractor::setupVorbisCodecSpecificData(sp meta, + AVCodecContext *avctx) +{ + uint8_t *header_start[3]; + int header_len[3]; + + if (avpriv_split_xiph_headers(avctx->extradata, + avctx->extradata_size, 30, + header_start, header_len) < 0) { + ALOGE("vorbis extradata corrupt."); + return false; + } + //identification header + meta->setData(kKeyVorbisInfo, 0, header_start[0], header_len[0]); + //setup header + meta->setData(kKeyVorbisBooks, 0, header_start[2], header_len[2]); + + return true; +} + void FFmpegExtractor::printTime(int64_t time) { int hours, mins, secs, us; @@ -773,7 +793,9 @@ int FFmpegExtractor::stream_component_open(int stream_index) ALOGV("VORBIS"); meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); - meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + if (!setupVorbisCodecSpecificData(meta, avctx)) { + return -1; + } break; case AV_CODEC_ID_AC3: ALOGV("AC3"); @@ -2059,7 +2081,7 @@ bool SniffFFMPEG( char value[PROPERTY_VALUE_MAX]; property_get("sys.media.parser.ffmpeg", value, "0"); if (atoi(value)) { - ALOGI("[debug] parser use ffmpeg"); + ALOGI("[debug] use ffmpeg parser"); *confidence = 0.88f; } diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.h b/libstagefright/FFmpegExtractor/FFmpegExtractor.h index f7a7e32..e43ee31 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.h +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.h @@ -49,6 +49,7 @@ extern "C" { #include "libavutil/opt.h" #include "libavutil/internal.h" #include "libavcodec/avfft.h" +#include "libavcodec/xiph.h" #include "libswresample/swresample.h" #ifdef __cplusplus @@ -136,6 +137,7 @@ private: void deInitStreams(); void buildFileName(const sp &meta); void setFFmpegDefaultOpts(); + bool setupVorbisCodecSpecificData(sp meta, AVCodecContext *avctx); void printTime(int64_t time); bool is_codec_supported(enum AVCodecID codec_id); int stream_component_open(int stream_index); -- 2.11.0 From b4ee2d989b5385c415b51509f3a807de5a741e2b Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Mon, 4 Nov 2013 01:25:55 +0800 Subject: [PATCH 05/16] add support for virbis decoder --- config/media_codecs.xml | 4 +- .../codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp | 78 +++++++++++++++++++--- .../codecs/ffmpegdec/adec/SoftFFmpegAudio.h | 4 ++ utils/ffmpeg_utils.cpp | 31 +++++++++ utils/ffmpeg_utils.h | 3 + 5 files changed, 109 insertions(+), 11 deletions(-) diff --git a/config/media_codecs.xml b/config/media_codecs.xml index ab48873..825e150 100644 --- a/config/media_codecs.xml +++ b/config/media_codecs.xml @@ -102,7 +102,7 @@ Only the three quirks included above are recognized at this point: - + @@ -121,7 +121,7 @@ Only the three quirks included above are recognized at this point: - + diff --git a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp index cc470e3..d3f67da 100644 --- a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp +++ b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp @@ -246,6 +246,7 @@ void SoftFFmpegAudio::resetCtx() { } status_t SoftFFmpegAudio::initDecoder() { + int32_t i = 0; status_t status; status = initFFmpeg(); @@ -306,18 +307,34 @@ status_t SoftFFmpegAudio::initDecoder() { mCtx->extradata = NULL; mCtx->extradata_size = 0; + //vorbis + for(i = 0; i < 3; i++) { + mVorbisHeaderStart[i] = NULL; + mVorbisHeaderLen[i] = 0; + } + memset(mSilenceBuffer, 0, kOutputBufferSize); return OK; } void SoftFFmpegAudio::deInitDecoder() { + int32_t i = 0; + if (mCtx) { if (!mCtx->extradata) { av_free(mCtx->extradata); mCtx->extradata = NULL; mCtx->extradata_size = 0; } + //vorbis + for(i = 0; i < 3; i++) { + if (mVorbisHeaderLen[i] > 0) { + av_free(mVorbisHeaderStart[i]); + mVorbisHeaderStart[i] = NULL; + mVorbisHeaderLen[i] = 0; + } + } if (mCodecAlreadyOpened) { avcodec_close(mCtx); av_free(mCtx); @@ -1010,6 +1027,34 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter( } } +int32_t SoftFFmpegAudio::handleVorbisExtradata(OMX_BUFFERHEADERTYPE *inHeader) +{ + uint8_t *p = inHeader->pBuffer + inHeader->nOffset; + int len = inHeader->nFilledLen; + int index = 0; + + if (p[0] == 1) { + index = 0; + } else if (p[0] == 3) { + index = 1; + } else if (p[0] == 5) { + index = 2; + } else { + ALOGE("error vorbis codec config"); + return ERR_INVALID_PARAM; + } + + mVorbisHeaderStart[index] = (uint8_t *)av_mallocz(len); + if (!mVorbisHeaderStart[index]) { + ALOGE("oom for vorbis extradata"); + return ERR_OOM; + } + memcpy(mVorbisHeaderStart[index], p, len); + mVorbisHeaderLen[index] = inHeader->nFilledLen; + + return ERR_OK; +} + int32_t SoftFFmpegAudio::handleExtradata() { List &inQueue = getPortQueue(kInputPortIndex); BufferInfo *inInfo = *inQueue.begin(); @@ -1023,18 +1068,26 @@ int32_t SoftFFmpegAudio::handleExtradata() { ALOGI("got extradata, size: %lu, but ignore it", inHeader->nFilledLen); } else { if (!mExtradataReady) { - int orig_extradata_size = mCtx->extradata_size; - mCtx->extradata_size += inHeader->nFilledLen; - mCtx->extradata = (uint8_t *)av_realloc(mCtx->extradata, + uint32_t ret = ERR_OK; + if (mCtx->codec_id == AV_CODEC_ID_VORBIS) { + if ((ret = handleVorbisExtradata(inHeader)) != ERR_OK) { + ALOGE("ffmpeg audio decoder failed to alloc vorbis extradata memory."); + return ret; + } + } else { + int orig_extradata_size = mCtx->extradata_size; + mCtx->extradata_size += inHeader->nFilledLen; + mCtx->extradata = (uint8_t *)av_realloc(mCtx->extradata, mCtx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!mCtx->extradata) { - ALOGE("ffmpeg audio decoder failed to alloc extradata memory."); - return ERR_OOM; - } + if (!mCtx->extradata) { + ALOGE("ffmpeg audio decoder failed to alloc extradata memory."); + return ERR_OOM; + } - memcpy(mCtx->extradata + orig_extradata_size, + memcpy(mCtx->extradata + orig_extradata_size, inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen); - memset(mCtx->extradata + mCtx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + memset(mCtx->extradata + mCtx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + } } } @@ -1053,6 +1106,13 @@ int32_t SoftFFmpegAudio::openDecoder() { } if (!mExtradataReady && !mIgnoreExtradata) { + if (mCtx->codec_id == AV_CODEC_ID_VORBIS) { + if (!setup_vorbis_extradata(&mCtx->extradata, + &mCtx->extradata_size, + (const uint8_t **)mVorbisHeaderStart, + mVorbisHeaderLen)) + return ERR_OOM; + } ALOGI("extradata is ready, size: %d", mCtx->extradata_size); hexdump(mCtx->extradata, mCtx->extradata_size); mExtradataReady = true; diff --git a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h index 3789efc..ebb0602 100644 --- a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h +++ b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h @@ -128,6 +128,9 @@ private: struct SwrContext *mSwrCtx; AVFrame *mFrame; + uint8_t *mVorbisHeaderStart[3]; + int mVorbisHeaderLen[3]; + EOSStatus mEOSStatus; bool mSignalledError; @@ -172,6 +175,7 @@ private: status_t initDecoder(); void deInitDecoder(); + int32_t handleVorbisExtradata(OMX_BUFFERHEADERTYPE *inHeader); int32_t handleExtradata(); int32_t openDecoder(); void updateTimeStamp(OMX_BUFFERHEADERTYPE *inHeader); diff --git a/utils/ffmpeg_utils.cpp b/utils/ffmpeg_utils.cpp index 5ad31e5..0688dce 100644 --- a/utils/ffmpeg_utils.cpp +++ b/utils/ffmpeg_utils.cpp @@ -385,5 +385,36 @@ int is_extradata_compatible_with_android(AVCodecContext *avctx) } } +////////////////////////////////////////////////////////////////////////////////// +// misc +////////////////////////////////////////////////////////////////////////////////// +bool setup_vorbis_extradata(uint8_t **extradata, int *extradata_size, + const uint8_t *header_start[3], const int header_len[3]) +{ + uint8_t *p = NULL; + int len = 0; + int i = 0; + + len = header_len[0] + header_len[1] + header_len[2]; + p = *extradata = (uint8_t *)av_mallocz(64 + len + len/255); + if (!p) { + ALOGE("oom for vorbis extradata"); + return false; + } + + *p++ = 2; + p += av_xiphlacing(p, header_len[0]); + p += av_xiphlacing(p, header_len[1]); + for (i = 0; i < 3; i++) { + if (header_len[i] > 0) { + memcpy(p, header_start[i], header_len[i]); + p += header_len[i]; + } + } + *extradata_size = p - *extradata; + + return true; +} + } // namespace android diff --git a/utils/ffmpeg_utils.h b/utils/ffmpeg_utils.h index ace88f8..be5b063 100644 --- a/utils/ffmpeg_utils.h +++ b/utils/ffmpeg_utils.h @@ -47,6 +47,9 @@ void nam_av_log_set_flags(int arg); int is_extradata_compatible_with_android(AVCodecContext *avctx); int parser_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size); +bool setup_vorbis_extradata(uint8_t **extradata, int *extradata_size, + const uint8_t *header_start[3], const int header_len[3]); + } // namespace android #endif // FFMPEG_UTILS_H_ -- 2.11.0 From 0fc3e28a22884d354368c1f3e14e7703d8bd1ef5 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Mon, 4 Nov 2013 22:43:27 +0800 Subject: [PATCH 06/16] cleanup vorbis decoder --- .../codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp | 45 +++++++++++++--------- .../codecs/ffmpegdec/adec/SoftFFmpegAudio.h | 4 +- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp index d3f67da..42e33ed 100644 --- a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp +++ b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp @@ -245,8 +245,26 @@ void SoftFFmpegAudio::resetCtx() { mAudioSrcChannelLayout = mAudioTgtChannelLayout = 0; } -status_t SoftFFmpegAudio::initDecoder() { +void SoftFFmpegAudio::initVorbisHdr() { int32_t i = 0; + for(i = 0; i < 3; i++) { + mVorbisHeaderStart[i] = NULL; + mVorbisHeaderLen[i] = 0; + } +} + +void SoftFFmpegAudio::deinitVorbisHdr() { + int32_t i = 0; + for(i = 0; i < 3; i++) { + if (mVorbisHeaderLen[i] > 0) { + av_free(mVorbisHeaderStart[i]); + mVorbisHeaderStart[i] = NULL; + mVorbisHeaderLen[i] = 0; + } + } +} + +status_t SoftFFmpegAudio::initDecoder() { status_t status; status = initFFmpeg(); @@ -307,11 +325,7 @@ status_t SoftFFmpegAudio::initDecoder() { mCtx->extradata = NULL; mCtx->extradata_size = 0; - //vorbis - for(i = 0; i < 3; i++) { - mVorbisHeaderStart[i] = NULL; - mVorbisHeaderLen[i] = 0; - } + initVorbisHdr(); memset(mSilenceBuffer, 0, kOutputBufferSize); @@ -319,22 +333,15 @@ status_t SoftFFmpegAudio::initDecoder() { } void SoftFFmpegAudio::deInitDecoder() { - int32_t i = 0; - if (mCtx) { if (!mCtx->extradata) { av_free(mCtx->extradata); mCtx->extradata = NULL; mCtx->extradata_size = 0; } - //vorbis - for(i = 0; i < 3; i++) { - if (mVorbisHeaderLen[i] > 0) { - av_free(mVorbisHeaderStart[i]); - mVorbisHeaderStart[i] = NULL; - mVorbisHeaderLen[i] = 0; - } - } + + deinitVorbisHdr(); + if (mCodecAlreadyOpened) { avcodec_close(mCtx); av_free(mCtx); @@ -1110,8 +1117,10 @@ int32_t SoftFFmpegAudio::openDecoder() { if (!setup_vorbis_extradata(&mCtx->extradata, &mCtx->extradata_size, (const uint8_t **)mVorbisHeaderStart, - mVorbisHeaderLen)) - return ERR_OOM; + mVorbisHeaderLen)) { + return ERR_OOM; + } + deinitVorbisHdr(); } ALOGI("extradata is ready, size: %d", mCtx->extradata_size); hexdump(mCtx->extradata, mCtx->extradata_size); diff --git a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h index ebb0602..d731a2a 100644 --- a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h +++ b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h @@ -175,8 +175,10 @@ private: status_t initDecoder(); void deInitDecoder(); - int32_t handleVorbisExtradata(OMX_BUFFERHEADERTYPE *inHeader); + void initVorbisHdr(); + void deinitVorbisHdr(); int32_t handleExtradata(); + int32_t handleVorbisExtradata(OMX_BUFFERHEADERTYPE *inHeader); int32_t openDecoder(); void updateTimeStamp(OMX_BUFFERHEADERTYPE *inHeader); void initPacket(AVPacket *pkt, OMX_BUFFERHEADERTYPE *inHeader); -- 2.11.0 From 4b26b8c01892c0b0d966486612adadba70e50987 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Tue, 5 Nov 2013 00:15:16 +0800 Subject: [PATCH 07/16] add adjust confidence funcs --- libstagefright/FFmpegExtractor/FFmpegExtractor.cpp | 68 +++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp index 303958c..44714c8 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp @@ -1829,6 +1829,62 @@ static void adjustMPEG4Confidence(AVFormatContext *ic, float *confidence) } } +static void adjustMPEG2TSConfidence(AVFormatContext *ic, float *confidence) +{ + enum AVCodecID codec_id = AV_CODEC_ID_NONE; + + codec_id = getCodecId(ic, AVMEDIA_TYPE_VIDEO); + if (codec_id != AV_CODEC_ID_NONE + && codec_id != AV_CODEC_ID_H264 + && codec_id != AV_CODEC_ID_MPEG4 + && codec_id != AV_CODEC_ID_MPEG1VIDEO + && codec_id != AV_CODEC_ID_MPEG2VIDEO) { + //the MEDIA_MIMETYPE_CONTAINER_MPEG2TS of confidence is 0.1f + ALOGI("[mpeg2ts]video codec(%s), confidence should be larger than MPEG2TSExtractor", + avcodec_get_name(codec_id)); + *confidence = 0.11f; + } + + codec_id = getCodecId(ic, AVMEDIA_TYPE_AUDIO); + if (codec_id != AV_CODEC_ID_NONE + && codec_id != AV_CODEC_ID_AAC + && codec_id != AV_CODEC_ID_PCM_S16LE //FIXME, AV_CODEC_ID_PCM_S24LE, AV_CODEC_ID_PCM_S32LE? + && codec_id != AV_CODEC_ID_MP1 + && codec_id != AV_CODEC_ID_MP2 + && codec_id != AV_CODEC_ID_MP3) { + ALOGI("[mpeg2ts]audio codec(%s), confidence should be larger than MPEG2TSExtractor", + avcodec_get_name(codec_id)); + *confidence = 0.11f; + } +} + +static void adjustMKVConfidence(AVFormatContext *ic, float *confidence) +{ + enum AVCodecID codec_id = AV_CODEC_ID_NONE; + + codec_id = getCodecId(ic, AVMEDIA_TYPE_VIDEO); + if (codec_id != AV_CODEC_ID_NONE + && codec_id != AV_CODEC_ID_H264 + && codec_id != AV_CODEC_ID_MPEG4 + && codec_id != AV_CODEC_ID_VP6 + && codec_id != AV_CODEC_ID_VP8) { + //the MEDIA_MIMETYPE_CONTAINER_MATROSKA of confidence is 0.6f + ALOGI("[mkv]video codec(%s), confidence should be larger than MatroskaExtractor", + avcodec_get_name(codec_id)); + *confidence = 0.61f; + } + + codec_id = getCodecId(ic, AVMEDIA_TYPE_AUDIO); + if (codec_id != AV_CODEC_ID_NONE + && codec_id != AV_CODEC_ID_AAC + && codec_id != AV_CODEC_ID_MP3 + && codec_id != AV_CODEC_ID_VORBIS) { + ALOGI("[mkv]audio codec(%s), confidence should be larger than MatroskaExtractor", + avcodec_get_name(codec_id)); + *confidence = 0.61f; + } +} + static void adjustVideoCodecConfidence(AVFormatContext *ic, enum AVCodecID codec_id, float *confidence) { @@ -1857,6 +1913,10 @@ static void adjustAudioCodecConfidence(AVFormatContext *ic, ALOGI("ffmpeg can demux mp1 and mp2 only"); *confidence = 0.88f; break; + case AV_CODEC_ID_DTS: + ALOGI("ffmpeg can demux dts only"); + *confidence = 0.88f; + break; default: break; } @@ -1891,14 +1951,20 @@ static void adjustCodecConfidence(AVFormatContext *ic, float *confidence) } } +//FIXME static void adjustConfidenceIfNeeded(const char *mime, AVFormatContext *ic, float *confidence) { + //check mime if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)) { adjustMPEG4Confidence(ic, confidence); + } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) { + adjustMPEG2TSConfidence(ic, confidence); + } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) { + adjustMKVConfidence(ic, confidence); } else { - //add to here; + //todo } //check codec -- 2.11.0 From 8fe298af76486cd3b6f454571730b620578e781e Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Thu, 7 Nov 2013 00:26:47 +0800 Subject: [PATCH 08/16] fix OMX_AUDIO_CodingMP2 --- libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp index 42e33ed..ba1487c 100644 --- a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp +++ b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp @@ -136,7 +136,7 @@ void SoftFFmpegAudio::initInputFormat(uint32_t mode, break; case MODE_MPEGL2: def.format.audio.cMIMEType = const_cast(MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II); - def.format.audio.eEncoding = OMX_AUDIO_CodingMP3; + def.format.audio.eEncoding = OMX_AUDIO_CodingMP2; break; case MODE_AC3: def.format.audio.cMIMEType = const_cast(MEDIA_MIMETYPE_AUDIO_AC3); @@ -247,7 +247,7 @@ void SoftFFmpegAudio::resetCtx() { void SoftFFmpegAudio::initVorbisHdr() { int32_t i = 0; - for(i = 0; i < 3; i++) { + for (i = 0; i < 3; i++) { mVorbisHeaderStart[i] = NULL; mVorbisHeaderLen[i] = 0; } @@ -255,7 +255,7 @@ void SoftFFmpegAudio::initVorbisHdr() { void SoftFFmpegAudio::deinitVorbisHdr() { int32_t i = 0; - for(i = 0; i < 3; i++) { + for (i = 0; i < 3; i++) { if (mVorbisHeaderLen[i] > 0) { av_free(mVorbisHeaderStart[i]); mVorbisHeaderStart[i] = NULL; -- 2.11.0 From 07b9a82520d581d85f8bbfb2412b87e8d2ef8a71 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Thu, 7 Nov 2013 00:27:32 +0800 Subject: [PATCH 09/16] fix set kKeyMIMEType --- libstagefright/FFmpegExtractor/FFmpegExtractor.cpp | 263 ++++++++++++++------- libstagefright/FFmpegExtractor/FFmpegExtractor.h | 2 +- 2 files changed, 178 insertions(+), 87 deletions(-) diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp index 44714c8..0e80f79 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp @@ -116,7 +116,7 @@ FFmpegExtractor::FFmpegExtractor(const sp &source, const spmAbortRequest; } -void FFmpegExtractor::buildFileName(const sp &meta) +void FFmpegExtractor::fetchStuffsFromSniffedMeta(const sp &meta) { AString url; + AString mime; - CHECK(meta.get() != NULL); + //url CHECK(meta->findString("extended-extractor-url", &url)); CHECK(url.c_str() != NULL); CHECK(url.size() < PATH_MAX); memcpy(mFilename, url.c_str(), url.size()); mFilename[url.size()] = '\0'; - ALOGD("build mFilename: %s", mFilename); + + //mime + CHECK(meta->findString("extended-extractor-mime", &mime)); + CHECK(mime.c_str() != NULL); + mMeta->setCString(kKeyMIMEType, mime.c_str()); } void FFmpegExtractor::setFFmpegDefaultOpts() @@ -1164,10 +1169,6 @@ int FFmpegExtractor::initStreams() av_dict_free(&opts[i]); av_freep(&opts); - mime = findMatchingContainer(mFormatCtx->iformat->name); - CHECK(mime != NULL); - mMeta->setCString(kKeyMIMEType, mime); - if (mFormatCtx->pb) mFormatCtx->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use url_feof() to test for the end @@ -1774,6 +1775,64 @@ static enum AVCodecID getCodecId(AVFormatContext *ic, AVMediaType codec_type) return AV_CODEC_ID_NONE; } +static bool hasAudioCodecOnly(AVFormatContext *ic) +{ + enum AVCodecID codec_id = AV_CODEC_ID_NONE; + bool haveVideo = false; + bool haveAudio = false; + + if (getCodecId(ic, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) { + haveVideo = true; + } + if (getCodecId(ic, AVMEDIA_TYPE_AUDIO) != AV_CODEC_ID_NONE) { + haveAudio = true; + } + + if (!haveVideo && haveAudio) { + return true; + } + + return false; +} + +//FIXME all codecs: frameworks/av/media/libstagefright/codecs/* +static bool isCodecSupportedByStagefright(enum AVCodecID codec_id) +{ + bool supported = false; + + switch(codec_id) { + //video + 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_VP6: + case AV_CODEC_ID_VP8: + //audio + case AV_CODEC_ID_AAC: + case AV_CODEC_ID_MP3: + case AV_CODEC_ID_AMR_NB: + case AV_CODEC_ID_AMR_WB: + case AV_CODEC_ID_FLAC: + case AV_CODEC_ID_VORBIS: + case AV_CODEC_ID_PCM_MULAW: //g711 + case AV_CODEC_ID_PCM_ALAW: //g711 + //case AV_CODEC_ID_PCM_XXX: //FIXME more PCM? + supported = true; + break; + + default: + break; + } + + ALOGD("%ssuppoted codec(%s) by official Stagefright", + (supported ? "" : "un"), + avcodec_get_name(codec_id)); + + return supported; +} + static void adjustMPEG4Confidence(AVFormatContext *ic, float *confidence) { AVDictionary *tags = NULL; @@ -1885,78 +1944,35 @@ static void adjustMKVConfidence(AVFormatContext *ic, float *confidence) } } -static void adjustVideoCodecConfidence(AVFormatContext *ic, - enum AVCodecID codec_id, float *confidence) -{ - switch (codec_id) { - case AV_CODEC_ID_HEVC: - ALOGI("ffmpeg can demux hevc only"); - *confidence = 0.88f; - break; - default: - break; - } -} - -//TODO. if the other stream(e.g. mp3) is supported by stagefright -static void adjustAudioCodecConfidence(AVFormatContext *ic, - enum AVCodecID codec_id, float *confidence) -{ - switch (codec_id) { - case AV_CODEC_ID_AC3: - ALOGI("ffmpeg can demux ac3 only"); - *confidence = 0.88f; - break; - 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; - break; - case AV_CODEC_ID_DTS: - ALOGI("ffmpeg can demux dts only"); - *confidence = 0.88f; - break; - default: - break; - } -} - static void adjustCodecConfidence(AVFormatContext *ic, float *confidence) { - unsigned int idx = 0; - AVCodecContext *avctx = NULL; - AVMediaType codec_type = AVMEDIA_TYPE_UNKNOWN; enum AVCodecID codec_id = AV_CODEC_ID_NONE; - bool haveVideo = false; - bool haveAudio = false; - bool haveMP3 = false; codec_id = getCodecId(ic, AVMEDIA_TYPE_VIDEO); if (codec_id != AV_CODEC_ID_NONE) { - haveVideo = true; - adjustVideoCodecConfidence(ic, codec_id, confidence); + if (!isCodecSupportedByStagefright(codec_id)) { + *confidence = 0.88f; + } } codec_id = getCodecId(ic, AVMEDIA_TYPE_AUDIO); if (codec_id != AV_CODEC_ID_NONE) { - haveAudio = true; - adjustAudioCodecConfidence(ic, codec_id, confidence); - if (codec_id == AV_CODEC_ID_MP3) - haveMP3 = true; + if (!isCodecSupportedByStagefright(codec_id)) { + *confidence = 0.88f; + } } - if (haveVideo && haveMP3) { - *confidence = 0.22f; // larger than MP3Extractor an MP3Extractor + if (getCodecId(ic, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE + && getCodecId(ic, AVMEDIA_TYPE_AUDIO) == AV_CODEC_ID_MP3) { + *confidence = 0.22f; //larger than MP3Extractor } } -//FIXME +//TODO need more checks static void adjustConfidenceIfNeeded(const char *mime, AVFormatContext *ic, float *confidence) { - - //check mime + //1. check mime if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)) { adjustMPEG4Confidence(ic, confidence); } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) { @@ -1964,13 +1980,76 @@ static void adjustConfidenceIfNeeded(const char *mime, } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) { adjustMKVConfidence(ic, confidence); } else { - //todo + //todo here } - //check codec + if (*confidence > 0.08) { + return; + } + + //2. check codec adjustCodecConfidence(ic, confidence); } +static void adjustContainerIfNeeded(const char **mime, AVFormatContext *ic) +{ + const char *newMime = *mime; + enum AVCodecID codec_id = AV_CODEC_ID_NONE; + + if (!hasAudioCodecOnly(ic)) { + return; + } + + codec_id = getCodecId(ic, AVMEDIA_TYPE_AUDIO); + CHECK(codec_id != AV_CODEC_ID_NONE); + switch (codec_id) { + case AV_CODEC_ID_MP3: + newMime = MEDIA_MIMETYPE_AUDIO_MPEG; + break; + case AV_CODEC_ID_AAC: + newMime = MEDIA_MIMETYPE_AUDIO_AAC; + break; + case AV_CODEC_ID_VORBIS: + newMime = MEDIA_MIMETYPE_AUDIO_VORBIS; + break; + case AV_CODEC_ID_FLAC: + newMime = MEDIA_MIMETYPE_AUDIO_FLAC; + break; + case AV_CODEC_ID_AC3: + newMime = MEDIA_MIMETYPE_AUDIO_AC3; + break; + case AV_CODEC_ID_APE: + newMime = MEDIA_MIMETYPE_AUDIO_APE; + break; + case AV_CODEC_ID_DTS: + newMime = MEDIA_MIMETYPE_AUDIO_DTS; + break; + case AV_CODEC_ID_MP2: + newMime = MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II; + break; + case AV_CODEC_ID_COOK: + newMime = MEDIA_MIMETYPE_AUDIO_RA; + break; + case AV_CODEC_ID_WMAV1: + case AV_CODEC_ID_WMAV2: + case AV_CODEC_ID_WMAPRO: + case AV_CODEC_ID_WMALOSSLESS: + newMime = MEDIA_MIMETYPE_AUDIO_WMA; + break; + default: + break; + } + + if (!strcmp(*mime, MEDIA_MIMETYPE_CONTAINER_FFMPEG)) { + newMime = MEDIA_MIMETYPE_AUDIO_FFMPEG; + } + + if (strcmp(*mime, newMime)) { + ALOGI("adjust mime(%s -> %s)", *mime, newMime); + *mime = newMime; + } +} + static const char *findMatchingContainer(const char *name) { size_t i = 0; @@ -1985,7 +2064,7 @@ static const char *findMatchingContainer(const char *name) for (i = 0; i < NELEM(FILE_FORMATS); ++i) { int len = strlen(FILE_FORMATS[i].format); - if (!av_strncasecmp(name, FILE_FORMATS[i].format, len)) { + if (!strncasecmp(name, FILE_FORMATS[i].format, len)) { container = FILE_FORMATS[i].container; break; } @@ -1996,12 +2075,12 @@ static const char *findMatchingContainer(const char *name) static const char *SniffFFMPEGCommon(const char *url, float *confidence) { - size_t i = 0; int err = 0; + size_t i = 0; + size_t nb_streams = 0; const char *container = NULL; AVFormatContext *ic = NULL; AVDictionary **opts = NULL; - size_t orig_nb_streams = 0; status_t status = initFFmpeg(); if (status != OK) { @@ -2023,13 +2102,13 @@ static const char *SniffFFMPEGCommon(const char *url, float *confidence) } opts = setup_find_stream_info_opts(ic, codec_opts); - orig_nb_streams = ic->nb_streams; + nb_streams = ic->nb_streams; err = avformat_find_stream_info(ic, opts); if (err < 0) { ALOGE("%s: could not find stream info, err:%s", url, av_err2str(err)); goto fail; } - for (i = 0; i < orig_nb_streams; i++) { + for (i = 0; i < nb_streams; i++) { av_dict_free(&opts[i]); } av_freep(&opts); @@ -2042,6 +2121,7 @@ static const char *SniffFFMPEGCommon(const char *url, float *confidence) container = findMatchingContainer(ic->iformat->name); if (container) { + adjustContainerIfNeeded(&container, ic); adjustConfidenceIfNeeded(container, ic, confidence); } @@ -2056,21 +2136,16 @@ fail: return container; } -static const char *LegacySniffFFMPEG(const sp &source, - float *confidence, sp meta) +static const char *BetterSniffFFMPEG(const sp &source, + float *confidence, sp meta) { const char *ret = NULL; char url[PATH_MAX] = {0}; - String8 uri = source->getUri(); - if (!uri.string()) { - return NULL; - } - - ALOGI("source url:%s", uri.string()); + ALOGI("android-source:%p", source.get()); - // pass the addr of smart pointer("source") + file name - snprintf(url, sizeof(url), "android-source:%p|file:%s", source.get(), uri.string()); + // pass the addr of smart pointer("source") + snprintf(url, sizeof(url), "android-source:%p", source.get()); ret = SniffFFMPEGCommon(url, confidence); if (ret) { @@ -2080,16 +2155,21 @@ static const char *LegacySniffFFMPEG(const sp &source, return ret; } -static const char *BetterSniffFFMPEG(const sp &source, - float *confidence, sp meta) +static const char *LegacySniffFFMPEG(const sp &source, + float *confidence, sp meta) { const char *ret = NULL; char url[PATH_MAX] = {0}; - ALOGI("android-source:%p", source.get()); + String8 uri = source->getUri(); + if (!uri.string()) { + return NULL; + } - // pass the addr of smart pointer("source") - snprintf(url, sizeof(url), "android-source:%p", source.get()); + ALOGI("source url:%s", uri.string()); + + // pass the addr of smart pointer("source") + file name + snprintf(url, sizeof(url), "android-source:%p|file:%s", source.get(), uri.string()); ret = SniffFFMPEGCommon(url, confidence); if (ret) { @@ -2142,6 +2222,7 @@ bool SniffFFMPEG( (*meta)->setString("extended-extractor", "extended-extractor"); (*meta)->setString("extended-extractor-subtype", "ffmpegextractor"); + (*meta)->setString("extended-extractor-mime", container); //debug only char value[PROPERTY_VALUE_MAX]; @@ -2162,9 +2243,18 @@ MediaExtractor *CreateFFmpegExtractor(const sp &source, const char * MediaExtractor *ret = NULL; AString notuse; if (meta.get() && meta->findString("extended-extractor", ¬use) && ( - !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4) || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG) || + !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC) || + !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS) || + !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC) || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3) || + !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_APE) || + !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_DTS) || + !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II) || + !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RA) || + !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_WMA) || + !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FFMPEG) || + !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4) || !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MOV) || !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA) || !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_TS) || @@ -2186,7 +2276,8 @@ MediaExtractor *CreateFFmpegExtractor(const sp &source, const char * !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG) || !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_VC1) || !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_HEVC) || - !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WMA))) { + !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WMA) || + !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_FFMPEG))) { ret = new FFmpegExtractor(source, meta); } diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.h b/libstagefright/FFmpegExtractor/FFmpegExtractor.h index e43ee31..d1a3616 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.h +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.h @@ -135,7 +135,7 @@ private: static int decode_interrupt_cb(void *ctx); int initStreams(); void deInitStreams(); - void buildFileName(const sp &meta); + void fetchStuffsFromSniffedMeta(const sp &meta); void setFFmpegDefaultOpts(); bool setupVorbisCodecSpecificData(sp meta, AVCodecContext *avctx); void printTime(int64_t time); -- 2.11.0 From 1875071606594472d252b5d477e27ea048da0f4f Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Sun, 10 Nov 2013 15:55:24 +0800 Subject: [PATCH 10/16] remove packet_queue_XXX funcs to ffmpeg_utils.cpp --- libstagefright/FFmpegExtractor/FFmpegExtractor.cpp | 147 +-------------------- libstagefright/FFmpegExtractor/FFmpegExtractor.h | 18 +-- utils/ffmpeg_utils.cpp | 138 ++++++++++++++++++- utils/ffmpeg_utils.h | 43 +++++- 4 files changed, 185 insertions(+), 161 deletions(-) diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp index 0e80f79..a1bf11b 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp @@ -63,12 +63,8 @@ enum { SEEK, }; -static AVPacket flush_pkt; - namespace android { -static const char *findMatchingContainer(const char *name); - struct FFmpegExtractor::Track : public MediaSource { Track(FFmpegExtractor *extractor, sp meta, bool isAVC, AVStream *stream, PacketQueue *queue); @@ -207,123 +203,6 @@ uint32_t FFmpegExtractor::flags() const { return flags; } -void FFmpegExtractor::packet_queue_init(PacketQueue *q) -{ - memset(q, 0, sizeof(PacketQueue)); - pthread_mutex_init(&q->mutex, NULL); - pthread_cond_init(&q->cond, NULL); - packet_queue_put(q, &flush_pkt); -} - -void FFmpegExtractor::packet_queue_destroy(PacketQueue *q) -{ - packet_queue_flush(q); - pthread_mutex_destroy(&q->mutex); - pthread_cond_destroy(&q->cond); -} - -void FFmpegExtractor::packet_queue_flush(PacketQueue *q) -{ - AVPacketList *pkt, *pkt1; - - pthread_mutex_lock(&q->mutex); - for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) { - pkt1 = pkt->next; - av_free_packet(&pkt->pkt); - av_freep(&pkt); - } - q->last_pkt = NULL; - q->first_pkt = NULL; - q->nb_packets = 0; - q->size = 0; - pthread_mutex_unlock(&q->mutex); -} - -void FFmpegExtractor::packet_queue_end(PacketQueue *q) -{ - packet_queue_flush(q); -} - -void FFmpegExtractor::packet_queue_abort(PacketQueue *q) -{ - pthread_mutex_lock(&q->mutex); - - q->abort_request = 1; - - pthread_cond_signal(&q->cond); - - pthread_mutex_unlock(&q->mutex); -} - -int FFmpegExtractor::packet_queue_put(PacketQueue *q, AVPacket *pkt) -{ - AVPacketList *pkt1; - - /* duplicate the packet */ - if (pkt != &flush_pkt && av_dup_packet(pkt) < 0) - return -1; - - pkt1 = (AVPacketList *)av_malloc(sizeof(AVPacketList)); - if (!pkt1) - return -1; - pkt1->pkt = *pkt; - pkt1->next = NULL; - - pthread_mutex_lock(&q->mutex); - - if (!q->last_pkt) - - q->first_pkt = pkt1; - else - q->last_pkt->next = pkt1; - q->last_pkt = pkt1; - q->nb_packets++; - //q->size += pkt1->pkt.size + sizeof(*pkt1); - q->size += pkt1->pkt.size; - pthread_cond_signal(&q->cond); - - pthread_mutex_unlock(&q->mutex); - return 0; -} - -/* packet queue handling */ -/* return < 0 if aborted, 0 if no packet and > 0 if packet. */ -int FFmpegExtractor::packet_queue_get(PacketQueue *q, AVPacket *pkt, int block) -{ - AVPacketList *pkt1; - int ret; - - pthread_mutex_lock(&q->mutex); - - for (;;) { - if (q->abort_request) { - ret = -1; - break; - } - - pkt1 = q->first_pkt; - if (pkt1) { - q->first_pkt = pkt1->next; - if (!q->first_pkt) - q->last_pkt = NULL; - q->nb_packets--; - //q->size -= pkt1->pkt.size + sizeof(*pkt1); - q->size -= pkt1->pkt.size; - *pkt = pkt1->pkt; - av_free(pkt1); - ret = 1; - break; - } else if (!block) { - ret = 0; - break; - } else { - pthread_cond_wait(&q->cond, &q->mutex); - } - } - pthread_mutex_unlock(&q->mutex); - return ret; -} - static void EncodeSize14(uint8_t **_ptr, size_t size) { CHECK_LE(size, 0x3fff); @@ -1125,10 +1004,6 @@ int FFmpegExtractor::initStreams() } mFFmpegInited = true; - av_init_packet(&flush_pkt); - flush_pkt.data = (uint8_t *)"FLUSH"; - flush_pkt.size = 0; - mFormatCtx = avformat_alloc_context(); if (!mFormatCtx) { @@ -1329,11 +1204,11 @@ void FFmpegExtractor::readerEntry() { } else { if (mAudioStreamIdx >= 0) { packet_queue_flush(&mAudioQ); - packet_queue_put(&mAudioQ, &flush_pkt); + packet_queue_put(&mAudioQ, &mAudioQ.flush_pkt); } if (mVideoStreamIdx >= 0) { packet_queue_flush(&mVideoQ); - packet_queue_put(&mVideoQ, &flush_pkt); + packet_queue_put(&mVideoQ, &mVideoQ.flush_pkt); } } mSeekReq = 0; @@ -1355,18 +1230,10 @@ void FFmpegExtractor::readerEntry() { if (eof) { if (mVideoStreamIdx >= 0) { - av_init_packet(pkt); - pkt->data = NULL; - pkt->size = 0; - pkt->stream_index = mVideoStreamIdx; - packet_queue_put(&mVideoQ, pkt); + packet_queue_put_nullpacket(&mVideoQ, mVideoStreamIdx); } if (mAudioStreamIdx >= 0) { - av_init_packet(pkt); - pkt->data = NULL; - pkt->size = 0; - pkt->stream_index = mAudioStreamIdx; - packet_queue_put(&mAudioQ, pkt); + packet_queue_put_nullpacket(&mAudioQ, mAudioStreamIdx); } usleep(10000); #if DEBUG_READ_ENTRY @@ -1592,13 +1459,13 @@ status_t FFmpegExtractor::Track::read( } retry: - if (mExtractor->packet_queue_get(mQueue, &pkt, 1) < 0) { + if (packet_queue_get(mQueue, &pkt, 1) < 0) { mExtractor->reachedEOS(mMediaType); return ERROR_END_OF_STREAM; } if (seeking) { - if (pkt.data != flush_pkt.data) { + if (pkt.data != mQueue->flush_pkt.data) { av_free_packet(&pkt); goto retry; } else { @@ -1609,7 +1476,7 @@ retry: } } - if (pkt.data == flush_pkt.data) { + if (pkt.data == mQueue->flush_pkt.data) { ALOGV("read %s flush pkt", av_get_media_type_string(mMediaType)); av_free_packet(&pkt); mFirstKeyPktTimestamp = AV_NOPTS_VALUE; diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.h b/libstagefright/FFmpegExtractor/FFmpegExtractor.h index d1a3616..c1089ae 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.h +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.h @@ -52,19 +52,12 @@ extern "C" { #include "libavcodec/xiph.h" #include "libswresample/swresample.h" +#include "utils/ffmpeg_utils.h" + #ifdef __cplusplus } #endif -typedef struct PacketQueue { - AVPacketList *first_pkt, *last_pkt; - int nb_packets; - int size; - int abort_request; - pthread_mutex_t mutex; - pthread_cond_t cond; -} PacketQueue; - namespace android { struct ABuffer; @@ -142,13 +135,6 @@ private: bool is_codec_supported(enum AVCodecID codec_id); int stream_component_open(int stream_index); void stream_component_close(int stream_index); - void packet_queue_init(PacketQueue *q); - void packet_queue_destroy(PacketQueue *q); - void packet_queue_flush(PacketQueue *q); - void packet_queue_end(PacketQueue *q); - void packet_queue_abort(PacketQueue *q); - int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block); - int packet_queue_put(PacketQueue *q, AVPacket *pkt); void reachedEOS(enum AVMediaType media_type); int stream_seek(int64_t pos, enum AVMediaType media_type); int check_extradata(AVCodecContext *avctx); diff --git a/utils/ffmpeg_utils.cpp b/utils/ffmpeg_utils.cpp index 0688dce..a509698 100644 --- a/utils/ffmpeg_utils.cpp +++ b/utils/ffmpeg_utils.cpp @@ -290,7 +290,7 @@ void deInitFFmpeg() ////////////////////////////////////////////////////////////////////////////////// // parser ////////////////////////////////////////////////////////////////////////////////// -/* H.264 bitstream with start codes, NOT AVC1! ref: libavcodec/h264_parser.c */ +/* H.264 bitstream with start codes, NOT AVC1! */ static int h264_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size, int check_compatible_only) { @@ -327,7 +327,6 @@ static int h264_split(AVCodecContext *avctx, return 0; } -/* ref: libavcodec/mpegvideo_parser.c */ static int mpegvideo_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size, int check_compatible_only) { @@ -386,6 +385,141 @@ int is_extradata_compatible_with_android(AVCodecContext *avctx) } ////////////////////////////////////////////////////////////////////////////////// +// packet queue +////////////////////////////////////////////////////////////////////////////////// +void packet_queue_init(PacketQueue *q) +{ + memset(q, 0, sizeof(PacketQueue)); + pthread_mutex_init(&q->mutex, NULL); + pthread_cond_init(&q->cond, NULL); + + av_init_packet(&q->flush_pkt); + q->flush_pkt.data = (uint8_t *)&q->flush_pkt; + q->flush_pkt.size = 0; + + packet_queue_put(q, &q->flush_pkt); +} + +void packet_queue_destroy(PacketQueue *q) +{ + packet_queue_flush(q); + pthread_mutex_destroy(&q->mutex); + pthread_cond_destroy(&q->cond); +} + +void packet_queue_flush(PacketQueue *q) +{ + AVPacketList *pkt, *pkt1; + + pthread_mutex_lock(&q->mutex); + for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) { + pkt1 = pkt->next; + av_free_packet(&pkt->pkt); + av_freep(&pkt); + } + q->last_pkt = NULL; + q->first_pkt = NULL; + q->nb_packets = 0; + q->size = 0; + pthread_mutex_unlock(&q->mutex); +} + +void packet_queue_end(PacketQueue *q) +{ + packet_queue_flush(q); +} + +void packet_queue_abort(PacketQueue *q) +{ + pthread_mutex_lock(&q->mutex); + + q->abort_request = 1; + + pthread_cond_signal(&q->cond); + + pthread_mutex_unlock(&q->mutex); +} + +int packet_queue_put(PacketQueue *q, AVPacket *pkt) +{ + AVPacketList *pkt1; + + /* duplicate the packet */ + if (pkt != &q->flush_pkt && av_dup_packet(pkt) < 0) + return -1; + + pkt1 = (AVPacketList *)av_malloc(sizeof(AVPacketList)); + if (!pkt1) + return -1; + pkt1->pkt = *pkt; + pkt1->next = NULL; + + pthread_mutex_lock(&q->mutex); + + if (!q->last_pkt) + + q->first_pkt = pkt1; + else + q->last_pkt->next = pkt1; + q->last_pkt = pkt1; + q->nb_packets++; + //q->size += pkt1->pkt.size + sizeof(*pkt1); + q->size += pkt1->pkt.size; + pthread_cond_signal(&q->cond); + + pthread_mutex_unlock(&q->mutex); + return 0; +} + +int packet_queue_put_nullpacket(PacketQueue *q, int stream_index) +{ + AVPacket pkt1, *pkt = &pkt1; + av_init_packet(pkt); + pkt->data = NULL; + pkt->size = 0; + pkt->stream_index = stream_index; + return packet_queue_put(q, pkt); +} + +/* packet queue handling */ +/* return < 0 if aborted, 0 if no packet and > 0 if packet. */ +int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block) +{ + AVPacketList *pkt1; + int ret; + + pthread_mutex_lock(&q->mutex); + + for (;;) { + if (q->abort_request) { + ret = -1; + break; + } + + pkt1 = q->first_pkt; + if (pkt1) { + q->first_pkt = pkt1->next; + if (!q->first_pkt) + q->last_pkt = NULL; + q->nb_packets--; + //q->size -= pkt1->pkt.size + sizeof(*pkt1); + q->size -= pkt1->pkt.size; + *pkt = pkt1->pkt; + av_free(pkt1); + ret = 1; + break; + } else if (!block) { + ret = 0; + break; + } else { + pthread_cond_wait(&q->cond, &q->mutex); + } + } + pthread_mutex_unlock(&q->mutex); + return ret; +} + +////////////////////////////////////////////////////////////////////////////////// // misc ////////////////////////////////////////////////////////////////////////////////// bool setup_vorbis_extradata(uint8_t **extradata, int *extradata_size, diff --git a/utils/ffmpeg_utils.h b/utils/ffmpeg_utils.h index be5b063..bf9f6c5 100644 --- a/utils/ffmpeg_utils.h +++ b/utils/ffmpeg_utils.h @@ -28,25 +28,62 @@ extern "C" { #endif #include "config.h" +#include "libavformat/avformat.h" #include "libavcodec/avcodec.h" #ifdef __cplusplus } #endif +//XXX hack!!! #define SF_NOPTS_VALUE ((uint64_t)AV_NOPTS_VALUE-1) namespace android { -status_t initFFmpeg(); -void deInitFFmpeg(); - +////////////////////////////////////////////////////////////////////////////////// +// log +////////////////////////////////////////////////////////////////////////////////// void nam_av_log_callback(void* ptr, int level, const char* fmt, va_list vl); void nam_av_log_set_flags(int arg); +////////////////////////////////////////////////////////////////////////////////// +// constructor and destructor +////////////////////////////////////////////////////////////////////////////////// +status_t initFFmpeg(); +void deInitFFmpeg(); + +////////////////////////////////////////////////////////////////////////////////// +// parser +////////////////////////////////////////////////////////////////////////////////// int is_extradata_compatible_with_android(AVCodecContext *avctx); int parser_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size); +////////////////////////////////////////////////////////////////////////////////// +// packet queue +////////////////////////////////////////////////////////////////////////////////// + +typedef struct PacketQueue { + AVPacket flush_pkt; + AVPacketList *first_pkt, *last_pkt; + int nb_packets; + int size; + int abort_request; + pthread_mutex_t mutex; + pthread_cond_t cond; +} PacketQueue; + +void packet_queue_init(PacketQueue *q); +void packet_queue_destroy(PacketQueue *q); +void packet_queue_flush(PacketQueue *q); +void packet_queue_end(PacketQueue *q); +void packet_queue_abort(PacketQueue *q); +int packet_queue_put(PacketQueue *q, AVPacket *pkt); +int packet_queue_put_nullpacket(PacketQueue *q, int stream_index); +int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block); + +////////////////////////////////////////////////////////////////////////////////// +// misc +////////////////////////////////////////////////////////////////////////////////// bool setup_vorbis_extradata(uint8_t **extradata, int *extradata_size, const uint8_t *header_start[3], const int header_len[3]); -- 2.11.0 From ab3fd2d047a2041185608f48f9ada671b3477766 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Sun, 10 Nov 2013 16:45:03 +0800 Subject: [PATCH 11/16] move some codec utils to codec_utils.cpp --- libstagefright/FFmpegExtractor/FFmpegExtractor.cpp | 105 ++--------------- utils/Android.mk | 6 +- utils/codec_utils.cpp | 125 +++++++++++++++++++++ utils/codec_utils.h | 38 +++++++ 4 files changed, 177 insertions(+), 97 deletions(-) create mode 100644 utils/codec_utils.cpp create mode 100644 utils/codec_utils.h diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp index a1bf11b..eaa9a6e 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp @@ -40,6 +40,7 @@ #include #include "include/avc_utils.h" +#include "utils/codec_utils.h" #include "utils/ffmpeg_utils.h" #include "utils/ffmpeg_cmdutils.h" #include "FFmpegExtractor.h" @@ -55,7 +56,6 @@ #define DEBUG_DISABLE_VIDEO 0 #define DEBUG_DISABLE_AUDIO 0 #define WAIT_KEY_PACKET_AFTER_SEEK 1 -#define DISABLE_NAL_TO_ANNEXB 0 #define DEBUG_PKT 0 enum { @@ -203,62 +203,6 @@ uint32_t FFmpegExtractor::flags() const { return flags; } -static void EncodeSize14(uint8_t **_ptr, size_t size) { - CHECK_LE(size, 0x3fff); - - uint8_t *ptr = *_ptr; - - *ptr++ = 0x80 | (size >> 7); - *ptr++ = size & 0x7f; - - *_ptr = ptr; -} - -static sp MakeMPEGVideoESDS(const sp &csd) { - sp esds = new ABuffer(csd->size() + 25); - - uint8_t *ptr = esds->data(); - *ptr++ = 0x03; - EncodeSize14(&ptr, 22 + csd->size()); - - *ptr++ = 0x00; // ES_ID - *ptr++ = 0x00; - - *ptr++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag - - *ptr++ = 0x04; - EncodeSize14(&ptr, 16 + csd->size()); - - *ptr++ = 0x40; // Audio ISO/IEC 14496-3 - - for (size_t i = 0; i < 12; ++i) { - *ptr++ = 0x00; - } - - *ptr++ = 0x05; - EncodeSize14(&ptr, csd->size()); - - memcpy(ptr, csd->data(), csd->size()); - - return esds; -} - -// Returns the sample rate based on the sampling frequency index -static uint32_t get_sample_rate(const uint8_t sf_index) -{ - static const uint32_t sample_rates[] = - { - 96000, 88200, 64000, 48000, 44100, 32000, - 24000, 22050, 16000, 12000, 11025, 8000 - }; - - if (sf_index < sizeof(sample_rates) / sizeof(sample_rates[0])) { - return sample_rates[sf_index]; - } - - return 0; -} - int FFmpegExtractor::check_extradata(AVCodecContext *avctx) { enum AVCodecID codec_id = AV_CODEC_ID_NONE; @@ -613,7 +557,6 @@ int FFmpegExtractor::stream_component_open(int stream_index) if (mVideoStream->duration != AV_NOPTS_VALUE) { int64_t duration = mVideoStream->duration * av_q2d(mVideoStream->time_base) * 1000000; printTime(duration); - ALOGV("video startTime: %lld", mVideoStream->start_time); if (mVideoStream->start_time != AV_NOPTS_VALUE) { ALOGV("video startTime:%lld", mVideoStream->start_time); } else { @@ -697,7 +640,7 @@ int FFmpegExtractor::stream_component_open(int stream_index) // c - channelConfig profile = ((header[0] & 0xf8) >> 3) - 1; sf_index = (header[0] & 0x07) << 1 | (header[1] & 0x80) >> 7; - sr = get_sample_rate(sf_index); + sr = getAACSampleRate(sf_index); if (sr == 0) { ALOGE("unsupport the sample rate"); return -1; @@ -1527,45 +1470,17 @@ retry: MediaBuffer *mediaBuffer = new MediaBuffer(pkt.size + FF_INPUT_BUFFER_PADDING_SIZE); mediaBuffer->meta_data()->clear(); mediaBuffer->set_range(0, pkt.size); -#if DISABLE_NAL_TO_ANNEXB - mNal2AnnexB = false; -#endif - if (mIsAVC && mNal2AnnexB) { - /* Convert H.264 NAL format to annex b */ - if (mNALLengthSize >= 3 && mNALLengthSize <= 4 ) - { - uint8_t *dst = (uint8_t *)mediaBuffer->data(); - - /* This only works for NAL sizes 3-4 */ - size_t len = pkt.size, i; - uint8_t *ptr = pkt.data; - while (len >= mNALLengthSize) { - uint32_t nal_len = 0; - for( i = 0; i < mNALLengthSize; i++ ) { - nal_len = (nal_len << 8) | ptr[i]; - dst[i] = 0; - } - dst[mNALLengthSize - 1] = 1; - if (nal_len > INT_MAX || nal_len > (unsigned int)len) { - status = ERROR_MALFORMED; - break; - } - dst += mNALLengthSize; - ptr += mNALLengthSize; - len -= mNALLengthSize; - memcpy(dst, ptr, nal_len); - - dst += nal_len; - ptr += nal_len; - len -= nal_len; - } - } else { - status = ERROR_MALFORMED; - } + //copy data + if (mIsAVC && mNal2AnnexB) { + /* This only works for NAL sizes 3-4 */ + CHECK(mNALLengthSize == 3 || mNALLengthSize == 4); + uint8_t *dst = (uint8_t *)mediaBuffer->data(); + /* Convert H.264 NAL format to annex b */ + status = convertNal2AnnexB(dst, pkt.size, pkt.data, pkt.size, mNALLengthSize); if (status != OK) { - ALOGV("status != OK"); + ALOGE("convertNal2AnnexB failed"); mediaBuffer->release(); mediaBuffer = NULL; av_free_packet(&pkt); diff --git a/utils/Android.mk b/utils/Android.mk index d2b5bb3..3a8e289 100644 --- a/utils/Android.mk +++ b/utils/Android.mk @@ -6,14 +6,16 @@ include external/ffmpeg/android/ffmpeg.mk LOCAL_SRC_FILES := \ ffmpeg_source.cpp \ ffmpeg_utils.cpp \ - ffmpeg_cmdutils.c + ffmpeg_cmdutils.c \ + codec_utils.cpp LOCAL_SHARED_LIBRARIES := \ libavcodec \ libavformat \ libavutil \ libutils \ - libcutils + libcutils \ + libstagefright_foundation LOCAL_MODULE := libffmpeg_utils diff --git a/utils/codec_utils.cpp b/utils/codec_utils.cpp new file mode 100644 index 0000000..8afc79e --- /dev/null +++ b/utils/codec_utils.cpp @@ -0,0 +1,125 @@ +/* + * Copyright 2012 Michael Chen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_NDEBUG 0 +#define LOG_TAG "codec_utils" +#include + +#include + +#include +#include +#include +#include + +#include "codec_utils.h" + +namespace android { + +static void EncodeSize14(uint8_t **_ptr, size_t size) { + CHECK_LE(size, 0x3fff); + + uint8_t *ptr = *_ptr; + + *ptr++ = 0x80 | (size >> 7); + *ptr++ = size & 0x7f; + + *_ptr = ptr; +} + +sp MakeMPEGVideoESDS(const sp &csd) { + sp esds = new ABuffer(csd->size() + 25); + + uint8_t *ptr = esds->data(); + *ptr++ = 0x03; + EncodeSize14(&ptr, 22 + csd->size()); + + *ptr++ = 0x00; // ES_ID + *ptr++ = 0x00; + + *ptr++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag + + *ptr++ = 0x04; + EncodeSize14(&ptr, 16 + csd->size()); + + *ptr++ = 0x40; // Audio ISO/IEC 14496-3 + + for (size_t i = 0; i < 12; ++i) { + *ptr++ = 0x00; + } + + *ptr++ = 0x05; + EncodeSize14(&ptr, csd->size()); + + memcpy(ptr, csd->data(), csd->size()); + + return esds; +} + +//Returns the sample rate based on the sampling frequency index +uint32_t getAACSampleRate(const uint8_t sf_index) +{ + static const uint32_t sample_rates[] = + { + 96000, 88200, 64000, 48000, 44100, 32000, + 24000, 22050, 16000, 12000, 11025, 8000 + }; + + if (sf_index < sizeof(sample_rates) / sizeof(sample_rates[0])) { + return sample_rates[sf_index]; + } + + return 0; +} + +//Convert H.264 NAL format to annex b +status_t convertNal2AnnexB(uint8_t *dst, size_t dst_size, + uint8_t *src, size_t src_size, size_t nal_len_size) +{ + size_t i = 0; + size_t nal_len = 0; + status_t status = OK; + + CHECK_EQ(dst_size, src_size); + CHECK(nal_len_size == 3 || nal_len_size == 4); + + while (src_size >= nal_len_size) { + nal_len = 0; + for( i = 0; i < nal_len_size; i++ ) { + nal_len = (nal_len << 8) | src[i]; + dst[i] = 0; + } + dst[nal_len_size - 1] = 1; + if (nal_len > INT_MAX || nal_len > src_size) { + status = ERROR_MALFORMED; + break; + } + dst += nal_len_size; + src += nal_len_size; + src_size -= nal_len_size; + + memcpy(dst, src, nal_len); + + dst += nal_len; + src += nal_len; + src_size -= nal_len; + } + + return status; +} + +} // namespace android + diff --git a/utils/codec_utils.h b/utils/codec_utils.h new file mode 100644 index 0000000..9c44109 --- /dev/null +++ b/utils/codec_utils.h @@ -0,0 +1,38 @@ +/* + * Copyright 2012 Michael Chen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CODEC_UTILS_H_ + +#define CODEC_UTILS_H_ + +#include +#include + +#include +#include + +namespace android { + +sp MakeMPEGVideoESDS(const sp &csd); +//Returns the sample rate based on the sampling frequency index +uint32_t getAACSampleRate(const uint8_t sf_index); +//Convert H.264 NAL format to annex b +status_t convertNal2AnnexB(uint8_t *dst, size_t dst_size, + uint8_t *src, size_t src_size, size_t nal_len_size); + +} // namespace android + +#endif // CODEC_UTILS_H_ -- 2.11.0 From 3199696cdc65dc9f1c1f1d08d25feba300be7c06 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Sun, 10 Nov 2013 20:54:38 +0800 Subject: [PATCH 12/16] fix rv20 --- libstagefright/FFmpegExtractor/FFmpegExtractor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp index eaa9a6e..c577d72 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp @@ -508,7 +508,7 @@ int FFmpegExtractor::stream_component_open(int stream_index) meta->setInt32(kKeyWMVVersion, kTypeWMVVer_9); break; case AV_CODEC_ID_RV20: - ALOGV("RV30"); + ALOGV("RV20"); 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 -- 2.11.0 From 7104d1ba1be5968a9c0a50e312f6859ab5116482 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Tue, 12 Nov 2013 00:30:36 +0800 Subject: [PATCH 13/16] cleanup FFmpegExtractor::stream_component_open --- libstagefright/FFmpegExtractor/FFmpegExtractor.cpp | 519 ++++++++------------- libstagefright/FFmpegExtractor/FFmpegExtractor.h | 39 +- .../codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp | 2 - .../codecs/ffmpegdec/adec/SoftFFmpegAudio.h | 30 +- .../codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp | 2 - .../codecs/ffmpegdec/vdec/SoftFFmpegVideo.h | 30 +- utils/Android.mk | 6 + utils/codec_utils.cpp | 383 ++++++++++++++- utils/codec_utils.h | 35 +- utils/ffmpeg_utils.cpp | 18 - utils/ffmpeg_utils.h | 18 + 11 files changed, 645 insertions(+), 437 deletions(-) diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp index c577d72..b12a613 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp @@ -22,6 +22,9 @@ #include /* INT_MAX */ #include +#include +#include +#include #include #include #include @@ -35,14 +38,11 @@ #include #include #include -#include -#include -#include - #include "include/avc_utils.h" + #include "utils/codec_utils.h" -#include "utils/ffmpeg_utils.h" #include "utils/ffmpeg_cmdutils.h" + #include "FFmpegExtractor.h" #define MAX_QUEUE_SIZE (15 * 1024 * 1024) @@ -66,7 +66,7 @@ enum { namespace android { struct FFmpegExtractor::Track : public MediaSource { - Track(FFmpegExtractor *extractor, sp meta, bool isAVC, + Track(FFmpegExtractor *extractor, sp meta, AVStream *stream, PacketQueue *queue); virtual status_t start(MetaData *params); @@ -269,26 +269,6 @@ int FFmpegExtractor::check_extradata(AVCodecContext *avctx) return 1; } -bool FFmpegExtractor::setupVorbisCodecSpecificData(sp meta, - AVCodecContext *avctx) -{ - uint8_t *header_start[3]; - int header_len[3]; - - if (avpriv_split_xiph_headers(avctx->extradata, - avctx->extradata_size, 30, - header_start, header_len) < 0) { - ALOGE("vorbis extradata corrupt."); - return false; - } - //identification header - meta->setData(kKeyVorbisInfo, 0, header_start[0], header_len[0]); - //setup header - meta->setData(kKeyVorbisBooks, 0, header_start[2], header_len[2]); - - return true; -} - void FFmpegExtractor::printTime(int64_t time) { int hours, mins, secs, us; @@ -355,11 +335,186 @@ bool FFmpegExtractor::is_codec_supported(enum AVCodecID codec_id) return supported; } +sp FFmpegExtractor::setVideoFormat(AVCodecContext *avctx) +{ + sp meta = NULL; + + CHECK_EQ(avctx->codec_type, AVMEDIA_TYPE_VIDEO); + + switch(avctx->codec_id) { + case AV_CODEC_ID_H264: + if (avctx->extradata[0] == 1) { + meta = setAVCFormat(avctx); + } else { + meta = setH264Format(avctx); + } + break; + case AV_CODEC_ID_MPEG4: + meta = setMPEG4Format(avctx); + break; + case AV_CODEC_ID_H263: + case AV_CODEC_ID_H263P: + case AV_CODEC_ID_H263I: + meta = setH263Format(avctx); + break; + case AV_CODEC_ID_MPEG1VIDEO: + case AV_CODEC_ID_MPEG2VIDEO: + meta = setMPEG2VIDEOFormat(avctx); + break; + case AV_CODEC_ID_VC1: + meta = setVC1Format(avctx); + break; + case AV_CODEC_ID_WMV1: + meta = setWMV1Format(avctx); + break; + case AV_CODEC_ID_WMV2: + meta = setWMV2Format(avctx); + break; + case AV_CODEC_ID_WMV3: + meta = setWMV3Format(avctx); + break; + case AV_CODEC_ID_RV20: + meta = setRV20Format(avctx); + break; + case AV_CODEC_ID_RV30: + meta = setRV30Format(avctx); + break; + case AV_CODEC_ID_RV40: + meta = setRV40Format(avctx); + break; + case AV_CODEC_ID_FLV1: + meta = setFLV1Format(avctx); + break; + case AV_CODEC_ID_HEVC: + meta = setHEVCFormat(avctx); + break; + default: + ALOGD("unsuppoted video codec(id:%d, name:%s), but give it a chance", + avctx->codec_id, avcodec_get_name(avctx->codec_id)); + meta = new MetaData; + meta->setInt32(kKeyCodecId, avctx->codec_id); + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_FFMPEG); + if (avctx->extradata_size > 0) { + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + } + //CHECK(!"Should not be here. Unsupported codec."); + break; + } + + if (meta != NULL) { + ALOGI("width: %d, height: %d, bit_rate: %d", + avctx->width, avctx->height, avctx->bit_rate); + + meta->setInt32(kKeyWidth, avctx->width); + meta->setInt32(kKeyHeight, avctx->height); + if (avctx->bit_rate > 0) { + meta->setInt32(kKeyBitRate, avctx->bit_rate); + } + } + + return meta; +} + +sp FFmpegExtractor::setAudioFormat(AVCodecContext *avctx) +{ + sp meta = NULL; + + CHECK_EQ(avctx->codec_type, AVMEDIA_TYPE_AUDIO); + + switch(avctx->codec_id) { + case AV_CODEC_ID_MP2: + meta = setMP2Format(avctx); + break; + case AV_CODEC_ID_MP3: + meta = setMP3Format(avctx); + break; + case AV_CODEC_ID_VORBIS: + meta = setVORBISFormat(avctx); + break; + case AV_CODEC_ID_AC3: + meta = setAC3Format(avctx); + break; + case AV_CODEC_ID_AAC: + meta = setAACFormat(avctx); + break; + case AV_CODEC_ID_WMAV1: + meta = setWMAV1Format(avctx); + break; + case AV_CODEC_ID_WMAV2: + meta = setWMAV2Format(avctx); + break; + case AV_CODEC_ID_WMAPRO: + meta = setWMAProFormat(avctx); + break; + case AV_CODEC_ID_WMALOSSLESS: + meta = setWMALossLessFormat(avctx); + break; + case AV_CODEC_ID_COOK: + meta = setRAFormat(avctx); + break; + case AV_CODEC_ID_APE: + meta = setAPEFormat(avctx); + break; + case AV_CODEC_ID_DTS: + meta = setDTSFormat(avctx); + break; + case AV_CODEC_ID_FLAC: + meta = setFLACFormat(avctx); + break; + default: + ALOGD("unsuppoted audio codec(id:%d, name:%s), but give it a chance", + avctx->codec_id, avcodec_get_name(avctx->codec_id)); + meta = new MetaData; + meta->setInt32(kKeyCodecId, avctx->codec_id); + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FFMPEG); + if (avctx->extradata_size > 0) { + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + } + //CHECK(!"Should not be here. Unsupported codec."); + break; + } + + if (meta != NULL) { + ALOGI("bit_rate: %d, sample_rate: %d, channels: %d, " + "bits_per_coded_sample: %d, block_align:%d", + avctx->bit_rate, avctx->sample_rate, avctx->channels, + avctx->bits_per_coded_sample, avctx->block_align); + + meta->setInt32(kKeyChannelCount, avctx->channels); + meta->setInt32(kKeyBitRate, avctx->bit_rate); + meta->setInt32(kKeyBitspersample, avctx->bits_per_coded_sample); + meta->setInt32(kKeySampleRate, avctx->sample_rate); + meta->setInt32(kKeyBlockAlign, avctx->block_align); + meta->setInt32(kKeySampleFormat, avctx->sample_fmt); + } + + return meta; +} + +void FFmpegExtractor::setStreamDurationMeta(AVStream *stream, sp &meta) +{ + AVCodecContext *avctx = stream->codec; + + if (stream->duration != AV_NOPTS_VALUE) { + int64_t duration = stream->duration * av_q2d(stream->time_base) * 1000000; + printTime(duration); + const char *s = av_get_media_type_string(avctx->codec_type); + if (stream->start_time != AV_NOPTS_VALUE) { + ALOGV("%s startTime:%lld", s, stream->start_time); + } else { + ALOGV("%s startTime:N/A", s); + } + meta->setInt64(kKeyDuration, duration); + } else { + // default when no stream duration + meta->setInt64(kKeyDuration, mFormatCtx->duration); + } +} + int FFmpegExtractor::stream_component_open(int stream_index) { AVCodecContext *avctx = NULL; sp meta = NULL; - bool isAVC = false; bool supported = false; uint32_t type = 0; const void *data = NULL; @@ -419,158 +574,17 @@ int FFmpegExtractor::stream_component_open(int stream_index) ALOGV("video stream no extradata, but we can ignore it."); } - meta = new MetaData; - - switch(avctx->codec_id) { - case AV_CODEC_ID_H264: - /** - * H.264 Video Types - * http://msdn.microsoft.com/en-us/library/dd757808(v=vs.85).aspx - */ - //if (avctx->codec_tag && avctx->codec_tag == AV_RL32("avc1")) { - if (avctx->extradata[0] == 1 /* configurationVersion */) { - // H.264 bitstream without start codes. - isAVC = true; - ALOGV("AVC"); - - if (avctx->width == 0 || avctx->height == 0) { - int32_t width, height; - sp seqParamSet = new ABuffer(avctx->extradata_size - 8); - memcpy(seqParamSet->data(), avctx->extradata + 8, avctx->extradata_size - 8); - FindAVCDimensions(seqParamSet, &width, &height); - avctx->width = width; - avctx->height = height; - } - - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); - meta->setData(kKeyAVCC, kTypeAVCC, avctx->extradata, avctx->extradata_size); - } else { - // H.264 bitstream with start codes. - isAVC = false; - ALOGV("H264"); - - /* set NULL to release meta as we will new a meta in MakeAVCCodecSpecificData() fxn */ - meta->clear(); - meta = NULL; - - sp buffer = new ABuffer(avctx->extradata_size); - memcpy(buffer->data(), avctx->extradata, avctx->extradata_size); - meta = MakeAVCCodecSpecificData(buffer); - } - break; - case AV_CODEC_ID_MPEG4: - ALOGV("MPEG4"); - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); - { - sp csd = new ABuffer(avctx->extradata_size); - memcpy(csd->data(), avctx->extradata, avctx->extradata_size); - sp esds = MakeMPEGVideoESDS(csd); - meta->setData(kKeyESDS, kTypeESDS, esds->data(), esds->size()); - } - break; - 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 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); - memcpy(csd->data(), avctx->extradata, avctx->extradata_size); - sp esds = MakeMPEGVideoESDS(csd); - meta->setData(kKeyESDS, kTypeESDS, esds->data(), esds->size()); - } - break; - 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 AV_CODEC_ID_WMV1: - ALOGV("WMV1"); - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_WMV); - meta->setInt32(kKeyWMVVersion, kTypeWMVVer_7); - break; - 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 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 AV_CODEC_ID_RV20: - ALOGV("RV20"); - 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 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 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 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)); - meta = new MetaData; - meta->setInt32(kKeyCodecId, avctx->codec_id); - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_FFMPEG); - if (avctx->extradata_size > 0) { - meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); - } - //CHECK(!"Should not be here. Unsupported codec."); - break; + meta = setVideoFormat(avctx); + if (meta == NULL) { + ALOGE("setVideoFormat failed"); + return -1; } - ALOGI("width: %d, height: %d, bit_rate: %d", - avctx->width, avctx->height, avctx->bit_rate); - - meta->setInt32(kKeyWidth, avctx->width); - meta->setInt32(kKeyHeight, avctx->height); - if (avctx->bit_rate > 0) - meta->setInt32(kKeyBitRate, avctx->bit_rate); - if (mVideoStream->duration != AV_NOPTS_VALUE) { - int64_t duration = mVideoStream->duration * av_q2d(mVideoStream->time_base) * 1000000; - printTime(duration); - if (mVideoStream->start_time != AV_NOPTS_VALUE) { - ALOGV("video startTime:%lld", mVideoStream->start_time); - } else { - ALOGV("video startTime:N/A"); - } - meta->setInt64(kKeyDuration, duration); - } else { - // default when no stream duration - meta->setInt64(kKeyDuration, mFormatCtx->duration); - } + setStreamDurationMeta(mVideoStream, meta); ALOGV("create a video track"); index = mTracks.add( - stream_index, new Track(this, meta, isAVC, mVideoStream, &mVideoQ)); + stream_index, new Track(this, meta, mVideoStream, &mVideoQ)); mDefersToCreateVideoTrack = false; @@ -600,149 +614,17 @@ int FFmpegExtractor::stream_component_open(int stream_index) ALOGV("audio stream no extradata, but we can ignore it."); } - switch(avctx->codec_id) { - case AV_CODEC_ID_MP2: - ALOGV("MP2"); - meta = new MetaData; - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II); - break; - case AV_CODEC_ID_MP3: - ALOGV("MP3"); - meta = new MetaData; - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); - break; - case AV_CODEC_ID_VORBIS: - ALOGV("VORBIS"); - meta = new MetaData; - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); - if (!setupVorbisCodecSpecificData(meta, avctx)) { - return -1; - } - break; - case AV_CODEC_ID_AC3: - ALOGV("AC3"); - meta = new MetaData; - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3); - break; - case AV_CODEC_ID_AAC: - ALOGV("AAC"); - uint32_t sr; - const uint8_t *header; - uint8_t profile, sf_index, channel; - - header = avctx->extradata; - CHECK(header != NULL); - - // AudioSpecificInfo follows - // oooo offf fccc c000 - // o - audioObjectType - // f - samplingFreqIndex - // c - channelConfig - profile = ((header[0] & 0xf8) >> 3) - 1; - sf_index = (header[0] & 0x07) << 1 | (header[1] & 0x80) >> 7; - sr = getAACSampleRate(sf_index); - if (sr == 0) { - ALOGE("unsupport the sample rate"); - return -1; - } - channel = (header[1] >> 3) & 0xf; - ALOGV("profile: %d, sf_index: %d, channel: %d", profile, sf_index, channel); - - meta = MakeAACCodecSpecificData(profile, sf_index, channel); - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); - break; - 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 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 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 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 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 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 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 AV_CODEC_ID_FLAC: - ALOGV("FLAC"); - meta = new MetaData; - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC); - meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); - break; - default: - ALOGD("unsuppoted audio codec(id:%d, name:%s), but give it a chance", - avctx->codec_id, avcodec_get_name(avctx->codec_id)); - meta = new MetaData; - meta->setInt32(kKeyCodecId, avctx->codec_id); - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FFMPEG); - if (avctx->extradata_size > 0) { - meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); - } - //CHECK(!"Should not be here. Unsupported codec."); - break; + meta = setAudioFormat(avctx); + if (meta == NULL) { + ALOGE("setAudioFormat failed"); + return -1; } - ALOGI("bit_rate: %d, sample_rate: %d, channels: %d, " - "bits_per_coded_sample: %d, block_align:%d", - avctx->bit_rate, avctx->sample_rate, avctx->channels, - avctx->bits_per_coded_sample, avctx->block_align); - - meta->setInt32(kKeyChannelCount, avctx->channels); - meta->setInt32(kKeyBitRate, avctx->bit_rate); - meta->setInt32(kKeyBitspersample, avctx->bits_per_coded_sample); - meta->setInt32(kKeySampleRate, avctx->sample_rate); - meta->setInt32(kKeyBlockAlign, avctx->block_align); - meta->setInt32(kKeySampleFormat, avctx->sample_fmt); - if (mAudioStream->duration != AV_NOPTS_VALUE) { - int64_t duration = mAudioStream->duration * av_q2d(mAudioStream->time_base) * 1000000; - printTime(duration); - if (mAudioStream->start_time != AV_NOPTS_VALUE) { - ALOGV("audio startTime:%lld", mAudioStream->start_time); - } else { - ALOGV("audio startTime:N/A"); - } - meta->setInt64(kKeyDuration, duration); - } else { - // default when no stream duration - meta->setInt64(kKeyDuration, mFormatCtx->duration); - } + setStreamDurationMeta(mAudioStream, meta); ALOGV("create a audio track"); index = mTracks.add( - stream_index, new Track(this, meta, false, mAudioStream, &mAudioQ)); + stream_index, new Track(this, meta, mAudioStream, &mAudioQ)); mDefersToCreateAudioTrack = false; @@ -1308,20 +1190,25 @@ fail: //////////////////////////////////////////////////////////////////////////////// FFmpegExtractor::Track::Track( - FFmpegExtractor *extractor, sp meta, bool isAVC, + FFmpegExtractor *extractor, sp meta, AVStream *stream, PacketQueue *queue) : mExtractor(extractor), mMeta(meta), - mIsAVC(isAVC), + mIsAVC(false), + mNal2AnnexB(false), mStream(stream), mQueue(queue) { const char *mime; /* H.264 Video Types */ { - mNal2AnnexB = false; + AVCodecContext *avctx = stream->codec; + + if (avctx->codec_id == AV_CODEC_ID_H264 + && avctx->extradata_size > 0 + && avctx->extradata[0] == 1) { + mIsAVC = true; - if (mIsAVC) { uint32_t type; const void *data; size_t size; diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.h b/libstagefright/FFmpegExtractor/FFmpegExtractor.h index c1089ae..f096dea 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.h +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.h @@ -23,41 +23,8 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include /* INT_MAX */ - -#include "config.h" -#include "libavutil/avstring.h" -#include "libavutil/colorspace.h" -#include "libavutil/mathematics.h" -#include "libavutil/pixdesc.h" -#include "libavutil/imgutils.h" -#include "libavutil/dict.h" -#include "libavutil/parseutils.h" -#include "libavutil/samplefmt.h" -#include "libavutil/avassert.h" -#include "libavformat/avformat.h" -#include "libavdevice/avdevice.h" -#include "libswscale/swscale.h" -#include "libavcodec/audioconvert.h" -#include "libavutil/opt.h" -#include "libavutil/internal.h" -#include "libavcodec/avfft.h" -#include "libavcodec/xiph.h" -#include "libswresample/swresample.h" - #include "utils/ffmpeg_utils.h" -#ifdef __cplusplus -} -#endif - namespace android { struct ABuffer; @@ -130,9 +97,11 @@ private: void deInitStreams(); void fetchStuffsFromSniffedMeta(const sp &meta); void setFFmpegDefaultOpts(); - bool setupVorbisCodecSpecificData(sp meta, AVCodecContext *avctx); void printTime(int64_t time); - bool is_codec_supported(enum AVCodecID codec_id); + bool is_codec_supported(enum AVCodecID codec_id); + sp setVideoFormat(AVCodecContext *avctx); + sp setAudioFormat(AVCodecContext *avctx); + void setStreamDurationMeta(AVStream *stream, sp &meta); int stream_component_open(int stream_index); void stream_component_close(int stream_index); void reachedEOS(enum AVMediaType media_type); diff --git a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp index ba1487c..82650dc 100644 --- a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp +++ b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp @@ -24,8 +24,6 @@ #include #include -#include "utils/ffmpeg_utils.h" - #define DEBUG_PKT 0 #define DEBUG_FRM 0 diff --git a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h index d731a2a..a9c2dec 100644 --- a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h +++ b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h @@ -25,35 +25,7 @@ #error "__GNUC__ cflags should be enabled" #endif -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include /* INT_MAX */ - -#include "config.h" -#include "libavutil/avstring.h" -#include "libavutil/colorspace.h" -#include "libavutil/mathematics.h" -#include "libavutil/pixdesc.h" -#include "libavutil/imgutils.h" -#include "libavutil/dict.h" -#include "libavutil/parseutils.h" -#include "libavutil/samplefmt.h" -#include "libavutil/avassert.h" -#include "libavformat/avformat.h" -#include "libavdevice/avdevice.h" -#include "libswscale/swscale.h" -#include "libavutil/opt.h" -#include "libavutil/internal.h" -#include "libavcodec/avfft.h" -#include "libswresample/swresample.h" - -#ifdef __cplusplus -} -#endif +#include "utils/ffmpeg_utils.h" const int AVCODEC_MAX_AUDIO_FRAME_SIZE = 192000; // Deprecated in ffmpeg diff --git a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp index 3634dcb..667b609 100644 --- a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp +++ b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp @@ -24,8 +24,6 @@ #include #include -#include "utils/ffmpeg_utils.h" - #define DEBUG_PKT 0 #define DEBUG_FRM 0 diff --git a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h index 8371fa1..5a971d9 100644 --- a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h +++ b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h @@ -20,35 +20,7 @@ #include "SimpleSoftOMXComponent.h" -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include /* INT_MAX */ - -#include "config.h" -#include "libavutil/avstring.h" -#include "libavutil/colorspace.h" -#include "libavutil/mathematics.h" -#include "libavutil/pixdesc.h" -#include "libavutil/imgutils.h" -#include "libavutil/dict.h" -#include "libavutil/parseutils.h" -#include "libavutil/samplefmt.h" -#include "libavutil/avassert.h" -#include "libavformat/avformat.h" -#include "libavdevice/avdevice.h" -#include "libswscale/swscale.h" -#include "libavutil/opt.h" -#include "libavutil/internal.h" -#include "libavcodec/avfft.h" -#include "libswresample/swresample.h" - -#ifdef __cplusplus -} -#endif +#include "utils/ffmpeg_utils.h" namespace android { diff --git a/utils/Android.mk b/utils/Android.mk index 3a8e289..25403a9 100644 --- a/utils/Android.mk +++ b/utils/Android.mk @@ -9,12 +9,18 @@ LOCAL_SRC_FILES := \ ffmpeg_cmdutils.c \ codec_utils.cpp +LOCAL_C_INCLUDES += \ + $(TOP)/frameworks/native/include/media/openmax \ + $(TOP)/frameworks/av/include \ + $(TOP)/frameworks/av/media/libstagefright + LOCAL_SHARED_LIBRARIES := \ libavcodec \ libavformat \ libavutil \ libutils \ libcutils \ + libstagefright \ libstagefright_foundation LOCAL_MODULE := libffmpeg_utils diff --git a/utils/codec_utils.cpp b/utils/codec_utils.cpp index 8afc79e..cc6a343 100644 --- a/utils/codec_utils.cpp +++ b/utils/codec_utils.cpp @@ -18,12 +18,23 @@ #define LOG_TAG "codec_utils" #include -#include +#ifdef __cplusplus +extern "C" { +#endif + +#include "config.h" +#include "libavcodec/xiph.h" +#ifdef __cplusplus +} +#endif + +#include #include #include #include #include +#include "include/avc_utils.h" #include "codec_utils.h" @@ -40,7 +51,7 @@ static void EncodeSize14(uint8_t **_ptr, size_t size) { *_ptr = ptr; } -sp MakeMPEGVideoESDS(const sp &csd) { +static sp MakeMPEGVideoESDS(const sp &csd) { sp esds = new ABuffer(csd->size() + 25); uint8_t *ptr = esds->data(); @@ -70,7 +81,7 @@ sp MakeMPEGVideoESDS(const sp &csd) { } //Returns the sample rate based on the sampling frequency index -uint32_t getAACSampleRate(const uint8_t sf_index) +static uint32_t getAACSampleRate(const uint8_t sf_index) { static const uint32_t sample_rates[] = { @@ -85,6 +96,372 @@ uint32_t getAACSampleRate(const uint8_t sf_index) return 0; } +//video + +//H.264 Video Types +//http://msdn.microsoft.com/en-us/library/dd757808(v=vs.85).aspx + +// H.264 bitstream without start codes. +sp setAVCFormat(AVCodecContext *avctx) +{ + ALOGV("AVC"); + + CHECK_EQ(avctx->codec_id, AV_CODEC_ID_H264); + CHECK_GT(avctx->extradata_size, 0); + CHECK_EQ(avctx->extradata[0], 1); //configurationVersion + + if (avctx->width == 0 || avctx->height == 0) { + int32_t width, height; + sp seqParamSet = new ABuffer(avctx->extradata_size - 8); + memcpy(seqParamSet->data(), avctx->extradata + 8, avctx->extradata_size - 8); + FindAVCDimensions(seqParamSet, &width, &height); + avctx->width = width; + avctx->height = height; + } + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); + meta->setData(kKeyAVCC, kTypeAVCC, avctx->extradata, avctx->extradata_size); + + return meta; +} + +// H.264 bitstream with start codes. +sp setH264Format(AVCodecContext *avctx) +{ + ALOGV("H264"); + + CHECK_EQ(avctx->codec_id, AV_CODEC_ID_H264); + CHECK_NE(avctx->extradata[0], 1); //configurationVersion + + sp buffer = new ABuffer(avctx->extradata_size); + memcpy(buffer->data(), avctx->extradata, avctx->extradata_size); + return MakeAVCCodecSpecificData(buffer); +} + +sp setMPEG4Format(AVCodecContext *avctx) +{ + ALOGV("MPEG4"); + + sp csd = new ABuffer(avctx->extradata_size); + memcpy(csd->data(), avctx->extradata, avctx->extradata_size); + sp esds = MakeMPEGVideoESDS(csd); + + sp meta = new MetaData; + meta->setData(kKeyESDS, kTypeESDS, esds->data(), esds->size()); + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); + + return meta; +} + +sp setH263Format(AVCodecContext *avctx) +{ + ALOGV("H263"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); + + return meta; +} + +sp setMPEG2VIDEOFormat(AVCodecContext *avctx) +{ + ALOGV("MPEG%uVIDEO", avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO ? 2 : 1); + + sp csd = new ABuffer(avctx->extradata_size); + memcpy(csd->data(), avctx->extradata, avctx->extradata_size); + sp esds = MakeMPEGVideoESDS(csd); + + sp meta = new MetaData; + meta->setData(kKeyESDS, kTypeESDS, esds->data(), esds->size()); + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2); + + return meta; +} + +sp setVC1Format(AVCodecContext *avctx) +{ + ALOGV("VC1"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VC1); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + + return meta; +} + +sp setWMV1Format(AVCodecContext *avctx) +{ + ALOGV("WMV1"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_WMV); + meta->setInt32(kKeyWMVVersion, kTypeWMVVer_7); + + return meta; +} + +sp setWMV2Format(AVCodecContext *avctx) +{ + ALOGV("WMV2"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_WMV); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + meta->setInt32(kKeyWMVVersion, kTypeWMVVer_8); + + return meta; +} + +sp setWMV3Format(AVCodecContext *avctx) +{ + ALOGV("WMV3"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_WMV); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + meta->setInt32(kKeyWMVVersion, kTypeWMVVer_9); + + return meta; +} + +sp setRV20Format(AVCodecContext *avctx) +{ + ALOGV("RV20"); + + sp meta = new MetaData; + 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/RealVide + + return meta; +} + +sp setRV30Format(AVCodecContext *avctx) +{ + ALOGV("RV30"); + + sp meta = new MetaData; + 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/RealVide + + return meta; +} + +sp setRV40Format(AVCodecContext *avctx) +{ + ALOGV("RV40"); + + sp meta = new MetaData; + 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/RealVide + + return meta; +} + +sp setFLV1Format(AVCodecContext *avctx) +{ + ALOGV("FLV1(Sorenson H263)"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_FLV1); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + + return meta; +} + +sp setHEVCFormat(AVCodecContext *avctx) +{ + ALOGV("HEVC"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + + return meta; +} + +//audio + +sp setMP2Format(AVCodecContext *avctx) +{ + ALOGV("MP2"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II); + + return meta; +} + +sp setMP3Format(AVCodecContext *avctx) +{ + ALOGV("MP3"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); + + return meta; +} + +sp setVORBISFormat(AVCodecContext *avctx) +{ + ALOGV("VORBIS"); + + uint8_t *header_start[3]; + int header_len[3]; + if (avpriv_split_xiph_headers(avctx->extradata, + avctx->extradata_size, 30, + header_start, header_len) < 0) { + ALOGE("vorbis extradata corrupt."); + return NULL; + } + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); + //identification header + meta->setData(kKeyVorbisInfo, 0, header_start[0], header_len[0]); + //setup header + meta->setData(kKeyVorbisBooks, 0, header_start[2], header_len[2]); + + return meta; +} + +sp setAC3Format(AVCodecContext *avctx) +{ + ALOGV("AC3"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3); + + return meta; +} + +sp setAACFormat(AVCodecContext *avctx) +{ + ALOGV("AAC"); + + uint32_t sr; + const uint8_t *header; + uint8_t profile, sf_index, channel; + + header = avctx->extradata; + CHECK(header != NULL); + + // AudioSpecificInfo follows + // oooo offf fccc c000 + // o - audioObjectType + // f - samplingFreqIndex + // c - channelConfig + profile = ((header[0] & 0xf8) >> 3) - 1; + sf_index = (header[0] & 0x07) << 1 | (header[1] & 0x80) >> 7; + sr = getAACSampleRate(sf_index); + if (sr == 0) { + ALOGE("unsupport the aac sample rate"); + return NULL; + } + channel = (header[1] >> 3) & 0xf; + ALOGV("aac profile: %d, sf_index: %d, channel: %d", profile, sf_index, channel); + + sp meta = MakeAACCodecSpecificData(profile, sf_index, channel); + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); + + return meta; +} + +sp setWMAV1Format(AVCodecContext *avctx) +{ + ALOGV("WMAV1"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_WMA); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + meta->setInt32(kKeyWMAVersion, kTypeWMA); //FIXME version? + + return meta; +} + +sp setWMAV2Format(AVCodecContext *avctx) +{ + ALOGV("WMAV2"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_WMA); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + meta->setInt32(kKeyWMAVersion, kTypeWMA); + + return meta; +} + +sp setWMAProFormat(AVCodecContext *avctx) +{ + ALOGV("WMAPro"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_WMA); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + meta->setInt32(kKeyWMAVersion, kTypeWMAPro); + + return meta; +} + +sp setWMALossLessFormat(AVCodecContext *avctx) +{ + ALOGV("WMALOSSLESS"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_WMA); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + meta->setInt32(kKeyWMAVersion, kTypeWMALossLess); + + return meta; +} + +sp setRAFormat(AVCodecContext *avctx) +{ + ALOGV("COOK"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RA); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + + return meta; +} + +sp setAPEFormat(AVCodecContext *avctx) +{ + ALOGV("APE"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_APE); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + + return meta; +} + +sp setDTSFormat(AVCodecContext *avctx) +{ + ALOGV("DTS"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_DTS); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + + return meta; +} + +sp setFLACFormat(AVCodecContext *avctx) +{ + ALOGV("FLAC"); + + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC); + meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size); + + return meta; +} + //Convert H.264 NAL format to annex b status_t convertNal2AnnexB(uint8_t *dst, size_t dst_size, uint8_t *src, size_t src_size, size_t nal_len_size) diff --git a/utils/codec_utils.h b/utils/codec_utils.h index 9c44109..723a72a 100644 --- a/utils/codec_utils.h +++ b/utils/codec_utils.h @@ -24,11 +24,40 @@ #include #include +#include "ffmpeg_utils.h" + namespace android { -sp MakeMPEGVideoESDS(const sp &csd); -//Returns the sample rate based on the sampling frequency index -uint32_t getAACSampleRate(const uint8_t sf_index); +//video +sp setAVCFormat(AVCodecContext *avctx); +sp setH264Format(AVCodecContext *avctx); +sp setMPEG4Format(AVCodecContext *avctx); +sp setH263Format(AVCodecContext *avctx); +sp setMPEG2VIDEOFormat(AVCodecContext *avctx); +sp setVC1Format(AVCodecContext *avctx); +sp setWMV1Format(AVCodecContext *avctx); +sp setWMV2Format(AVCodecContext *avctx); +sp setWMV3Format(AVCodecContext *avctx); +sp setRV20Format(AVCodecContext *avctx); +sp setRV30Format(AVCodecContext *avctx); +sp setRV40Format(AVCodecContext *avctx); +sp setFLV1Format(AVCodecContext *avctx); +sp setHEVCFormat(AVCodecContext *avctx); +//audio +sp setMP2Format(AVCodecContext *avctx); +sp setMP3Format(AVCodecContext *avctx); +sp setVORBISFormat(AVCodecContext *avctx); +sp setAC3Format(AVCodecContext *avctx); +sp setAACFormat(AVCodecContext *avctx); +sp setWMAV1Format(AVCodecContext *avctx); +sp setWMAV2Format(AVCodecContext *avctx); +sp setWMAProFormat(AVCodecContext *avctx); +sp setWMALossLessFormat(AVCodecContext *avctx); +sp setRAFormat(AVCodecContext *avctx); +sp setAPEFormat(AVCodecContext *avctx); +sp setDTSFormat(AVCodecContext *avctx); +sp setFLACFormat(AVCodecContext *avctx); + //Convert H.264 NAL format to annex b status_t convertNal2AnnexB(uint8_t *dst, size_t dst_size, uint8_t *src, size_t src_size, size_t nal_len_size); diff --git a/utils/ffmpeg_utils.cpp b/utils/ffmpeg_utils.cpp index a509698..4ba2af7 100644 --- a/utils/ffmpeg_utils.cpp +++ b/utils/ffmpeg_utils.cpp @@ -32,24 +32,6 @@ extern "C" { #include #include /* INT_MAX */ -#include "libavutil/avstring.h" -#include "libavutil/colorspace.h" -#include "libavutil/mathematics.h" -#include "libavutil/pixdesc.h" -#include "libavutil/imgutils.h" -#include "libavutil/dict.h" -#include "libavutil/parseutils.h" -#include "libavutil/samplefmt.h" -#include "libavutil/avassert.h" -#include "libavformat/avformat.h" -#include "libavdevice/avdevice.h" -#include "libswscale/swscale.h" -#include "libavcodec/audioconvert.h" -#include "libavutil/opt.h" -#include "libavutil/internal.h" -#include "libavcodec/avfft.h" -#include "libswresample/swresample.h" - #undef strncpy #include diff --git a/utils/ffmpeg_utils.h b/utils/ffmpeg_utils.h index bf9f6c5..b47cc7e 100644 --- a/utils/ffmpeg_utils.h +++ b/utils/ffmpeg_utils.h @@ -31,6 +31,24 @@ extern "C" { #include "libavformat/avformat.h" #include "libavcodec/avcodec.h" +#include "libavutil/avstring.h" +#include "libavutil/colorspace.h" +#include "libavutil/mathematics.h" +#include "libavutil/pixdesc.h" +#include "libavutil/imgutils.h" +#include "libavutil/dict.h" +#include "libavutil/parseutils.h" +#include "libavutil/samplefmt.h" +#include "libavutil/avassert.h" +#include "libavformat/avformat.h" +#include "libavdevice/avdevice.h" +#include "libswscale/swscale.h" +#include "libavutil/opt.h" +#include "libavutil/internal.h" +#include "libavcodec/avfft.h" +#include "libavcodec/xiph.h" +#include "libswresample/swresample.h" + #ifdef __cplusplus } #endif -- 2.11.0 From 5ab624e1bd993e300a9d4ae03adaeef6013aed35 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Wed, 13 Nov 2013 19:45:53 +0800 Subject: [PATCH 14/16] cleanup --- libstagefright/FFmpegExtractor/FFmpegExtractor.cpp | 22 ++++++++++++---------- libstagefright/FFmpegExtractor/FFmpegExtractor.h | 6 +++--- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp index b12a613..af5ddb4 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp @@ -335,10 +335,12 @@ bool FFmpegExtractor::is_codec_supported(enum AVCodecID codec_id) return supported; } -sp FFmpegExtractor::setVideoFormat(AVCodecContext *avctx) +sp FFmpegExtractor::setVideoFormat(AVStream *stream) { + AVCodecContext *avctx = NULL; sp meta = NULL; + avctx = stream->codec; CHECK_EQ(avctx->codec_type, AVMEDIA_TYPE_VIDEO); switch(avctx->codec_id) { @@ -409,16 +411,19 @@ sp FFmpegExtractor::setVideoFormat(AVCodecContext *avctx) meta->setInt32(kKeyHeight, avctx->height); if (avctx->bit_rate > 0) { meta->setInt32(kKeyBitRate, avctx->bit_rate); - } + } + setDurationMetaData(stream, meta); } return meta; } -sp FFmpegExtractor::setAudioFormat(AVCodecContext *avctx) +sp FFmpegExtractor::setAudioFormat(AVStream *stream) { + AVCodecContext *avctx = NULL; sp meta = NULL; + avctx = stream->codec; CHECK_EQ(avctx->codec_type, AVMEDIA_TYPE_AUDIO); switch(avctx->codec_id) { @@ -486,12 +491,13 @@ sp FFmpegExtractor::setAudioFormat(AVCodecContext *avctx) meta->setInt32(kKeySampleRate, avctx->sample_rate); meta->setInt32(kKeyBlockAlign, avctx->block_align); meta->setInt32(kKeySampleFormat, avctx->sample_fmt); + setDurationMetaData(stream, meta); } return meta; } -void FFmpegExtractor::setStreamDurationMeta(AVStream *stream, sp &meta) +void FFmpegExtractor::setDurationMetaData(AVStream *stream, sp &meta) { AVCodecContext *avctx = stream->codec; @@ -574,14 +580,12 @@ int FFmpegExtractor::stream_component_open(int stream_index) ALOGV("video stream no extradata, but we can ignore it."); } - meta = setVideoFormat(avctx); + meta = setVideoFormat(mVideoStream); if (meta == NULL) { ALOGE("setVideoFormat failed"); return -1; } - setStreamDurationMeta(mVideoStream, meta); - ALOGV("create a video track"); index = mTracks.add( stream_index, new Track(this, meta, mVideoStream, &mVideoQ)); @@ -614,14 +618,12 @@ int FFmpegExtractor::stream_component_open(int stream_index) ALOGV("audio stream no extradata, but we can ignore it."); } - meta = setAudioFormat(avctx); + meta = setAudioFormat(mAudioStream); if (meta == NULL) { ALOGE("setAudioFormat failed"); return -1; } - setStreamDurationMeta(mAudioStream, meta); - ALOGV("create a audio track"); index = mTracks.add( stream_index, new Track(this, meta, mAudioStream, &mAudioQ)); diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.h b/libstagefright/FFmpegExtractor/FFmpegExtractor.h index f096dea..78c6352 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.h +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.h @@ -99,9 +99,9 @@ private: void setFFmpegDefaultOpts(); void printTime(int64_t time); bool is_codec_supported(enum AVCodecID codec_id); - sp setVideoFormat(AVCodecContext *avctx); - sp setAudioFormat(AVCodecContext *avctx); - void setStreamDurationMeta(AVStream *stream, sp &meta); + sp setVideoFormat(AVStream *stream); + sp setAudioFormat(AVStream *stream); + void setDurationMetaData(AVStream *stream, sp &meta); int stream_component_open(int stream_index); void stream_component_close(int stream_index); void reachedEOS(enum AVMediaType media_type); -- 2.11.0 From b1d88351276e41f4449eed26c8d9fd73d1cd79f4 Mon Sep 17 00:00:00 2001 From: Chih-Wei Huang Date: Thu, 23 Jan 2014 15:25:00 +0800 Subject: [PATCH 15/16] change OMX.ffmpeg.vpx.decoder to OMX.ffmpeg.vp8.decoder for kitkat Add OMX.ffmpeg.vp9.decoder as well. --- .../codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp | 41 +++++++++++++++------- .../codecs/ffmpegdec/vdec/SoftFFmpegVideo.h | 3 +- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp index 667b609..7bf6c75 100644 --- a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp +++ b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp @@ -53,8 +53,10 @@ void SoftFFmpegVideo::setMode(const char *name) { mMode = MODE_RV; } else if (!strcmp(name, "OMX.ffmpeg.h264.decoder")) { mMode = MODE_H264; - } else if (!strcmp(name, "OMX.ffmpeg.vpx.decoder")) { - mMode = MODE_VPX; + } else if (!strcmp(name, "OMX.ffmpeg.vp8.decoder")) { + mMode = MODE_VP8; + } else if (!strcmp(name, "OMX.ffmpeg.vp9.decoder")) { + mMode = MODE_VP9; } else if (!strcmp(name, "OMX.ffmpeg.vc1.decoder")) { mMode = MODE_VC1; } else if (!strcmp(name, "OMX.ffmpeg.flv1.decoder")) { @@ -94,9 +96,9 @@ SoftFFmpegVideo::SoftFFmpegVideo( mStride(320), mOutputPortSettingsChange(NONE) { - setMode(name); + ALOGD("SoftFFmpegVideo component: %s mMode: %d appData: %p", name, mMode, appData); - ALOGD("SoftFFmpegVideo component: %s mMode: %d", name, mMode); + setMode(name); initPorts(); CHECK_EQ(initDecoder(), (status_t)OK); @@ -137,9 +139,13 @@ void SoftFFmpegVideo::initInputFormat(uint32_t mode, def.format.video.cMIMEType = const_cast(MEDIA_MIMETYPE_VIDEO_AVC); def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; break; - case MODE_VPX: - def.format.video.cMIMEType = const_cast(MEDIA_MIMETYPE_VIDEO_VPX); - def.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; + case MODE_VP8: + def.format.video.cMIMEType = const_cast(MEDIA_MIMETYPE_VIDEO_VP8); + def.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8; + break; + case MODE_VP9: + def.format.video.cMIMEType = const_cast(MEDIA_MIMETYPE_VIDEO_VP9); + def.format.video.eCompressionFormat = OMX_VIDEO_CodingVP9; break; case MODE_VC1: def.format.video.cMIMEType = const_cast(MEDIA_MIMETYPE_VIDEO_VC1); @@ -287,9 +293,12 @@ status_t SoftFFmpegVideo::initDecoder() { case MODE_H264: mCtx->codec_id = AV_CODEC_ID_H264; break; - case MODE_VPX: + case MODE_VP8: mCtx->codec_id = AV_CODEC_ID_VP8; break; + case MODE_VP9: + mCtx->codec_id = AV_CODEC_ID_VP9; + break; case MODE_VC1: mCtx->codec_id = AV_CODEC_ID_VC1; break; @@ -365,8 +374,11 @@ void SoftFFmpegVideo::getInputFormat(uint32_t mode, case MODE_H264: formatParams->eCompressionFormat = OMX_VIDEO_CodingAVC; break; - case MODE_VPX: - formatParams->eCompressionFormat = OMX_VIDEO_CodingVPX; + case MODE_VP8: + formatParams->eCompressionFormat = OMX_VIDEO_CodingVP8; + break; + case MODE_VP9: + formatParams->eCompressionFormat = OMX_VIDEO_CodingVP9; break; case MODE_VC1: formatParams->eCompressionFormat = OMX_VIDEO_CodingVC1; @@ -506,9 +518,14 @@ OMX_ERRORTYPE SoftFFmpegVideo::isRoleSupported( "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE - 1)) supported = false; break; - case MODE_VPX: + case MODE_VP8: + if (strncmp((const char *)roleParams->cRole, + "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE - 1)) + supported = false; + break; + case MODE_VP9: if (strncmp((const char *)roleParams->cRole, - "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE - 1)) + "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE - 1)) supported = false; break; case MODE_VC1: diff --git a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h index 5a971d9..6c28769 100644 --- a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h +++ b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h @@ -59,7 +59,8 @@ private: MODE_WMV, MODE_RV, MODE_H264, - MODE_VPX, + MODE_VP8, + MODE_VP9, MODE_VC1, MODE_FLV1, MODE_DIVX, -- 2.11.0 From 8f1521a5fa9a8f1ffe9d82a53dba8f91ad5672ed Mon Sep 17 00:00:00 2001 From: Chih-Wei Huang Date: Thu, 5 Jun 2014 10:47:52 +0800 Subject: [PATCH 16/16] disable verbose log --- libstagefright/FFmpegExtractor/FFmpegExtractor.cpp | 10 +++++----- libstagefright/NamExtractor.cpp | 1 - libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp | 8 +++++--- libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp | 8 +++++--- utils/codec_utils.cpp | 1 - utils/ffmpeg_source.cpp | 2 +- utils/ffmpeg_utils.cpp | 1 - 7 files changed, 16 insertions(+), 15 deletions(-) diff --git a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp index af5ddb4..cd6f851 100644 --- a/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp +++ b/libstagefright/FFmpegExtractor/FFmpegExtractor.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#define LOG_NDEBUG 0 #define LOG_TAG "FFmpegExtractor" #include @@ -57,6 +56,7 @@ #define DEBUG_DISABLE_AUDIO 0 #define WAIT_KEY_PACKET_AFTER_SEEK 1 #define DEBUG_PKT 0 +#define DEBUG_EXTRADATA 0 enum { NO_SEEK = 0, @@ -572,14 +572,14 @@ int FFmpegExtractor::stream_component_open(int stream_index) } return ret; } - +#if DEBUG_EXTRADATA if (avctx->extradata) { ALOGV("video stream extradata:"); hexdump(avctx->extradata, avctx->extradata_size); } else { ALOGV("video stream no extradata, but we can ignore it."); } - +#endif meta = setVideoFormat(mVideoStream); if (meta == NULL) { ALOGE("setVideoFormat failed"); @@ -610,14 +610,14 @@ int FFmpegExtractor::stream_component_open(int stream_index) } return ret; } - +#if DEBUG_EXTRADATA if (avctx->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."); } - +#endif meta = setAudioFormat(mAudioStream); if (meta == NULL) { ALOGE("setAudioFormat failed"); diff --git a/libstagefright/NamExtractor.cpp b/libstagefright/NamExtractor.cpp index 2b8b697..65b2ccf 100755 --- a/libstagefright/NamExtractor.cpp +++ b/libstagefright/NamExtractor.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#define LOG_NDEBUG 0 #define LOG_TAG "NamExtractor" #include diff --git a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp index 82650dc..d518691 100644 --- a/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp +++ b/libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#define LOG_NDEBUG 0 #define LOG_TAG "SoftFFmpegAudio" #include @@ -26,6 +25,7 @@ #define DEBUG_PKT 0 #define DEBUG_FRM 0 +#define DEBUG_EXTRADATA 0 namespace android { @@ -1064,11 +1064,11 @@ int32_t SoftFFmpegAudio::handleExtradata() { List &inQueue = getPortQueue(kInputPortIndex); BufferInfo *inInfo = *inQueue.begin(); OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; - +#if DEBUG_EXTRADATA ALOGI("got extradata, ignore: %d, size: %lu", mIgnoreExtradata, inHeader->nFilledLen); hexdump(inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen); - +#endif if (mIgnoreExtradata) { ALOGI("got extradata, size: %lu, but ignore it", inHeader->nFilledLen); } else { @@ -1120,8 +1120,10 @@ int32_t SoftFFmpegAudio::openDecoder() { } deinitVorbisHdr(); } +#if DEBUG_EXTRADATA ALOGI("extradata is ready, size: %d", mCtx->extradata_size); hexdump(mCtx->extradata, mCtx->extradata_size); +#endif mExtradataReady = true; } diff --git a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp index 7bf6c75..92b904d 100644 --- a/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp +++ b/libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#define LOG_NDEBUG 0 #define LOG_TAG "SoftFFmpegVideo" #include @@ -26,6 +25,7 @@ #define DEBUG_PKT 0 #define DEBUG_FRM 0 +#define DEBUG_EXTRADATA 0 static int decoder_reorder_pts = -1; @@ -718,11 +718,11 @@ int32_t SoftFFmpegVideo::handleExtradata() { List &inQueue = getPortQueue(kInputPortIndex); BufferInfo *inInfo = *inQueue.begin(); OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; - +#if DEBUG_EXTRADATA ALOGI("got extradata, ignore: %d, size: %lu", mIgnoreExtradata, inHeader->nFilledLen); hexdump(inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen); - +#endif if (mIgnoreExtradata) { ALOGI("got extradata, size: %lu, but ignore it", inHeader->nFilledLen); } else { @@ -760,8 +760,10 @@ int32_t SoftFFmpegVideo::openDecoder() { } if (!mExtradataReady) { +#if DEBUG_EXTRADATA ALOGI("extradata is ready, size: %d", mCtx->extradata_size); hexdump(mCtx->extradata, mCtx->extradata_size); +#endif mExtradataReady = true; } diff --git a/utils/codec_utils.cpp b/utils/codec_utils.cpp index cc6a343..14cc856 100644 --- a/utils/codec_utils.cpp +++ b/utils/codec_utils.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#define LOG_NDEBUG 0 #define LOG_TAG "codec_utils" #include diff --git a/utils/ffmpeg_source.cpp b/utils/ffmpeg_source.cpp index 9199194..c221333 100644 --- a/utils/ffmpeg_source.cpp +++ b/utils/ffmpeg_source.cpp @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define LOG_NDEBUG 0 + #define LOG_TAG "FFMPEG" #include diff --git a/utils/ffmpeg_utils.cpp b/utils/ffmpeg_utils.cpp index 4ba2af7..bb5f680 100644 --- a/utils/ffmpeg_utils.cpp +++ b/utils/ffmpeg_utils.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#define LOG_NDEBUG 0 #define LOG_TAG "FFMPEG" #include -- 2.11.0