Skip to content

Loading…

[ffmpeg] Convert from av_audio_convert API to the swresample one. #882

Closed
wants to merge 3 commits into from

3 participants

@aballier

That way we can drop usage of the internal av_audio_convert API.

aballier added some commits
@aballier aballier SwResample: Map swr_alloc_set_opts, swr_init, swr_free and swr_conver…
…t functions.

That way we can use the libswresample API instead of the private libavcodec::audioconvert API.
918b7a0
@aballier aballier [dvdplayer]: Use the SwResample API.
This drops all usage of the private libavcodec::audiocovert API in xbmc.
9cf29df
@aballier aballier [ffmpeg]: Drop mapping of the private av_audio_convert API now that i…
…t is unused.
5a2bd5f
@elupus
Team Kodi member

@amejia1 So here we come to the next libav issue. They have not merged back libswresample...

@elupus
Team Kodi member

@aballier don't take above as me not wanting to merge this. I really do.

@amejia1
Team Kodi member

@elupus libav are to make libavresample available soon. See http://lists.libav.org/pipermail/libav-devel/2012-April/025629.html

Not sure how different this is than libswresample yet.

@amejia1
Team Kodi member

@elupus ok, as to the two lib*resample libs being incompatible, the answer is yes, they are completely incompatible.

@elupus
Team Kodi member

How utterly stupid..

@amejia1
Team Kodi member

Ok, libav implemented libavresample and ffmpeg merged it.

@elupus Michael did the merge. Here is his reason https://lists.ffmpeg.org/pipermail/ffmpeg-devel/2012-April/123746.html

@elupus
Team Kodi member

Would be nice to get this pull request updated. Either to libavresample or libswresample

@aballier

yes, i've had absolutely no time to work on xbmc lately, though, imho, we should support both with a preference over libswresample if available: it is only available withing ffmpeg and they promised (are?) to port the libavresample improvements to swr.

@aballier aballier closed this
@aballier

lets close this for now, i'll reopen a new one rebased on current master

@mikedm139 mikedm139 pushed a commit to mikedm139/plex-home-theater-public that referenced this pull request
@tru tru Add back more filtering options for Home Movie sections.
Fixes #882
af577b6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 14, 2012
  1. @aballier

    SwResample: Map swr_alloc_set_opts, swr_init, swr_free and swr_conver…

    aballier committed
    …t functions.
    
    That way we can use the libswresample API instead of the private libavcodec::audioconvert API.
  2. @aballier

    [dvdplayer]: Use the SwResample API.

    aballier committed
    This drops all usage of the private libavcodec::audiocovert API in xbmc.
  3. @aballier
View
40 lib/DllAvCodec.h
@@ -58,20 +58,8 @@ extern "C" {
#include <ffmpeg/avformat.h>
#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()
View
26 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 */
View
25 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;
View
4 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();
};
View
23 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;
View
4 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;
Something went wrong with that request. Please try again.