OSDN Git Service

CLI: Missed file from SubRip - a symptom of too many views and patches
[handbrake-jp/handbrake-jp-git.git] / libhb / muxmp4.c
index 0f06deb..aaaa7d9 100644 (file)
@@ -23,8 +23,6 @@ struct hb_mux_object_s
     // bias to keep render offsets in ctts atom positive (set up by encx264)
     int64_t init_delay;
 
-    uint64_t sum_sub_duration; // sum of subtitle frame durations so far
-
     /* Chapter state information for muxing */
     MP4TrackId chapter_track;
     int current_chapter;
@@ -33,9 +31,11 @@ struct hb_mux_object_s
 
 struct hb_mux_data_s
 {
-    MP4TrackId track;
-    uint8_t    subtitle;
-    int        sub_format;
+    MP4TrackId  track;
+    uint8_t     subtitle;
+    int         sub_format;
+
+    uint64_t    sum_dur; // sum of the frame durations so far
 };
 
 /* Tune video track chunk duration.
@@ -77,6 +77,7 @@ static int MP4Init( hb_mux_object_t * m )
     hb_audio_t    * audio;
     hb_mux_data_t * mux_data;
     int i;
+    int subtitle_default;
 
     /* Flags for enabling/disabling tracks in an MP4. */
     typedef enum { TRACK_DISABLED = 0x0, TRACK_ENABLED = 0x1, TRACK_IN_MOVIE = 0x2, TRACK_IN_PREVIEW = 0x4, TRACK_IN_POSTER = 0x8}  track_header_flags;
@@ -403,18 +404,41 @@ static int MP4Init( hb_mux_object_t * m )
 
     }
 
+    // Quicktime requires that at least one subtitle is enabled,
+    // else it doesn't show any of the subtitles.
+    // So check to see if any of the subtitles are flagged to be
+    // the defualt.  The default will the the enabled track, else
+    // enable the first track.
+    subtitle_default = 0;
     for( i = 0; i < hb_list_count( job->list_subtitle ); i++ )
     {
         hb_subtitle_t *subtitle = hb_list_item( job->list_subtitle, i );
 
         if( subtitle && subtitle->format == TEXTSUB && 
-            subtitle->dest == PASSTHRUSUB )
+            subtitle->config.dest == PASSTHRUSUB )
         {
+            if ( subtitle->config.default_track )
+                subtitle_default = 1;
+        }
+    }
+    for( i = 0; i < hb_list_count( job->list_subtitle ); i++ )
+    {
+        hb_subtitle_t *subtitle = hb_list_item( job->list_subtitle, i );
+
+        if( subtitle && subtitle->format == TEXTSUB && 
+            subtitle->config.dest == PASSTHRUSUB )
+        {
+            uint64_t width, height = 60;
+            if( job->anamorphic.mode )
+                width = job->width * ( (float) job->anamorphic.par_width / job->anamorphic.par_height );
+            else
+                width = job->width;
+
             mux_data = calloc(1, sizeof( hb_mux_data_t ) );
             subtitle->mux_data = mux_data;
             mux_data->subtitle = 1;
             mux_data->sub_format = subtitle->format;
-            mux_data->track = MP4AddSubtitleTrack( m->file, 1 );
+            mux_data->track = MP4AddSubtitleTrack( m->file, 90000, width, height );
 
             MP4SetTrackLanguage(m->file, mux_data->track, subtitle->iso639_2);
 
@@ -422,21 +446,17 @@ static int MP4Init( hb_mux_object_t * m )
             MP4TuneTrackDurationPerChunk( m, mux_data->track );
 
             const uint8_t textColor[4] = { 255,255,255,255 };
-            uint64_t subHeight = 60;
 
             MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.alternate_group", 2);
 
-            MP4SetTrackFloatProperty(m->file, mux_data->track, "tkhd.width", job->width);
-            MP4SetTrackFloatProperty(m->file, mux_data->track, "tkhd.height", subHeight);
-
             MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.dataReferenceIndex", 1);
             MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.horizontalJustification", 1);
             MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.verticalJustification", 0);
 
             MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.bgColorAlpha", 255);
 
-            MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.defTextBoxBottom", subHeight);
-            MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.defTextBoxRight", job->width);
+            MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.defTextBoxBottom", height);
+            MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.defTextBoxRight", width);
 
             MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.fontID", 1);
             MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.fontSize", 24);
@@ -455,7 +475,7 @@ static int MP4Init( hb_mux_object_t * m )
             MP4GetTrackBytesProperty(m->file, mux_data->track, "tkhd.matrix", &val, &size);
             memcpy(nval, val, size);
 
-            const uint32_t ytranslation = (job->height - subHeight) * 0x10000;
+            const uint32_t ytranslation = (job->height - height) * 0x10000;
                 
 #ifdef WORDS_BIGENDIAN
             ptr32[7] = ytranslation;
@@ -466,6 +486,15 @@ static int MP4Init( hb_mux_object_t * m )
 #endif
 
             MP4SetTrackBytesProperty(m->file, mux_data->track, "tkhd.matrix", nval, size);  
+            if ( !subtitle_default || subtitle->config.default_track ) {
+                /* Enable the default subtitle track */
+                MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_ENABLED | TRACK_IN_MOVIE));
+                subtitle_default = 1;
+            }
+            else
+            {
+                MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_DISABLED | TRACK_IN_MOVIE));
+            }
         }
     }
 
