#include "ffmpeg_decoder.h" #include #include DecoderFFmpeg::DecoderFFmpeg(const std::string& filename) { av_register_all(); 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); av_dump_format(lavf_ctx, 0, filename.c_str(), 0); lavc_ctx = lavf_ctx->streams[0]->codec; samplerate = lavc_ctx->sample_rate; channels = lavc_ctx->channels; codec = avcodec_find_decoder(lavc_ctx->codec_id); std::cerr << "Opening decoder: " << avcodec_open(lavc_ctx, codec) << std::endl; temp_buffer = NULL; } DecoderFFmpeg::~DecoderFFmpeg() { avcodec_close(lavc_ctx); av_close_input_file(lavf_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; int len = avcodec_decode_audio3(lavc_ctx, (int16_t*)local_buf, (int*)&local_buf_size, &packet); av_free_packet(&packet); 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; } }