summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2011-01-06 06:13:12 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2011-01-06 06:13:12 +0100
commit822ae13835c2f6443d5b4fface6f3f547bcfcb11 (patch)
tree2a9c2ec01f90b8dcb26b2d873fd23443ed8d4a14
parent6f2fefdd9ff5f8561b3538efb5eb0765a9b4a141 (diff)
Implemented rudimentary ffmpeg-based decoder.
-rw-r--r--SConstruct2
-rw-r--r--decoder.cpp2
-rw-r--r--decoders/ffmpeg_decoder.cpp36
-rw-r--r--decoders/ffmpeg_decoder.h24
-rw-r--r--encoders/lame_encoder.cpp4
-rw-r--r--music.cpp4
6 files changed, 67 insertions, 5 deletions
diff --git a/SConstruct b/SConstruct
index b3c7009..ed654ef 100644
--- a/SConstruct
+++ b/SConstruct
@@ -3,7 +3,7 @@ AddOption('--release', action = 'store_true')
env = Environment(CPPPATH = ['.'], CCFLAGS = ['-pthread'], LINKFLAGS = ['-pthread'])
if env['PLATFORM'] == 'darwin':
- env.Append(LIBS = ['boost_system', 'boost_filesystem', 'boost_regex', 'boost_thread', 'boost_program_options', 'mp3lame', 'soci_core'])
+ env.Append(LIBS = ['boost_system', 'boost_filesystem', 'boost_regex', 'boost_thread', 'boost_program_options', 'mp3lame', 'avformat', 'avcodec', 'soci_core'])
else:
conf = Configure(env)
for lib in ['boost_system-mt', 'boost_filesystem-mt', 'boost_regex-mt','boost_thread-mt', 'boost_program_options-mt', 'mp3lame']:
diff --git a/decoder.cpp b/decoder.cpp
index 9330c6e..3cfbd81 100644
--- a/decoder.cpp
+++ b/decoder.cpp
@@ -1,5 +1,6 @@
#include "decoder.h"
#include "decoders/mpg123_decoder.h"
+#include "decoders/ffmpeg_decoder.h"
#include <boost/function.hpp>
#include <boost/functional/factory.hpp>
@@ -12,6 +13,7 @@ std::map<std::string, DecoderFactory> decoder_factories;
void Decoder::init() {
mpg123_init(); // initialize the mpg123 library
decoder_factories["mpg123"] = boost::factory<boost::shared_ptr<DecoderMpg123> >();
+ decoder_factories["ffmpeg"] = boost::factory<boost::shared_ptr<DecoderFFmpeg> >();
}
Decoder::p Decoder::get(const std::string& name, const std::string& filename) {
diff --git a/decoders/ffmpeg_decoder.cpp b/decoders/ffmpeg_decoder.cpp
new file mode 100644
index 0000000..d66c72b
--- /dev/null
+++ b/decoders/ffmpeg_decoder.cpp
@@ -0,0 +1,36 @@
+#include "ffmpeg_decoder.h"
+
+#include <iostream>
+
+DecoderFFmpeg::DecoderFFmpeg(const std::string& filename) {
+ av_register_all();
+
+ std::cerr << "Opening file: " << av_open_input_file(&lavf_ctx, filename.c_str(), 0, 0, 0) << std::endl;
+
+ av_find_stream_info(lavf_ctx);
+
+ dump_format(lavf_ctx, 0, filename.c_str(), 0);
+
+ lavc_ctx = lavf_ctx->streams[0]->codec;
+ codec = avcodec_find_decoder(lavc_ctx->codec_id);
+
+ std::cerr << "Opening decoder: " << avcodec_open(lavc_ctx, codec) << std::endl;
+}
+
+DecoderFFmpeg::~DecoderFFmpeg() {
+
+}
+
+std::size_t DecoderFFmpeg::read(char* buf, std::size_t buf_size) {
+ AVPacket packet;
+
+ av_read_packet(lavf_ctx, &packet);
+
+ int len = avcodec_decode_audio3(lavc_ctx, (int16_t*)buf, (int*)&buf_size, &packet);
+
+ std::cerr << "Decoded " << len << " bytes of data to " << buf_size << " bytes of raw data." << std::endl;
+
+ av_free_packet(&packet);
+
+ return buf_size;
+}
diff --git a/decoders/ffmpeg_decoder.h b/decoders/ffmpeg_decoder.h
new file mode 100644
index 0000000..a77e303
--- /dev/null
+++ b/decoders/ffmpeg_decoder.h
@@ -0,0 +1,24 @@
+#ifndef FFMPEG_DECODER_H
+#define FFMPEG_DECODER_H
+
+#include "decoder.h"
+
+extern "C" {
+ #include <libavformat/avformat.h>
+ #include <libavcodec/avcodec.h>
+}
+
+class DecoderFFmpeg : public Decoder {
+ private:
+ AVFormatContext* lavf_ctx;
+ AVCodecContext* lavc_ctx;
+ AVCodec* codec;
+
+ public:
+ DecoderFFmpeg(const std::string& filename);
+ ~DecoderFFmpeg();
+
+ virtual std::size_t read(char* buf, std::size_t buf_size);
+};
+
+#endif
diff --git a/encoders/lame_encoder.cpp b/encoders/lame_encoder.cpp
index be6f684..6616b87 100644
--- a/encoders/lame_encoder.cpp
+++ b/encoders/lame_encoder.cpp
@@ -24,8 +24,8 @@ size_t EncoderLame::flush(uint8_t *output, size_t output_size) {
}
std::size_t EncoderLame::read(char* buf, std::size_t buf_size) {
- char src_data[0x2000];
- std::streamsize src_read = source->read(src_data, 0x2000);
+ char src_data[0x30000];
+ std::streamsize src_read = source->read(src_data, 0x30000);
if(src_read < 0)
src_read = 0;
std::streamsize size = encode((const uint8_t*)src_data, src_read, (uint8_t*)buf, buf_size);
diff --git a/music.cpp b/music.cpp
index 3faa10b..cebf745 100644
--- a/music.cpp
+++ b/music.cpp
@@ -241,10 +241,10 @@ void MusicTrack::render(HTTP::Connection::p req) {
Encoder::p encoder = Encoder::get(req->args["encoder"], decoder);
// TODO: Make an encoder-to-istream adapter to get rid of this:
- char data[0x1000];
+ char data[0x10000];
std::streamsize size = 1;
while(size) {
- size = encoder->read(data, 0x1000);
+ size = encoder->read(data, 0x10000);
if(size > 0)
req->send_data(data, size);
}