@@ -643,22 +672,21 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
         if( mux_data->sub_format == TEXTSUB )
         {
             /* Write an empty sample */
-            if ( m->sum_sub_duration < buf->start )
+            if ( mux_data->sum_dur < buf->start )
             {
                 uint8_t empty[2] = {0,0};
                 if( !MP4WriteSample( m->file,
                                     mux_data->track,
                                     empty,
                                     2,
-                                    buf->start - m->sum_sub_duration,
+                                    buf->start - mux_data->sum_dur,
                                     0,
                                     1 ))
                 {
                     hb_error("Failed to write to output file, disk full?");
                     *job->die = 1;
                 } 
-                hb_log("Subtitle not due yet, adding delay of %lld",  buf->start - m->sum_sub_duration);
-                m->sum_sub_duration += buf->start - m->sum_sub_duration;
+                mux_data->sum_dur += buf->start - mux_data->sum_dur;
             }
 
             /* Write the subtitle sample */
@@ -670,7 +698,7 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
             if( !MP4WriteSample( m->file,
                                  mux_data->track,
                                  buffer,
-                                 buf->size,
+                                 buf->size + 2,
                                  buf->stop - buf->start,
                                  0,
                                  1 ))
@@ -679,10 +707,10 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
                 *job->die = 1;
             }
 
-            m->sum_sub_duration += (buf->stop - buf->start);
-            hb_log("MuxMP4:Sub:%lld:%lld:%lld: %s", buf->start, buf->stop, 
+            mux_data->sum_dur += (buf->stop - buf->start);
+            hb_deep_log(3, "MuxMP4:Sub:%fs:%lld:%lld:%lld: %s", (float)buf->start / 90000, buf->start, buf->stop, 
                    (buf->stop - buf->start), buf->data);
-            hb_log("MuxMP4:Total time elapsed:%lld", m->sum_sub_duration);
+            hb_deep_log(3, "MuxMP4:Total time elapsed:%lld", mux_data->sum_dur);
         }
     }
     else
@@ -764,13 +792,20 @@ static int MP4End( hb_mux_object_t * m )
         MP4TagsFetch( tags, m->file );
 
         /* populate */
-        MP4TagsSetName( tags, md->name );
-        MP4TagsSetArtist( tags, md->artist );
-        MP4TagsSetComposer( tags, md->composer );
-        MP4TagsSetComments( tags, md->comment );
-        MP4TagsSetReleaseDate( tags, md->release_date );
-        MP4TagsSetAlbum( tags, md->album );
-        MP4TagsSetGenre( tags, md->genre );
+        if( strlen( md->name ))
+            MP4TagsSetName( tags, md->name );
+        if( strlen( md->artist ))
+            MP4TagsSetArtist( tags, md->artist );
+        if( strlen( md->composer ))
+            MP4TagsSetComposer( tags, md->composer );
+        if( strlen( md->comment ))
+            MP4TagsSetComments( tags, md->comment );
+        if( strlen( md->release_date ))
+            MP4TagsSetReleaseDate( tags, md->release_date );
+        if( strlen( md->album ))
+            MP4TagsSetAlbum( tags, md->album );
+        if( strlen( md->genre ))
+            MP4TagsSetGenre( tags, md->genre );
 
         if( md->coverart )
         {