OSDN Git Service

- Add COLR atom support to mpeg4ip
authorvan <van@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Wed, 18 Jun 2008 21:48:00 +0000 (21:48 +0000)
committervan <van@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Wed, 18 Jun 2008 21:48:00 +0000 (21:48 +0000)
 - Add COLR atom to mp4 video tracks
 - Add colorspace info to h.264 VUI header

git-svn-id: svn://localhost/HandBrake/trunk@1528 b64f7644-9d1e-0410-96f1-a4d463321fa5

contrib/Jamfile
contrib/patch-mpeg4ip-colr.patch [new file with mode: 0644]
libhb/encx264.c
libhb/muxmp4.c

index 0b4b846..5d77079 100644 (file)
@@ -247,6 +247,7 @@ rule LibMp4v2
     LIBMP4V2_PATCH += "$(PATCH) -p1 < ../patch-mpeg4ip.patch && " ;
     LIBMP4V2_PATCH += "$(PATCH) -p1 < ../patch-mpeg4ip-nasm-2.00-configure.patch && " ;
     LIBMP4V2_PATCH += "$(PATCH) -p1 < ../patch-mpeg4ip-ac3.patch && " ;
+    LIBMP4V2_PATCH += "$(PATCH) -p1 < ../patch-mpeg4ip-colr.patch && " ;
     Depends $(<) : $(>) ;
     Depends lib  : $(<) ;
 }
