Tentative support for 3D from alternate frames.
authorCarl Hetherington <cth@carlh.net>
Tue, 18 Mar 2014 14:24:08 +0000 (14:24 +0000)
committerCarl Hetherington <cth@carlh.net>
Tue, 18 Mar 2014 14:24:08 +0000 (14:24 +0000)
Also remove references to libpostproc.

Requested-by: Jean-Jacques Mantello
17 files changed:
ChangeLog
src/lib/ffmpeg.cc
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_decoder.h
src/lib/image.cc
src/lib/image_content.cc
src/lib/scaler.h
src/lib/types.h
src/lib/util.cc
src/lib/video_content.cc
src/lib/video_content.h
src/lib/video_decoder.cc
src/lib/video_decoder.h
src/wx/timing_panel.cc
src/wx/video_panel.cc
test/play_test.cc

index 5a99d30ff0a76a1525db6738a009684081a72bc8..45847805a4b6ec914323cd8cd4fc314a829a92fd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-03-18  Carl Hetherington  <cth@carlh.net>
+
+       * Tentative support for 3D from alternate frames of the source.
+
 2014-03-17  Carl Hetherington  <cth@carlh.net>
 
        * Improve behaviour of the position slider at the end of films.
index fae9baa2b9da70cef4086e424fd34261472de473..60eea6ec7756b626cf76fb996f552940196730b9 100644 (file)
@@ -21,7 +21,6 @@ extern "C" {
 #include <libavcodec/avcodec.h>
 #include <libavformat/avformat.h>
 #include <libswscale/swscale.h>
-#include <libpostproc/postprocess.h>
 }
 #include "ffmpeg.h"
 #include "ffmpeg_content.h"
index fadeec9cdc00a3126f2d9d066df8d04518229015..b7551c96af36ed3a85e47671ac6e1237a8d96499 100644 (file)
@@ -239,7 +239,7 @@ FFmpegContent::information () const
        
        stringstream s;
        
-       s << String::compose (_("%1 frames; %2 frames per second"), video_length(), video_frame_rate()) << "\n";
+       s << String::compose (_("%1 frames; %2 frames per second"), video_length_after_3d_combine(), video_frame_rate()) << "\n";
        s << VideoContent::information ();
 
        return s.str ();
@@ -272,7 +272,7 @@ FFmpegContent::audio_length () const
 {
        int const cafr = content_audio_frame_rate ();
        int const vfr  = video_frame_rate ();
-       VideoContent::Frame const vl = video_length ();
+       VideoContent::Frame const vl = video_length_after_3d_combine ();
 
        boost::mutex::scoped_lock lm (_mutex);
        if (!_audio_stream) {
@@ -429,7 +429,7 @@ FFmpegContent::full_length () const
        assert (film);
        
        FrameRateConversion frc (video_frame_rate (), film->video_frame_rate ());
-       return video_length() * frc.factor() * TIME_HZ / film->video_frame_rate ();
+       return video_length_after_3d_combine() * frc.factor() * TIME_HZ / film->video_frame_rate ();
 }
 
 AudioMapping
index 851c64606b705af1974c1c953fa1d14863c6af89..1920f9275c66ba92d3ae85c9ddf81fbe2591253c 100644 (file)
@@ -142,7 +142,7 @@ FFmpegDecoder::flush ()
        }
 
        /* 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 ();
 }
 
index 63a8f0c717be592a59930501a14cc4c67c54728d..d4b4fa1c02984f8690c42bd264434b5266cff52e 100644 (file)
@@ -29,7 +29,6 @@
 #include <boost/thread/mutex.hpp>
 extern "C" {
 #include <libavcodec/avcodec.h>
-#include <libpostproc/postprocess.h>
 }
 #include "util.h"
 #include "decoder.h"
index 25d1ef2760b0e9faa82ace72b81d006ae1926d6b..d083cf3f6c17612caa6e249cf86413116f655667 100644 (file)
@@ -26,7 +26,6 @@ extern "C" {
 #include <libswscale/swscale.h>
 #include <libavutil/pixfmt.h>
 #include <libavutil/pixdesc.h>
-#include <libpostproc/postprocess.h>
 }
 #include "image.h"
 #include "exceptions.h"
index fd0b578943639a0871b529f2df2cd90947e110a6..13f7c52e3d12dec4256479d0d0bdbcec7c795253 100644 (file)
@@ -127,7 +127,7 @@ ImageContent::full_length () const
        assert (film);
        
        FrameRateConversion frc (video_frame_rate(), film->video_frame_rate ());
-       return video_length() * frc.factor() * TIME_HZ / video_frame_rate();
+       return video_length_after_3d_combine() * frc.factor() * TIME_HZ / video_frame_rate();
 }
 
 string
index 6a039edd8d037878503ea79fdf971c5e2d1eb782..14077ff1dc803349c75b4faf3452f411531e007b 100644 (file)
@@ -36,7 +36,7 @@ class Scaler : public boost::noncopyable
 public:
        Scaler (int f, std::string i, std::string n);
 
-       /** @return id used for calls to FFmpeg's pp_postprocess */
+       /** @return id used for calls to FFmpeg's sws_getContext */
        int ffmpeg_id () const {
                return _ffmpeg_id;
        }
