blob: c0a1f5f3610cc882c81a94fe95a281680406133d [file] [log] [blame]
From fff7e63650c1569908bf80f11a123e051e993f31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ludger=20Kr=C3=A4mer?= <dbluelle@blau-weissoedingen.de>
Date: Fri, 16 Aug 2013 20:30:28 +0200
Subject: [PATCH] fix compilation with ffmpeg 2.0 avcodec_decode_audio4 seems
not to deliver data in AV_SAMPLE_FMT_S16 format, so we have to use
libavresample for resampling
---
CMakeLists.txt | 2 +-
conf/FindFFMpeg.cmake | 6 ++++-
src/backends/decoder.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++------
src/backends/decoder.h | 8 ++++++
4 files changed, 70 insertions(+), 10 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 33dbb85..d3a964b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -286,7 +286,7 @@ IF(AUDIO_BACKEND)
ENDIF(AUDIO_BACKEND)
IF(ENABLE_LIBAVCODEC)
- pkg_check_modules(FFMPEG libavcodec libavutil libavformat)
+ pkg_check_modules(FFMPEG libavcodec libavutil libavformat libavresample)
IF(NOT(FFMPEG_FOUND))
INCLUDE(FindFFMpeg REQUIRED)
ENDIF(NOT(FFMPEG_FOUND))
diff --git a/conf/FindFFMpeg.cmake b/conf/FindFFMpeg.cmake
index 2b4dd98..8246c15 100644
--- a/conf/FindFFMpeg.cmake
+++ b/conf/FindFFMpeg.cmake
@@ -23,7 +23,11 @@ FIND_LIBRARY(FFMPEG_AVFORMAT_LIBRARY NAMES
avformat
)
-SET(FFMPEG_LIBRARY ${FFMPEG_AVCODEC_LIBRARY} ${FFMPEG_AVUTIL_LIBRARY} ${FFMPEG_AVFORMAT_LIBRARY})
+FIND_LIBRARY(FFMPEG_AVRESAMPLE_LIBRARY NAMES
+ avresample
+)
+
+SET(FFMPEG_LIBRARY ${FFMPEG_AVCODEC_LIBRARY} ${FFMPEG_AVUTIL_LIBRARY} ${FFMPEG_AVFORMAT_LIBRARY} ${FFMPEG_AVRESAMPLE_LIBRARY})
MARK_AS_ADVANCED(FFMPEG_LIBRARY)
# handle the QUIETLY and REQUIRED arguments and set FFMPEG_FOUND to TRUE if
diff --git a/src/backends/decoder.cpp b/src/backends/decoder.cpp
index 22eac2e..4b3148c 100755
--- a/src/backends/decoder.cpp
+++ b/src/backends/decoder.cpp
@@ -295,6 +295,8 @@ bool FFMpegVideoDecoder::decodePacket(AVPacket* pkt, uint32_t time)
#else
int ret=avcodec_decode_video(codecContext, frameIn, &frameOk, pkt->data, pkt->size);
#endif
+ if (ret < 0)
+ return false;
assert_and_throw(ret==(int)pkt->size);
if(frameOk)
@@ -612,10 +614,33 @@ uint32_t FFMpegAudioDecoder::decodeData(uint8_t* data, int32_t datalen, uint32_t
ret=-1;
else
{
- //This is suboptimal but equivalent to what libavcodec
- //does for the compatibility version of avcodec_decode_audio3
- memcpy(curTail.samples, frameIn->extended_data[0], frameIn->linesize[0]);
- maxLen=frameIn->linesize[0];
+ if (frameIn->format != AV_SAMPLE_FMT_S16)
+ {
+ AVAudioResampleContext * avr = avresample_alloc_context();
+ av_opt_set_int(avr, "in_channel_layout", frameIn->channel_layout, 0);
+ av_opt_set_int(avr, "out_channel_layout", frameIn->channel_layout, 0);
+ av_opt_set_int(avr, "in_sample_rate", frameIn->sample_rate, 0);
+ av_opt_set_int(avr, "out_sample_rate", frameIn->sample_rate, 0);
+ av_opt_set_int(avr, "in_sample_fmt", frameIn->format, 0);
+ av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+ avresample_open(avr);
+
+ uint8_t *output;
+ int out_linesize;
+ int out_samples = avresample_available(avr) + av_rescale_rnd(avresample_get_delay(avr) + frameIn->linesize[0], frameIn->sample_rate, frameIn->sample_rate, AV_ROUND_UP);
+ av_samples_alloc(&output, &out_linesize, frameIn->nb_samples, out_samples, AV_SAMPLE_FMT_S16, 0);
+ maxLen = avresample_convert(avr, &output, out_linesize, out_samples, frameIn->extended_data, frameIn->linesize[0], frameIn->nb_samples)*4;
+ memcpy(curTail.samples, output, maxLen);
+ av_freep(&output);
+ avresample_free(&avr);
+ }
+ else
+ {
+ //This is suboptimal but equivalent to what libavcodec
+ //does for the compatibility version of avcodec_decode_audio3
+ memcpy(curTail.samples, frameIn->extended_data[0], frameIn->linesize[0]);
+ maxLen=frameIn->linesize[0];
+ }
}
#else
int32_t ret=avcodec_decode_audio3(codecContext, curTail.samples, &maxLen, &pkt);
@@ -660,10 +685,33 @@ uint32_t FFMpegAudioDecoder::decodePacket(AVPacket* pkt, uint32_t time)
ret=-1;
else
{
- //This is suboptimal but equivalent to what libavcodec
- //does for the compatibility version of avcodec_decode_audio3
- memcpy(curTail.samples, frameIn->extended_data[0], frameIn->linesize[0]);
- maxLen=frameIn->linesize[0];
+ if (frameIn->format != AV_SAMPLE_FMT_S16)
+ {
+ AVAudioResampleContext * avr = avresample_alloc_context();
+ av_opt_set_int(avr, "in_channel_layout", frameIn->channel_layout, 0);
+ av_opt_set_int(avr, "out_channel_layout", frameIn->channel_layout, 0);
+ av_opt_set_int(avr, "in_sample_rate", frameIn->sample_rate, 0);
+ av_opt_set_int(avr, "out_sample_rate", frameIn->sample_rate, 0);
+ av_opt_set_int(avr, "in_sample_fmt", frameIn->format, 0);
+ av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+ avresample_open(avr);
+
+ uint8_t *output;
+ int out_linesize;
+ int out_samples = avresample_available(avr) + av_rescale_rnd(avresample_get_delay(avr) + frameIn->linesize[0], frameIn->sample_rate, frameIn->sample_rate, AV_ROUND_UP);
+ av_samples_alloc(&output, &out_linesize, frameIn->nb_samples, out_samples, AV_SAMPLE_FMT_S16, 0);
+ maxLen = avresample_convert(avr, &output, out_linesize, out_samples, frameIn->extended_data, frameIn->linesize[0], frameIn->nb_samples)*4;
+ memcpy(curTail.samples, output, maxLen);
+ av_freep(&output);
+ avresample_free(&avr);
+ }
+ else
+ {
+ //This is suboptimal but equivalent to what libavcodec
+ //does for the compatibility version of avcodec_decode_audio3
+ memcpy(curTail.samples, frameIn->extended_data[0], frameIn->linesize[0]);
+ maxLen=frameIn->linesize[0];
+ }
}
#elif HAVE_AVCODEC_DECODE_AUDIO3
int ret=avcodec_decode_audio3(codecContext, curTail.samples, &maxLen, pkt);
diff --git a/src/backends/decoder.h b/src/backends/decoder.h
index 93950ad..28bd232 100644
--- a/src/backends/decoder.h
+++ b/src/backends/decoder.h
@@ -28,6 +28,14 @@
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
+#include <libavresample/avresample.h>
+#include <libavutil/opt.h>
+#ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
+#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
+#endif
+#ifndef CodecID
+#define CodecID AVCodecID
+#endif
#define MAX_AUDIO_FRAME_SIZE AVCODEC_MAX_AUDIO_FRAME_SIZE
}
#else
--
1.8.4