1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-11 15:40:39 +00:00

Merge remote-tracking branch 'cc9cii/ffmpeg-swresample'

This commit is contained in:
Marc Zinnschlag 2014-09-15 12:44:38 +02:00
commit 3f671c86a8
8 changed files with 343 additions and 60 deletions

View File

@ -12,7 +12,7 @@ before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq libgtest-dev google-mock
- sudo apt-get install -qq libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev libboost-wave-dev
- sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev
- sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavresample-dev
- sudo apt-get install -qq libbullet-dev libogre-1.9-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev
- sudo mkdir /usr/src/gtest/build
- cd /usr/src/gtest/build

View File

@ -140,10 +140,24 @@ set(OPENMW_LIBS ${OENGINE_ALL})
set(OPENMW_LIBS_HEADER)
# Sound setup
set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
find_package(FFmpeg REQUIRED)
set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE SWRESAMPLE AVRESAMPLE)
unset(FFMPEG_LIBRARIES CACHE)
find_package(FFmpeg)
if ( NOT AVCODEC_FOUND OR NOT AVFORMAT_FOUND OR NOT AVUTIL_FOUND OR NOT SWSCALE_FOUND )
message(FATAL_ERROR "FFmpeg component required, but not found!")
endif()
set(SOUND_INPUT_INCLUDES ${FFMPEG_INCLUDE_DIRS})
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARIES})
if( SWRESAMPLE_FOUND )
add_definitions(-DHAVE_LIBSWRESAMPLE)
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWRESAMPLE_LIBRARIES})
else()
if( AVRESAMPLE_FOUND )
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${AVRESAMPLE_LIBRARIES})
else()
message(FATAL_ERROR "Install either libswresample (FFmpeg) or libavresample (Libav).")
endif()
endif()
# TinyXML
option(USE_SYSTEM_TINYXML "Use system TinyXML library instead of internal." OFF)

View File

