/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <iomanip>
#include <iostream>
#include <stdint.h>
-#include <boost/lexical_cast.hpp>
#include <sndfile.h>
extern "C" {
#include <libavcodec/avcodec.h>
#include "filter_graph.h"
#include "audio_buffers.h"
#include "ffmpeg_content.h"
+#include "image_proxy.h"
#include "i18n.h"
+#define LOG_GENERAL(...) film->log()->log (String::compose (__VA_ARGS__), Log::TYPE_GENERAL);
+#define LOG_ERROR(...) film->log()->log (String::compose (__VA_ARGS__), Log::TYPE_ERROR);
+#define LOG_WARNING(...) film->log()->log (__VA_ARGS__, Log::TYPE_WARNING);
+
using std::cout;
using std::string;
using std::vector;
}
/* Stop us being asked for any more data */
- _video_position = _ffmpeg_content->video_length ();
+ _video_position = _ffmpeg_content->video_length_after_3d_combine ();
_audio_position = _ffmpeg_content->audio_length ();
}
av_strerror (r, buf, sizeof(buf));
shared_ptr<const Film> film = _film.lock ();
assert (film);
- film->log()->log (String::compose (N_("error on av_read_frame (%1) (%2)"), buf, r));
+ LOG_ERROR (N_("error on av_read_frame (%1) (%2)"), buf, r);
}
flush ();
av_free_packet (&_packet);
}
+
+ /* _video_position should be the next thing to be emitted, which will the one after the thing
+ we just saw.
+ */
+ _video_position++;
}
void
if (decode_result < 0) {
shared_ptr<const Film> film = _film.lock ();
assert (film);
- film->log()->log (String::compose ("avcodec_decode_audio4 failed (%1)", decode_result));
+ LOG_ERROR ("avcodec_decode_audio4 failed (%1)", decode_result);
return;
}
if (pts > 0) {
/* Emit some silence */
- shared_ptr<AudioBuffers> silence (
- new AudioBuffers (
- _ffmpeg_content->audio_channels(),
- pts * _ffmpeg_content->content_audio_frame_rate()
- )
- );
+ int64_t frames = pts * _ffmpeg_content->content_audio_frame_rate ();
+ while (frames > 0) {
+ int64_t const this_time = min (frames, (int64_t) _ffmpeg_content->content_audio_frame_rate() / 2);
+
+ shared_ptr<AudioBuffers> silence (
+ new AudioBuffers (_ffmpeg_content->audio_channels(), this_time)
+ );
- silence->make_silent ();
- audio (silence, _audio_position);
+ silence->make_silent ();
+ audio (silence, _audio_position);
+ frames -= this_time;
+ }
}
}
graph.reset (new FilterGraph (_ffmpeg_content, libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format));
_filter_graphs.push_back (graph);
- film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format));
+ LOG_GENERAL (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format);
} else {
graph = *i;
}
list<pair<shared_ptr<Image>, int64_t> > images = graph->process (_frame);
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
for (list<pair<shared_ptr<Image>, int64_t> >::iterator i = images.begin(); i != images.end(); ++i) {
shared_ptr<Image> image = i->first;
)
);
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
black->make_black ();
- video (image, false, _video_position);
+ video (shared_ptr<ImageProxy> (new RawImageProxy (image, film->log())), false, _video_position);
delta -= one_frame;
}
if (delta > -one_frame) {
/* This PTS is within a frame of being right; emit this (otherwise it will be dropped) */
- video (image, false, _video_position);
+ video (shared_ptr<ImageProxy> (new RawImageProxy (image, film->log())), false, _video_position);
}
} else {
- shared_ptr<const Film> film = _film.lock ();
- assert (film);
- film->log()->log ("Dropping frame without PTS");
+ LOG_WARNING ("Dropping frame without PTS");
}
}