#include "ffmpeg_content.h"
#include "video_content.h"
+#include "audio_content.h"
#include "ffmpeg_examiner.h"
#include "ffmpeg_subtitle_stream.h"
#include "ffmpeg_audio_stream.h"
#include "frame_rate_change.h"
#include "safe_stringstream.h"
#include "raw_convert.h"
+#include "subtitle_content.h"
#include <libcxml/cxml.h>
extern "C" {
#include <libavformat/avformat.h>
FFmpegContent::FFmpegContent (shared_ptr<const Film> film, boost::filesystem::path p)
: Content (film, p)
- , AudioContent (film, p)
- , SubtitleContent (film, p)
- , video (new VideoContent (film))
{
+ video.reset (new VideoContent (this, film));
+ audio.reset (new AudioContent (this, film));
+ subtitle.reset (new SubtitleContent (this, film));
+
set_default_colour_conversion ();
}
FFmpegContent::FFmpegContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version, list<string>& notes)
: Content (film, node)
- , AudioContent (film, node)
- , SubtitleContent (film, node, version)
- , video (new VideoContent (film, node, version))
{
+ video.reset (new VideoContent (this, film, node, version));
+ audio.reset (new AudioContent (this, film, node));
+ subtitle.reset (new SubtitleContent (this, film, node, version));
+
list<cxml::NodePtr> c = node->node_children ("SubtitleStream");
for (list<cxml::NodePtr>::const_iterator i = c.begin(); i != c.end(); ++i) {
_subtitle_streams.push_back (shared_ptr<FFmpegSubtitleStream> (new FFmpegSubtitleStream (*i, version)));
c = node->node_children ("AudioStream");
for (list<cxml::NodePtr>::const_iterator i = c.begin(); i != c.end(); ++i) {
- _audio_streams.push_back (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream (*i, version)));
+ shared_ptr<FFmpegAudioStream> as (new FFmpegAudioStream (*i, version));
+ audio->add_stream (as);
if (version < 11 && !(*i)->optional_node_child ("Selected")) {
/* This is an old file and this stream is not selected, so un-map it */
- _audio_streams.back()->set_mapping (AudioMapping (_audio_streams.back()->channels (), MAX_DCP_AUDIO_CHANNELS));
+ as->set_mapping (AudioMapping (as->channels (), MAX_DCP_AUDIO_CHANNELS));
}
}
FFmpegContent::FFmpegContent (shared_ptr<const Film> film, vector<boost::shared_ptr<Content> > c)
: Content (film, c)
- , AudioContent (film, c)
- , SubtitleContent (film, c)
- , video (new VideoContent (film, c))
{
+ video.reset (new VideoContent (this, film, c));
+ audio.reset (new AudioContent (this, film, c));
+ subtitle.reset (new SubtitleContent (this, film, c));
+
shared_ptr<FFmpegContent> ref = dynamic_pointer_cast<FFmpegContent> (c[0]);
DCPOMATIC_ASSERT (ref);
for (size_t i = 0; i < c.size(); ++i) {
shared_ptr<FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> (c[i]);
- if (fc->use_subtitles() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) {
+ if (fc->subtitle->use() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) {
throw JoinError (_("Content to be joined must use the same subtitle stream."));
}
}
_subtitle_streams = ref->subtitle_streams ();
_subtitle_stream = ref->subtitle_stream ();
- _audio_streams = ref->ffmpeg_audio_streams ();
_first_video = ref->_first_video;
_filters = ref->_filters;
_color_range = ref->_color_range;
node->add_child("Type")->add_child_text ("FFmpeg");
Content::as_xml (node);
video->as_xml (node);
- AudioContent::as_xml (node);
- SubtitleContent::as_xml (node);
+ audio->as_xml (node);
+ subtitle->as_xml (node);
boost::mutex::scoped_lock lm (_mutex);
(*i)->as_xml (t);
}
- for (vector<shared_ptr<FFmpegAudioStream> >::const_iterator i = _audio_streams.begin(); i != _audio_streams.end(); ++i) {
- (*i)->as_xml (node->add_child("AudioStream"));
+ BOOST_FOREACH (AudioStreamPtr i, audio->streams ()) {
+ shared_ptr<FFmpegAudioStream> f = dynamic_pointer_cast<FFmpegAudioStream> (i);
+ DCPOMATIC_ASSERT (f);
+ f->as_xml (node->add_child("AudioStream"));
}
for (vector<Filter const *>::const_iterator i = _filters.begin(); i != _filters.end(); ++i) {
Content::examine (job);
shared_ptr<FFmpegExaminer> examiner (new FFmpegExaminer (shared_from_this (), job));
- take_from_video_examiner (examiner);
+ video->take_from_examiner (examiner);
set_default_colour_conversion ();
{
_subtitle_stream = _subtitle_streams.front ();
}
- _audio_streams = examiner->audio_streams ();
+ BOOST_FOREACH (shared_ptr<FFmpegAudioStream> i, examiner->audio_streams ()) {
+ audio->add_stream (i);
+ }
- if (!_audio_streams.empty ()) {
- AudioMapping m = _audio_streams.front()->mapping ();
+ if (!audio->streams().empty ()) {
+ AudioStreamPtr as = audio->streams().front();
+ AudioMapping m = as->mapping ();
film()->make_audio_mapping_default (m);
- _audio_streams.front()->set_mapping (m);
+ as->set_mapping (m);
}
_first_video = examiner->first_video ();
signal_changed (FFmpegContentProperty::SUBTITLE_STREAMS);
signal_changed (FFmpegContentProperty::SUBTITLE_STREAM);
- signal_changed (AudioContentProperty::AUDIO_STREAMS);
}
string
return Content::technical_summary() + " - "
+ video->technical_summary() + " - "
- + AudioContent::technical_summary() + " - "
+ + audio->technical_summary() + " - "
+ String::compose (
"ffmpeg: audio %1 subtitle %2 filters %3", as, ss, filt
);
DCPTime
FFmpegContent::full_length () const
{
- FrameRateChange const frc (video_frame_rate (), film()->video_frame_rate ());
- return DCPTime::from_frames (llrint (video_length_after_3d_combine() * frc.factor()), film()->video_frame_rate());
+ FrameRateChange const frc (video->frame_rate (), film()->video_frame_rate ());
+ return DCPTime::from_frames (llrint (video->length_after_3d_combine() * frc.factor()), film()->video_frame_rate());
}
void
s << Content::identifier() << "_"
<< video->identifier() << "_"
- << SubtitleContent::identifier();
+ << subtitle->identifier();
boost::mutex::scoped_lock lm (_mutex);
void
FFmpegContent::set_default_colour_conversion ()
{
- dcp::Size const s = video_size ();
+ dcp::Size const s = video->size ();
boost::mutex::scoped_lock lm (_mutex);
if (s.width < 1080) {
- _colour_conversion = PresetColourConversion::from_id ("rec601").conversion;
+ video->set_colour_conversion (PresetColourConversion::from_id ("rec601").conversion);
} else {
- _colour_conversion = PresetColourConversion::from_id ("rec709").conversion;
+ video->set_colour_conversion (PresetColourConversion::from_id ("rec709").conversion);
}
}
-vector<AudioStreamPtr>
-FFmpegContent::audio_streams () const
-{
- boost::mutex::scoped_lock lm (_mutex);
-
- vector<AudioStreamPtr> s;
- copy (_audio_streams.begin(), _audio_streams.end(), back_inserter (s));
- return s;
-}
-
void
FFmpegContent::add_properties (list<UserProperty>& p) const
{
Content::add_properties (p);
video->add_properties (p);
- AudioContent::add_properties (p);
+ audio->add_properties (p);
if (_bits_per_pixel) {
int const sub = 219 * pow (2, _bits_per_pixel.get() - 8);
signal_changed (FFmpegContentProperty::SUBTITLE_STREAM);
}
-double
-FFmpegContent::subtitle_video_frame_rate () const
+void
+FFmpegContent::changed (int property)
{
- return video->video_frame_rate ();
+ if (property == VideoContentProperty::FRAME_RATE && subtitle) {
+ subtitle->set_video_frame_rate (video->frame_rate ());
+ }
+}
+
+vector<shared_ptr<FFmpegAudioStream> >
+FFmpegContent::ffmpeg_audio_streams () const
+{
+ vector<shared_ptr<FFmpegAudioStream> > fa;
+ BOOST_FOREACH (AudioStreamPtr i, audio->streams()) {
+ fa.push_back (dynamic_pointer_cast<FFmpegAudioStream> (i));
+ }
+ return fa;
}