index 96b993a8e15866b4674324735e05cdadd968f2f7..8a16818bddae84b86ecc9d55cf5b5ed600fe547f 100644 (file)
@@ -69,7 +69,8 @@ enum VideoFrameType
 {
        VIDEO_FRAME_TYPE_2D,
        VIDEO_FRAME_TYPE_3D_LEFT_RIGHT,
-       VIDEO_FRAME_TYPE_3D_TOP_BOTTOM
+       VIDEO_FRAME_TYPE_3D_TOP_BOTTOM,
+       VIDEO_FRAME_TYPE_3D_ALTERNATE
 };
 
 enum Eyes
index 35385ab40be03ff67260993352629ec84ab1f1b3..85c52b039f10fb91cf614ddd1e1014099ba24833 100644 (file)
@@ -57,7 +57,6 @@ extern "C" {
 #include <libavformat/avformat.h>
 #include <libswscale/swscale.h>
 #include <libavfilter/avfiltergraph.h>
-#include <libpostproc/postprocess.h>
 #include <libavutil/pixfmt.h>
 }
 #include "util.h"
@@ -248,7 +247,6 @@ dependency_version_summary ()
          << N_("libavfilter ") << ffmpeg_version_to_string (avfilter_version()) << N_(", ")
          << N_("libavformat ") << ffmpeg_version_to_string (avformat_version()) << N_(", ")
          << N_("libavutil ") << ffmpeg_version_to_string (avutil_version()) << N_(", ")
-         << N_("libpostproc ") << ffmpeg_version_to_string (postproc_version()) << N_(", ")
          << N_("libswscale ") << ffmpeg_version_to_string (swscale_version()) << N_(", ")
          << MagickVersion << N_(", ")
          << N_("libssh ") << ssh_version (0) << N_(", ")
index 966b8e8b34e4a32bd3e1d7e1c803f9624cd2e30f..4a1ef95acfc3335995f420685e3f5d1de0a8fd9e 100644 (file)
@@ -317,7 +317,10 @@ VideoContent::set_video_frame_type (VideoFrameType t)
 string
 VideoContent::technical_summary () const
 {
-       return String::compose ("video: length %1, size %2x%3, rate %4", video_length(), video_size().width, video_size().height, video_frame_rate());
+       return String::compose (
+               "video: length %1, size %2x%3, rate %4",
+               video_length_after_3d_combine(), video_size().width, video_size().height, video_frame_rate()
+               );
 }
 
 libdcp::Size
@@ -326,6 +329,7 @@ VideoContent::video_size_after_3d_split () const
        libdcp::Size const s = video_size ();
        switch (video_frame_type ()) {
        case VIDEO_FRAME_TYPE_2D:
+       case VIDEO_FRAME_TYPE_3D_ALTERNATE:
                return s;
        case VIDEO_FRAME_TYPE_3D_LEFT_RIGHT:
                return libdcp::Size (s.width / 2, s.height);
index ea4676cecbe1607fe4a86e47a71c278e763e86b2..f846b7ac97a095e4db0eb95d5fb0a33d17f341f2 100644 (file)
@@ -96,6 +96,15 @@ public:
                return _video_length;
        }
 
