OSDN Git Service

- encx264 sets HB_FRAME_REF to expose ref/non-ref frame status to muxer.
authorkonablend <konablend@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sun, 3 May 2009 14:34:16 +0000 (14:34 +0000)
committerkonablend <konablend@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sun, 3 May 2009 14:34:16 +0000 (14:34 +0000)
- bump libmp4v2 r286 -> r290; required for new API (sdtp atom support).
- use new API MP4WriteSampleDependency() in muxer to signal disposable frames and set a few other dependency bits for sdtp atom.

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

contrib/libmp4v2/module.defs
libhb/encx264.c
libhb/muxmp4.c

index 784fc16..a467690 100644 (file)
@@ -1,7 +1,7 @@
 $(eval $(call import.MODULE.defs,LIBMP4V2,libmp4v2))
 $(eval $(call import.CONTRIB.defs,LIBMP4V2))
 
-LIBMP4V2.FETCH.url = http://download.m0k.org/handbrake/contrib/libmp4v2-2.0-r286.tar.gz
+LIBMP4V2.FETCH.url = http://download.m0k.org/handbrake/contrib/libmp4v2-2.0-r290.tar.gz
 LIBMP4V2.EXTRACT.tarbase = libmp4v2
 
 ## propagate more flags
index 360dc84..374c921 100644 (file)
@@ -508,6 +508,12 @@ static hb_buffer_t *nal_encode( hb_work_object_t *w, x264_picture_t *pic_out,
             (nal[i].i_ref_idc != NAL_PRIORITY_DISPOSABLE) )
             buf->frametype = HB_FRAME_BREF;
 
+        /* Expose disposable bit to muxer. */
+        if( nal[i].i_ref_idc == NAL_PRIORITY_DISPOSABLE )
+            buf->flags &= ~HB_FRAME_REF;
+        else
+            buf->flags |= HB_FRAME_REF;
+
         buf->size += size;
     }
     // make sure we found at least one video frame
index 7442532..29d08ca 100644 (file)
@@ -514,18 +514,73 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
         duration = MP4_INVALID_DURATION;
     }
 
-    // Here's where the sample actually gets muxed.
-    if( !MP4WriteSample( m->file,
-                         mux_data->track,
-                         buf->data,
-                         buf->size,
-                         duration,
-                         offset,
-                         ( job->vcodec == HB_VCODEC_X264 && mux_data == job->mux_data ) ?
-                            ( buf->frametype == HB_FRAME_IDR ) : ( ( buf->frametype & HB_FRAME_KEY ) != 0 ) ) )
+    /* Here's where the sample actually gets muxed. */
+    if( job->vcodec == HB_VCODEC_X264 && mux_data == job->mux_data )
     {
-        hb_error("Failed to write to output file, disk full?");
-        *job->die = 1;
+        /* Compute dependency flags.
+         *
+         * This mechanism is (optionally) used by media players such as QuickTime
+         * to offer better scrubbing performance. The most influential bits are
+         * MP4_SDT_HAS_NO_DEPENDENTS and MP4_SDT_EARLIER_DISPLAY_TIMES_ALLOWED.
+         *
+         * Other bits are possible but no example media using such bits have been
+         * found.
+         *
+         * It is acceptable to supply 0-bits for any samples which characteristics
+         * cannot be positively guaranteed.
+         */
+        int sync = 0;
+        uint32_t dflags = 0;
+
+        /* encoding layer signals if frame is referenced by other frames */
+        if( buf->flags & HB_FRAME_REF )
+            dflags |= MP4_SDT_HAS_DEPENDENTS;
+        else
+            dflags |= MP4_SDT_HAS_NO_DEPENDENTS; /* disposable */
+
+        switch( buf->frametype )
+        {
+            case HB_FRAME_IDR:
+                sync = 1;
+                break;
+            case HB_FRAME_I:
+                dflags |= MP4_SDT_EARLIER_DISPLAY_TIMES_ALLOWED;
+                break;
+            case HB_FRAME_P:
+                dflags |= MP4_SDT_EARLIER_DISPLAY_TIMES_ALLOWED;
+                break;
+            case HB_FRAME_BREF:
+            case HB_FRAME_B:
+            default:
+                break; /* nothing to mark */
+        }
+
+        if( !MP4WriteSampleDependency( m->file,
+                                       mux_data->track,
+                                       buf->data,
+                                       buf->size,
+                                       duration,
+                                       offset,
+                                       sync,
+                                       dflags ))
+        {
+            hb_error("Failed to write to output file, disk full?");
+            *job->die = 1;
+        }
+    }
+    else
+    {
+        if( !MP4WriteSample( m->file,
+                             mux_data->track,
+                             buf->data,
+                             buf->size,
+                             duration,
+                             offset,
+                             ( buf->frametype & HB_FRAME_KEY ) != 0 ))
+        {
+            hb_error("Failed to write to output file, disk full?");
+            *job->die = 1;
+        }
     }
 
     return 0;