diff --git a/lib/DllAvCodec.h b/lib/DllAvCodec.h index 9f3b16c3a9120..29c4af44fa043 100644 --- a/lib/DllAvCodec.h +++ b/lib/DllAvCodec.h @@ -58,20 +58,8 @@ extern "C" { #include #endif #endif - - /* From non-public audioconvert.h */ - struct AVAudioConvert; - typedef struct AVAudioConvert AVAudioConvert; - AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels, - enum AVSampleFormat in_fmt, int in_channels, - const float *matrix, int flags); - void av_audio_convert_free(AVAudioConvert *ctx); - int av_audio_convert(AVAudioConvert *ctx, - void * const out[6], const int out_stride[6], - const void * const in[6], const int in_stride[6], int len); #else #include "libavcodec/avcodec.h" - #include "libavcodec/audioconvert.h" #endif } @@ -115,13 +103,6 @@ class DllAvCodecInterface virtual int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic)=0; virtual void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic)=0; virtual AVCodec *av_codec_next(AVCodec *c)=0; - virtual AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels, - enum AVSampleFormat in_fmt , int in_channels, - const float *matrix , int flags)=0; - virtual void av_audio_convert_free(AVAudioConvert *ctx)=0; - virtual int av_audio_convert(AVAudioConvert *ctx, - void * const out[6], const int out_stride[6], - const void * const in[6], const int in_stride[6], int len)=0; virtual int av_dup_packet(AVPacket *pkt)=0; virtual void av_init_packet(AVPacket *pkt)=0; }; @@ -189,17 +170,6 @@ class DllAvCodec : public DllDynamic, DllAvCodecInterface virtual void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic) { ::avcodec_default_release_buffer(s, pic); } virtual enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat *fmt) { return ::avcodec_default_get_format(s, fmt); } virtual AVCodec *av_codec_next(AVCodec *c) { return ::av_codec_next(c); } - virtual AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels, - enum AVSampleFormat in_fmt , int in_channels, - const float *matrix , int flags) - { return ::av_audio_convert_alloc(out_fmt, out_channels, in_fmt, in_channels, matrix, flags); } - virtual void av_audio_convert_free(AVAudioConvert *ctx) - { ::av_audio_convert_free(ctx); } - - virtual int av_audio_convert(AVAudioConvert *ctx, - void * const out[6], const int out_stride[6], - const void * const in[6], const int in_stride[6], int len) - { return ::av_audio_convert(ctx, out, out_stride, in, in_stride, len); } virtual int av_dup_packet(AVPacket *pkt) { return ::av_dup_packet(pkt); } virtual void av_init_packet(AVPacket *pkt) { return ::av_init_packet(pkt); } @@ -251,13 +221,6 @@ class DllAvCodec : public DllDynamic, DllAvCodecInterface DEFINE_METHOD2(enum PixelFormat, avcodec_default_get_format, (struct AVCodecContext *p1, const enum PixelFormat *p2)) DEFINE_METHOD1(AVCodec*, av_codec_next, (AVCodec *p1)) - DEFINE_METHOD6(AVAudioConvert*, av_audio_convert_alloc, (enum AVSampleFormat p1, int p2, - enum AVSampleFormat p3, int p4, - const float *p5, int p6)) - DEFINE_METHOD1(void, av_audio_convert_free, (AVAudioConvert *p1)); - DEFINE_METHOD6(int, av_audio_convert, (AVAudioConvert *p1, - void * const p2[6], const int p3[6], - const void * const p4[6], const int p5[6], int p6)) BEGIN_METHOD_RESOLVE() RESOLVE_METHOD(avcodec_flush_buffers) RESOLVE_METHOD_RENAME(avcodec_open2,avcodec_open2_dont_call) @@ -288,9 +251,6 @@ class DllAvCodec : public DllDynamic, DllAvCodecInterface RESOLVE_METHOD(avcodec_default_release_buffer) RESOLVE_METHOD(avcodec_default_get_format) RESOLVE_METHOD(av_codec_next) - RESOLVE_METHOD(av_audio_convert_alloc) - RESOLVE_METHOD(av_audio_convert_free) - RESOLVE_METHOD(av_audio_convert) RESOLVE_METHOD(av_dup_packet) RESOLVE_METHOD(av_init_packet) END_METHOD_RESOLVE() diff --git a/lib/DllSwResample.h b/lib/DllSwResample.h index 8a990720c370b..7ac6a8889a8f7 100644 --- a/lib/DllSwResample.h +++ b/lib/DllSwResample.h @@ -42,11 +42,20 @@ extern "C" { #endif } +class DllSwResampleInterface +{ +public: + virtual ~DllSwResampleInterface() {} + virtual struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, int log_offset, void *log_ctx)=0; + virtual int swr_init(struct SwrContext *s)=0; + virtual void swr_free(struct SwrContext **s)=0; + virtual int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, const uint8_t **in , int in_count)=0; +}; #if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN) // Use direct mapping -class DllSwResample : public DllDynamic +class DllSwResample : public DllDynamic, DllSwResampleInterface { public: virtual ~DllSwResample() {} @@ -58,17 +67,30 @@ class DllSwResample : public DllDynamic return true; } virtual void Unload() {} + virtual struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, int log_offset, void *log_ctx) { return ::swr_alloc_set_opts(s, out_ch_layout, out_sample_fmt, out_sample_rate, in_ch_layout, in_sample_fmt, in_sample_rate, log_offset, log_ctx); } + virtual int swr_init(struct SwrContext *s) { return ::swr_init(s); } + virtual void swr_free(struct SwrContext **s){ return ::swr_free(s); } + virtual int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, const uint8_t **in , int in_count){ return ::swr_convert(s, out, out_count, in, in_count); } }; #else -class DllSwResample : public DllDynamic +class DllSwResample : public DllDynamic, DllSwResampleInterface { DECLARE_DLL_WRAPPER(DllSwResample, DLL_PATH_LIBSWRESAMPLE) LOAD_SYMBOLS() + DEFINE_METHOD9(SwrContext*, swr_alloc_set_opts, (struct SwrContext *p1, int64_t p2, enum AVSampleFormat p3, int p4, int64_t p5, enum AVSampleFormat p6, int p7, int p8, void * p9)); + DEFINE_METHOD1(int, swr_init, (struct SwrContext *p1)) + DEFINE_METHOD1(void, swr_free, (struct SwrContext **p1)) + DEFINE_METHOD5(int, swr_convert, (struct SwrContext *p1, uint8_t **p2, int p3, const uint8_t **p4, int p5)) + BEGIN_METHOD_RESOLVE() + RESOLVE_METHOD(swr_alloc_set_opts) + RESOLVE_METHOD(swr_init) + RESOLVE_METHOD(swr_free) + RESOLVE_METHOD(swr_convert) END_METHOD_RESOLVE() /* dependencies of libavformat */ diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp index c55c3923c2c88..f78ade795de5c 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp @@ -55,7 +55,7 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options AVCodec* pCodec; m_bOpenedCodec = false; - if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load()) + if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllSwResample.Load()) return false; m_dllAvCodec.avcodec_register_all(); @@ -112,8 +112,7 @@ void CDVDAudioCodecFFmpeg::Dispose() if (m_pConvert) { - m_dllAvCodec.av_audio_convert_free(m_pConvert); - m_pConvert = NULL; + m_dllSwResample.swr_free(&m_pConvert); } if (m_pCodecContext) @@ -172,17 +171,19 @@ int CDVDAudioCodecFFmpeg::Decode(BYTE* pData, int iSize) { if(m_pConvert && m_pCodecContext->sample_fmt != m_iSampleFormat) { - m_dllAvCodec.av_audio_convert_free(m_pConvert); - m_pConvert = NULL; + m_dllSwResample.swr_free(&m_pConvert); } if(!m_pConvert) { m_iSampleFormat = m_pCodecContext->sample_fmt; - m_pConvert = m_dllAvCodec.av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1, m_pCodecContext->sample_fmt, 1, NULL, 0); + m_pConvert = m_dllSwResample.swr_alloc_set_opts(NULL, + m_dllAvUtil.av_get_default_channel_layout(1), AV_SAMPLE_FMT_S16, m_pCodecContext->sample_rate, + m_dllAvUtil.av_get_default_channel_layout(1), m_pCodecContext->sample_fmt, m_pCodecContext->sample_rate, + 0, NULL); } - if(!m_pConvert) + if(!m_pConvert || m_dllSwResample.swr_init(m_pConvert)) { CLog::Log(LOGERROR, "CDVDAudioCodecFFmpeg::Decode - Unable to convert %d to AV_SAMPLE_FMT_S16", m_pCodecContext->sample_fmt); m_iBufferSize1 = 0; @@ -190,12 +191,8 @@ int CDVDAudioCodecFFmpeg::Decode(BYTE* pData, int iSize) return iBytesUsed; } - const void *ibuf[6] = { m_pFrame1->data[0] }; - void *obuf[6] = { m_pBuffer2 }; - int istr[6] = { m_dllAvUtil.av_get_bytes_per_sample(m_pCodecContext->sample_fmt) }; - int ostr[6] = { 2 }; - int len = m_iBufferSize1 / istr[0]; - if(m_dllAvCodec.av_audio_convert(m_pConvert, obuf, ostr, ibuf, istr, len) < 0) + int len = m_iBufferSize1 / m_dllAvUtil.av_get_bytes_per_sample(m_pCodecContext->sample_fmt); + if(m_dllSwResample.swr_convert(m_pConvert, &m_pBuffer2, len, (const uint8_t**)m_pFrame1->data, m_pFrame1->nb_samples) < 0) { CLog::Log(LOGERROR, "CDVDAudioCodecFFmpeg::Decode - Unable to convert %d to AV_SAMPLE_FMT_S16", (int)m_pCodecContext->sample_fmt); m_iBufferSize1 = 0; @@ -204,7 +201,7 @@ int CDVDAudioCodecFFmpeg::Decode(BYTE* pData, int iSize) } m_iBufferSize1 = 0; - m_iBufferSize2 = len * ostr[0]; + m_iBufferSize2 = len * 2; } return iBytesUsed; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h index 4c01499ca12c5..2be3ec6adf5ed 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h @@ -25,6 +25,7 @@ #include "DllAvCodec.h" #include "DllAvFormat.h" #include "DllAvUtil.h" +#include "DllSwResample.h" class CDVDAudioCodecFFmpeg : public CDVDAudioCodec { @@ -46,7 +47,7 @@ class CDVDAudioCodecFFmpeg : public CDVDAudioCodec protected: AVCodecContext* m_pCodecContext; - AVAudioConvert* m_pConvert;; + struct SwrContext* m_pConvert;; enum AVSampleFormat m_iSampleFormat; enum PCMChannels m_channelMap[PCM_MAX_CH + 1]; @@ -64,6 +65,7 @@ class CDVDAudioCodecFFmpeg : public CDVDAudioCodec DllAvCodec m_dllAvCodec; DllAvUtil m_dllAvUtil; + DllSwResample m_dllSwResample; void BuildChannelMap(); }; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.cpp index 0189e659d8efe..acefe2a71f813 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.cpp @@ -42,10 +42,10 @@ CDVDAudioEncoderFFmpeg::~CDVDAudioEncoderFFmpeg() m_dllAvUtil.av_freep(&m_CodecCtx); } - if(m_dllAvCodec.IsLoaded()) + if(m_dllSwResample.IsLoaded()) { if (m_AudioConvert) - m_dllAvCodec.av_audio_convert_free(m_AudioConvert); + m_dllSwResample.swr_free(&m_AudioConvert); } delete[] m_Buffer; delete[] m_TmpBuffer; @@ -55,7 +55,7 @@ CDVDAudioEncoderFFmpeg::~CDVDAudioEncoderFFmpeg() bool CDVDAudioEncoderFFmpeg::Initialize(unsigned int channels, enum PCMChannels *channelMap, unsigned int bitsPerSample, unsigned int sampleRate) { Reset(); - if (!channelMap || !m_dllAvUtil.Load() || !m_dllAvCodec.Load()) + if (!channelMap || !m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllSwResample.Load()) return false; m_dllAvCodec.avcodec_register_all(); @@ -93,9 +93,11 @@ bool CDVDAudioEncoderFFmpeg::Initialize(unsigned int channels, enum PCMChannels /* the input format was not supported, initiate conversion to the first * supported format */ CLog::Log(LOGDEBUG, "CDVDAudioEncoderFFmpeg: Initializing audio conversion for encoding"); - m_AudioConvert = m_dllAvCodec.av_audio_convert_alloc(codec->sample_fmts[0], 1, - m_CodecCtx->sample_fmt, 1, NULL, 0); - if (!m_AudioConvert) + m_AudioConvert = m_dllSwResample.swr_alloc_set_opts(NULL, + m_dllAvUtil.av_get_default_channel_layout(1), codec->sample_fmts[0], codec->supported_samplerates ? codec->supported_samplerates[0] : m_CodecCtx->sample_rate, + m_dllAvUtil.av_get_default_channel_layout(1), m_CodecCtx->sample_fmt, m_CodecCtx->sample_rate, + 0, NULL); + if (!m_AudioConvert || m_dllSwResample.swr_init(m_AudioConvert)) { m_dllAvUtil.av_freep(&m_CodecCtx); return false; @@ -183,12 +185,9 @@ int CDVDAudioEncoderFFmpeg::Encode(uint8_t *data, int size) m_Remap.Remap(data, m_TmpBuffer, m_NeededFrames); if (m_AudioConvert) { - void *convInBuf[] = { m_TmpBuffer }; - int convInStr[] = { m_BitsPerSample / 8 }; - void *convOutBuf[] = { m_TmpBuffer2 }; - int convOutStr[] = { m_dllAvUtil.av_get_bytes_per_sample(m_CodecCtx->sample_fmt) }; - if (m_dllAvCodec.av_audio_convert(m_AudioConvert, convOutBuf, convOutStr, - convInBuf, convInStr, m_NeededFrames * m_CodecCtx->channels) < 0) { + if (m_dllSwResample.swr_convert(m_AudioConvert, + &m_TmpBuffer2, m_NeededFrames * m_CodecCtx->channels, + (const uint8_t**)&m_TmpBuffer, m_NeededFrames * m_CodecCtx->channels) < 0) { CLog::Log(LOGERROR, "CDVDAudioEncoderFFmpeg: Audio conversion failed"); m_BufferSize = 0; return m_NeededBytes; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.h index 40be42bc42082..a8c5a61c718cd 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.h @@ -24,6 +24,7 @@ #include "DllAvCodec.h" #include "DllAvFormat.h" #include "DllAvUtil.h" +#include "DllSwResample.h" class CDVDAudioEncoderFFmpeg: public IDVDAudioEncoder { @@ -44,9 +45,10 @@ class CDVDAudioEncoderFFmpeg: public IDVDAudioEncoder private: DllAvCodec m_dllAvCodec; DllAvUtil m_dllAvUtil; + DllSwResample m_dllSwResample; AVCodecContext *m_CodecCtx; - AVAudioConvert *m_AudioConvert; + SwrContext *m_AudioConvert; enum PCMChannels m_ChannelMap[PCM_MAX_CH]; CPCMRemap m_Remap; uint8_t *m_Buffer;