1 /* muxavformat.c
2
3 Copyright (c) 2003-2021 HandBrake Team
4 This file is part of the HandBrake source code
5 Homepage: <http://handbrake.fr/>.
6 It may be used under the terms of the GNU General Public License v2.
7 For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
8 */
9
10 #include <ogg/ogg.h>
11 #include "libavformat/avformat.h"
12 #include "libavutil/avstring.h"
13 #include "libavutil/intreadwrite.h"
14
15 #include "handbrake/handbrake.h"
16 #include "handbrake/ssautil.h"
17 #include "handbrake/lang.h"
18 #include "handbrake/hbffmpeg.h"
19
20 struct hb_mux_data_s
21 {
22 enum
23 {
24 MUX_TYPE_VIDEO,
25 MUX_TYPE_AUDIO,
26 MUX_TYPE_SUBTITLE
27 } type;
28
29 AVStream *st;
30
31 int64_t duration;
32
33 hb_buffer_t * delay_buf;
34
35 int64_t prev_chapter_tc;
36 int16_t current_chapter;
37
38 AVBSFContext * bitstream_context;
39 hb_tx3g_style_context_t * tx3g;
40 };
41
42 struct hb_mux_object_s
43 {
44 HB_MUX_COMMON;
45
46 hb_job_t * job;
47
48 AVFormatContext * oc;
49 AVRational time_base;
50 AVPacket * pkt;
51 AVPacket * empty_pkt;
52
53 int ntracks;
54 hb_mux_data_t ** tracks;
55 };
56
57 enum
58 {
59 META_HB,
60 META_MUX_MP4,
61 META_MUX_MKV,
62 META_MUX_WEBM,
63 META_MUX_LAST
64 };
65
66 const char *metadata_keys[][META_MUX_LAST] =
67 {
68 {"Name", "title", "TITLE"},
69 {"Artist", "artist", "ARTIST"},
70 {"AlbumArtist", "album_artist", "DIRECTOR"},
71 {"Composer", "composer", "COMPOSER"},
72 {"ReleaseDate", "date", "DATE_RELEASED"},
73 {"Comment", "comment", "SUMMARY"},
74 {"Album", "album", NULL},
75 {"Genre", "genre", "GENRE"},
76 {"Description", "description", "DESCRIPTION"},
77 {"LongDescription", "synopsis", "SYNOPSIS"},
78 {NULL}
79 };
80
lookup_meta_mux_key(int meta_mux,const char * hb_key)81 static const char * lookup_meta_mux_key(int meta_mux, const char * hb_key)
82 {
83 int ii;
84
85 for (ii = 0; metadata_keys[ii][META_HB] != NULL; ii++)
86 {
87 if (!strcmp(hb_key, metadata_keys[ii][META_HB]))
88 {
89 return metadata_keys[ii][meta_mux];
90 }
91 }
92 return NULL;
93 }
94
hb_lookup_meta_key(const char * mux_key)95 const char * hb_lookup_meta_key(const char * mux_key)
96 {
97 int ii, jj;
98
99 for (ii = 0; metadata_keys[ii][META_HB] != NULL; ii++)
100 {
101 for (jj = 0; jj < META_MUX_LAST; jj++)
102 {
103 if (metadata_keys[ii][jj] != NULL &&
104 !strcmp(mux_key, metadata_keys[ii][jj]))
105 {
106 return metadata_keys[ii][META_HB];
107 }
108 }
109 }
110 return NULL;
111 }
112
lookup_lang_code(int mux,char * iso639_2)113 static char* lookup_lang_code(int mux, char *iso639_2)
114 {
115 iso639_lang_t *lang;
116 char *out = NULL;
117
118 switch (mux)
119 {
120 case HB_MUX_AV_MP4:
121 out = iso639_2;
122 break;
123 case HB_MUX_AV_MKV:
124 case HB_MUX_AV_WEBM: // webm is a subset of mkv
125 // MKV lang codes should be ISO-639-2B if it exists,
126 // else ISO-639-2
127 lang = lang_for_code2( iso639_2 );
128 out = lang->iso639_2b && *lang->iso639_2b ? lang->iso639_2b :
129 lang->iso639_2;
130 break;
131 default:
132 break;
133 }
134 return out;
135 }
136
137 /**********************************************************************
138 * avformatInit
139 **********************************************************************
140 * Allocates hb_mux_data_t structures, create file and write headers
141 *********************************************************************/
avformatInit(hb_mux_object_t * m)142 static int avformatInit( hb_mux_object_t * m )
143 {
144 hb_job_t * job = m->job;
145 hb_audio_t * audio;
146 hb_mux_data_t * track;
147 int meta_mux;
148 int max_tracks;
149 int ii, jj, ret;
150
151 int clock_min, clock_max, clock;
152 hb_video_framerate_get_limits(&clock_min, &clock_max, &clock);
153
154 const char *muxer_name = NULL;
155
156 uint8_t default_track_flag = 1;
157 uint8_t need_fonts = 0;
158 char *lang;
159
160 m->pkt = av_packet_alloc();
161 m->empty_pkt = av_packet_alloc();
162
163 m->pkt = av_packet_alloc();
164 if (m->pkt == NULL || m->empty_pkt == NULL)
165 {
166 hb_error("muxavformat: av_packet_alloc failed");
167 goto error;
168 }
169
170 max_tracks = 1 + hb_list_count( job->list_audio ) +
171 hb_list_count( job->list_subtitle );
172 m->tracks = calloc(max_tracks, sizeof(hb_mux_data_t*));
173
174 AVDictionary * av_opts = NULL;
175 switch (job->mux)
176 {
177 case HB_MUX_AV_MP4:
178 m->time_base.num = 1;
179 m->time_base.den = 90000;
180 if( job->ipod_atom )
181 muxer_name = "ipod";
182 else
183 muxer_name = "mp4";
184 meta_mux = META_MUX_MP4;
185
186 av_dict_set(&av_opts, "brand", "mp42", 0);
187 if (job->mp4_optimize)
188 av_dict_set(&av_opts, "movflags", "faststart+disable_chpl+write_colr", 0);
189 else
190 av_dict_set(&av_opts, "movflags", "+disable_chpl+write_colr", 0);
191 break;
192
193 case HB_MUX_AV_MKV:
194 // libavformat is essentially hard coded such that it only
195 // works with a timebase of 1/1000
196 m->time_base.num = 1;
197 m->time_base.den = 1000;
198 muxer_name = "matroska";
199 meta_mux = META_MUX_MKV;
200 av_dict_set(&av_opts, "default_mode", "passthrough", 0);
201 break;
202
203 case HB_MUX_AV_WEBM:
204 // libavformat is essentially hard coded such that it only
205 // works with a timebase of 1/1000
206 m->time_base.num = 1;
207 m->time_base.den = 1000;
208 muxer_name = "webm";
209 meta_mux = META_MUX_WEBM;
210 av_dict_set(&av_opts, "default_mode", "passthrough", 0);
211 break;
212
213 default:
214 {
215 hb_error("Invalid Mux %x", job->mux);
216 goto error;
217 }
218 }
219
220 ret = avformat_alloc_output_context2(&m->oc, NULL, muxer_name, job->file);
221 if (ret < 0)
222 {
223 hb_error( "Could not initialize avformat context." );
224 goto error;
225 }
226
227 ret = avio_open2(&m->oc->pb, job->file, AVIO_FLAG_WRITE,
228 &m->oc->interrupt_callback, NULL);
229 if( ret < 0 )
230 {
231 if( ret == -2 )
232 {
233 hb_error( "avio_open2 failed, errno -2: Could not write to indicated output file. Please check destination path and file permissions" );
234 }
235 else
236 hb_error( "avio_open2 failed, errno %d", ret);
237 goto error;
238 }
239
240 /* Video track */
241 track = m->tracks[m->ntracks++] = calloc(1, sizeof( hb_mux_data_t ) );
242 job->mux_data = track;
243
244 track->type = MUX_TYPE_VIDEO;
245 track->prev_chapter_tc = AV_NOPTS_VALUE;
246 track->st = avformat_new_stream(m->oc, NULL);
247 if (track->st == NULL)
248 {
249 hb_error("Could not initialize video stream");
250 goto error;
251 }
252
253 track->st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
254 track->st->time_base = m->time_base;
255
256 uint8_t *priv_data = NULL;
257 int priv_size = 0;
258 switch (job->vcodec)
259 {
260 case HB_VCODEC_X264_8BIT:
261 case HB_VCODEC_X264_10BIT:
262 case HB_VCODEC_QSV_H264:
263 track->st->codecpar->codec_id = AV_CODEC_ID_H264;
264 if (job->mux == HB_MUX_AV_MP4 && job->inline_parameter_sets)
265 {
266 track->st->codecpar->codec_tag = MKTAG('a','v','c','3');
267 }
268 else
269 {
270 track->st->codecpar->codec_tag = MKTAG('a','v','c','1');
271 }
272
273 /* Taken from x264 muxers.c */
274 priv_size = 5 + 1 + 2 + job->config.h264.sps_length + 1 + 2 +
275 job->config.h264.pps_length;
276 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
277 if (priv_data == NULL)
278 {
279 hb_error("H.264 extradata: malloc failure");
280 goto error;
281 }
282
283 priv_data[0] = 1;
284 priv_data[1] = job->config.h264.sps[1]; /* AVCProfileIndication */
285 priv_data[2] = job->config.h264.sps[2]; /* profile_compat */
286 priv_data[3] = job->config.h264.sps[3]; /* AVCLevelIndication */
287 priv_data[4] = 0xff; // nalu size length is four bytes
288 priv_data[5] = 0xe1; // one sps
289
290 priv_data[6] = job->config.h264.sps_length >> 8;
291 priv_data[7] = job->config.h264.sps_length;
292
293 memcpy(priv_data+8, job->config.h264.sps,
294 job->config.h264.sps_length);
295
296 priv_data[8+job->config.h264.sps_length] = 1; // one pps
297 priv_data[9+job->config.h264.sps_length] =
298 job->config.h264.pps_length >> 8;
299 priv_data[10+job->config.h264.sps_length] =
300 job->config.h264.pps_length;
301
302 memcpy(priv_data+11+job->config.h264.sps_length,
303 job->config.h264.pps, job->config.h264.pps_length );
304 break;
305
306 case HB_VCODEC_FFMPEG_VCE_H264:
307 case HB_VCODEC_FFMPEG_NVENC_H264:
308 case HB_VCODEC_FFMPEG_VT_H264:
309 case HB_VCODEC_FFMPEG_MF_H264:
310 track->st->codecpar->codec_id = AV_CODEC_ID_H264;
311 if (job->mux == HB_MUX_AV_MP4 && job->inline_parameter_sets)
312 {
313 track->st->codecpar->codec_tag = MKTAG('a','v','c','3');
314 }
315 else
316 {
317 track->st->codecpar->codec_tag = MKTAG('a','v','c','1');
318 }
319 if (job->config.extradata.length > 0)
320 {
321 priv_size = job->config.extradata.length;
322 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
323 if (priv_data == NULL)
324 {
325 hb_error("H.264 extradata: malloc failure");
326 goto error;
327 }
328 memcpy(priv_data,
329 job->config.extradata.bytes,
330 job->config.extradata.length);
331 }
332 break;
333
334 case HB_VCODEC_FFMPEG_MPEG4:
335 track->st->codecpar->codec_id = AV_CODEC_ID_MPEG4;
336
337 if (job->config.extradata.length > 0)
338 {
339 priv_size = job->config.extradata.length;
340 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
341 if (priv_data == NULL)
342 {
343 hb_error("MPEG-4 extradata: malloc failure");
344 goto error;
345 }
346 memcpy(priv_data,
347 job->config.extradata.bytes,
348 job->config.extradata.length);
349 }
350 break;
351
352 case HB_VCODEC_FFMPEG_MPEG2:
353 track->st->codecpar->codec_id = AV_CODEC_ID_MPEG2VIDEO;
354
355 if (job->config.extradata.length > 0)
356 {
357 priv_size = job->config.extradata.length;
358 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
359 if (priv_data == NULL)
360 {
361 hb_error("MPEG-2 extradata: malloc failure");
362 goto error;
363 }
364 memcpy(priv_data,
365 job->config.extradata.bytes,
366 job->config.extradata.length);
367 }
368 break;
369
370 case HB_VCODEC_FFMPEG_VP8:
371 track->st->codecpar->codec_id = AV_CODEC_ID_VP8;
372 priv_data = NULL;
373 priv_size = 0;
374 break;
375
376 case HB_VCODEC_FFMPEG_VP9:
377 track->st->codecpar->codec_id = AV_CODEC_ID_VP9;
378 priv_data = NULL;
379 priv_size = 0;
380 break;
381
382 case HB_VCODEC_THEORA:
383 {
384 track->st->codecpar->codec_id = AV_CODEC_ID_THEORA;
385
386 int size = 0;
387 ogg_packet *ogg_headers[3];
388
389 for (ii = 0; ii < 3; ii++)
390 {
391 ogg_headers[ii] = (ogg_packet *)job->config.theora.headers[ii];
392 size += ogg_headers[ii]->bytes + 2;
393 }
394
395 priv_size = size;
396 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
397 if (priv_data == NULL)
398 {
399 hb_error("Theora extradata: malloc failure");
400 goto error;
401 }
402
403 size = 0;
404 for(ii = 0; ii < 3; ii++)
405 {
406 AV_WB16(priv_data + size, ogg_headers[ii]->bytes);
407 size += 2;
408 memcpy(priv_data+size, ogg_headers[ii]->packet,
409 ogg_headers[ii]->bytes);
410 size += ogg_headers[ii]->bytes;
411 }
412 } break;
413
414 case HB_VCODEC_X265_8BIT:
415 case HB_VCODEC_X265_10BIT:
416 case HB_VCODEC_X265_12BIT:
417 case HB_VCODEC_X265_16BIT:
418 case HB_VCODEC_QSV_H265:
419 case HB_VCODEC_QSV_H265_10BIT:
420 track->st->codecpar->codec_id = AV_CODEC_ID_HEVC;
421 if (job->mux == HB_MUX_AV_MP4 && job->inline_parameter_sets)
422 {
423 track->st->codecpar->codec_tag = MKTAG('h','e','v','1');
424 }
425 else
426 {
427 track->st->codecpar->codec_tag = MKTAG('h','v','c','1');
428 }
429
430 if (job->config.h265.headers_length > 0)
431 {
432 priv_size = job->config.h265.headers_length;
433 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
434 if (priv_data == NULL)
435 {
436 hb_error("H.265 extradata: malloc failure");
437 goto error;
438 }
439 memcpy(priv_data, job->config.h265.headers, priv_size);
440 }
441 break;
442
443 case HB_VCODEC_FFMPEG_VCE_H265:
444 case HB_VCODEC_FFMPEG_NVENC_H265:
445 case HB_VCODEC_FFMPEG_VT_H265:
446 case HB_VCODEC_FFMPEG_VT_H265_10BIT:
447 case HB_VCODEC_FFMPEG_MF_H265:
448 track->st->codecpar->codec_id = AV_CODEC_ID_HEVC;
449 if (job->mux == HB_MUX_AV_MP4 && job->inline_parameter_sets)
450 {
451 track->st->codecpar->codec_tag = MKTAG('h','e','v','1');
452 }
453 else
454 {
455 track->st->codecpar->codec_tag = MKTAG('h','v','c','1');
456 }
457 if (job->config.extradata.length > 0)
458 {
459 priv_size = job->config.extradata.length;
460 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
461 if (priv_data == NULL)
462 {
463 hb_error("H.265 extradata: malloc failure");
464 goto error;
465 }
466 memcpy(priv_data,
467 job->config.extradata.bytes,
468 job->config.extradata.length);
469 }
470 break;
471
472 default:
473 hb_error("muxavformat: Unknown video codec: %x", job->vcodec);
474 goto error;
475 }
476 track->st->codecpar->extradata = priv_data;
477 track->st->codecpar->extradata_size = priv_size;
478
479 track->st->sample_aspect_ratio.num = job->par.num;
480 track->st->sample_aspect_ratio.den = job->par.den;
481 track->st->codecpar->sample_aspect_ratio.num = job->par.num;
482 track->st->codecpar->sample_aspect_ratio.den = job->par.den;
483 track->st->codecpar->width = job->width;
484 track->st->codecpar->height = job->height;
485 track->st->disposition |= AV_DISPOSITION_DEFAULT;
486
487 track->st->codecpar->color_primaries = hb_output_color_prim(job);
488 track->st->codecpar->color_trc = hb_output_color_transfer(job);
489 track->st->codecpar->color_space = hb_output_color_matrix(job);
490 track->st->codecpar->color_range = job->color_range;
491
492 if (job->color_transfer == HB_COLR_TRA_SMPTEST2084)
493 {
494 if (job->mastering.has_primaries || job->mastering.has_luminance)
495 {
496 AVMasteringDisplayMetadata mastering = hb_mastering_hb_to_ff(job->mastering);
497
498 uint8_t *mastering_data = av_malloc(sizeof(AVMasteringDisplayMetadata));
499 memcpy(mastering_data, &mastering, sizeof(AVMasteringDisplayMetadata));
500
501 av_stream_add_side_data(track->st,
502 AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
503 mastering_data,
504 sizeof(AVMasteringDisplayMetadata));
505 }
506
507 if (job->coll.max_cll && job->coll.max_fall)
508 {
509 AVContentLightMetadata coll;
510 coll.MaxCLL = job->coll.max_cll;
511 coll.MaxFALL = job->coll.max_fall;
512
513 uint8_t *coll_data = av_malloc(sizeof(AVContentLightMetadata));
514 memcpy(coll_data, &coll, sizeof(AVContentLightMetadata));
515
516 av_stream_add_side_data(track->st,
517 AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
518 coll_data,
519 sizeof(AVContentLightMetadata));
520 }
521 }
522
523 hb_rational_t vrate = job->vrate;
524
525 // If the vrate is the internal clock rate, there's a good chance
526 // this is a standard rate that we have in our hb_video_rates table.
527 // Because of rounding errors and approximations made while
528 // measuring framerate, the actual value may not be exact. So
529 // we look for rates that are "close" and make an adjustment
530 // to fps.den.
531 if (vrate.num == clock)
532 {
533 const hb_rate_t *video_framerate = NULL;
534 while ((video_framerate = hb_video_framerate_get_next(video_framerate)) != NULL)
535 {
536 if (abs(vrate.den - video_framerate->rate) < 10)
537 {
538 vrate.den = video_framerate->rate;
539 break;
540 }
541 }
542 }
543 hb_reduce(&vrate.num, &vrate.den, vrate.num, vrate.den);
544 track->st->avg_frame_rate.num = vrate.num;
545 track->st->avg_frame_rate.den = vrate.den;
546
547 /* add the audio tracks */
548 for(ii = 0; ii < hb_list_count( job->list_audio ); ii++ )
549 {
550 audio = hb_list_item( job->list_audio, ii );
551 track = m->tracks[m->ntracks++] = calloc(1, sizeof( hb_mux_data_t ) );
552 audio->priv.mux_data = track;
553
554 track->type = MUX_TYPE_AUDIO;
555
556 track->st = avformat_new_stream(m->oc, NULL);
557 if (track->st == NULL)
558 {
559 hb_error("Could not initialize audio stream");
560 goto error;
561 }
562
563 track->st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
564 track->st->codecpar->initial_padding = audio->priv.config.init_delay *
565 audio->config.out.samplerate / 90000;
566 track->st->codecpar->frame_size = audio->config.out.samples_per_frame;
567 if (job->mux == HB_MUX_AV_MP4)
568 {
569 track->st->time_base.num = 1;
570 track->st->time_base.den = audio->config.out.samplerate;
571 }
572 else
573 {
574 track->st->time_base = m->time_base;
575 }
576
577 priv_data = NULL;
578 priv_size = 0;
579 switch (audio->config.out.codec & HB_ACODEC_MASK)
580 {
581 case HB_ACODEC_DCA:
582 case HB_ACODEC_DCA_HD:
583 track->st->codecpar->codec_id = AV_CODEC_ID_DTS;
584 break;
585 case HB_ACODEC_AC3:
586 track->st->codecpar->codec_id = AV_CODEC_ID_AC3;
587 break;
588 case HB_ACODEC_FFEAC3:
589 track->st->codecpar->codec_id = AV_CODEC_ID_EAC3;
590 break;
591 case HB_ACODEC_FFTRUEHD:
592 track->st->codecpar->codec_id = AV_CODEC_ID_TRUEHD;
593 break;
594 case HB_ACODEC_MP2:
595 track->st->codecpar->codec_id = AV_CODEC_ID_MP2;
596 break;
597 case HB_ACODEC_LAME:
598 case HB_ACODEC_MP3:
599 track->st->codecpar->codec_id = AV_CODEC_ID_MP3;
600 break;
601 case HB_ACODEC_VORBIS:
602 {
603 track->st->codecpar->codec_id = AV_CODEC_ID_VORBIS;
604
605 int jj, size = 0;
606 ogg_packet *ogg_headers[3];
607
608 for (jj = 0; jj < 3; jj++)
609 {
610 ogg_headers[jj] = (ogg_packet *)audio->priv.config.vorbis.headers[jj];
611 size += ogg_headers[jj]->bytes + 2;
612 }
613
614 priv_size = size;
615 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
616 if (priv_data == NULL)
617 {
618 hb_error("Vorbis extradata: malloc failure");
619 goto error;
620 }
621
622 size = 0;
623 for(jj = 0; jj < 3; jj++)
624 {
625 AV_WB16(priv_data + size, ogg_headers[jj]->bytes);
626 size += 2;
627 memcpy(priv_data+size, ogg_headers[jj]->packet,
628 ogg_headers[jj]->bytes);
629 size += ogg_headers[jj]->bytes;
630 }
631 } break;
632 case HB_ACODEC_OPUS:
633 track->st->codecpar->codec_id = AV_CODEC_ID_OPUS;
634
635 if (audio->priv.config.extradata.length)
636 {
637 priv_size = audio->priv.config.extradata.length;
638 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
639 if (priv_data == NULL)
640 {
641 hb_error("OPUS extradata: malloc failure");
642 goto error;
643 }
644 memcpy(priv_data,
645 audio->priv.config.extradata.bytes,
646 audio->priv.config.extradata.length);
647 }
648 break;
649 case HB_ACODEC_FFFLAC:
650 case HB_ACODEC_FFFLAC24:
651 track->st->codecpar->codec_id = AV_CODEC_ID_FLAC;
652
653 if (audio->priv.config.extradata.length)
654 {
655 priv_size = audio->priv.config.extradata.length;
656 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
657 if (priv_data == NULL)
658 {
659 hb_error("FLAC extradata: malloc failure");
660 goto error;
661 }
662 memcpy(priv_data,
663 audio->priv.config.extradata.bytes,
664 audio->priv.config.extradata.length);
665 }
666 break;
667 case HB_ACODEC_FFAAC:
668 case HB_ACODEC_CA_AAC:
669 case HB_ACODEC_CA_HAAC:
670 case HB_ACODEC_FDK_AAC:
671 case HB_ACODEC_FDK_HAAC:
672 track->st->codecpar->codec_id = AV_CODEC_ID_AAC;
673
674 // libav mkv muxer expects there to be extradata for
675 // AAC and will crash if it is NULL.
676 //
677 // Also, libav can over-read the buffer by up to 8 bytes
678 // when it fills it's get_bits cache.
679 //
680 // So allocate extra bytes
681 priv_size = audio->priv.config.extradata.length;
682 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
683 if (priv_data == NULL)
684 {
685 hb_error("AAC extradata: malloc failure");
686 goto error;
687 }
688 memcpy(priv_data,
689 audio->priv.config.extradata.bytes,
690 audio->priv.config.extradata.length);
691
692 // AAC from pass-through source may be ADTS.
693 // Therefore inserting "aac_adtstoasc" bitstream filter is
694 // preferred.
695 // The filter does nothing for non-ADTS bitstream.
696 if (audio->config.out.codec == HB_ACODEC_AAC_PASS)
697 {
698 const AVBitStreamFilter * bsf;
699 AVBSFContext * ctx;
700 int ret;
701
702 bsf = av_bsf_get_by_name("aac_adtstoasc");
703 ret = av_bsf_alloc(bsf, &ctx);
704 if (ret < 0)
705 {
706 hb_error("AAC bitstream filter: alloc failure");
707 goto error;
708 }
709 ctx->time_base_in.num = 1;
710 ctx->time_base_in.den = audio->config.out.samplerate;
711 track->bitstream_context = ctx;
712 }
713 break;
714 default:
715 hb_error("muxavformat: Unknown audio codec: %x",
716 audio->config.out.codec);
717 goto error;
718 }
719 track->st->codecpar->extradata = priv_data;
720 track->st->codecpar->extradata_size = priv_size;
721 if (track->bitstream_context != NULL)
722 {
723 int ret;
724
725 avcodec_parameters_copy(track->bitstream_context->par_in,
726 track->st->codecpar);
727 ret = av_bsf_init(track->bitstream_context);
728 if (ret < 0)
729 {
730 hb_error("bitstream filter: init failure");
731 goto error;
732 }
733 }
734
735 if( default_track_flag )
736 {
737 track->st->disposition |= AV_DISPOSITION_DEFAULT;
738 default_track_flag = 0;
739 }
740
741 lang = lookup_lang_code(job->mux, audio->config.lang.iso639_2 );
742 if (lang != NULL)
743 {
744 av_dict_set(&track->st->metadata, "language", lang, 0);
745 }
746 track->st->codecpar->sample_rate = audio->config.out.samplerate;
747 if (audio->config.out.codec & HB_ACODEC_PASS_FLAG)
748 {
749 track->st->codecpar->channels = av_get_channel_layout_nb_channels(audio->config.in.channel_layout);
750 track->st->codecpar->channel_layout = audio->config.in.channel_layout;
751 }
752 else
753 {
754 track->st->codecpar->channels = hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown);
755 track->st->codecpar->channel_layout = hb_ff_mixdown_xlat(audio->config.out.mixdown, NULL);
756 }
757
758 const char *name;
759 if (audio->config.out.name == NULL)
760 {
761 switch (track->st->codecpar->channels)
762 {
763 case 1:
764 name = "Mono";
765 break;
766
767 case 2:
768 name = "Stereo";
769 break;
770
771 default:
772 name = "Surround";
773 break;
774 }
775 }
776 else
777 {
778 name = audio->config.out.name;
779 }
780 // Set audio track title
781 av_dict_set(&track->st->metadata, "title", name, 0);
782 if (job->mux == HB_MUX_AV_MP4)
783 {
784 // Some software (MPC, mediainfo) use hdlr description
785 // for track title
786 av_dict_set(&track->st->metadata, "handler_name", name, 0);
787 }
788 }
789
790 // Check for audio track associations
791 for (ii = 0; ii < hb_list_count(job->list_audio); ii++)
792 {
793 audio = hb_list_item(job->list_audio, ii);
794 switch (audio->config.out.codec & HB_ACODEC_MASK)
795 {
796 case HB_ACODEC_FFAAC:
797 case HB_ACODEC_CA_AAC:
798 case HB_ACODEC_CA_HAAC:
799 case HB_ACODEC_FDK_AAC:
800 case HB_ACODEC_FDK_HAAC:
801 break;
802
803 default:
804 {
805 // Mark associated fallback audio tracks for any non-aac track
806 for(jj = 0; jj < hb_list_count( job->list_audio ); jj++ )
807 {
808 hb_audio_t * fallback;
809 int codec;
810
811 if (ii == jj) continue;
812
813 fallback = hb_list_item( job->list_audio, jj );
814 codec = fallback->config.out.codec & HB_ACODEC_MASK;
815 if (fallback->config.in.track == audio->config.in.track &&
816 (codec == HB_ACODEC_FFAAC ||
817 codec == HB_ACODEC_CA_AAC ||
818 codec == HB_ACODEC_CA_HAAC ||
819 codec == HB_ACODEC_FDK_AAC ||
820 codec == HB_ACODEC_FDK_HAAC))
821 {
822 hb_mux_data_t * fallback_track;
823 int * sd;
824
825 track = audio->priv.mux_data;
826 fallback_track = fallback->priv.mux_data;
827 sd = (int*)av_stream_new_side_data(track->st,
828 AV_PKT_DATA_FALLBACK_TRACK,
829 sizeof(int));
830 if (sd != NULL)
831 {
832 *sd = fallback_track->st->index;
833 }
834 }
835 }
836 } break;
837 }
838 }
839
840 char * subidx_fmt =
841 "size: %dx%d\n"
842 "org: %d, %d\n"
843 "scale: 100%%, 100%%\n"
844 "alpha: 100%%\n"
845 "smooth: OFF\n"
846 "fadein/out: 50, 50\n"
847 "align: OFF at LEFT TOP\n"
848 "time offset: 0\n"
849 "forced subs: %s\n"
850 "palette: %06x, %06x, %06x, %06x, %06x, %06x, "
851 "%06x, %06x, %06x, %06x, %06x, %06x, %06x, %06x, %06x, %06x\n"
852 "custom colors: OFF, tridx: 0000, "
853 "colors: 000000, 000000, 000000, 000000\n";
854
855 int subtitle_default = -1;
856 for( ii = 0; ii < hb_list_count( job->list_subtitle ); ii++ )
857 {
858 hb_subtitle_t *subtitle = hb_list_item( job->list_subtitle, ii );
859
860 if( subtitle->config.dest == PASSTHRUSUB )
861 {
862 if ( subtitle->config.default_track )
863 subtitle_default = ii;
864 }
865 }
866 // Quicktime requires that at least one subtitle is enabled,
867 // else it doesn't show any of the subtitles.
868 // So check to see if any of the subtitles are flagged to be
869 // the default. The default will be the enabled track, else
870 // enable the first track.
871 if (job->mux == HB_MUX_AV_MP4 && subtitle_default == -1)
872 {
873 subtitle_default = 0;
874 }
875
876 for( ii = 0; ii < hb_list_count( job->list_subtitle ); ii++ )
877 {
878 hb_subtitle_t * subtitle;
879 uint32_t rgb[16];
880 char subidx[2048];
881 int len;
882
883 subtitle = hb_list_item( job->list_subtitle, ii );
884 if (subtitle->config.dest != PASSTHRUSUB)
885 continue;
886
887 track = m->tracks[m->ntracks++] = calloc(1, sizeof( hb_mux_data_t ) );
888 subtitle->mux_data = track;
889
890 track->type = MUX_TYPE_SUBTITLE;
891 track->st = avformat_new_stream(m->oc, NULL);
892 if (track->st == NULL)
893 {
894 hb_error("Could not initialize subtitle stream");
895 goto error;
896 }
897
898 track->st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
899 track->st->time_base = m->time_base;
900 track->st->codecpar->width = subtitle->width;
901 track->st->codecpar->height = subtitle->height;
902
903 priv_data = NULL;
904 priv_size = 0;
905 switch (subtitle->source)
906 {
907 case VOBSUB:
908 {
909 int jj;
910 track->st->codecpar->codec_id = AV_CODEC_ID_DVD_SUBTITLE;
911
912 for (jj = 0; jj < 16; jj++)
913 rgb[jj] = hb_yuv2rgb(subtitle->palette[jj]);
914 len = snprintf(subidx, 2048, subidx_fmt,
915 subtitle->width, subtitle->height,
916 0, 0, "OFF",
917 rgb[0], rgb[1], rgb[2], rgb[3],
918 rgb[4], rgb[5], rgb[6], rgb[7],
919 rgb[8], rgb[9], rgb[10], rgb[11],
920 rgb[12], rgb[13], rgb[14], rgb[15]);
921
922 priv_size = len + 1;
923 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
924 if (priv_data == NULL)
925 {
926 hb_error("VOBSUB extradata: malloc failure");
927 goto error;
928 }
929 memcpy(priv_data, subidx, priv_size);
930 } break;
931
932 case PGSSUB:
933 {
934 track->st->codecpar->codec_id = AV_CODEC_ID_HDMV_PGS_SUBTITLE;
935 } break;
936
937 case DVBSUB:
938 {
939 track->st->codecpar->codec_id = AV_CODEC_ID_DVB_SUBTITLE;
940 if (subtitle->extradata != NULL)
941 {
942 priv_size = subtitle->extradata_size;
943 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
944 memcpy(priv_data, subtitle->extradata, priv_size);
945 }
946 } break;
947
948 case CC608SUB:
949 case CC708SUB:
950 case TX3GSUB:
951 case UTF8SUB:
952 case SSASUB:
953 case IMPORTSRT:
954 case IMPORTSSA:
955 {
956 if (job->mux == HB_MUX_AV_MP4)
957 {
958 track->st->codecpar->codec_id = AV_CODEC_ID_MOV_TEXT;
959 track->tx3g = hb_tx3g_style_init(
960 job->height, (char*)subtitle->extradata);
961 }
962 else
963 {
964 track->st->codecpar->codec_id = AV_CODEC_ID_ASS;
965 need_fonts = 1;
966
967 if (subtitle->extradata_size)
968 {
969 priv_size = subtitle->extradata_size;
970 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
971 if (priv_data == NULL)
972 {
973 hb_error("SSA extradata: malloc failure");
974 goto error;
975 }
976 memcpy(priv_data, subtitle->extradata, priv_size);
977 }
978 }
979 } break;
980
981 default:
982 continue;
983 }
984 if (track->st->codecpar->codec_id == AV_CODEC_ID_MOV_TEXT)
985 {
986 // Build codec extradata for tx3g.
987 // If we were using a libav codec to generate this data
988 // this would (or should) be done for us.
989 uint8_t properties[] = {
990 0x00, 0x00, 0x00, 0x00, // Display Flags
991 0x01, // Horiz. Justification
992 0xff, // Vert. Justification
993 0x00, 0x00, 0x00, 0xff, // Bg color
994 0x00, 0x00, 0x00, 0x00, // Default text box
995 0x00, 0x00, 0x00, 0x00,
996 0x00, 0x00, 0x00, 0x00, // Reserved
997 0x00, 0x01, // Font ID
998 0x00, // Font face
999 0x18, // Font size
1000 0xff, 0xff, 0xff, 0xff, // Fg color
1001 // Font table:
1002 0x00, 0x00, 0x00, 0x12, // Font table size
1003 'f','t','a','b', // Tag
1004 0x00, 0x01, // Count
1005 0x00, 0x01, // Font ID
1006 0x05, // Font name length
1007 'A','r','i','a','l' // Font name
1008 };
1009
1010 int width, height, font_size;
1011 width = job->width * job->par.num / job->par.den;
1012 font_size = 0.05 * job->height;
1013 if (font_size < 12)
1014 {
1015 font_size = 12;
1016 }
1017 else if (font_size > 255)
1018 {
1019 font_size = 255;
1020 }
1021 properties[25] = font_size;
1022 height = 3 * font_size;
1023 track->st->codecpar->width = width;
1024 track->st->codecpar->height = height;
1025 properties[14] = height >> 8;
1026 properties[15] = height & 0xff;
1027 properties[16] = width >> 8;
1028 properties[17] = width & 0xff;
1029
1030 priv_size = sizeof(properties);
1031 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
1032 if (priv_data == NULL)
1033 {
1034 hb_error("TX3G extradata: malloc failure");
1035 goto error;
1036 }
1037 memcpy(priv_data, properties, priv_size);
1038 }
1039 track->st->codecpar->extradata = priv_data;
1040 track->st->codecpar->extradata_size = priv_size;
1041
1042 if (ii == subtitle_default)
1043 {
1044 track->st->disposition |= AV_DISPOSITION_DEFAULT;
1045 }
1046 if (subtitle->config.default_track)
1047 {
1048 track->st->disposition |= AV_DISPOSITION_FORCED;
1049 }
1050
1051 lang = lookup_lang_code(job->mux, subtitle->iso639_2 );
1052 if (lang != NULL)
1053 {
1054 av_dict_set(&track->st->metadata, "language", lang, 0);
1055 }
1056 if (subtitle->config.name != NULL && subtitle->config.name[0] != 0)
1057 {
1058 // Set subtitle track title
1059 av_dict_set(&track->st->metadata, "title",
1060 subtitle->config.name, 0);
1061 if (job->mux == HB_MUX_AV_MP4)
1062 {
1063 // Some software (MPC, mediainfo) use hdlr description
1064 // for track title
1065 av_dict_set(&track->st->metadata, "handler_name",
1066 subtitle->config.name, 0);
1067 }
1068 }
1069 }
1070
1071 if (need_fonts)
1072 {
1073 hb_list_t * list_attachment = job->list_attachment;
1074 int i;
1075 for ( i = 0; i < hb_list_count(list_attachment); i++ )
1076 {
1077 hb_attachment_t * attachment = hb_list_item( list_attachment, i );
1078
1079 if ((attachment->type == FONT_TTF_ATTACH || attachment->type == FONT_OTF_ATTACH) &&
1080 attachment->size > 0)
1081 {
1082 AVStream *st = avformat_new_stream(m->oc, NULL);
1083 if (st == NULL)
1084 {
1085 hb_error("Could not initialize attachment stream");
1086 goto error;
1087 }
1088
1089 st->codecpar->codec_type = AVMEDIA_TYPE_ATTACHMENT;
1090 if (attachment->type == FONT_TTF_ATTACH)
1091 {
1092 st->codecpar->codec_id = AV_CODEC_ID_TTF;
1093 }
1094 else if (attachment->type == FONT_OTF_ATTACH)
1095 {
1096 st->codecpar->codec_id = MKBETAG( 0 ,'O','T','F');
1097 av_dict_set(&st->metadata, "mimetype", "application/vnd.ms-opentype", 0);
1098 }
1099
1100 priv_size = attachment->size;
1101 priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE);
1102 if (priv_data == NULL)
1103 {
1104 hb_error("Font extradata: malloc failure");
1105 goto error;
1106 }
1107 memcpy(priv_data, attachment->data, priv_size);
1108
1109 st->codecpar->extradata = priv_data;
1110 st->codecpar->extradata_size = priv_size;
1111
1112 av_dict_set(&st->metadata, "filename", attachment->name, 0);
1113 }
1114 }
1115 }
1116
1117 if( job->metadata && job->metadata->dict )
1118 {
1119 hb_deep_log(2, "Writing Metadata to output file...");
1120 hb_dict_iter_t iter = hb_dict_iter_init(job->metadata->dict);
1121
1122 while (iter != HB_DICT_ITER_DONE)
1123 {
1124 const char * key;
1125 hb_value_t * val;
1126
1127 hb_dict_iter_next_ex(job->metadata->dict, &iter, &key, &val);
1128 if (key != NULL && val != NULL)
1129 {
1130 const char * str = hb_value_get_string(val);
1131
1132 if (str != NULL)
1133 {
1134 const char * mux_key = lookup_meta_mux_key(meta_mux, key);
1135
1136 if (mux_key != NULL)
1137 {
1138 av_dict_set(&m->oc->metadata, mux_key, str, 0);
1139 }
1140 }
1141 }
1142 }
1143 }
1144
1145 char tool_string[80];
1146 snprintf(tool_string, sizeof(tool_string), "HandBrake %s %i",
1147 HB_PROJECT_VERSION, HB_PROJECT_BUILD);
1148 av_dict_set(&m->oc->metadata, "encoding_tool", tool_string, 0);
1149 time_t now = time(NULL);
1150 struct tm * now_utc = gmtime(&now);
1151 char now_8601[24];
1152 strftime(now_8601, sizeof(now_8601), "%Y-%m-%dT%H:%M:%SZ", now_utc);
1153 av_dict_set(&m->oc->metadata, "creation_time", now_8601, 0);
1154
1155 ret = avformat_write_header(m->oc, &av_opts);
1156 if( ret < 0 )
1157 {
1158 av_dict_free( &av_opts );
1159 hb_error( "muxavformat: avformat_write_header failed!");
1160 goto error;
1161 }
1162
1163 AVDictionaryEntry *t = NULL;
1164 while( ( t = av_dict_get( av_opts, "", t, AV_DICT_IGNORE_SUFFIX ) ) )
1165 {
1166 hb_log( "muxavformat: Unknown option %s", t->key );
1167 }
1168 av_dict_free( &av_opts );
1169
1170 return 0;
1171
1172 error:
1173 free(job->mux_data);
1174 job->mux_data = NULL;
1175 avformat_free_context(m->oc);
1176 *job->done_error = HB_ERROR_INIT;
1177 *job->die = 1;
1178 return -1;
1179 }
1180
add_chapter(hb_mux_object_t * m,int64_t start,int64_t end,char * title)1181 static int add_chapter(hb_mux_object_t *m, int64_t start, int64_t end, char * title)
1182 {
1183 AVChapter *chap;
1184 AVChapter **chapters;
1185 int nchap = m->oc->nb_chapters;
1186
1187 nchap++;
1188 chapters = av_realloc(m->oc->chapters, nchap * sizeof(AVChapter*));
1189 if (chapters == NULL)
1190 {
1191 hb_error("chapter array: malloc failure");
1192 return -1;
1193 }
1194
1195 chap = av_mallocz(sizeof(AVChapter));
1196 if (chap == NULL)
1197 {
1198 hb_error("chapter: malloc failure");
1199 return -1;
1200 }
1201
1202 m->oc->chapters = chapters;
1203 m->oc->chapters[nchap-1] = chap;
1204 m->oc->nb_chapters = nchap;
1205
1206 chap->id = nchap;
1207 chap->time_base = m->time_base;
1208 // libav does not currently have a good way to deal with chapters and
1209 // delayed stream timestamps. It makes no corrections to the chapter
1210 // track. A patch to libav would touch a lot of things, so for now,
1211 // work around the issue here.
1212 chap->start = start;
1213 chap->end = end;
1214 av_dict_set(&chap->metadata, "title", title, 0);
1215
1216 return 0;
1217 }
1218
avformatMux(hb_mux_object_t * m,hb_mux_data_t * track,hb_buffer_t * buf)1219 static int avformatMux(hb_mux_object_t *m, hb_mux_data_t *track, hb_buffer_t *buf)
1220 {
1221 int64_t dts, pts, duration = AV_NOPTS_VALUE;
1222 hb_job_t * job = m->job;
1223 uint8_t * sub_out = NULL;
1224
1225 if (track->type == MUX_TYPE_VIDEO && (job->mux & HB_MUX_MASK_MP4))
1226 {
1227 // compute dts duration for MP4 files
1228 hb_buffer_t * tmp;
1229
1230 // delay by one frame so that we can compute duration properly.
1231 tmp = track->delay_buf;
1232 track->delay_buf = buf;
1233 buf = tmp;
1234 }
1235 if (buf == NULL)
1236 {
1237 if (job->mux == HB_MUX_AV_MP4 && track->type == MUX_TYPE_SUBTITLE)
1238 {
1239 // Write a final "empty" subtitle to terminate the last
1240 // subtitle that was written
1241 if (track->duration > 0)
1242 {
1243 uint8_t empty[2] = {0,0};
1244
1245 m->empty_pkt->data = empty;
1246 m->empty_pkt->size = 2;
1247 m->empty_pkt->dts = track->duration;
1248 m->empty_pkt->pts = track->duration;
1249 m->empty_pkt->duration = 90;
1250 m->empty_pkt->stream_index = track->st->index;
1251 av_interleaved_write_frame(m->oc, m->empty_pkt);
1252 av_packet_unref(m->empty_pkt);
1253 }
1254 }
1255 return 0;
1256 }
1257
1258 if (track->type == MUX_TYPE_VIDEO &&
1259 (job->mux & (HB_MUX_MASK_MKV | HB_MUX_MASK_WEBM)) &&
1260 buf->s.renderOffset < 0)
1261 {
1262 // libav matroska muxer doesn't write dts to the output, but
1263 // if it sees a negative dts, it applies an offset to both pts
1264 // and dts to make it positive. This offset breaks chapter
1265 // start times and A/V sync. libav also requires that dts is
1266 // "monotonically increasing", which means it last_dts <= next_dts.
1267 // It also uses dts to determine track interleaving, so we need
1268 // to provide some reasonable dts value.
1269 // So when renderOffset < 0, set to 0 for mkv.
1270 buf->s.renderOffset = 0;
1271 // Note: for MP4, libav allows negative dts and creates an edts
1272 // (edit list) entry in this case.
1273 }
1274 if (buf->s.renderOffset == AV_NOPTS_VALUE)
1275 {
1276 dts = av_rescale_q(buf->s.start, (AVRational){1,90000},
1277 track->st->time_base);
1278 }
1279 else
1280 {
1281 dts = av_rescale_q(buf->s.renderOffset, (AVRational){1,90000},
1282 track->st->time_base);
1283 }
1284
1285 pts = av_rescale_q(buf->s.start, (AVRational){1,90000},
1286 track->st->time_base);
1287
1288 if (track->type == MUX_TYPE_VIDEO && track->delay_buf != NULL)
1289 {
1290 int64_t delayed_dts;
1291 delayed_dts = av_rescale_q(track->delay_buf->s.renderOffset,
1292 (AVRational){1,90000},
1293 track->st->time_base);
1294 duration = delayed_dts - dts;
1295 }
1296 if (duration < 0 && buf->s.duration > 0)
1297 {
1298 duration = av_rescale_q(buf->s.duration, (AVRational){1,90000},
1299 track->st->time_base);
1300 }
1301 if (duration < 0)
1302 {
1303 // There is a possibility that some subtitles get through the pipeline
1304 // without ever discovering their true duration. Make the duration
1305 // 10 seconds in this case. Unless they are PGS subs which should
1306 // have zero duration.
1307 if (track->type == MUX_TYPE_SUBTITLE &&
1308 track->st->codecpar->codec_id != AV_CODEC_ID_HDMV_PGS_SUBTITLE)
1309 {
1310 duration = av_rescale_q(10, (AVRational){1,1},
1311 track->st->time_base);
1312 }
1313 else if (track->type == MUX_TYPE_VIDEO)
1314 {
1315 duration = av_rescale_q(
1316 (int64_t)job->vrate.den * 90000 / job->vrate.num,
1317 (AVRational){1,90000}, track->st->time_base);
1318 }
1319 else
1320 {
1321 duration = 0;
1322 }
1323 }
1324
1325 m->pkt->data = buf->data;
1326 m->pkt->size = buf->size;
1327 m->pkt->dts = dts;
1328 m->pkt->pts = pts;
1329 m->pkt->duration = duration;
1330
1331 if (track->type == MUX_TYPE_VIDEO)
1332 {
1333 if ((buf->s.frametype == HB_FRAME_IDR) ||
1334 (buf->s.flags & HB_FLAG_FRAMETYPE_KEY))
1335 {
1336 m->pkt->flags |= AV_PKT_FLAG_KEY;
1337 }
1338 #ifdef AV_PKT_FLAG_DISPOSABLE
1339 if (!(buf->s.flags & HB_FLAG_FRAMETYPE_REF))
1340 {
1341 m->pkt->flags |= AV_PKT_FLAG_DISPOSABLE;
1342 }
1343 #endif
1344 }
1345 else if (buf->s.frametype & HB_FRAME_MASK_KEY)
1346 {
1347 m->pkt->flags |= AV_PKT_FLAG_KEY;
1348 }
1349
1350 switch (track->type)
1351 {
1352 case MUX_TYPE_VIDEO:
1353 {
1354 if (job->chapter_markers && buf->s.new_chap)
1355 {
1356 if (track->current_chapter > 0)
1357 {
1358 hb_chapter_t *chapter;
1359
1360 // reached chapter N, write marker for chapter N-1
1361 // we don't know the end time of chapter N-1 till we receive
1362 // chapter N. So we are always writing the previous chapter
1363 // mark.
1364 // chapter numbers start at 1, but the list starts at 0
1365 chapter = hb_list_item(job->list_chapter,
1366 track->current_chapter - 1);
1367
1368 // make sure we're not writing a chapter that has 0 length
1369 if (chapter != NULL &&
1370 track->prev_chapter_tc != AV_NOPTS_VALUE &&
1371 track->prev_chapter_tc < m->pkt->pts)
1372 {
1373 char title[1024];
1374 if (chapter->title != NULL)
1375 {
1376 snprintf(title, 1023, "%s", chapter->title);
1377 }
1378 else
1379 {
1380 snprintf(title, 1023, "Chapter %d",
1381 track->current_chapter);
1382 }
1383 add_chapter(m, track->prev_chapter_tc, m->pkt->pts, title);
1384 }
1385 }
1386 track->current_chapter = buf->s.new_chap;
1387 track->prev_chapter_tc = m->pkt->pts;
1388 }
1389 } break;
1390
1391 case MUX_TYPE_SUBTITLE:
1392 {
1393 if (job->mux == HB_MUX_AV_MP4)
1394 {
1395 /* Write an empty sample */
1396 if ( track->duration < pts )
1397 {
1398 uint8_t empty[2] = {0,0};
1399
1400 m->empty_pkt->data = empty;
1401 m->empty_pkt->size = 2;
1402 m->empty_pkt->dts = track->duration;
1403 m->empty_pkt->pts = track->duration;
1404 m->empty_pkt->duration = pts - track->duration;
1405 m->empty_pkt->stream_index = track->st->index;
1406 int ret = av_interleaved_write_frame(m->oc, m->empty_pkt);
1407 av_packet_unref(m->empty_pkt);
1408 if (ret < 0)
1409 {
1410 char errstr[64];
1411 av_strerror(ret, errstr, sizeof(errstr));
1412 hb_error("avformatMux: track %d, av_interleaved_write_frame failed with error '%s' (empty_pkt)",
1413 track->st->index, errstr);
1414 *job->done_error = HB_ERROR_UNKNOWN;
1415 *job->die = 1;
1416 return -1;
1417 }
1418 }
1419 if (track->st->codecpar->codec_id == AV_CODEC_ID_MOV_TEXT)
1420 {
1421 uint8_t * styleatom;
1422 uint16_t stylesize = 0;
1423 uint8_t * buffer;
1424 uint16_t buffersize = 0;
1425
1426 /*
1427 * Copy the subtitle into buffer stripping markup and
1428 * creating style atoms for them.
1429 */
1430 hb_muxmp4_process_subtitle_style(
1431 track->tx3g, buf->data, &buffer,
1432 &styleatom, &stylesize);
1433
1434 if (buffer != NULL)
1435 {
1436 buffersize = strlen((char*)buffer);
1437 if (styleatom == NULL)
1438 {
1439 stylesize = 0;
1440 }
1441 sub_out = malloc(2 + buffersize + stylesize);
1442
1443 /* Write the subtitle sample */
1444 memcpy(sub_out + 2, buffer, buffersize);
1445 memcpy(sub_out + 2 + buffersize, styleatom, stylesize);
1446 sub_out[0] = (buffersize >> 8) & 0xff;
1447 sub_out[1] = buffersize & 0xff;
1448 m->pkt->data = sub_out;
1449 m->pkt->size = buffersize + stylesize + 2;
1450 }
1451 free(buffer);
1452 free(styleatom);
1453 }
1454 }
1455 if (m->pkt->data == NULL)
1456 {
1457 // Memory allocation failure!
1458 hb_error("avformatMux: subtitle memory allocation failure");
1459 *job->done_error = HB_ERROR_UNKNOWN;
1460 *job->die = 1;
1461 return -1;
1462 }
1463 } break;
1464 case MUX_TYPE_AUDIO:
1465 default:
1466 break;
1467 }
1468 track->duration = pts + m->pkt->duration;
1469
1470 if (track->bitstream_context)
1471 {
1472 int ret;
1473 ret = av_bsf_send_packet(track->bitstream_context, m->pkt);
1474 if (ret < 0)
1475 {
1476 hb_error("avformatMux: track %d av_bsf_send_packet failed",
1477 track->st->index);
1478 return ret;
1479 }
1480 ret = av_bsf_receive_packet(track->bitstream_context, m->pkt);
1481 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
1482 {
1483 return 0;
1484 }
1485 else if (ret < 0)
1486 {
1487 hb_error("avformatMux: track %d av_bsf_receive_packet failed",
1488 track->st->index);
1489 return ret;
1490 }
1491 }
1492
1493 m->pkt->stream_index = track->st->index;
1494 int ret = av_interleaved_write_frame(m->oc, m->pkt);
1495 av_packet_unref(m->pkt);
1496 if (sub_out != NULL)
1497 {
1498 free(sub_out);
1499 }
1500 // Many avformat muxer functions do not check the error status
1501 // of the AVIOContext. So we need to check it ourselves to detect
1502 // write errors (like disk full condition).
1503 if (ret < 0 || m->oc->pb->error != 0)
1504 {
1505 char errstr[64];
1506 av_strerror(ret < 0 ? ret : m->oc->pb->error, errstr, sizeof(errstr));
1507 hb_error("avformatMux: track %d, av_interleaved_write_frame failed with error '%s'",
1508 track->st->index, errstr);
1509 *job->done_error = HB_ERROR_UNKNOWN;
1510 *job->die = 1;
1511 return -1;
1512 }
1513
1514 hb_buffer_close( &buf );
1515 return 0;
1516 }
1517
avformatEnd(hb_mux_object_t * m)1518 static int avformatEnd(hb_mux_object_t *m)
1519 {
1520 hb_job_t *job = m->job;
1521 hb_mux_data_t *track = job->mux_data;
1522
1523 if( !job->mux_data )
1524 {
1525 /*
1526 * We must have failed to create the file in the first place.
1527 */
1528 return 0;
1529 }
1530
1531 // Flush any delayed frames
1532 int ii;
1533 for (ii = 0; ii < m->ntracks; ii++)
1534 {
1535 avformatMux(m, m->tracks[ii], NULL);
1536
1537 if (m->tracks[ii]->bitstream_context)
1538 {
1539 av_bsf_free(&m->tracks[ii]->bitstream_context);
1540 }
1541 if (m->tracks[ii]->tx3g)
1542 {
1543 hb_tx3g_style_close(&m->tracks[ii]->tx3g);
1544 }
1545 }
1546
1547 if (job->chapter_markers)
1548 {
1549 hb_chapter_t *chapter;
1550
1551 // get the last chapter
1552 chapter = hb_list_item(job->list_chapter, track->current_chapter - 1);
1553
1554 // only write the last chapter marker if it lasts at least 1.5 second
1555 if (chapter != NULL && chapter->duration > 135000LL)
1556 {
1557 char title[1024];
1558 if (chapter->title != NULL)
1559 {
1560 snprintf(title, 1023, "%s", chapter->title);
1561 }
1562 else
1563 {
1564 snprintf(title, 1023, "Chapter %d", track->current_chapter);
1565 }
1566 add_chapter(m, track->prev_chapter_tc, track->duration, title);
1567 }
1568 }
1569
1570 // Update and track private data that can change during
1571 // encode.
1572 for(ii = 0; ii < hb_list_count( job->list_audio ); ii++)
1573 {
1574 AVStream *st;
1575 hb_audio_t * audio;
1576
1577 audio = hb_list_item(job->list_audio, ii);
1578 st = audio->priv.mux_data->st;
1579
1580 switch (audio->config.out.codec & HB_ACODEC_MASK)
1581 {
1582 case HB_ACODEC_FFFLAC:
1583 case HB_ACODEC_FFFLAC24:
1584 if( audio->priv.config.extradata.length )
1585 {
1586 uint8_t *priv_data;
1587 int priv_size;
1588
1589 priv_size = audio->priv.config.extradata.length;
1590 priv_data = av_realloc(st->codecpar->extradata, priv_size +
1591 AV_INPUT_BUFFER_PADDING_SIZE);
1592 if (priv_data == NULL)
1593 {
1594 break;
1595 }
1596 memcpy(priv_data,
1597 audio->priv.config.extradata.bytes,
1598 audio->priv.config.extradata.length);
1599 st->codecpar->extradata = priv_data;
1600 st->codecpar->extradata_size = priv_size;
1601 }
1602 break;
1603 default:
1604 break;
1605 }
1606 }
1607
1608 av_write_trailer(m->oc);
1609 avio_close(m->oc->pb);
1610 avformat_free_context(m->oc);
1611 av_packet_free(&m->pkt);
1612 av_packet_free(&m->empty_pkt);
1613 free(m->tracks);
1614 m->oc = NULL;
1615
1616 return 0;
1617 }
1618
hb_mux_avformat_init(hb_job_t * job)1619 hb_mux_object_t * hb_mux_avformat_init( hb_job_t * job )
1620 {
1621 hb_mux_object_t * m = calloc( sizeof( hb_mux_object_t ), 1 );
1622 m->init = avformatInit;
1623 m->mux = avformatMux;
1624 m->end = avformatEnd;
1625 m->job = job;
1626 return m;
1627 }
1628