+ u_int16_t language_code;
+
+ /* 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;
+
+ if( (audio = hb_list_item(title->list_audio, 0)) != NULL )
+ {
+ /* Need the sample rate of the first audio track to use as the timescale. */
+ m->samplerate = audio->config.out.samplerate;
+ audio = NULL;
+ }
+ else
+ {
+ m->samplerate = 90000;
+ }
+
+ /* Create an empty mp4 file */
+ if (job->largeFileSize)
+ /* Use 64-bit MP4 file */
+ {
+ m->file = MP4Create( job->file, MP4_DETAILS_ERROR, MP4_CREATE_64BIT_DATA );
+ hb_log("Using 64-bit MP4 formatting.");
+ }
+ else
+ /* Limit MP4s to less than 4 GB */
+ {
+ m->file = MP4Create( job->file, MP4_DETAILS_ERROR, 0 );
+ }
+
+ if (m->file == MP4_INVALID_FILE_HANDLE)
+ {
+ hb_error("muxmp4.c: MP4Create failed!");
+ *job->die = 1;
+ return 0;
+ }
+
+ /* Video track */
+ mux_data = malloc( sizeof( hb_mux_data_t ) );
+ job->mux_data = mux_data;
+
+ /* When using the standard 90000 timescale, QuickTime tends to have
+ synchronization issues (audio not playing at the correct speed).
+ To workaround this, we use the audio samplerate as the
+ timescale */
+ if (!(MP4SetTimeScale( m->file, m->samplerate )))
+ {
+ hb_error("muxmp4.c: MP4SetTimeScale failed!");
+ *job->die = 1;
+ return 0;
+ }
+
+ if( job->vcodec == HB_VCODEC_X264 )
+ {
+ /* Stolen from mp4creator */
+ if(!(MP4SetVideoProfileLevel( m->file, 0x7F )))
+ {
+ hb_error("muxmp4.c: MP4SetVideoProfileLevel failed!");
+ *job->die = 1;
+ return 0;
+ }
+
+ mux_data->track = MP4AddH264VideoTrack( m->file, m->samplerate,
+ MP4_INVALID_DURATION, job->width, job->height,
+ job->config.h264.sps[1], /* AVCProfileIndication */
+ job->config.h264.sps[2], /* profile_compat */
+ job->config.h264.sps[3], /* AVCLevelIndication */
+ 3 ); /* 4 bytes length before each NAL unit */
+
+
+ MP4AddH264SequenceParameterSet( m->file, mux_data->track,
+ job->config.h264.sps, job->config.h264.sps_length );
+ MP4AddH264PictureParameterSet( m->file, mux_data->track,
+ job->config.h264.pps, job->config.h264.pps_length );
+
+ if( job->h264_level == 30 || job->ipod_atom)
+ {
+ hb_log("About to add iPod atom");
+ AddIPodUUID(m->file, mux_data->track);
+ }
+
+ m->init_delay = job->config.h264.init_delay;
+ }
+ else /* FFmpeg or XviD */
+ {
+ if(!(MP4SetVideoProfileLevel( m->file, MPEG4_SP_L3 )))
+ {
+ hb_error("muxmp4.c: MP4SetVideoProfileLevel failed!");
+ *job->die = 1;
+ return 0;
+ }
+ mux_data->track = MP4AddVideoTrack( m->file, m->samplerate,
+ MP4_INVALID_DURATION, job->width, job->height,
+ MP4_MPEG4_VIDEO_TYPE );
+ if (mux_data->track == MP4_INVALID_TRACK_ID)
+ {
+ hb_error("muxmp4.c: MP4AddVideoTrack failed!");
+ *job->die = 1;
+ return 0;
+ }
+
+
+ /* VOL from FFmpeg or XviD */
+ if (!(MP4SetTrackESConfiguration( m->file, mux_data->track,
+ job->config.mpeg4.bytes, job->config.mpeg4.length )))
+ {
+ hb_error("muxmp4.c: MP4SetTrackESConfiguration failed!");
+ *job->die = 1;
+ return 0;
+ }
+ }
+
+ // 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);