WIP: hacks to allow joining of files which don't all have subtitle streams. 2187-examine-vobs
authorCarl Hetherington <cth@carlh.net>
Sun, 27 Mar 2022 22:23:16 +0000 (00:23 +0200)
committerCarl Hetherington <cth@carlh.net>
Sun, 27 Mar 2022 22:23:16 +0000 (00:23 +0200)
src/lib/ffmpeg.cc
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_stream.cc
src/lib/text_content.cc

index 0f63ea1727ee5374ce3d41ecd3c96a9f874386cf..15a4f130d6efae44dba74a6b3fff48f70703506c 100644 (file)
@@ -204,6 +204,7 @@ FFmpeg::setup_decoders ()
 {
        boost::mutex::scoped_lock lm (_mutex);
 
+       std::cout << this << " has " << _format_context->nb_streams << "\n";
        _codec_context.resize (_format_context->nb_streams);
        for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
                auto codec = avcodec_find_decoder (_format_context->streams[i]->codecpar->codec_id);
@@ -213,6 +214,7 @@ FFmpeg::setup_decoders ()
                                throw std::bad_alloc ();
                        }
                        _codec_context[i] = context;
+                       std::cout << this << " context " << i << " = " << context << "\n";
 
                        int r = avcodec_parameters_to_context (context, _format_context->streams[i]->codecpar);
                        if (r < 0) {
@@ -260,12 +262,21 @@ FFmpeg::video_codec_context () const
 AVCodecContext *
 FFmpeg::subtitle_codec_context () const
 {
+       std::cout << "get subtitle_codec_context\n";
        auto str = _ffmpeg_content->subtitle_stream();
        if (!str) {
-               return nullptr;
+               std::cout << "no stream.\n";
+               return {};
+       }
+
+       auto index = str->index(_format_context);
+       if (index == -1) {
+               std::cout << "stream not in fc.\n";
+               return {};
        }
 
-       return _codec_context[str->index(_format_context)];
+       std::cout << this << " using cc " << index << "\n";
+       return _codec_context[index];
 }
 
 
index 9017ad605dd9cb021e10e46bfcff307cc34c3f46..0d567f425b62fcf2ba0bf8428ed941ec2bdcd91b 100644 (file)
@@ -132,49 +132,53 @@ FFmpegContent::FFmpegContent (cxml::ConstNodePtr node, int version, list<string>
 }
 
 
-FFmpegContent::FFmpegContent (vector<shared_ptr<Content>> c)
-       : Content (c)
+FFmpegContent::FFmpegContent (vector<shared_ptr<Content>> content)
+       : Content (content)
 {
-       auto i = c.begin ();
+       auto i = content.begin ();
 
        bool need_video = false;
        bool need_audio = false;
-       bool need_text = false;
+       bool any_text = false;
 
-       if (i != c.end ()) {
+       if (i != content.end()) {
                need_video = static_cast<bool> ((*i)->video);
                need_audio = static_cast<bool> ((*i)->audio);
-               need_text = !(*i)->text.empty();
+               any_text = !(*i)->text.empty();
        }
 
-       while (i != c.end ()) {
+       while (i != content.end()) {
                if (need_video != static_cast<bool> ((*i)->video)) {
                        throw JoinError (_("Content to be joined must all have or not have video"));
                }
                if (need_audio != static_cast<bool> ((*i)->audio)) {
                        throw JoinError (_("Content to be joined must all have or not have audio"));
                }
-               if (need_text != !(*i)->text.empty()) {
-                       throw JoinError (_("Content to be joined must all have or not have subtitles or captions"));
+               if (!(*i)->text.empty()) {
+                       any_text = true;
                }
                ++i;
        }
 
        if (need_video) {
-               video = make_shared<VideoContent>(this, c);
+               video = make_shared<VideoContent>(this, content);
        }
        if (need_audio) {
-               audio = make_shared<AudioContent>(this, c);
+               audio = make_shared<AudioContent>(this, content);
        }
-       if (need_text) {
-               text.push_back (make_shared<TextContent>(this, c));
+       if (any_text) {
+               text.push_back (make_shared<TextContent>(this, content));
        }
 
-       auto ref = dynamic_pointer_cast<FFmpegContent> (c[0]);
+       /* Use the first content with a text as the reference */
+
+       auto ref_iter = std::find_if(content.begin(), content.end(), [](shared_ptr<Content> c) { return !c->text.empty(); });
+       DCPOMATIC_ASSERT (ref_iter != content.end());
+       auto ref = dynamic_pointer_cast<FFmpegContent>(*ref_iter);
        DCPOMATIC_ASSERT (ref);
 
-       for (size_t i = 0; i < c.size(); ++i) {
-               auto fc = dynamic_pointer_cast<FFmpegContent>(c[i]);
+       for (size_t i = 0; i < content.size(); ++i) {
+               auto fc = dynamic_pointer_cast<FFmpegContent>(content[i]);
                if (fc->only_text() && fc->only_text()->use() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) {
                        throw JoinError (_("Content to be joined must use the same subtitle stream."));
                }
index 2d85a90bb69fcf81bc595b2ec3f96439bb5b1de4..d5ed7c6197ff5f368bbc444b93f24639b6f2bca1 100644 (file)
@@ -78,6 +78,5 @@ FFmpegStream::index (AVFormatContext const * fc) const
                ++i;
        }
 
-       DCPOMATIC_ASSERT (false);
-       return 0;
+       return -1;
 }
index 87bb2db463d3b864b986b958f52dbe34fb45e914..e654695416cc7758e1ae937f29ed3e42065d584e 100644 (file)
@@ -258,15 +258,18 @@ TextContent::TextContent (Content* parent, cxml::ConstNodePtr node, int version,
 TextContent::TextContent (Content* parent, vector<shared_ptr<Content>> content)
        : ContentPart (parent)
 {
-       /* This constructor is for join which is only supported for content types
-          that have a single text, so we can use only_text() here.
-       */
-       auto ref = content[0]->only_text();
+       auto ref_iter = std::find_if(content.begin(), content.end(), [](shared_ptr<Content> c) { return !c->text.empty(); });
+       DCPOMATIC_ASSERT (ref_iter != content.end());
+       auto ref = (*ref_iter)->only_text();
        DCPOMATIC_ASSERT (ref);
        auto ref_fonts = ref->fonts ();
 
        for (size_t i = 1; i < content.size(); ++i) {
 
+               if (content[i]->text.empty()) {
+                       continue;
+               }
+
                if (content[i]->only_text()->use() != ref->use()) {
                        throw JoinError (_("Content to be joined must have the same 'use subtitles' setting."));
                }