3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.m0k.org/>.
5 It may be used under the terms of the GNU General Public License. */
14 /* Scale factor to apply to timecodes to convert from HandBrake's
15 * 1/90000s to nanoseconds as expected by libmkv */
16 #define TIMECODE_SCALE 1000000000 / 90000
18 struct hb_mux_object_s
30 uint64_t prev_chapter_tc
;
31 uint16_t current_chapter
;
34 /**********************************************************************
36 **********************************************************************
37 * Allocates hb_mux_data_t structures, create file and write headers
38 *********************************************************************/
39 static int MKVInit( hb_mux_object_t
* m
)
41 hb_job_t
* job
= m
->job
;
42 hb_title_t
* title
= job
->title
;
44 hb_mux_data_t
* mux_data
;
47 uint8_t default_track_flag
= 1;
49 ogg_packet
*ogg_headers
[3];
50 mk_TrackConfig
*track
;
52 track
= calloc(1, sizeof(mk_TrackConfig
));
54 m
->file
= mk_createWriter(job
->file
, 1000000, 1);
58 hb_error( "Could not create output file, Disk Full?" );
65 mux_data
= calloc(1, sizeof( hb_mux_data_t
) );
66 job
->mux_data
= mux_data
;
68 track
->trackType
= MK_TRACK_VIDEO
;
69 track
->flagDefault
= 1;
70 track
->flagEnabled
= 1;
74 track
->codecID
= MK_VCODEC_MP4AVC
;
75 /* Taken from x264 muxers.c */
76 avcC_len
= 5 + 1 + 2 + job
->config
.h264
.sps_length
+ 1 + 2 + job
->config
.h264
.pps_length
;
77 avcC
= malloc(avcC_len
);
82 avcC
[1] = job
->config
.h264
.sps
[1]; /* AVCProfileIndication */
83 avcC
[2] = job
->config
.h264
.sps
[2]; /* profile_compat */
84 avcC
[3] = job
->config
.h264
.sps
[3]; /* AVCLevelIndication */
85 avcC
[4] = 0xff; // nalu size length is four bytes
86 avcC
[5] = 0xe1; // one sps
88 avcC
[6] = job
->config
.h264
.sps_length
>> 8;
89 avcC
[7] = job
->config
.h264
.sps_length
;
91 memcpy(avcC
+8, job
->config
.h264
.sps
, job
->config
.h264
.sps_length
);
93 avcC
[8+job
->config
.h264
.sps_length
] = 1; // one pps
94 avcC
[9+job
->config
.h264
.sps_length
] = job
->config
.h264
.pps_length
>> 8;
95 avcC
[10+job
->config
.h264
.sps_length
] = job
->config
.h264
.pps_length
;
97 memcpy( avcC
+11+job
->config
.h264
.sps_length
, job
->config
.h264
.pps
, job
->config
.h264
.pps_length
);
98 track
->codecPrivate
= avcC
;
99 track
->codecPrivateSize
= avcC_len
;
104 case HB_VCODEC_FFMPEG
:
105 track
->codecID
= MK_VCODEC_MP4ASP
;
106 track
->codecPrivate
= job
->config
.mpeg4
.bytes
;
107 track
->codecPrivateSize
= job
->config
.mpeg4
.length
;
111 hb_error("muxmkv: Unknown video codec: %x", job
->vcodec
);
115 track
->video
.pixelWidth
= job
->width
;
116 track
->video
.pixelHeight
= job
->height
;
117 track
->video
.displayHeight
= job
->height
;
120 track
->video
.displayWidth
= job
->width
* ((double)job
->pixel_aspect_width
/ (double)job
->pixel_aspect_height
);
124 track
->video
.displayWidth
= job
->width
;
128 track
->defaultDuration
= (int64_t)(((float)job
->vrate_base
/ (float)job
->vrate
) * 1000000000);
130 mux_data
->track
= mk_createTrack(m
->file
, track
);
132 memset(track
, 0, sizeof(mk_TrackConfig
));
134 /* add the audio tracks */
135 for( i
= 0; i
< hb_list_count( title
->list_audio
); i
++ )
137 audio
= hb_list_item( title
->list_audio
, i
);
138 mux_data
= malloc( sizeof( hb_mux_data_t
) );
139 audio
->mux_data
= mux_data
;
144 track
->codecPrivate
= NULL
;
145 track
->codecPrivateSize
= 0;
146 track
->codecID
= MK_ACODEC_AC3
;
149 track
->codecPrivate
= NULL
;
150 track
->codecPrivateSize
= 0;
151 track
->codecID
= MK_ACODEC_MP3
;
153 case HB_ACODEC_VORBIS
:
156 uint64_t cp_size
= 0;
157 track
->codecID
= MK_ACODEC_VORBIS
;
158 uint64_t header_sizes
[3];
159 for (i
= 0; i
< 3; ++i
)
161 ogg_headers
[i
] = (ogg_packet
*)audio
->config
.vorbis
.headers
[i
];
162 ogg_headers
[i
]->packet
= (unsigned char *)&audio
->config
.vorbis
.headers
[i
] + sizeof( ogg_packet
);
163 header_sizes
[i
] = ogg_headers
[i
]->bytes
;
165 track
->codecPrivate
= mk_laceXiph(header_sizes
, 2, &cp_size
);
166 track
->codecPrivate
= realloc(track
->codecPrivate
, cp_size
+ ogg_headers
[0]->bytes
+ ogg_headers
[1]->bytes
+ ogg_headers
[2]->bytes
);
167 for(i
= 0; i
< 3; ++i
)
169 memcpy(track
->codecPrivate
+ cp_size
, ogg_headers
[i
]->packet
, ogg_headers
[i
]->bytes
);
170 cp_size
+= ogg_headers
[i
]->bytes
;
172 track
->codecPrivateSize
= cp_size
;
176 track
->codecPrivate
= audio
->config
.aac
.bytes
;
177 track
->codecPrivateSize
= audio
->config
.aac
.length
;
178 track
->codecID
= MK_ACODEC_AAC
;
182 hb_error("muxmkv: Unknown audio codec: %x", job
->acodec
);
186 if (default_track_flag
)
188 track
->flagDefault
= 1;
189 default_track_flag
= 0;
191 track
->flagEnabled
= 1;
192 track
->trackType
= MK_TRACK_AUDIO
;
193 track
->language
= audio
->iso639_2
;
194 track
->audio
.samplingFreq
= (float)job
->arate
;
195 track
->audio
.channels
= (job
->acodec
== HB_ACODEC_AC3
) ? HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio
->input_channel_layout
) : HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio
->amixdown
);
196 // track->defaultDuration = job->arate * 1000;
197 mux_data
->track
= mk_createTrack(m
->file
, track
);
198 if (job
->acodec
== HB_ACODEC_VORBIS
&& track
->codecPrivate
!= NULL
)
199 free(track
->codecPrivate
);
202 if( mk_writeHeader( m
->file
, "HandBrake " HB_VERSION
) < 0 )
204 hb_error( "Failed to write to output file, disk full?");
215 static int MKVMux( hb_mux_object_t
* m
, hb_mux_data_t
* mux_data
,
218 hb_job_t
* job
= m
->job
;
219 hb_title_t
* title
= job
->title
;
220 uint64_t timecode
= 0;
221 hb_chapter_t
*chapter_data
;
222 char tmp_buffer
[1024];
223 char *string
= tmp_buffer
;
224 if (mux_data
== job
->mux_data
)
227 if ((job
->vcodec
== HB_VCODEC_X264
) && (buf
->frametype
& HB_FRAME_REF
))
229 timecode
= (buf
->start
+ (buf
->renderOffset
- 1000000)) * TIMECODE_SCALE
;
233 timecode
= buf
->start
* TIMECODE_SCALE
;
236 if (job
->chapter_markers
&& (buf
->new_chap
|| timecode
== 0))
238 /* Make sure we're not writing a chapter that has 0 length */
239 if (mux_data
->prev_chapter_tc
!= timecode
)
241 chapter_data
= hb_list_item( title
->list_chapter
, mux_data
->current_chapter
++ );
242 tmp_buffer
[0] = '\0';
244 if( chapter_data
!= NULL
)
246 string
= chapter_data
->title
;
249 if( strlen(string
) == 0 || strlen(string
) >= 1024 )
251 snprintf( tmp_buffer
, 1023, "Chapter %02i", mux_data
->current_chapter
);
254 mk_createChapterSimple(m
->file
, mux_data
->prev_chapter_tc
, mux_data
->prev_chapter_tc
, string
);
256 mux_data
->prev_chapter_tc
= timecode
;
262 timecode
= buf
->start
* TIMECODE_SCALE
;
263 if (job
->acodec
== HB_ACODEC_VORBIS
)
265 /* ughhh, vorbis is a pain :( */
268 op
= (ogg_packet
*)buf
->data
;
269 op
->packet
= buf
->data
+ sizeof( ogg_packet
);
270 mk_startFrame(m
->file
, mux_data
->track
);
271 mk_addFrameData(m
->file
, mux_data
->track
, op
->packet
, op
->bytes
);
272 mk_setFrameFlags(m
->file
, mux_data
->track
, timecode
, 1);
277 if( mk_startFrame(m
->file
, mux_data
->track
) < 0)
279 hb_error( "Failed to write frame to output file, Disk Full?" );
282 mk_addFrameData(m
->file
, mux_data
->track
, buf
->data
, buf
->size
);
283 mk_setFrameFlags(m
->file
, mux_data
->track
, timecode
,
284 ((job
->vcodec
== HB_VCODEC_X264
&& mux_data
== job
->mux_data
) ? (buf
->frametype
== HB_FRAME_IDR
) : ((buf
->frametype
& HB_FRAME_KEY
) != 0)) );
288 static int MKVEnd( hb_mux_object_t
* m
)
290 hb_job_t
*job
= m
->job
;
291 hb_mux_data_t
*mux_data
= job
->mux_data
;
292 hb_title_t
*title
= job
->title
;
293 hb_chapter_t
*chapter_data
;
294 char tmp_buffer
[1024];
295 char *string
= tmp_buffer
;
300 * We must have failed to create the file in the first place.
305 chapter_data
= hb_list_item( title
->list_chapter
, mux_data
->current_chapter
++ );
307 if(job
->chapter_markers
)
309 tmp_buffer
[0] = '\0';
311 if( chapter_data
!= NULL
)
313 string
= chapter_data
->title
;
316 if( strlen(string
) == 0 || strlen(string
) >= 1024 )
318 snprintf( tmp_buffer
, 1023, "Chapter %02i", mux_data
->current_chapter
);
321 mk_createChapterSimple(m
->file
, mux_data
->prev_chapter_tc
, mux_data
->prev_chapter_tc
, string
);
324 if( mk_close(m
->file
) < 0 )
326 hb_error( "Failed to flush the last frame and close the output file, Disk Full?" );
330 // TODO: Free what we alloc'd
335 hb_mux_object_t
* hb_mux_mkv_init( hb_job_t
* job
)
337 hb_mux_object_t
* m
= calloc( sizeof( hb_mux_object_t
), 1 );