@ -55,7 +55,7 @@ add_openmw_dir (mwscript
)
add_openmw_dir (mwsound
soundmanagerimp openal_output ffmpeg_decoder sound sound_decoder sound_output loudness
soundmanagerimp openal_output ffmpeg_decoder sound sound_decoder sound_output loudness libavwrapper
)
add_openmw_dir (mwworld

View File

@ -32,10 +32,15 @@ extern "C"
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
// From libavformat version 55.0.100 and onward the declaration of av_gettime() is removed from libavformat/avformat.h and moved
// to libavutil/time.h
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1)
#define av_frame_alloc avcodec_alloc_frame
#endif
// From libavformat version 55.0.100 and onward the declaration of av_gettime() is
// removed from libavformat/avformat.h and moved to libavutil/time.h
// https://github.com/FFmpeg/FFmpeg/commit/06a83505992d5f49846c18507a6c3eb8a47c650e
#if AV_VERSION_INT(55, 0, 100) <= AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO)
#if AV_VERSION_INT(55, 0, 100) <= AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO)
#include <libavutil/time.h>
#endif
@ -46,30 +51,25 @@ extern "C"
LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO)
#include <libavutil/channel_layout.h>
#endif
}
#ifdef _WIN32
// Decide whether to play binkaudio.
#include <libavcodec/version.h>
// libavcodec versions 54.10.100 (or maybe earlier) to 54.54.100 potentially crashes Windows 64bit.
// From version 54.56 or higher, there's no sound due to the encoding format changing from S16 to FLTP
// (see https://gitorious.org/ffmpeg/ffmpeg/commit/7bfd1766d1c18f07b0a2dd042418a874d49ea60d and
// http://git.videolan.org/?p=ffmpeg.git;a=commitdiff;h=3049d5b9b32845c86aa5588bb3352bdeb2edfdb2;hp=43c6b45a53a186a187f7266e4d6bd3c2620519f1),
// but does not crash (or at least no known crash).
#if (LIBAVCODEC_VERSION_MAJOR > 54)
#define FFMPEG_PLAY_BINKAUDIO
// WARNING: avcodec versions up to 54.54.100 potentially crashes on Windows 64bit.
// From version 54.56 binkaudio encoding format changed from S16 to FLTP. See:
// https://gitorious.org/ffmpeg/ffmpeg/commit/7bfd1766d1c18f07b0a2dd042418a874d49ea60d
// http://ffmpeg.zeranoe.com/forum/viewtopic.php?f=15&t=872
#ifdef HAVE_LIBSWRESAMPLE
#include <libswresample/swresample.h>
#else
#ifdef _WIN64
#if ((LIBAVCODEC_VERSION_MAJOR == 54) && (LIBAVCODEC_VERSION_MINOR >= 55))
#define FFMPEG_PLAY_BINKAUDIO
#endif
#else
#if ((LIBAVCODEC_VERSION_MAJOR == 54) && (LIBAVCODEC_VERSION_MINOR >= 10))
#define FFMPEG_PLAY_BINKAUDIO
#endif
#endif
/* FIXME: remove this section once libswresample is available on all platforms */
#include <libavresample/avresample.h>
#include <libavutil/opt.h>
#define SwrContext AVAudioResampleContext
int swr_init(AVAudioResampleContext *avr);
void swr_free(AVAudioResampleContext **avr);
int swr_convert( AVAudioResampleContext *avr, uint8_t** output, int out_samples, const uint8_t** input, int in_samples);
AVAudioResampleContext * swr_alloc_set_opts( AVAudioResampleContext *avr, int64_t out_ch_layout, AVSampleFormat out_fmt, int out_rate, int64_t in_ch_layout, AVSampleFormat in_fmt, int in_rate, int o, void* l);
#endif
#endif
}
#define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
#define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
@ -317,6 +317,12 @@ class MovieAudioDecoder : public MWSound::Sound_Decoder
VideoState *mVideoState;
AVStream *mAVStream;
SwrContext *mSwr;
enum AVSampleFormat mOutputSampleFormat;
uint8_t *mDataBuf;
uint8_t **mFrameData;
int mDataBufLen;
AutoAVPacket mPacket;
AVFrame *mFrame;
ssize_t mFramePos;
@ -383,6 +389,28 @@ class MovieAudioDecoder : public MWSound::Sound_Decoder
if(!got_frame || frame->nb_samples <= 0)
continue;
if(mSwr)
{
if(!mDataBuf || mDataBufLen < frame->nb_samples)
{
av_freep(&mDataBuf);
if(av_samples_alloc(&mDataBuf, NULL, mAVStream->codec->channels,
frame->nb_samples, mOutputSampleFormat, 0) < 0)
break;
else
mDataBufLen = frame->nb_samples;
}
if(swr_convert(mSwr, (uint8_t**)&mDataBuf, frame->nb_samples,
(const uint8_t**)frame->extended_data, frame->nb_samples) < 0)
{
break;
}
mFrameData = &mDataBuf;
}
else
mFrameData = &frame->data[0];
mAudioClock += (double)frame->nb_samples /
(double)mAVStream->codec->sample_rate;
@ -420,7 +448,7 @@ public:
MovieAudioDecoder(VideoState *is)
: mVideoState(is)
, mAVStream(*is->audio_st)
, mFrame(avcodec_alloc_frame())
, mFrame(av_frame_alloc())
, mFramePos(0)
, mFrameSize(0)
, mAudioClock(0.0)
@ -429,10 +457,17 @@ public:
/* Correct audio only if larger error than this */
, mAudioDiffThreshold(2.0 * 0.050/* 50 ms */)
, mAudioDiffAvgCount(0)
, mSwr(0)
, mOutputSampleFormat(AV_SAMPLE_FMT_NONE)
, mDataBuf(NULL)
, mFrameData(NULL)
, mDataBufLen(0)
{ }
virtual ~MovieAudioDecoder()
{
av_freep(&mFrame);
swr_free(&mSwr);
av_freep(&mDataBuf);
}
void getInfo(int *samplerate, MWSound::ChannelConfig *chans, MWSound::SampleType * type)
@ -443,10 +478,18 @@ public:
*type = MWSound::SampleType_Int16;
else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_FLT)
*type = MWSound::SampleType_Float32;
else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_U8P)
*type = MWSound::SampleType_UInt8;
else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_S16P)
*type = MWSound::SampleType_Int16;
else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_FLTP)
*type = MWSound::SampleType_Float32;
else
fail(std::string("Unsupported sample format: ")+
av_get_sample_fmt_name(mAVStream->codec->sample_fmt));
int64_t ch_layout = mAVStream->codec->channel_layout;
if(mAVStream->codec->channel_layout == AV_CH_LAYOUT_MONO)
*chans = MWSound::ChannelConfig_Mono;
else if(mAVStream->codec->channel_layout == AV_CH_LAYOUT_STEREO)
@ -461,9 +504,15 @@ public:
{
/* Unknown channel layout. Try to guess. */
if(mAVStream->codec->channels == 1)
{
*chans = MWSound::ChannelConfig_Mono;
ch_layout = AV_CH_LAYOUT_MONO;
}
else if(mAVStream->codec->channels == 2)
{
*chans = MWSound::ChannelConfig_Stereo;
ch_layout = AV_CH_LAYOUT_STEREO;
}
else
{
std::stringstream sstr("Unsupported raw channel count: ");
@ -480,6 +529,30 @@ public:
}
*samplerate = mAVStream->codec->sample_rate;
if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_U8P)
mOutputSampleFormat = AV_SAMPLE_FMT_U8;
else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_S16P)
mOutputSampleFormat = AV_SAMPLE_FMT_S16;
else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_FLTP)
mOutputSampleFormat = AV_SAMPLE_FMT_FLT;
if(mOutputSampleFormat != AV_SAMPLE_FMT_NONE)
{
mSwr = swr_alloc_set_opts(mSwr, // SwrContext
ch_layout, // output ch layout
mOutputSampleFormat, // output sample format
mAVStream->codec->sample_rate, // output sample rate
ch_layout, // input ch layout
mAVStream->codec->sample_fmt, // input sample format
mAVStream->codec->sample_rate, // input sample rate
0, // logging level offset
NULL); // log context
if(!mSwr)
fail(std::string("Couldn't allocate SwrContext"));
if(swr_init(mSwr) < 0)
fail(std::string("Couldn't initialize SwrContext"));
}
}
size_t read(char *stream, size_t len)
@ -500,7 +573,8 @@ public:
}
mFramePos = std::min<ssize_t>(mFrameSize, sample_skip);
sample_skip -= mFramePos;
if(sample_skip > 0 || mFrameSize > -sample_skip)
sample_skip -= mFramePos;
continue;
}
@ -508,7 +582,7 @@ public:
if(mFramePos >= 0)
{
len1 = std::min<size_t>(len1, mFrameSize-mFramePos);
memcpy(stream, mFrame->data[0]+mFramePos, len1);
memcpy(stream, mFrameData[0]+mFramePos, len1);
}
else
{
@ -519,29 +593,29 @@ public:
/* add samples by copying the first sample*/
if(n == 1)
memset(stream, *mFrame->data[0], len1);
memset(stream, *mFrameData[0], len1);
else if(n == 2)
{
const int16_t val = *((int16_t*)mFrame->data[0]);
const int16_t val = *((int16_t*)mFrameData[0]);
for(size_t nb = 0;nb < len1;nb += n)
*((int16_t*)(stream+nb)) = val;
}
else if(n == 4)
{
const int32_t val = *((int32_t*)mFrame->data[0]);
const int32_t val = *((int32_t*)mFrameData[0]);
for(size_t nb = 0;nb < len1;nb += n)
*((int32_t*)(stream+nb)) = val;
}
else if(n == 8)
{
const int64_t val = *((int64_t*)mFrame->data[0]);
const int64_t val = *((int64_t*)mFrameData[0]);
for(size_t nb = 0;nb < len1;nb += n)
*((int64_t*)(stream+nb)) = val;
}
else
{
for(size_t nb = 0;nb < len1;nb += n)
memcpy(stream+nb, mFrame->data[0], n);
memcpy(stream+nb, mFrameData[0], n);
}
}
@ -768,9 +842,9 @@ void VideoState::video_thread_loop(VideoState *self)
AVFrame *pFrame;
double pts;
pFrame = avcodec_alloc_frame();
pFrame = av_frame_alloc();
self->rgbaFrame = avcodec_alloc_frame();
self->rgbaFrame = av_frame_alloc();
avpicture_alloc((AVPicture*)self->rgbaFrame, PIX_FMT_RGBA, (*self->video_st)->codec->width, (*self->video_st)->codec->height);
while(self->videoq.get(packet, self) >= 0)
@ -992,12 +1066,8 @@ void VideoState::init(const std::string& resourceName)
this->external_clock_base = av_gettime();
#if !defined(_WIN32) || defined(FFMPEG_PLAY_BINKAUDIO)
if(audio_index >= 0)
this->stream_open(audio_index, this->format_ctx);
#else
std::cout<<"FFmpeg sound disabled for \""+resourceName+"\""<<std::endl;
#endif
if(video_index >= 0)
{

View File

@ -5,6 +5,16 @@
#include <stdexcept>
extern "C" {
#ifndef HAVE_LIBSWRESAMPLE
/* FIXME: remove this section once libswresample is available on all platforms */
int swr_init(AVAudioResampleContext *avr);
void swr_free(AVAudioResampleContext **avr);
int swr_convert( AVAudioResampleContext *avr, uint8_t** output, int out_samples, const uint8_t** input, int in_samples);
AVAudioResampleContext * swr_alloc_set_opts( AVAudioResampleContext *avr, int64_t out_ch_layout, AVSampleFormat out_fmt, int out_rate, int64_t in_ch_layout, AVSampleFormat in_fmt, int in_rate, int o, void* l);
#endif
}
namespace MWSound
{
@ -95,6 +105,29 @@ bool FFmpeg_Decoder::getAVAudioData()
memmove(mPacket.data, &mPacket.data[len], remaining);
av_shrink_packet(&mPacket, remaining);
}
if(mSwr)
{
if(!mDataBuf || mDataBufLen < mFrame->nb_samples)
{
av_freep(&mDataBuf);
if(av_samples_alloc(&mDataBuf, NULL, (*mStream)->codec->channels,
mFrame->nb_samples, mOutputSampleFormat, 0) < 0)
break;
else
mDataBufLen = mFrame->nb_samples;
}
if(swr_convert(mSwr, (uint8_t**)&mDataBuf, mFrame->nb_samples,
(const uint8_t**)mFrame->extended_data, mFrame->nb_samples) < 0)
{
break;
}
mFrameData = &mDataBuf;
}
else
mFrameData = &mFrame->data[0];
} while(got_frame == 0 || mFrame->nb_samples == 0);
mNextPts += (double)mFrame->nb_samples / (double)(*mStream)->codec->sample_rate;
@ -122,7 +155,7 @@ size_t FFmpeg_Decoder::readAVAudioData(void *data, size_t length)
size_t rem = std::min<size_t>(length-dec, mFrameSize-mFramePos);
/* Copy the data to the app's buffer and increment */
memcpy(data, mFrame->data[0]+mFramePos, rem);
memcpy(data, mFrameData[0]+mFramePos, rem);
data = (char*)data + rem;
dec += rem;
mFramePos += rem;
@ -132,19 +165,6 @@ size_t FFmpeg_Decoder::readAVAudioData(void *data, size_t length)
return dec;
}
static AVSampleFormat ffmpegNonPlanarSampleFormat (AVSampleFormat format)
{
switch (format)
{
case AV_SAMPLE_FMT_U8P: return AV_SAMPLE_FMT_U8;
case AV_SAMPLE_FMT_S16P: return AV_SAMPLE_FMT_S16;
case AV_SAMPLE_FMT_S32P: return AV_SAMPLE_FMT_S32;
case AV_SAMPLE_FMT_FLTP: return AV_SAMPLE_FMT_FLT;
case AV_SAMPLE_FMT_DBLP: return AV_SAMPLE_FMT_DBL;
default:return format;
}
}
void FFmpeg_Decoder::open(const std::string &fname)
{
close();
@ -191,7 +211,7 @@ void FFmpeg_Decoder::open(const std::string &fname)
if(!mStream)
fail("No audio streams in "+fname);
(*mStream)->codec->request_sample_fmt = ffmpegNonPlanarSampleFormat ((*mStream)->codec->sample_fmt);
(*mStream)->codec->request_sample_fmt = (*mStream)->codec->sample_fmt;
AVCodec *codec = avcodec_find_decoder((*mStream)->codec->codec_id);
if(!codec)
@ -203,7 +223,7 @@ void FFmpeg_Decoder::open(const std::string &fname)
if(avcodec_open2((*mStream)->codec, codec, NULL) < 0)
fail("Failed to open audio codec " + std::string(codec->long_name));
mFrame = avcodec_alloc_frame();
mFrame = av_frame_alloc();
}
catch(std::exception&)
{
@ -228,6 +248,8 @@ void FFmpeg_Decoder::close()
av_free_packet(&mPacket);
av_freep(&mFrame);
swr_free(&mSwr);
av_freep(&mDataBuf);
if(mFormatCtx)
{
@ -268,10 +290,18 @@ void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *
*type = SampleType_Int16;
else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_FLT)
*type = SampleType_Float32;
else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_U8P)
*type = SampleType_UInt8;
else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_S16P)
*type = SampleType_Int16;
else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_FLTP)
*type = SampleType_Float32;
else
fail(std::string("Unsupported sample format: ")+
av_get_sample_fmt_name((*mStream)->codec->sample_fmt));
int64_t ch_layout = (*mStream)->codec->channel_layout;
if((*mStream)->codec->channel_layout == AV_CH_LAYOUT_MONO)
*chans = ChannelConfig_Mono;
else if((*mStream)->codec->channel_layout == AV_CH_LAYOUT_STEREO)
@ -286,9 +316,15 @@ void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *
{
/* Unknown channel layout. Try to guess. */
if((*mStream)->codec->channels == 1)
{
*chans = ChannelConfig_Mono;
ch_layout = AV_CH_LAYOUT_MONO;
}
else if((*mStream)->codec->channels == 2)
{
*chans = ChannelConfig_Stereo;
ch_layout = AV_CH_LAYOUT_STEREO;
}
else
{
std::stringstream sstr("Unsupported raw channel count: ");
@ -305,6 +341,31 @@ void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *
}
*samplerate = (*mStream)->codec->sample_rate;
if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_U8P)
mOutputSampleFormat = AV_SAMPLE_FMT_U8;
else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_S16P)
mOutputSampleFormat = AV_SAMPLE_FMT_S16;
else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_FLTP)
mOutputSampleFormat = AV_SAMPLE_FMT_FLT;
if(mOutputSampleFormat != AV_SAMPLE_FMT_NONE)
{
mSwr = swr_alloc_set_opts(mSwr, // SwrContext
ch_layout, // output ch layout
mOutputSampleFormat, // output sample format
(*mStream)->codec->sample_rate, // output sample rate
ch_layout, // input ch layout
(*mStream)->codec->sample_fmt, // input sample format
(*mStream)->codec->sample_rate, // input sample rate
0, // logging level offset
NULL); // log context
if(!mSwr)
fail(std::string("Couldn't allocate SwrContext"));
if(swr_init(mSwr) < 0)
fail(std::string("Couldn't initialize SwrContext"));
}
}
size_t FFmpeg_Decoder::read(char *buffer, size_t bytes)
@ -323,7 +384,7 @@ void FFmpeg_Decoder::readAll(std::vector<char> &output)
{
size_t got = mFrame->nb_samples * (*mStream)->codec->channels *
av_get_bytes_per_sample((*mStream)->codec->sample_fmt);
const char *inbuf = reinterpret_cast<char*>(mFrame->data[0]);
const char *inbuf = reinterpret_cast<char*>(mFrameData[0]);
output.insert(output.end(), inbuf, inbuf+got);
}
}
@ -352,6 +413,11 @@ FFmpeg_Decoder::FFmpeg_Decoder()
, mFrameSize(0)
, mFramePos(0)
, mNextPts(0.0)
, mSwr(0)
, mOutputSampleFormat(AV_SAMPLE_FMT_NONE)
, mDataBuf(NULL)
, mFrameData(NULL)
, mDataBufLen(0)
{
memset(&mPacket, 0, sizeof(mPacket));

View File

@ -18,6 +18,21 @@ extern "C"
LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO)
#include <libavutil/channel_layout.h>
#endif
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1)
#define av_frame_alloc avcodec_alloc_frame
#endif
// From version 54.56 binkaudio encoding format changed from S16 to FLTP. See:
// https://gitorious.org/ffmpeg/ffmpeg/commit/7bfd1766d1c18f07b0a2dd042418a874d49ea60d
// http://ffmpeg.zeranoe.com/forum/viewtopic.php?f=15&t=872
#ifdef HAVE_LIBSWRESAMPLE
#include <libswresample/swresample.h>
#else
#include <libavresample/avresample.h>
#include <libavutil/opt.h>
#define SwrContext AVAudioResampleContext
#endif
}
#include <string>
@ -40,6 +55,12 @@ namespace MWSound
double mNextPts;
SwrContext *mSwr;
enum AVSampleFormat mOutputSampleFormat;
uint8_t *mDataBuf;
uint8_t **mFrameData;
int mDataBufLen;
bool getNextPacket();
Ogre::DataStreamPtr mDataStream;