diff --git a/contrib/patch-mpeg4ip-colr.patch b/contrib/patch-mpeg4ip-colr.patch
new file mode 100644 (file)
index 0000000..105267b
--- /dev/null
@@ -0,0 +1,223 @@
+diff -Nur -x Makefile -x config.log -x config.status -x libtool -x '*.Plo' -x '*.lo' ../handbrake/contrib/mpeg4ip/lib/mp4v2/Makefile.am mpeg4ip/lib/mp4v2/Makefile.am
+--- ../handbrake/contrib/mpeg4ip/lib/mp4v2/Makefile.am 2008-06-13 11:22:55.000000000 -0700
++++ mpeg4ip/lib/mp4v2/Makefile.am      2008-06-17 16:21:54.000000000 -0700
+@@ -14,6 +14,7 @@
+       atom_amr.cpp \
+       atom_avc1.cpp \
+       atom_avcC.cpp \
++      atom_colr.cpp \
+       atom_d263.cpp \
+       atom_damr.cpp \
+       atom_dref.cpp \
+diff -Nur -x Makefile -x config.log -x config.status -x libtool -x '*.Plo' -x '*.lo' ../handbrake/contrib/mpeg4ip/lib/mp4v2/Makefile.in mpeg4ip/lib/mp4v2/Makefile.in
+--- ../handbrake/contrib/mpeg4ip/lib/mp4v2/Makefile.in 2008-06-13 11:22:55.000000000 -0700
++++ mpeg4ip/lib/mp4v2/Makefile.in      2008-06-17 16:21:54.000000000 -0700
+@@ -53,7 +53,7 @@
+ LTLIBRARIES = $(lib_LTLIBRARIES)
+ libmp4v2_la_LIBADD =
+ am_libmp4v2_la_OBJECTS = 3gp.lo atom_amr.lo atom_avc1.lo atom_avcC.lo \
+-      atom_d263.lo atom_damr.lo atom_dref.lo atom_elst.lo \
++      atom_colr.lo atom_d263.lo atom_damr.lo atom_dref.lo atom_elst.lo \
+       atom_enca.lo atom_encv.lo atom_free.lo atom_ftyp.lo \
+       atom_gmin.lo atom_text.lo atom_ac3.lo \
+       atom_hdlr.lo atom_hinf.lo atom_hnti.lo atom_href.lo \
+@@ -76,6 +76,7 @@
+ @AMDEP_TRUE@  ./$(DEPDIR)/atom_ac3.Plo \
+ @AMDEP_TRUE@  ./$(DEPDIR)/atom_avc1.Plo \
+ @AMDEP_TRUE@  ./$(DEPDIR)/atom_avcC.Plo \
++@AMDEP_TRUE@  ./$(DEPDIR)/atom_colr.Plo \
+ @AMDEP_TRUE@  ./$(DEPDIR)/atom_d263.Plo \
+ @AMDEP_TRUE@  ./$(DEPDIR)/atom_damr.Plo \
+ @AMDEP_TRUE@  ./$(DEPDIR)/atom_dref.Plo \
+@@ -347,6 +348,7 @@
+       atom_amr.cpp \
+       atom_avc1.cpp \
+       atom_avcC.cpp \
++      atom_colr.cpp \
+       atom_d263.cpp \
+       atom_damr.cpp \
+       atom_dref.cpp \
+@@ -503,6 +505,7 @@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atom_amr.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atom_avc1.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atom_avcC.Plo@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atom_colr.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atom_d263.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atom_damr.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atom_dref.Plo@am__quote@
+diff -Nur -x Makefile -x config.log -x config.status -x libtool -x '*.Plo' -x '*.lo' ../handbrake/contrib/mpeg4ip/lib/mp4v2/atom_colr.cpp mpeg4ip/lib/mp4v2/atom_colr.cpp
+--- ../handbrake/contrib/mpeg4ip/lib/mp4v2/atom_colr.cpp       1969-12-31 16:00:00.000000000 -0800
++++ mpeg4ip/lib/mp4v2/atom_colr.cpp    2008-06-18 13:51:37.000000000 -0700
+@@ -0,0 +1,45 @@
++/*
++ * The contents of this file are subject to the Mozilla Public
++ * License Version 1.1 (the "License"); you may not use this file
++ * except in compliance with the License. You may obtain a copy of
++ * the License at http://www.mozilla.org/MPL/
++ * 
++ * Software distributed under the License is distributed on an "AS
++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
++ * implied. See the License for the specific language governing
++ * rights and limitations under the License.
++ * 
++ * The Original Code is MPEG4IP.
++ * 
++ * Contributer has declined to give copyright information, and gives
++ * it freely to the world.
++ * 
++ * Contributor(s): 
++ */
++
++#include "mp4common.h"
++
++MP4ColrAtom::MP4ColrAtom() 
++      : MP4Atom("colr") 
++{
++    MP4StringProperty* cpt = new MP4StringProperty("colorParameterType");
++    cpt->SetFixedLength(4);
++    AddProperty(cpt); /* 0 */
++
++      AddProperty( /* 1 */ new MP4Integer16Property("primariesIndex"));
++
++      AddProperty( /* 2 */ new MP4Integer16Property("transferFunctionIndex")); 
++
++      AddProperty( /* 3 */ new MP4Integer16Property("matrixIndex")); 
++}
++
++void MP4ColrAtom::Generate()
++{
++      MP4Atom::Generate();
++
++      ((MP4StringProperty*)m_pProperties[0])->SetValue("nclc");
++    // default to ITU BT.709 values
++      ((MP4Integer16Property*)m_pProperties[1])->SetValue(1);
++      ((MP4Integer16Property*)m_pProperties[2])->SetValue(1);
++      ((MP4Integer16Property*)m_pProperties[3])->SetValue(1);
++}
+diff -Nur -x Makefile -x config.log -x config.status -x libtool -x '*.Plo' -x '*.lo' ../handbrake/contrib/mpeg4ip/lib/mp4v2/atom_stsd.cpp mpeg4ip/lib/mp4v2/atom_stsd.cpp
+--- ../handbrake/contrib/mpeg4ip/lib/mp4v2/atom_stsd.cpp       2008-06-13 11:22:55.000000000 -0700
++++ mpeg4ip/lib/mp4v2/atom_stsd.cpp    2008-06-17 16:21:54.000000000 -0700
+@@ -52,6 +52,7 @@
+       ExpectChildAtom("text", Optional, Many);
+       ExpectChildAtom("pasp", Optional, Many);
+       ExpectChildAtom("ac-3", Optional, Many);
++      ExpectChildAtom("colr", Optional, Many);
+ }
+ void MP4StsdAtom::Read() 
+diff -Nur -x Makefile -x config.log -x config.status -x libtool -x '*.Plo' -x '*.lo' ../handbrake/contrib/mpeg4ip/lib/mp4v2/atoms.h mpeg4ip/lib/mp4v2/atoms.h
+--- ../handbrake/contrib/mpeg4ip/lib/mp4v2/atoms.h     2008-06-13 11:22:55.000000000 -0700
++++ mpeg4ip/lib/mp4v2/atoms.h  2008-06-17 16:21:54.000000000 -0700
+@@ -406,4 +406,10 @@
+     void Generate();
+ };
++class MP4ColrAtom : public MP4Atom {
++ public:
++    MP4ColrAtom();
++    void Generate();
++};
++
+ #endif /* __MP4_ATOMS_INCLUDED__ */
+diff -Nur -x Makefile -x config.log -x config.status -x libtool -x '*.Plo' -x '*.lo' ../handbrake/contrib/mpeg4ip/lib/mp4v2/mp4.cpp mpeg4ip/lib/mp4v2/mp4.cpp
+--- ../handbrake/contrib/mpeg4ip/lib/mp4v2/mp4.cpp     2008-06-13 11:22:55.000000000 -0700
++++ mpeg4ip/lib/mp4v2/mp4.cpp  2008-06-17 16:21:54.000000000 -0700
+@@ -1003,6 +1003,21 @@
+       return MP4_INVALID_TRACK_ID;
+ }
++extern "C" MP4TrackId MP4AddColr(
++      MP4FileHandle hFile, MP4TrackId refTrackId, u_int16_t pri, u_int16_t tran, u_int16_t mat)
++{
++      if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
++              try {
++                      return ((MP4File*)hFile)->AddColr(refTrackId, pri, tran, mat);
++              }
++              catch (MP4Error* e) {
++                      PRINT_ERROR(e);
++                      delete e;
++              }
++      }
++      return MP4_INVALID_TRACK_ID;
++}
++
+ extern "C" MP4TrackId MP4CloneTrack(
+       MP4FileHandle srcFile, 
+diff -Nur -x Makefile -x config.log -x config.status -x libtool -x '*.Plo' -x '*.lo' ../handbrake/contrib/mpeg4ip/lib/mp4v2/mp4.h mpeg4ip/lib/mp4v2/mp4.h
+--- ../handbrake/contrib/mpeg4ip/lib/mp4v2/mp4.h       2008-06-13 11:22:55.000000000 -0700
++++ mpeg4ip/lib/mp4v2/mp4.h    2008-06-18 14:03:17.000000000 -0700
+@@ -559,6 +559,13 @@
+     u_int32_t hSpacing,
+     u_int32_t vSpacing);
++MP4TrackId MP4AddColr(
++      MP4FileHandle hFile, 
++      MP4TrackId refTrackId,
++    u_int16_t primary,
++    u_int16_t transfer,
++    u_int16_t matrix);
++
+ MP4TrackId MP4CloneTrack(
+       MP4FileHandle srcFile, 
+       MP4TrackId srcTrackId,
+diff -Nur -x Makefile -x config.log -x config.status -x libtool -x '*.Plo' -x '*.lo' ../handbrake/contrib/mpeg4ip/lib/mp4v2/mp4atom.cpp mpeg4ip/lib/mp4v2/mp4atom.cpp
+--- ../handbrake/contrib/mpeg4ip/lib/mp4v2/mp4atom.cpp 2008-06-13 11:22:55.000000000 -0700
++++ mpeg4ip/lib/mp4v2/mp4atom.cpp      2008-06-17 16:21:54.000000000 -0700
+@@ -90,6 +90,8 @@
+     case 'c':
+       if (ATOMID(type) == ATOMID("chap")) {
+       pAtom = new MP4TrefTypeAtom(type);
++      } else if (ATOMID(type) == ATOMID("colr")) {
++      pAtom = new MP4ColrAtom();
+         }
+         break;
+diff -Nur -x Makefile -x config.log -x config.status -x libtool -x '*.Plo' -x '*.lo' ../handbrake/contrib/mpeg4ip/lib/mp4v2/mp4file.cpp mpeg4ip/lib/mp4v2/mp4file.cpp
+--- ../handbrake/contrib/mpeg4ip/lib/mp4v2/mp4file.cpp 2008-06-13 11:22:55.000000000 -0700
++++ mpeg4ip/lib/mp4v2/mp4file.cpp      2008-06-17 16:21:54.000000000 -0700
+@@ -2000,6 +2000,33 @@
+       return trackId;
+ }
++MP4TrackId MP4File::AddColr(MP4TrackId trackId,
++                            u_int16_t primariesIndex,
++                            u_int16_t transferFunctionIndex,
++                            u_int16_t matrixIndex)
++{
++      // validate reference track id
++  (void)FindTrackIndex(trackId);
++    const char *format = GetTrackMediaDataName (trackId);
++    
++    if (!strcasecmp(format, "avc1"))
++    {
++        AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.avc1"), "colr");
++        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.colr.primariesIndex", primariesIndex);
++        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.colr.transferFunctionIndex", transferFunctionIndex);
++        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.colr.matrixIndex", matrixIndex);
++    }
++    else if (!strcasecmp(format, "mp4v"))
++    {
++        AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.mp4v"), "colr");
++        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.mp4v.colr.primariesIndex", primariesIndex);
++        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.mp4v.colr.transferFunctionIndex", transferFunctionIndex);
++        SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.mp4v.colr.matrixIndex", matrixIndex);
++    }
++
++      return trackId;
++}
++
+ void MP4File::DeleteTrack(MP4TrackId trackId)
+ {
+       ProtectWriteOperation("MP4DeleteTrack");
+diff -Nur -x Makefile -x config.log -x config.status -x libtool -x '*.Plo' -x '*.lo' ../handbrake/contrib/mpeg4ip/lib/mp4v2/mp4file.h mpeg4ip/lib/mp4v2/mp4file.h
+--- ../handbrake/contrib/mpeg4ip/lib/mp4v2/mp4file.h   2008-06-13 11:22:55.000000000 -0700
++++ mpeg4ip/lib/mp4v2/mp4file.h        2008-06-17 16:21:54.000000000 -0700
+@@ -305,6 +305,7 @@
+       MP4TrackId AddChapterTextTrack(MP4TrackId refTrackId);
+       MP4TrackId AddPixelAspectRatio(MP4TrackId trackId, u_int32_t hSpacing, u_int32_t vSpacing);
++      MP4TrackId AddColr(MP4TrackId trackId, u_int16_t pri, u_int16_t tran, u_int16_t mat);
+       MP4SampleId GetTrackNumberOfSamples(MP4TrackId trackId);
index 6c1f347..da8c7f9 100644 (file)
@@ -198,6 +198,23 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
         free(x264opts_start);
     }
 
