+ 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
+ // the user can set it from job->color_matrix, otherwise by default
+ // 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->color_matrix == 1 )
+ {
+ // ITU BT.601 DVD or SD TV content
+ MP4AddColr(m->file, mux_data->track, 6, 1, 6);
+ }
+ else if( job->color_matrix == 2 )
+ {
+ // ITU BT.709 HD content
+ MP4AddColr(m->file, mux_data->track, 1, 1, 1);
+ }
+ else if ( job->title->width >= 1280 || 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->anamorphic.mode )
+ {
+ /* PASP atom for anamorphic video */
+ float width, height;
+
+ width = job->anamorphic.par_width;
+
+ height = job->anamorphic.par_height;
+
+ MP4AddPixelAspectRatio(m->file, mux_data->track, (uint32_t)width, (uint32_t)height);
+
+ MP4SetTrackFloatProperty(m->file, mux_data->track, "tkhd.width", job->width * (width / height));
+ }
+
+ /* add the audio tracks */
+ for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+ {
+ audio = hb_list_item( title->list_audio, i );
+ mux_data = calloc(1, sizeof( hb_mux_data_t ) );
+ audio->priv.mux_data = mux_data;
+
+ if( audio->config.out.codec == HB_ACODEC_AC3 )
+ {
+ uint8_t fscod = 0;
+ uint8_t bsid = audio->config.in.version;
+ uint8_t bsmod = audio->config.in.mode;
+ uint8_t acmod = audio->config.flags.ac3 & 0x7;
+ uint8_t lfeon = (audio->config.flags.ac3 & A52_LFE) ? 1 : 0;
+ uint8_t bit_rate_code = 0;
+
+ /*
+ * Rewrite AC3 information into correct format for dac3 atom
+ */
+ switch( audio->config.in.samplerate )
+ {
+ case 48000:
+ fscod = 0;
+ break;
+ case 44100:
+ fscod = 1;
+ break;
+ case 32000:
+ fscod = 2;
+ break;
+ default:
+ /*
+ * Error value, tells decoder to not decode this audio.
+ */
+ fscod = 3;
+ break;
+ }
+
+ switch( audio->config.in.bitrate )
+ {
+ case 32000:
+ bit_rate_code = 0;
+ break;
+ case 40000:
+ bit_rate_code = 1;
+ break;
+ case 48000:
+ bit_rate_code = 2;
+ break;
+ case 56000:
+ bit_rate_code = 3;
+ break;
+ case 64000:
+ bit_rate_code = 4;
+ break;
+ case 80000:
+ bit_rate_code = 5;
+ break;
+ case 96000:
+ bit_rate_code = 6;
+ break;
+ case 112000:
+ bit_rate_code = 7;
+ break;
+ case 128000:
+ bit_rate_code = 8;
+ break;
+ case 160000:
+ bit_rate_code = 9;
+ break;
+ case 192000:
+ bit_rate_code = 10;
+ break;
+ case 224000:
+ bit_rate_code = 11;
+ break;
+ case 256000:
+ bit_rate_code = 12;
+ break;
+ case 320000:
+ bit_rate_code = 13;
+ break;
+ case 384000:
+ bit_rate_code = 14;
+ break;
+ case 448000:
+ bit_rate_code = 15;
+ break;
+ case 512000:
+ bit_rate_code = 16;
+ break;
+ case 576000:
+ bit_rate_code = 17;
+ break;
+ case 640000:
+ bit_rate_code = 18;
+ break;
+ default:
+ hb_error("Unknown AC3 bitrate");
+ bit_rate_code = 0;
+ break;
+ }
+
+ mux_data->track = MP4AddAC3AudioTrack(
+ m->file,
+ audio->config.out.samplerate,
+ fscod,
+ bsid,
+ bsmod,
+ acmod,
+ lfeon,
+ bit_rate_code);
+
+ /* Tune track chunk duration */
+ MP4TuneTrackDurationPerChunk( m, mux_data->track );
+
+ if (audio->config.out.name == NULL) {
+ MP4SetTrackBytesProperty(
+ m->file, mux_data->track,
+ "udta.name.value",
+ (const uint8_t*)"Surround", strlen("Surround"));
+ }
+ else {
+ MP4SetTrackBytesProperty(
+ m->file, mux_data->track,
+ "udta.name.value",
+ (const uint8_t*)(audio->config.out.name),
+ strlen(audio->config.out.name));
+ }
+ } else {
+ mux_data->track = MP4AddAudioTrack(
+ m->file,
+ audio->config.out.samplerate, 1024, MP4_MPEG4_AUDIO_TYPE );
+
+ /* Tune track chunk duration */
+ MP4TuneTrackDurationPerChunk( m, mux_data->track );
+
+ if (audio->config.out.name == NULL) {
+ MP4SetTrackBytesProperty(
+ m->file, mux_data->track,
+ "udta.name.value",
+ (const uint8_t*)"Stereo", strlen("Stereo"));
+ }
+ else {
+ MP4SetTrackBytesProperty(
+ m->file, mux_data->track,
+ "udta.name.value",
+ (const uint8_t*)(audio->config.out.name),
+ strlen(audio->config.out.name));
+ }
+
+ MP4SetAudioProfileLevel( m->file, 0x0F );
+ MP4SetTrackESConfiguration(
+ m->file, mux_data->track,
+ audio->priv.config.aac.bytes, audio->priv.config.aac.length );
+
+ /* Set the correct number of channels for this track */
+ MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.mp4a.channels", (uint16_t)HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown));
+ }
+
+ /* Set the language for this track */
+ MP4SetTrackLanguage(m->file, mux_data->track, audio->config.lang.iso639_2);
+
+ if( hb_list_count( title->list_audio ) > 1 )
+ {
+ /* Set the audio track alternate group */
+ MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.alternate_group", 1);
+ }
+
+ if (i == 0) {
+ /* Enable the first audio track */
+ MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_ENABLED | TRACK_IN_MOVIE));
+ }
+ else
+ /* Disable the other audio tracks so QuickTime doesn't play
+ them all at once. */
+ {
+ MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_DISABLED | TRACK_IN_MOVIE));
+ hb_deep_log( 2, "muxmp4: disabled extra audio track %u", MP4FindTrackIndex( m->file, mux_data->track ));
+ }
+