OSDN Git Service

BuildSystem: conversion from jam-based to make-based system.
[handbrake-jp/handbrake-jp-git.git] / libhb / muxmp4.c
1 /* $Id: muxmp4.c,v 1.24 2005/11/04 13:09:41 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.fr/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "mp4v2/mp4v2.h"
8 #include "a52dec/a52.h"
9
10 #include "hb.h"
11
12 struct hb_mux_object_s
13 {
14     HB_MUX_COMMON;
15
16     hb_job_t * job;
17
18     /* libmp4v2 handle */
19     MP4FileHandle file;
20
21     /* Cumulated durations so far, in output & input timescale units (see MP4Mux) */
22     int64_t sum_dur;        // duration in output timescale units
23     int64_t sum_dur_in;     // duration in input 90KHz timescale units
24
25     // bias to keep render offsets in ctts atom positive (set up by encx264)
26     int64_t init_delay;
27
28     /* Chapter state information for muxing */
29     MP4TrackId chapter_track;
30     int current_chapter;
31     uint64_t chapter_duration;
32
33     /* Sample rate of the first audio track.
34      * Used for the timescale
35      */
36     int samplerate;
37 };
38
39 struct hb_mux_data_s
40 {
41     MP4TrackId track;
42 };
43
44
45 /**********************************************************************
46  * MP4Init
47  **********************************************************************
48  * Allocates hb_mux_data_t structures, create file and write headers
49  *********************************************************************/
50 static int MP4Init( hb_mux_object_t * m )
51 {
52     hb_job_t   * job   = m->job;
53     hb_title_t * title = job->title;
54
55     hb_audio_t    * audio;
56     hb_mux_data_t * mux_data;
57     int i;
58
59     /* Flags for enabling/disabling tracks in an MP4. */
60     typedef enum { TRACK_DISABLED = 0x0, TRACK_ENABLED = 0x1, TRACK_IN_MOVIE = 0x2, TRACK_IN_PREVIEW = 0x4, TRACK_IN_POSTER = 0x8}  track_header_flags;
61
62     if( (audio = hb_list_item(title->list_audio, 0)) != NULL )
63     {
64         /* Need the sample rate of the first audio track to use as the timescale. */
65         m->samplerate = audio->config.out.samplerate;
66         audio = NULL;
67     }
68     else
69     {
70         m->samplerate = 90000;
71     }
72
73     /* Create an empty mp4 file */
74     if (job->largeFileSize)
75     /* Use 64-bit MP4 file */
76     {
77         m->file = MP4Create( job->file, MP4_DETAILS_ERROR, MP4_CREATE_64BIT_DATA );
78         hb_deep_log( 2, "muxmp4: using 64-bit MP4 formatting.");
79     }
80     else
81     /* Limit MP4s to less than 4 GB */
82     {
83         m->file = MP4Create( job->file, MP4_DETAILS_ERROR, 0 );
84     }
85
86     if (m->file == MP4_INVALID_FILE_HANDLE)
87     {
88         hb_error("muxmp4.c: MP4Create failed!");
89         *job->die = 1;
90         return 0;
91     }
92
93     /* Video track */
94     mux_data      = malloc( sizeof( hb_mux_data_t ) );
95     job->mux_data = mux_data;
96
97     /* When using the standard 90000 timescale, QuickTime tends to have
98        synchronization issues (audio not playing at the correct speed).
99        To workaround this, we use the audio samplerate as the
100        timescale */
101     if (!(MP4SetTimeScale( m->file, m->samplerate )))
102     {
103         hb_error("muxmp4.c: MP4SetTimeScale failed!");
104         *job->die = 1;
105         return 0;
106     }
107
108     if( job->vcodec == HB_VCODEC_X264 )
109     {
110         /* Stolen from mp4creator */
111         MP4SetVideoProfileLevel( m->file, 0x7F );
112                 mux_data->track = MP4AddH264VideoTrack( m->file, m->samplerate,
113                         MP4_INVALID_DURATION, job->width, job->height,
114                         job->config.h264.sps[1], /* AVCProfileIndication */
115                         job->config.h264.sps[2], /* profile_compat */
116                         job->config.h264.sps[3], /* AVCLevelIndication */
117                         3 );      /* 4 bytes length before each NAL unit */
118
119
120         MP4AddH264SequenceParameterSet( m->file, mux_data->track,
121                 job->config.h264.sps, job->config.h264.sps_length );
122         MP4AddH264PictureParameterSet( m->file, mux_data->track,
123                 job->config.h264.pps, job->config.h264.pps_length );
124
125                 if( job->h264_level == 30 || job->ipod_atom)
126                 {
127                         hb_deep_log( 2, "muxmp4: adding iPod atom");
128                         MP4AddIPodUUID(m->file, mux_data->track);
129                 }
130
131         m->init_delay = job->config.h264.init_delay;
132     }
133     else /* FFmpeg or XviD */
134     {
135         MP4SetVideoProfileLevel( m->file, MPEG4_SP_L3 );
136         mux_data->track = MP4AddVideoTrack( m->file, m->samplerate,
137                 MP4_INVALID_DURATION, job->width, job->height,
138                 MP4_MPEG4_VIDEO_TYPE );
139         if (mux_data->track == MP4_INVALID_TRACK_ID)
140         {
141             hb_error("muxmp4.c: MP4AddVideoTrack failed!");
142             *job->die = 1;
143             return 0;
144         }
145
146
147         /* VOL from FFmpeg or XviD */
148         if (!(MP4SetTrackESConfiguration( m->file, mux_data->track,
149                 job->config.mpeg4.bytes, job->config.mpeg4.length )))
150         {
151             hb_error("muxmp4.c: MP4SetTrackESConfiguration failed!");
152             *job->die = 1;
153             return 0;
154         }
155     }
156
157     // COLR atom for color and gamma correction.
158     // Per the notes at:
159     //   http://developer.apple.com/quicktime/icefloe/dispatch019.html#colr
160     //   http://forum.doom9.org/showthread.php?t=133982#post1090068
161     // the user can set it from job->color_matrix, otherwise by default
162     // we say anything that's likely to be HD content is ITU BT.709 and
163     // DVD, SD TV & other content is ITU BT.601.  We look at the title height
164     // rather than the job height here to get uncropped input dimensions.
165     if( job->color_matrix == 1 )
166     {
167         // ITU BT.601 DVD or SD TV content
168         MP4AddColr(m->file, mux_data->track, 6, 1, 6);
169     }
170     else if( job->color_matrix == 2 )
171     {
172         // ITU BT.709 HD content
173         MP4AddColr(m->file, mux_data->track, 1, 1, 1);        
174     }
175     else if ( job->title->width >= 1280 || job->title->height >= 720 )
176     {
177         // we guess that 720p or above is ITU BT.709 HD content
178         MP4AddColr(m->file, mux_data->track, 1, 1, 1);
179     }
180     else
181     {
182         // ITU BT.601 DVD or SD TV content
183         MP4AddColr(m->file, mux_data->track, 6, 1, 6);
184     }
185
186     if( job->anamorphic.mode )
187     {
188         /* PASP atom for anamorphic video */
189         float width, height;
190
191         width  = job->anamorphic.par_width;
192
193         height = job->anamorphic.par_height;
194
195         MP4AddPixelAspectRatio(m->file, mux_data->track, (uint32_t)width, (uint32_t)height);
196
197         MP4SetTrackFloatProperty(m->file, mux_data->track, "tkhd.width", job->width * (width / height));
198     }
199
200         /* add the audio tracks */
201     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
202     {
203         audio = hb_list_item( title->list_audio, i );
204         mux_data = malloc( sizeof( hb_mux_data_t ) );
205         audio->priv.mux_data = mux_data;
206
207         if( audio->config.out.codec == HB_ACODEC_AC3 )
208         {
209             uint8_t fscod = 0;
210             uint8_t bsid = audio->config.in.version;
211             uint8_t bsmod = audio->config.in.mode;
212             uint8_t acmod = audio->config.flags.ac3 & 0x7;
213             uint8_t lfeon = (audio->config.flags.ac3 & A52_LFE) ? 1 : 0;
214             uint8_t bit_rate_code = 0;
215
216             /*
217              * Rewrite AC3 information into correct format for dac3 atom
218              */
219             switch( audio->config.in.samplerate )
220             {
221             case 48000:
222                 fscod = 0;
223                 break;
224             case 44100:
225                 fscod = 1;
226                 break;
227             case 32000:
228                 fscod = 2;
229                 break;
230             default:
231                 /*
232                  * Error value, tells decoder to not decode this audio.
233                  */
234                 fscod = 3;
235                 break;
236             }
237
238             switch( audio->config.in.bitrate )
239             {
240             case 32000:
241                 bit_rate_code = 0;
242                 break;
243             case 40000:
244                 bit_rate_code = 1;
245                 break;
246             case 48000:
247                 bit_rate_code = 2;
248                 break;
249             case 56000:
250                 bit_rate_code = 3;
251                 break;
252             case 64000:
253                 bit_rate_code = 4;
254                 break;
255             case 80000:
256                 bit_rate_code = 5;
257                 break;
258             case 96000:
259                 bit_rate_code = 6;
260                 break;
261             case 112000:
262                 bit_rate_code = 7;
263                 break;
264             case 128000:
265                 bit_rate_code = 8;
266                 break;
267             case 160000:
268                 bit_rate_code = 9;
269                 break;
270             case 192000:
271                 bit_rate_code = 10;
272                 break;
273             case 224000:
274                 bit_rate_code = 11;
275                 break;
276             case 256000:
277                 bit_rate_code = 12;
278                 break;
279             case 320000:
280                 bit_rate_code = 13;
281                 break;
282             case 384000:
283                 bit_rate_code = 14;
284                 break;
285             case 448000:
286                 bit_rate_code = 15;
287                 break;
288             case 512000:
289                 bit_rate_code = 16;
290                 break;
291             case 576000:
292                 bit_rate_code = 17;
293                 break;
294             case 640000:
295                 bit_rate_code = 18;
296                 break;
297             default:
298                 hb_error("Unknown AC3 bitrate");
299                 bit_rate_code = 0;
300                 break;
301             }
302
303             mux_data->track = MP4AddAC3AudioTrack(
304                 m->file,
305                 audio->config.out.samplerate, 
306                 fscod,
307                 bsid,
308                 bsmod,
309                 acmod,
310                 lfeon,
311                 bit_rate_code);
312
313             if (audio->config.out.name == NULL) {
314                 MP4SetTrackBytesProperty(
315                     m->file, mux_data->track,
316                     "udta.name.value",
317                     (const uint8_t*)"Surround", strlen("Surround"));
318             }
319             else {
320                 MP4SetTrackBytesProperty(
321                     m->file, mux_data->track,
322                     "udta.name.value",
323                     (const uint8_t*)(audio->config.out.name),
324                     strlen(audio->config.out.name));
325             }
326         } else {
327             mux_data->track = MP4AddAudioTrack(
328                 m->file,
329                 audio->config.out.samplerate, 1024, MP4_MPEG4_AUDIO_TYPE );
330             if (audio->config.out.name == NULL) {
331                 MP4SetTrackBytesProperty(
332                     m->file, mux_data->track,
333                     "udta.name.value",
334                     (const uint8_t*)"Stereo", strlen("Stereo"));
335             }
336             else {
337                 MP4SetTrackBytesProperty(
338                     m->file, mux_data->track,
339                     "udta.name.value",
340                     (const uint8_t*)(audio->config.out.name),
341                     strlen(audio->config.out.name));
342             }
343
344             MP4SetAudioProfileLevel( m->file, 0x0F );
345             MP4SetTrackESConfiguration(
346                 m->file, mux_data->track,
347                 audio->priv.config.aac.bytes, audio->priv.config.aac.length );
348
349             /* Set the correct number of channels for this track */
350              MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.mp4a.channels", (uint16_t)HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown));
351         }
352
353         /* Set the language for this track */
354         MP4SetTrackLanguage(m->file, mux_data->track, audio->config.lang.iso639_2);
355
356         if( hb_list_count( title->list_audio ) > 1 )
357         {
358             /* Set the audio track alternate group */
359             MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.alternate_group", 1);
360         }
361
362         if (i == 0) {
363             /* Enable the first audio track */
364             MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_ENABLED | TRACK_IN_MOVIE));
365         }
366         else
367             /* Disable the other audio tracks so QuickTime doesn't play
368                them all at once. */
369         {
370             MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_DISABLED | TRACK_IN_MOVIE));
371             hb_deep_log( 2, "muxp4: disabled extra audio track %i", mux_data->track-1);
372         }
373
374     }
375
376     if (job->chapter_markers)
377     {
378         /* add a text track for the chapters. We add the 'chap' atom to track
379            one which is usually the video track & should never be disabled.
380            The Quicktime spec says it doesn't matter which media track the
381            chap atom is on but it has to be an enabled track. */
382         MP4TrackId textTrack;
383         textTrack = MP4AddChapterTextTrack(m->file, 1, 0);
384
385         m->chapter_track = textTrack;
386         m->chapter_duration = 0;
387         m->current_chapter = job->chapter_start;
388     }
389
390     /* Add encoded-by metadata listing version and build date */
391     char *tool_string;
392     tool_string = (char *)malloc(80);
393     snprintf( tool_string, 80, "HandBrake %s %i", HB_PROJECT_VERSION, HB_PROJECT_BUILD);
394     MP4SetMetadataTool(m->file, tool_string);
395     free(tool_string);
396
397     return 0;
398 }
399
400 static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
401                    hb_buffer_t * buf )
402 {
403     hb_job_t * job = m->job;
404     int64_t duration;
405     int64_t offset = 0;
406
407     if( mux_data == job->mux_data )
408     {
409         /* Video */
410
411         // if there are b-frames compute the render offset
412         // (we'll need it for both the video frame & the chapter track)
413         if ( m->init_delay )
414         {
415             offset = ( buf->start + m->init_delay ) * m->samplerate / 90000 -
416                      m->sum_dur;
417         }
418
419         /* Add the sample before the new frame.
420            It is important that this be calculated prior to the duration
421            of the new video sample, as we want to sync to right after it.
422            (This is because of how durations for text tracks work in QT) */
423         if( job->chapter_markers && buf->new_chap )
424         {    
425             hb_chapter_t *chapter = NULL;
426
427             // this chapter is postioned by writing out the previous chapter.
428             // the duration of the previous chapter is the duration up to but
429             // not including the current frame minus the duration of all
430             // chapters up to the previous.
431             duration = m->sum_dur - m->chapter_duration + offset;
432             if ( duration <= 0 )
433             {
434                 /* The initial & final chapters can have very short durations
435                  * (less than the error in our total duration estimate) so
436                  * the duration calc above can result in a negative number.
437                  * when this happens give the chapter a short duration (1/3
438                  * of an ntsc frame time). */
439                 duration = 1000 * m->samplerate / 90000;
440             }
441
442             chapter = hb_list_item( m->job->title->list_chapter,
443                                     buf->new_chap - 2 );
444
445             MP4AddChapter( m->file,
446                            m->chapter_track,
447                            duration,
448                            (chapter != NULL) ? chapter->title : NULL);
449
450             m->current_chapter = buf->new_chap;
451             m->chapter_duration += duration;
452         }
453
454         // since we're changing the sample rate we need to keep track of
455         // the truncation bias so that the audio and video don't go out
456         // of sync. m->sum_dur_in is the sum of the input durations so far.
457         // m->sum_dur is the sum of the output durations. Their difference
458         // (in output sample rate units) is the accumulated truncation bias.
459         int64_t bias = ( m->sum_dur_in * m->samplerate / 90000 ) - m->sum_dur;
460         int64_t dur_in = buf->stop - buf->start;
461         duration = dur_in * m->samplerate / 90000 + bias;
462         if ( duration <= 0 )
463         {
464             /* We got an illegal mp4/h264 duration. This shouldn't
465                be possible and usually indicates a bug in the upstream code.
466                Complain in the hope that someone will go find the bug but
467                try to fix the error so that the file will still be playable. */
468             hb_log("MP4Mux: illegal duration %lld, bias %lld, start %lld (%lld),"
469                    "stop %lld (%lld), sum_dur %lld",
470                    duration, bias, buf->start * m->samplerate / 90000, buf->start,
471                    buf->stop * m->samplerate / 90000, buf->stop, m->sum_dur );
472             /* we don't know when the next frame starts so we can't pick a
473                valid duration for this one so we pick something "short"
474                (roughly 1/3 of an NTSC frame time) and rely on the bias calc
475                for the next frame to correct things (a duration underestimate
476                just results in a large bias on the next frame). */
477             duration = 1000 * m->samplerate / 90000;
478         }
479         m->sum_dur += duration;
480         m->sum_dur_in += dur_in;
481     }
482     else
483     {
484         /* Audio */
485         duration = MP4_INVALID_DURATION;
486     }
487
488     // Here's where the sample actually gets muxed.
489     if( !MP4WriteSample( m->file,
490                          mux_data->track,
491                          buf->data,
492                          buf->size,
493                          duration,
494                          offset,
495                          ( job->vcodec == HB_VCODEC_X264 && mux_data == job->mux_data ) ?
496                             ( buf->frametype == HB_FRAME_IDR ) : ( ( buf->frametype & HB_FRAME_KEY ) != 0 ) ) )
497     {
498         hb_error("Failed to write to output file, disk full?");
499         *job->die = 1;
500     }
501
502     return 0;
503 }
504
505 static int MP4End( hb_mux_object_t * m )
506 {
507     hb_job_t   * job   = m->job;
508     hb_title_t * title = job->title;
509
510     /* Write our final chapter marker */
511     if( m->job->chapter_markers )
512     {
513         hb_chapter_t *chapter = NULL;
514         int64_t duration = m->sum_dur - m->chapter_duration;
515         /* The final chapter can have a very short duration - if it's less
516          * than a second just skip it. */
517         if ( duration >= m->samplerate )
518         {
519
520             chapter = hb_list_item( m->job->title->list_chapter,
521                                     m->current_chapter - 1 );
522
523             MP4AddChapter( m->file,
524                            m->chapter_track,
525                            duration,
526                            (chapter != NULL) ? chapter->title : NULL);
527         }
528     }
529
530     if (job->areBframes)
531     {
532            // Insert track edit to get A/V back in sync.  The edit amount is
533            // the init_delay.
534            int64_t edit_amt = m->init_delay * m->samplerate / 90000;
535            MP4AddTrackEdit(m->file, 1, MP4_INVALID_EDIT_ID, edit_amt,
536                            MP4GetTrackDuration(m->file, 1), 0);
537             if ( m->job->chapter_markers )
538             {
539                 // apply same edit to chapter track to keep it in sync with video
540                 MP4AddTrackEdit(m->file, m->chapter_track, MP4_INVALID_EDIT_ID,
541                                 edit_amt,
542                                 MP4GetTrackDuration(m->file, m->chapter_track), 0);
543             }
544      }
545
546     /*
547      * Write the MP4 iTunes metadata if we have any metadata
548      */
549     if( title->metadata )
550     {
551         hb_metadata_t *md = title->metadata;
552
553         hb_deep_log( 2, "Writing Metadata to output file...");
554
555         MP4SetMetadataName( m->file, md->name );
556         MP4SetMetadataArtist( m->file, md->artist );
557         MP4SetMetadataComposer( m->file, md->composer );
558         MP4SetMetadataComment( m->file, md->comment );
559         MP4SetMetadataReleaseDate( m->file, md->release_date );
560         MP4SetMetadataAlbum( m->file, md->album );
561         MP4SetMetadataGenre( m->file, md->genre );
562         if( md->coverart )
563         {
564             MP4SetMetadataCoverArt( m->file, md->coverart, md->coverart_size);
565         }
566     }
567
568     MP4Close( m->file );
569
570     if ( job->mp4_optimize )
571     {
572         hb_log( "muxmp4: optimizing file" );
573         char filename[1024]; memset( filename, 0, 1024 );
574         snprintf( filename, 1024, "%s.tmp", job->file );
575         MP4Optimize( job->file, filename, MP4_DETAILS_ERROR );
576         remove( job->file );
577         rename( filename, job->file );
578     }
579
580     return 0;
581 }
582
583 hb_mux_object_t * hb_mux_mp4_init( hb_job_t * job )
584 {
585     hb_mux_object_t * m = calloc( sizeof( hb_mux_object_t ), 1 );
586     m->init      = MP4Init;
587     m->mux       = MP4Mux;
588     m->end       = MP4End;
589     m->job       = job;
590     return m;
591 }
592