Finished source/

This commit is contained in:
Nicolay Korslund 2009-12-29 10:34:40 +01:00
parent cb638cd44e
commit 6281685f73
2 changed files with 22 additions and 44 deletions

View file

@ -1,14 +1,10 @@
// NOT UPDATED - WIP
#include "input_ffmpeg.h" #include "input_ffmpeg.h"
#include <assert.h>
using namespace Mangle::Sound; using namespace Mangle::Sound;
// Static output buffer. Not thread safe, but supports multiple // Static output buffer. Not thread safe, but supports multiple
// streams operated from the same thread. // streams operated from the same thread.
static uint8_t outBuf[AVCODEC_MAX_AUDIO_FRAME_SIZE]; static uint8_t outBuf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
bool FFM_InputManager::init = false;
/// FFmpeg exception. /// FFmpeg exception.
class FFM_Exception : public std::exception class FFM_Exception : public std::exception
@ -35,44 +31,23 @@ static void fail(const std::string &msg)
throw FFM_Exception("FFMpeg exception: " + msg); throw FFM_Exception("FFMpeg exception: " + msg);
} }
// --- Loader ---
// --- Manager --- static bool init = false;
FFM_InputManager::FFM_InputManager() FFMpegLoader::FFMpegLoader(bool setup)
{ {
if(!init) if(setup && !init)
{ {
av_register_all(); av_register_all();
av_log_set_level(AV_LOG_ERROR); av_log_set_level(AV_LOG_ERROR);
init = true; init = true;
} }
canLoadStream = false;
} }
InputSource *FFM_InputManager::load(const std::string &file)
{ return new FFM_InputSource(file); }
// --- Source --- // --- Source ---
FFM_InputSource::FFM_InputSource(const std::string &file) FFMpegSource::FFMpegSource(const std::string &file)
{
// FFmpeg doesn't handle several instances from one source. So we
// just store the filename.
name = file;
}
InputStream *FFM_InputSource::getStream()
{ return new FFM_InputStream(name); }
void FFM_InputSource::drop()
{ delete this; }
// --- Stream ---
FFM_InputStream::FFM_InputStream(const std::string &file)
{ {
std::string msg; std::string msg;
AVCodec *codec; AVCodec *codec;
@ -97,7 +72,7 @@ FFM_InputStream::FFM_InputStream(const std::string &file)
} }
if(StreamNum == FmtCtx->nb_streams) if(StreamNum == FmtCtx->nb_streams)
fail("File " + file + " didn't contain any audio streams"); fail("File '" + file + "' didn't contain any audio streams");
// Open the decoder // Open the decoder
CodecCtx = FmtCtx->streams[StreamNum]->codec; CodecCtx = FmtCtx->streams[StreamNum]->codec;
@ -105,7 +80,7 @@ FFM_InputStream::FFM_InputStream(const std::string &file)
if(!codec || avcodec_open(CodecCtx, codec) < 0) if(!codec || avcodec_open(CodecCtx, codec) < 0)
{ {
msg = "Error loading " + file + ": "; msg = "Error loading '" + file + "': ";
if(codec) if(codec)
msg += "coded error"; msg += "coded error";
else else
@ -122,24 +97,24 @@ FFM_InputStream::FFM_InputStream(const std::string &file)
fail(msg); fail(msg);
} }
FFM_InputStream::~FFM_InputStream() FFMpegSource::~FFMpegSource()
{ {
avcodec_close(CodecCtx); avcodec_close(CodecCtx);
av_close_input_file(FmtCtx); av_close_input_file(FmtCtx);
} }
void FFM_InputStream::getInfo(int32_t *rate, int32_t *channels, int32_t *bits) void FFMpegSource::getInfo(int32_t *rate, int32_t *channels, int32_t *bits)
{ {
if(rate) *rate = CodecCtx->sample_rate; if(rate) *rate = CodecCtx->sample_rate;
if(channels) *channels = CodecCtx->channels; if(channels) *channels = CodecCtx->channels;
if(bits) *bits = 16; if(bits) *bits = 16;
} }
uint32_t FFM_InputStream::getData(void *data, uint32_t length) size_t FFMpegSource::read(void *data, size_t length)
{ {
if(empty) return 0; if(isEof) return 0;
uint32_t left = length; size_t left = length;
uint8_t *outPtr = (uint8_t*)data; uint8_t *outPtr = (uint8_t*)data;
// First, copy over any stored data we might be sitting on // First, copy over any stored data we might be sitting on
@ -209,7 +184,7 @@ uint32_t FFM_InputStream::getData(void *data, uint32_t length)
memcpy(outPtr, outBuf, copy); memcpy(outPtr, outBuf, copy);
// left = how much space is left in the caller output // left = how much space is left in the caller output
// buffer // buffer. This loop repeats as long left is > 0
left -= copy; left -= copy;
outPtr += copy; outPtr += copy;
assert(left >= 0); assert(left >= 0);
@ -229,10 +204,7 @@ uint32_t FFM_InputStream::getData(void *data, uint32_t length)
// If we're returning less than asked for, then we're done // If we're returning less than asked for, then we're done
if(left > 0) if(left > 0)
empty = true; isEof = true;
return length - left; return length - left;
} }
void FFM_InputStream::drop()
{ delete this; }

View file

@ -20,7 +20,6 @@ class FFMpegSource : public SampleSource
AVFormatContext *FmtCtx; AVFormatContext *FmtCtx;
AVCodecContext *CodecCtx; AVCodecContext *CodecCtx;
int StreamNum; int StreamNum;
bool empty;
std::vector<uint8_t> storage; std::vector<uint8_t> storage;
@ -41,7 +40,14 @@ class FFMpegSource : public SampleSource
#include "loadertemplate.h" #include "loadertemplate.h"
/// A factory that loads FFMpegSources from file /// A factory that loads FFMpegSources from file
typedef SSL_Template<AudiereSource,false,true> AudiereLoader; class FFMpegLoader : public SSL_Template<AudiereSource,false,true>
{
public:
/// Sets up the libavcodec library. If you want to do your own
/// setup, send a setup=false parameter.
FFMpegLoader(bool setup=true);
};
}} // namespaces }} // namespaces
#endif #endif