diff options
| author | Martin Lambers <marlam@marlam.de> | 2013-01-27 11:08:23 +0100 |
|---|---|---|
| committer | Martin Lambers <marlam@marlam.de> | 2013-01-27 11:08:23 +0100 |
| commit | 25cb165ae138968c277dbcb11823e99a1b78a1d0 (patch) | |
| tree | c20fc9b2eefd7d7a35667405c6c9e89aac8e1dec | |
| parent | 1b2576e5cd7813609d710060a139af5ef4caabab (diff) | |
| download | bino-25cb165ae138968c277dbcb11823e99a1b78a1d0.tar.gz | |
Media object: chase FFmpeg interface changes.
FFmpeg now produces planar audio with some decoders, and we have to convert
that to interleaved ourselves. This requires updating to
avcodec_decode_audio4().
A few other minor updates were made.
| -rw-r--r-- | src/media_object.cpp | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/src/media_object.cpp b/src/media_object.cpp index 84e1cd6..28f9b3d 100644 --- a/src/media_object.cpp +++ b/src/media_object.cpp @@ -1,7 +1,7 @@ /* * This file is part of bino, a 3D video player. * - * Copyright (C) 2010, 2011, 2012 + * Copyright (C) 2010, 2011, 2012, 2013 * Martin Lambers <marlam@marlam.de> * Frédéric Devernay <frederic.devernay@inrialpes.fr> * Joe <cuchac@email.cz> @@ -341,9 +341,7 @@ media_object::media_object(bool always_convert_to_bgra32) : { avdevice_register_all(); av_register_all(); -#if LIBAVFORMAT_VERSION_MAJOR >= 53 && LIBAVFORMAT_VERSION_MINOR >= 13 avformat_network_init(); -#endif switch (msg::level()) { case msg::DBG: @@ -724,23 +722,28 @@ void media_object::set_audio_blob_template(int index) } audio_blob_template.channels = audio_codec_ctx->channels; audio_blob_template.rate = audio_codec_ctx->sample_rate; - if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_U8) + if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_U8 + || audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_U8P) { audio_blob_template.sample_format = audio_blob::u8; } - else if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_S16) + else if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_S16 + || audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_S16P) { audio_blob_template.sample_format = audio_blob::s16; } - else if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_FLT) + else if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_FLT + || audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_FLTP) { audio_blob_template.sample_format = audio_blob::f32; } - else if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_DBL) + else if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_DBL + || audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_DBLP) { audio_blob_template.sample_format = audio_blob::d64; } - else if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_S32 + else if ((audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_S32 + || audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_S32P) && sizeof(int32_t) == sizeof(float)) { // we need to convert this to AV_SAMPLE_FMT_FLT after decoding @@ -1475,7 +1478,6 @@ read_frame: &(_ffmpeg->video_packets[_video_stream])); } while (!frame_finished); -#if LIBAVCODEC_VERSION_MAJOR >= 53 && LIBAVCODEC_VERSION_MINOR >= 8 if (_ffmpeg->video_frames[_video_stream]->width != _ffmpeg->video_frame_templates[_video_stream].raw_width || _ffmpeg->video_frames[_video_stream]->height != _ffmpeg->video_frame_templates[_video_stream].raw_height) { @@ -1483,7 +1485,6 @@ read_frame: _ffmpeg->video_frames[_video_stream]->width, _ffmpeg->video_frames[_video_stream]->height); goto read_frame; } -#endif if (_frame.layout == video_frame::bgra32) { sws_scale(_ffmpeg->video_sws_ctxs[_video_stream], @@ -1622,12 +1623,13 @@ void audio_decode_thread::run() } // Decode audio data + AVFrame audioframe = { { 0 } }; tmppacket = packet; while (tmppacket.size > 0) { - int tmpbuf_size = audio_tmpbuf_size; - int len = avcodec_decode_audio3(_ffmpeg->audio_codec_ctxs[_audio_stream], - reinterpret_cast<int16_t *>(&(_ffmpeg->audio_tmpbufs[_audio_stream][0])), &tmpbuf_size, &tmppacket); + int got_frame = 0; + int len = avcodec_decode_audio4(_ffmpeg->audio_codec_ctxs[_audio_stream], + &audioframe, &got_frame, &tmppacket); if (len < 0) { tmppacket.size = 0; @@ -1635,10 +1637,35 @@ void audio_decode_thread::run() } tmppacket.data += len; tmppacket.size -= len; - if (tmpbuf_size <= 0) + if (!got_frame) { continue; } + int plane_size; + int tmpbuf_size = av_samples_get_buffer_size(&plane_size, + _ffmpeg->audio_codec_ctxs[_audio_stream]->channels, + audioframe.nb_samples, + _ffmpeg->audio_codec_ctxs[_audio_stream]->sample_fmt, 1); + if (av_sample_fmt_is_planar(_ffmpeg->audio_codec_ctxs[_audio_stream]->sample_fmt) + && _ffmpeg->audio_codec_ctxs[_audio_stream]->channels > 1) + { + int dummy; + int sample_size = av_samples_get_buffer_size(&dummy, 1, 1, + _ffmpeg->audio_codec_ctxs[_audio_stream]->sample_fmt, 1); + uint8_t *out = reinterpret_cast<uint8_t *>(&(_ffmpeg->audio_tmpbufs[_audio_stream][0])); + for (int s = 0; s < audioframe.nb_samples; s++) + { + for (int c = 0; c < _ffmpeg->audio_codec_ctxs[_audio_stream]->channels; c++) + { + std::memcpy(out, audioframe.extended_data[c] + s * sample_size, sample_size); + out += sample_size; + } + } + } + else + { + std::memcpy(&(_ffmpeg->audio_tmpbufs[_audio_stream][0]), audioframe.extended_data[0], plane_size); + } // Put it in the decoded audio data buffer if (_ffmpeg->audio_codec_ctxs[_audio_stream]->sample_fmt == AV_SAMPLE_FMT_S32) { @@ -2065,7 +2092,7 @@ void media_object::close() av_free_packet(&_ffmpeg->subtitle_packet_queues[i][j]); } } - av_close_input_file(_ffmpeg->format_ctx); + avformat_close_input(&_ffmpeg->format_ctx); } delete _ffmpeg->reader; delete _ffmpeg; |