View File

@ -0,0 +1,109 @@
#ifndef HAVE_LIBSWRESAMPLE
extern "C"
{
#define __STDC_CONSTANT_MACROS
#include <stdint.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
// From libavutil version 52.2.0 and onward the declaration of
// AV_CH_LAYOUT_* is removed from libavcodec/avcodec.h and moved to
// libavutil/channel_layout.h
#if AV_VERSION_INT(52, 2, 0) <= AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO)
#include <libavutil/channel_layout.h>
#endif
#include <libavresample/avresample.h>
#include <libavutil/opt.h>
/* FIXME: delete this file once libswresample is available on all platforms */
int swr_init(AVAudioResampleContext *avr) { return 1; }
void swr_free(AVAudioResampleContext **avr) { avresample_free(avr); }
int swr_convert(
AVAudioResampleContext *avr,
uint8_t** output,
int out_samples,
const uint8_t** input,
int in_samples)
{
// FIXME: potential performance hit
int out_plane_size = 0;
int in_plane_size = 0;
return avresample_convert(avr, output, out_plane_size, out_samples,
(uint8_t **)input, in_plane_size, in_samples);
}
AVAudioResampleContext * swr_alloc_set_opts(
AVAudioResampleContext *avr,
int64_t out_ch_layout,
AVSampleFormat out_fmt,
int out_rate,
int64_t in_ch_layout,
AVSampleFormat in_fmt,
int in_rate,
int o,
void* l)
{
avr = avresample_alloc_context();
if(!avr)
return 0;
int res;
res = av_opt_set_int(avr, "out_channel_layout", out_ch_layout, 0);
if(res < 0)
{
av_log(avr, AV_LOG_ERROR, "av_opt_set_int: out_ch_layout = %d\n", res);
return 0;
}
res = av_opt_set_int(avr, "out_sample_fmt", out_fmt, 0);
if(res < 0)
{
av_log(avr, AV_LOG_ERROR, "av_opt_set_int: out_fmt = %d\n", res);
return 0;
}
res = av_opt_set_int(avr, "out_sample_rate", out_rate, 0);
if(res < 0)
{
av_log(avr, AV_LOG_ERROR, "av_opt_set_int: out_rate = %d\n", res);
return 0;
}
res = av_opt_set_int(avr, "in_channel_layout", in_ch_layout, 0);
if(res < 0)
{
av_log(avr, AV_LOG_ERROR, "av_opt_set_int: in_ch_layout = %d\n", res);
return 0;
}
res = av_opt_set_int(avr, "in_sample_fmt", in_fmt, 0);
if(res < 0)
{
av_log(avr, AV_LOG_ERROR, "av_opt_set_int: in_fmt = %d\n", res);
return 0;
}
res = av_opt_set_int(avr, "in_sample_rate", in_rate, 0);
if(res < 0)
{
av_log(avr, AV_LOG_ERROR, "av_opt_set_int: in_rate = %d\n", res);
return 0;
}
res = av_opt_set_int(avr, "internal_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
if(res < 0)
{
av_log(avr, AV_LOG_ERROR, "av_opt_set_int: internal_sample_fmt\n");
return 0;
}
if(avresample_open(avr) < 0)
{
av_log(avr, AV_LOG_ERROR, "Error opening context\n");
return 0;
}
else
return avr;
}
}
#endif

View File

@ -14,6 +14,7 @@
# - AVUTIL
# - POSTPROCESS
# - SWSCALE
# - SWRESAMPLE
# the following variables will be defined
# <component>_FOUND - System has <component>
# <component>_INCLUDE_DIRS - Include directory necessary for using the <component> headers
@ -112,6 +113,8 @@ if (NOT FFMPEG_LIBRARIES)
find_component(AVUTIL libavutil avutil libavutil/avutil.h)
find_component(SWSCALE libswscale swscale libswscale/swscale.h)
find_component(POSTPROC libpostproc postproc libpostproc/postprocess.h)
find_component(SWRESAMPLE libswresample swresample libswresample/swresample.h)
find_component(AVRESAMPLE libavresample avresample libavresample/avresample.h)
# Check if the required components were found and add their stuff to the FFMPEG_* vars.
foreach (_component ${FFmpeg_FIND_COMPONENTS})
@ -142,7 +145,7 @@ if (NOT FFMPEG_LIBRARIES)
endif ()
# Now set the noncached _FOUND vars for the components.
foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE)
foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE SWRESAMPLE AVRESAMPLE)
set_component_found(${_component})
endforeach ()