hrev44000 adds 1 changeset to branch 'master' old head: e6cafb1a4882d34d99708e1641668f4480104472 new head: b95fa2488ad09133ca040fde61914b132680a079 ---------------------------------------------------------------------------- b95fa24: ffmpeg: don't use deprecated API in AVCodecDecoder. [ Jérôme Duval <jerome.duval@xxxxxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev44000 Commit: b95fa2488ad09133ca040fde61914b132680a079 URL: http://cgit.haiku-os.org/haiku/commit/?id=b95fa24 Author: Jérôme Duval <jerome.duval@xxxxxxxxx> Date: Wed Apr 11 21:44:50 2012 UTC ---------------------------------------------------------------------------- 5 files changed, 85 insertions(+), 78 deletions(-) .../media/plugins/ffmpeg/AVCodecDecoder.cpp | 51 +++++---- src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h | 2 +- .../media/plugins/ffmpeg/AVFormatReader.cpp | 100 ++++++++-------- .../media/plugins/ffmpeg/AVFormatWriter.cpp | 8 +- src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h | 2 +- ---------------------------------------------------------------------------- diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp index 9a1e0d3..1a08c0e 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp @@ -74,7 +74,7 @@ AVCodecDecoder::AVCodecDecoder() fFrame(0), fIsAudio(false), fCodec(NULL), - fContext(avcodec_alloc_context()), + fContext(avcodec_alloc_context3(NULL)), fInputPicture(avcodec_alloc_frame()), fOutputPicture(avcodec_alloc_frame()), @@ -100,15 +100,15 @@ AVCodecDecoder::AVCodecDecoder() fChunkBufferSize(0), fAudioDecodeError(false), - fOutputBuffer(NULL), + fOutputFrame(avcodec_alloc_frame()), fOutputBufferOffset(0), fOutputBufferSize(0) { TRACE("AVCodecDecoder::AVCodecDecoder()\n"); - fContext->error_recognition = FF_ER_CAREFUL; + fContext->err_recognition = AV_EF_CAREFUL; fContext->error_concealment = 3; - avcodec_thread_init(fContext, 1); + fContext->thread_count = 1; } @@ -130,6 +130,7 @@ AVCodecDecoder::~AVCodecDecoder() av_free(fOutputPicture); av_free(fInputPicture); av_free(fContext); + av_free(fOutputFrame); #if USE_SWS_FOR_COLOR_SPACE_CONVERSION if (fSwsContext != NULL) @@ -137,7 +138,6 @@ AVCodecDecoder::~AVCodecDecoder() #endif delete[] fExtraData; - delete[] fOutputBuffer; } @@ -162,12 +162,6 @@ AVCodecDecoder::Setup(media_format* ioEncodedFormat, const void* infoBuffer, fIsAudio = (ioEncodedFormat->type == B_MEDIA_ENCODED_AUDIO); TRACE("[%c] AVCodecDecoder::Setup()\n", fIsAudio?('a'):('v')); - if (fIsAudio && fOutputBuffer == NULL) { - fOutputBuffer = new(std::nothrow) char[AVCODEC_MAX_AUDIO_FRAME_SIZE]; - if (fOutputBuffer == NULL) - return B_NO_MEMORY; - } - #ifdef TRACE_AV_CODEC char buffer[1024]; string_for_format(*ioEncodedFormat, buffer, sizeof(buffer)); @@ -372,7 +366,7 @@ AVCodecDecoder::_NegotiateAudioOutputFormat(media_format* inOutFormat) } // open new - int result = avcodec_open(fContext, fCodec); + int result = avcodec_open2(fContext, fCodec, NULL); fCodecInitDone = (result >= 0); fStartTime = 0; @@ -454,7 +448,7 @@ AVCodecDecoder::_NegotiateVideoOutputFormat(media_format* inOutFormat) avcodec_close(fContext); } // TODO: Set n-th fContext->pix_fmt here - if (avcodec_open(fContext, fCodec) >= 0) { + if (avcodec_open2(fContext, fCodec, NULL) >= 0) { fCodecInitDone = true; #if USE_SWS_FOR_COLOR_SPACE_CONVERSION @@ -529,17 +523,19 @@ AVCodecDecoder::_DecodeAudio(void* _buffer, int64* outFrameCount, while (*outFrameCount < fOutputFrameCount) { // Check conditions which would hint at broken code below. if (fOutputBufferSize < 0) { - debugger("Decoding read past the end of the output buffer!"); + fprintf(stderr, "Decoding read past the end of the output buffer! " + "%ld\n", fOutputBufferSize); fOutputBufferSize = 0; } if (fChunkBufferSize < 0) { - debugger("Decoding read past the end of the chunk buffer!"); + fprintf(stderr, "Decoding read past the end of the chunk buffer! " + "%ld\n", fChunkBufferSize); fChunkBufferSize = 0; } if (fOutputBufferSize > 0) { // We still have decoded audio frames from the last - // invokation, which start at fOutputBuffer + fOutputBufferOffset + // invokation, which start at fOutputBufferOffset // and are of fOutputBufferSize. Copy those into the buffer, // but not more than it can hold. int32 frames = min_c(fOutputFrameCount - *outFrameCount, @@ -547,7 +543,8 @@ AVCodecDecoder::_DecodeAudio(void* _buffer, int64* outFrameCount, if (frames == 0) debugger("fOutputBufferSize not multiple of frame size!"); size_t remainingSize = frames * fOutputFrameSize; - memcpy(buffer, fOutputBuffer + fOutputBufferOffset, remainingSize); + memcpy(buffer, fOutputFrame->data[0] + fOutputBufferOffset, + remainingSize); fOutputBufferOffset += remainingSize; fOutputBufferSize -= remainingSize; buffer += remainingSize; @@ -582,10 +579,11 @@ AVCodecDecoder::_DecodeAudio(void* _buffer, int64* outFrameCount, fTempPacket.data = (uint8_t*)fChunkBuffer + fChunkBufferOffset; fTempPacket.size = fChunkBufferSize; - // Initialize decodedBytes to the output buffer size. - int decodedBytes = AVCODEC_MAX_AUDIO_FRAME_SIZE; - int usedBytes = avcodec_decode_audio3(fContext, - (int16*)fOutputBuffer, &decodedBytes, &fTempPacket); + + avcodec_get_frame_defaults(fOutputFrame); + int gotFrame = 0; + int usedBytes = avcodec_decode_audio4(fContext, + fOutputFrame, &gotFrame, &fTempPacket); if (usedBytes < 0 && !fAudioDecodeError) { // Report failure if not done already printf("########### audio decode error, " @@ -597,12 +595,20 @@ AVCodecDecoder::_DecodeAudio(void* _buffer, int64* outFrameCount, // Error or failure to produce decompressed output. // Skip the chunk buffer data entirely. usedBytes = fChunkBufferSize; - decodedBytes = 0; + fOutputBufferSize = 0; // Assume the audio decoded until now is broken. memset(_buffer, 0, buffer - (uint8*)_buffer); } else { // Success fAudioDecodeError = false; + if (gotFrame == 1) { + fOutputBufferSize = av_samples_get_buffer_size(NULL, + fContext->channels, fOutputFrame->nb_samples, + fContext->sample_fmt, 1); + if (fOutputBufferSize < 0) + fOutputBufferSize = 0; + } else + fOutputBufferSize = 0; } //printf(" chunk size: %d, decoded: %d, used: %d\n", //fTempPacket.size, decodedBytes, usedBytes); @@ -610,7 +616,6 @@ AVCodecDecoder::_DecodeAudio(void* _buffer, int64* outFrameCount, fChunkBufferOffset += usedBytes; fChunkBufferSize -= usedBytes; fOutputBufferOffset = 0; - fOutputBufferSize = decodedBytes; } fFrame += *outFrameCount; TRACE_AUDIO(" frame count: %lld current: %lld\n", *outFrameCount, fFrame); diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h index e7a897d..0d64146 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h +++ b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h @@ -98,7 +98,7 @@ private: size_t fChunkBufferSize; bool fAudioDecodeError; - char* fOutputBuffer; + AVFrame* fOutputFrame; int32 fOutputBufferOffset; int32 fOutputBufferSize; diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp index 71eaa4e..9b3de2d 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp @@ -76,56 +76,56 @@ avformat_to_beos_byte_order(SampleFormat format) static void -avmetadata_to_message(AVMetadata* metaData, BMessage* message) +avdictionary_to_message(AVDictionary* dictionary, BMessage* message) { - if (metaData == NULL) + if (dictionary == NULL) return; - AVMetadataTag* tag = NULL; - while ((tag = av_metadata_get(metaData, "", tag, + AVDictionaryEntry* entry = NULL; + while ((entry = av_dict_get(dictionary, "", entry, AV_METADATA_IGNORE_SUFFIX))) { - // convert tag keys into something more meaningful using the names from + // convert entry keys into something more meaningful using the names from // id3v2.c - if (strcmp(tag->key, "TALB") == 0 || strcmp(tag->key, "TAL") == 0) - message->AddString("album", tag->value); - else if (strcmp(tag->key, "TCOM") == 0) - message->AddString("composer", tag->value); - else if (strcmp(tag->key, "TCON") == 0 || strcmp(tag->key, "TCO") == 0) - message->AddString("genre", tag->value); - else if (strcmp(tag->key, "TCOP") == 0) - message->AddString("copyright", tag->value); - else if (strcmp(tag->key, "TDRL") == 0 || strcmp(tag->key, "TDRC") == 0) - message->AddString("date", tag->value); - else if (strcmp(tag->key, "TENC") == 0 || strcmp(tag->key, "TEN") == 0) - message->AddString("encoded_by", tag->value); - else if (strcmp(tag->key, "TIT2") == 0 || strcmp(tag->key, "TT2") == 0) - message->AddString("title", tag->value); - else if (strcmp(tag->key, "TLAN") == 0) - message->AddString("language", tag->value); - else if (strcmp(tag->key, "TPE1") == 0 || strcmp(tag->key, "TP1") == 0) - message->AddString("artist", tag->value); - else if (strcmp(tag->key, "TPE2") == 0 || strcmp(tag->key, "TP2") == 0) - message->AddString("album_artist", tag->value); - else if (strcmp(tag->key, "TPE3") == 0 || strcmp(tag->key, "TP3") == 0) - message->AddString("performer", tag->value); - else if (strcmp(tag->key, "TPOS") == 0) - message->AddString("disc", tag->value); - else if (strcmp(tag->key, "TPUB") == 0) - message->AddString("publisher", tag->value); - else if (strcmp(tag->key, "TRCK") == 0 || strcmp(tag->key, "TRK") == 0) - message->AddString("track", tag->value); - else if (strcmp(tag->key, "TSOA") == 0) - message->AddString("album-sort", tag->value); - else if (strcmp(tag->key, "TSOP") == 0) - message->AddString("artist-sort", tag->value); - else if (strcmp(tag->key, "TSOT") == 0) - message->AddString("title-sort", tag->value); - else if (strcmp(tag->key, "TSSE") == 0) - message->AddString("encoder", tag->value); - else if (strcmp(tag->key, "TYER") == 0) - message->AddString("year", tag->value); + if (strcmp(entry->key, "TALB") == 0 || strcmp(entry->key, "TAL") == 0) + message->AddString("album", entry->value); + else if (strcmp(entry->key, "TCOM") == 0) + message->AddString("composer", entry->value); + else if (strcmp(entry->key, "TCON") == 0 || strcmp(entry->key, "TCO") == 0) + message->AddString("genre", entry->value); + else if (strcmp(entry->key, "TCOP") == 0) + message->AddString("copyright", entry->value); + else if (strcmp(entry->key, "TDRL") == 0 || strcmp(entry->key, "TDRC") == 0) + message->AddString("date", entry->value); + else if (strcmp(entry->key, "TENC") == 0 || strcmp(entry->key, "TEN") == 0) + message->AddString("encoded_by", entry->value); + else if (strcmp(entry->key, "TIT2") == 0 || strcmp(entry->key, "TT2") == 0) + message->AddString("title", entry->value); + else if (strcmp(entry->key, "TLAN") == 0) + message->AddString("language", entry->value); + else if (strcmp(entry->key, "TPE1") == 0 || strcmp(entry->key, "TP1") == 0) + message->AddString("artist", entry->value); + else if (strcmp(entry->key, "TPE2") == 0 || strcmp(entry->key, "TP2") == 0) + message->AddString("album_artist", entry->value); + else if (strcmp(entry->key, "TPE3") == 0 || strcmp(entry->key, "TP3") == 0) + message->AddString("performer", entry->value); + else if (strcmp(entry->key, "TPOS") == 0) + message->AddString("disc", entry->value); + else if (strcmp(entry->key, "TPUB") == 0) + message->AddString("publisher", entry->value); + else if (strcmp(entry->key, "TRCK") == 0 || strcmp(entry->key, "TRK") == 0) + message->AddString("track", entry->value); + else if (strcmp(entry->key, "TSOA") == 0) + message->AddString("album-sort", entry->value); + else if (strcmp(entry->key, "TSOP") == 0) + message->AddString("artist-sort", entry->value); + else if (strcmp(entry->key, "TSOT") == 0) + message->AddString("title-sort", entry->value); + else if (strcmp(entry->key, "TSSE") == 0) + message->AddString("encoder", entry->value); + else if (strcmp(entry->key, "TYER") == 0) + message->AddString("year", entry->value); else - message->AddString(tag->key, tag->value); + message->AddString(entry->key, entry->value); } } @@ -288,8 +288,8 @@ StreamBase::Open() // Retrieve stream information - if (av_find_stream_info(fContext) < 0) { - TRACE("StreamBase::Open() - av_find_stream_info() failed!\n"); + if (avformat_find_stream_info(fContext, NULL) < 0) { + TRACE("StreamBase::Open() - avformat_find_stream_info() failed!\n"); return B_NOT_SUPPORTED; } @@ -1220,7 +1220,7 @@ AVFormatReader::Stream::GetMetaData(BMessage* data) { BAutolock _(&fLock); - avmetadata_to_message(fStream->metadata, data); + avdictionary_to_message(fStream->metadata, data); return B_OK; } @@ -1619,7 +1619,7 @@ AVFormatReader::GetMetaData(BMessage* _data) if (context == NULL) return B_NO_INIT; - avmetadata_to_message(context->metadata, _data); + avdictionary_to_message(context->metadata, _data); // Add chapter info for (unsigned i = 0; i < context->nb_chapters; i++) { @@ -1632,14 +1632,14 @@ AVFormatReader::GetMetaData(BMessage* _data) * chapter->end * chapter->time_base.num / chapter->time_base.den + 0.5)); - avmetadata_to_message(chapter->metadata, &chapterData); + avdictionary_to_message(chapter->metadata, &chapterData); _data->AddMessage("be:chapter", &chapterData); } // Add program info for (unsigned i = 0; i < context->nb_programs; i++) { BMessage progamData; - avmetadata_to_message(context->programs[i]->metadata, &progamData); + avdictionary_to_message(context->programs[i]->metadata, &progamData); _data->AddMessage("be:program", &progamData); } diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp b/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp index cc9d701..1e2bcfe 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp @@ -322,6 +322,7 @@ AVFormatWriter::AVFormatWriter() : fContext(avformat_alloc_context()), fHeaderWritten(false), + fIOContext(NULL), fStreamLock("stream lock") { TRACE("AVFormatWriter::AVFormatWriter\n"); @@ -345,7 +346,8 @@ AVFormatWriter::~AVFormatWriter() } av_free(fContext); - av_free(fIOContext.buffer); + av_free(fIOContext->buffer); + av_free(fIOContext); } @@ -363,14 +365,14 @@ AVFormatWriter::Init(const media_file_format* fileFormat) // Init I/O context with buffer and hook functions, pass ourself as // cookie. - if (init_put_byte(&fIOContext, buffer, kIOBufferSize, 1, this, + if (init_put_byte(fIOContext, buffer, kIOBufferSize, 1, this, 0, _Write, _Seek) != 0) { TRACE(" init_put_byte() failed!\n"); return B_ERROR; } // Setup I/O hooks. This seems to be enough. - fContext->pb = &fIOContext; + fContext->pb = fIOContext; // Set the AVOutputFormat according to fileFormat... fContext->oformat = av_guess_format(fileFormat->short_name, diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h b/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h index 34a4140..a913fa0 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h +++ b/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h @@ -54,7 +54,7 @@ private: AVFormatContext* fContext; bool fHeaderWritten; - ByteIOContext fIOContext; + AVIOContext* fIOContext; StreamCookie** fStreams; BLocker fStreamLock;