+    /* set up the VUI color model & gamma to match what the COLR atom
+     * set in muxmp4.c says. See libhb/muxmp4.c for notes. */
+
+    if ( job->title->height >= 720 )
+    {
+        // we guess that 720p or above is ITU BT.709 HD content
+        param.vui.i_colorprim = 1;
+        param.vui.i_transfer = 1;
+        param.vui.i_colmatrix = 1;
+    }
+    else
+    {
+        // ITU BT.601 DVD or SD TV content
+        param.vui.i_colorprim = 6;
+        param.vui.i_transfer = 1;
+        param.vui.i_colmatrix = 6;
+    }
 
     if( job->pixel_ratio )
     {
index b20b9a4..638bc7e 100644 (file)
@@ -247,6 +247,24 @@ static int MP4Init( hb_mux_object_t * m )
         }
     }
 
+    // COLR atom for color and gamma correction.
+    // Per the notes at:
+    //   http://developer.apple.com/quicktime/icefloe/dispatch019.html#colr
+    //   http://forum.doom9.org/showthread.php?t=133982#post1090068
+    // we say anything that's likely to be HD content is ITU BT.709 and
+    // DVD, SD TV & other content is ITU BT.601.  We look at the title height
+    // rather than the job height here to get uncropped input dimensions.
+    if ( job->title->height >= 720 )
+    {
+        // we guess that 720p or above is ITU BT.709 HD content
+        MP4AddColr(m->file, mux_data->track, 1, 1, 1);
+    }
+    else
+    {
+        // ITU BT.601 DVD or SD TV content
+        MP4AddColr(m->file, mux_data->track, 6, 1, 6);
+    }
+
     if( job->pixel_ratio )
     {
         /* PASP atom for anamorphic video */