summaryrefslogtreecommitdiff
path: root/rotord/libavaudioloader.cpp
diff options
context:
space:
mode:
authorComment <tim@gray.(none)>2013-04-20 02:01:49 +0100
committerComment <tim@gray.(none)>2013-04-20 02:01:49 +0100
commitb05e391e126f2bba2a4bd2915786d93731d2dbc9 (patch)
tree97e525d765043af95837db15bc22cc8bf9f7efb7 /rotord/libavaudioloader.cpp
parentda05e29b124b2f6d553dedb1c63a4a655fc4f7b6 (diff)
audio muxer ongoing
Diffstat (limited to 'rotord/libavaudioloader.cpp')
-rw-r--r--rotord/libavaudioloader.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/rotord/libavaudioloader.cpp b/rotord/libavaudioloader.cpp
new file mode 100644
index 0000000..8a2d81a
--- /dev/null
+++ b/rotord/libavaudioloader.cpp
@@ -0,0 +1,133 @@
+#include "libavaudioloader.h"
+
+bool libav::audioloader::setup(const std::string &filename){
+
+ av_register_all();
+
+ frame = avcodec_alloc_frame();
+ if (!frame)
+ {
+ std::cout << "Error allocating the frame" << std::endl;
+ return false;
+ }
+
+ formatContext = NULL;
+ if (avformat_open_input(&formatContext, filename.c_str(), NULL, NULL) != 0)
+ {
+ av_free(frame);
+ std::cout << "Error opening the file" << std::endl;
+ return false;
+ }
+
+ if (avformat_find_stream_info(formatContext, NULL) < 0)
+ {
+ av_free(frame);
+ avformat_close_input(&formatContext);
+ std::cout << "Error finding the stream info" << std::endl;
+ return false;
+ }
+
+ audioStream = NULL;
+ for (unsigned int i = 0; i < formatContext->nb_streams; ++i)
+ {
+ if (formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+ {
+ audioStream = formatContext->streams[i];
+ break;
+ }
+ }
+
+ if (audioStream == NULL)
+ {
+ av_free(frame);
+ avformat_close_input(&formatContext);
+ std::cout << "Could not find any audio stream in the file" << std::endl;
+ return false;
+ }
+
+ codecContext = audioStream->codec;
+
+ codecContext->codec = avcodec_find_decoder(codecContext->codec_id);
+ if (codecContext->codec == NULL)
+ {
+ av_free(frame);
+ avformat_close_input(&formatContext);
+ std::cout << "Couldn't find a proper decoder" << std::endl;
+ return false;
+ }
+ else if (avcodec_open2(codecContext, codecContext->codec, NULL) != 0)
+ {
+ av_free(frame);
+ avformat_close_input(&formatContext);
+ std::cout << "Couldn't open the context with the decoder" << std::endl;
+ return false;
+ }
+
+ av_dump_format(formatContext, 0, 0, false); //avformat.h line 1256
+ int samples = ((formatContext->duration + 5000)*codecContext->sample_rate)/AV_TIME_BASE;
+
+ std::cout << "This stream has " << codecContext->channels << " channels, a sample rate of " << codecContext->sample_rate << "Hz and "<<samples <<" samples" << std::endl;
+ std::cout << "The data is in format " <<codecContext->sample_fmt<< " (aka "<< av_get_sample_fmt_name(codecContext->sample_fmt) << ") "<<std::endl;
+
+ av_init_packet(&packet);
+ sample_processed=0;
+ ready=true;
+ return true;
+ }
+ AVFrame* libav::audioloader::get_frame() {
+
+ if (!ready) return nullptr;
+
+ int frameFinished = 0;
+ while (!frameFinished) {
+ int ret=av_read_frame(formatContext, &packet);
+ if (ret<0) {
+ std::cerr << "finished with code "<<ret <<(ret==AVERROR_EOF?" ,EOF":"")<<std::endl;
+ ready=false;
+ return nullptr;
+ }
+ if (packet.stream_index == audioStream->index)
+ {
+ //int bytes =
+ avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet);
+
+ // Some frames rely on multiple packets, so we have to make sure the frame is finished before
+ // we can use it
+ }
+ // You *must* call av_free_packet() after each call to av_read_frame() or else you'll leak memory
+ av_free_packet(&packet);
+ }
+ return frame;
+
+ }
+
+/*
+ // Some codecs will cause frames to be buffered up in the decoding process. If the CODEC_CAP_DELAY flag
+ // is set, there can be buffered up frames that need to be flushed, so we'll do that
+ if (codecContext->codec->capabilities & CODEC_CAP_DELAY)
+ {
+ av_init_packet(&packet);
+ // Decode all the remaining frames in the buffer, until the end is reached
+ int frameFinished = 0;
+ int bytes = avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet);
+ while (bytes >= 0 && frameFinished)
+ {
+ for (auto p: processors) {
+ p->process_frame(frame->data[0],frame->nb_samples);
+ }
+ mutex.lock();
+ progress=((double)sample_processed)/samples;
+ mutex.unlock();
+ }
+ }
+
+ cerr << "finished processing: "<<sample_processed << " samples of "<<samples<<", "<<((double)sample_processed*100)/samples<<"%"<< std::endl;
+*/
+
+ bool libav::audioloader::close() {
+ av_free(frame);
+ avcodec_close(codecContext);
+ avformat_close_input(&formatContext);
+
+ return true;
+ } \ No newline at end of file