From a83e2311dafcba608254ee31a6c0fee66c505eef Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Fri, 8 Jul 2011 21:42:55 +0200 Subject: Fixed ffmpeg decoder. --- decoders/ffmpeg_decoder.cpp | 53 +++++++++++++++++++++++++++++++++++---------- decoders/ffmpeg_decoder.h | 3 +++ 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/decoders/ffmpeg_decoder.cpp b/decoders/ffmpeg_decoder.cpp index d66c72b..630e38e 100644 --- a/decoders/ffmpeg_decoder.cpp +++ b/decoders/ffmpeg_decoder.cpp @@ -1,36 +1,67 @@ #include "ffmpeg_decoder.h" #include +#include DecoderFFmpeg::DecoderFFmpeg(const std::string& filename) { av_register_all(); - std::cerr << "Opening file: " << av_open_input_file(&lavf_ctx, filename.c_str(), 0, 0, 0) << std::endl; + lavf_ctx = NULL; + std::cerr << "Opening file: " << avformat_open_input(&lavf_ctx, filename.c_str(), 0, 0) << std::endl; av_find_stream_info(lavf_ctx); - dump_format(lavf_ctx, 0, filename.c_str(), 0); + av_dump_format(lavf_ctx, 0, filename.c_str(), 0); lavc_ctx = lavf_ctx->streams[0]->codec; codec = avcodec_find_decoder(lavc_ctx->codec_id); std::cerr << "Opening decoder: " << avcodec_open(lavc_ctx, codec) << std::endl; + + temp_buffer = NULL; } DecoderFFmpeg::~DecoderFFmpeg() { - + av_close_input_file(lavf_ctx); + avcodec_close(lavc_ctx); } std::size_t DecoderFFmpeg::read(char* buf, std::size_t buf_size) { + if(temp_buffer) { + std::size_t buffer_size = std::min(temp_buffer_size - temp_buffer_pos, buf_size); + std::memcpy(buf, temp_buffer + temp_buffer_pos, buffer_size); + temp_buffer_pos += buffer_size; + if(temp_buffer_pos == temp_buffer_size) { + delete[] temp_buffer; + temp_buffer = NULL; + } + return buffer_size; + } + AVPacket packet; + + if(av_read_frame(lavf_ctx, &packet) < 0) + return -1; + + char local_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; + std::size_t local_buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; - av_read_packet(lavf_ctx, &packet); - - int len = avcodec_decode_audio3(lavc_ctx, (int16_t*)buf, (int*)&buf_size, &packet); - - std::cerr << "Decoded " << len << " bytes of data to " << buf_size << " bytes of raw data." << std::endl; - + int len = avcodec_decode_audio3(lavc_ctx, (int16_t*)local_buf, (int*)&local_buf_size, &packet); + av_free_packet(&packet); - - return buf_size; + + if(len < 0) + return -1; + + if(local_buf_size > buf_size) { + std::memcpy(buf, local_buf, buf_size); + temp_buffer_size = local_buf_size - buf_size; + temp_buffer = new char[temp_buffer_size]; + temp_buffer_pos = 0; + memcpy(temp_buffer, local_buf + buf_size, temp_buffer_size); + return buf_size; + } else { + std::memcpy(buf, local_buf, local_buf_size); + return local_buf_size; + } } diff --git a/decoders/ffmpeg_decoder.h b/decoders/ffmpeg_decoder.h index c6e0db1..2acfd8e 100644 --- a/decoders/ffmpeg_decoder.h +++ b/decoders/ffmpeg_decoder.h @@ -16,6 +16,9 @@ class DecoderFFmpeg : public Decoder { AVFormatContext* lavf_ctx; AVCodecContext* lavc_ctx; AVCodec* codec; + char *temp_buffer; + std::size_t temp_buffer_size; + std::size_t temp_buffer_pos; public: DecoderFFmpeg(const std::string& filename); -- cgit v1.2.3