+       VideoContent::Frame video_length_after_3d_combine () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               if (_video_frame_type == VIDEO_FRAME_TYPE_3D_ALTERNATE) {
+                       return _video_length / 2;
+               }
+               
+               return _video_length;
+       }
+
        libdcp::Size video_size () const {
                boost::mutex::scoped_lock lm (_mutex);
                return _video_size;
index e7ddec5e6cd19df910966a66fcb9e969b5c5b6ee..3ae963a202f7081322f8e9bab5ab525d0d7309cc 100644 (file)
@@ -40,6 +40,9 @@ VideoDecoder::video (shared_ptr<const Image> image, bool same, VideoContent::Fra
        case VIDEO_FRAME_TYPE_2D:
                Video (image, EYES_BOTH, same, frame);
                break;
+       case VIDEO_FRAME_TYPE_3D_ALTERNATE:
+               Video (image, (frame % 2) ? EYES_RIGHT : EYES_LEFT, same, frame / 2);
+               break;
        case VIDEO_FRAME_TYPE_3D_LEFT_RIGHT:
        {
                int const half = image->size().width / 2;
index 142320a049c8e7a23bf7aff2d618149d6259941d..255a038a9073f75be2a1c268e11aaf709642072b 100644 (file)
@@ -51,6 +51,9 @@ protected:
 
        void video (boost::shared_ptr<const Image>, bool, VideoContent::Frame);
        boost::shared_ptr<const VideoContent> _video_content;
+       /** This is in frames without taking 3D into account (e.g. if we are doing 3D alternate,
+        *  this would equal 2 on the left-eye second frame (not 1)).
+        */
        VideoContent::Frame _video_position;
 };
 
index 34702463cd80cf7efac1436ebccfe5732868cd5e..2321fd0dfdbfb7ac84ce8f1d12b603d9064adcf9 100644 (file)
@@ -87,7 +87,11 @@ TimingPanel::film_content_changed (int property)
                } else {
                        _position->set (0, 24);
                }
-       } else if (property == ContentProperty::LENGTH || property == VideoContentProperty::VIDEO_FRAME_RATE) {
+       } else if (
+               property == ContentProperty::LENGTH ||
+               property == VideoContentProperty::VIDEO_FRAME_RATE ||
+               property == VideoContentProperty::VIDEO_FRAME_TYPE
+               ) {
                if (content) {
                        _full_length->set (content->full_length (), _editor->film()->video_frame_rate ());
                        _play_length->set (content->length_after_trim (), _editor->film()->video_frame_rate ());
index 38604248cb759440160eea127a5ba762420d3df7..56848907b3e96a72e2d7d42f9e75af8cb91aed38 100644 (file)
@@ -196,6 +196,7 @@ VideoPanel::VideoPanel (FilmEditor* e)
        _frame_type->wrapped()->Append (_("2D"));
        _frame_type->wrapped()->Append (_("3D left/right"));
        _frame_type->wrapped()->Append (_("3D top/bottom"));
+       _frame_type->wrapped()->Append (_("3D alternate"));
 
        _filters_button->Bind           (wxEVT_COMMAND_BUTTON_CLICKED,   boost::bind (&VideoPanel::edit_filters_clicked, this));
        _colour_conversion_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED,   boost::bind (&VideoPanel::edit_colour_conversion_clicked, this));
index dfa597431fee6b818d42e195f3676af6bf6229e8..51e2272568acbf26a1bc321d0ad1bdf63af3bc36 100644 (file)
@@ -89,13 +89,13 @@ BOOST_AUTO_TEST_CASE (play_test)
        film->examine_and_add_content (A);
        wait_for_jobs ();
 
-       BOOST_CHECK_EQUAL (A->video_length(), 16);
+       BOOST_CHECK_EQUAL (A->video_length_after_3d_combine(), 16);
 
        shared_ptr<FFmpegContent> B (new FFmpegContent (film, "test/data/red_30.mp4"));
        film->examine_and_add_content (B);
        wait_for_jobs ();
 
-       BOOST_CHECK_EQUAL (B->video_length(), 16);
+       BOOST_CHECK_EQUAL (B->video_length_after_3d_combine(), 16);
        
        /* Film should have been set to 25fps */
        BOOST_CHECK_EQUAL (film->video_frame_rate(), 25);