3 Copyright (c) 2003-2015 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
11 #include "libavformat/avformat.h"
12 #include "openclwrapper.h"
16 #include "qsv_common.h"
17 #include "qsv_filter_pp.h"
23 hb_job_t
** current_job
;
24 hb_error_code
* error
;
29 static void work_func();
30 static void do_job( hb_job_t
*);
31 static void work_loop( void * );
32 static void filter_loop( void * );
34 #define FIFO_UNBOUNDED 65536
35 #define FIFO_UNBOUNDED_WAKE 65535
37 #define FIFO_LARGE_WAKE 16
39 #define FIFO_SMALL_WAKE 15
41 #define FIFO_MINI_WAKE 3
44 * Allocates work object and launches work thread with work_func.
45 * @param jobs Handle to hb_list_t.
46 * @param die Handle to user inititated exit indicator.
47 * @param error Handle to error indicator.
49 hb_thread_t
* hb_work_init( hb_list_t
* jobs
, volatile int * die
, hb_error_code
* error
, hb_job_t
** job
)
51 hb_work_t
* work
= calloc( sizeof( hb_work_t
), 1 );
54 work
->current_job
= job
;
58 return hb_thread_init( "work", work_func
, work
, HB_LOW_PRIORITY
);
61 static void InitWorkState(hb_handle_t
*h
, int pass_id
, int pass
, int pass_count
)
65 state
.state
= HB_STATE_WORKING
;
66 #define p state.param.working
69 p
.pass_count
= pass_count
;
78 hb_set_state( h
, &state
);
83 * Iterates through job list and calls do_job for each job.
84 * @param _work Handle work object.
86 static void work_func( void * _work
)
88 hb_work_t
* work
= _work
;
91 hb_log( "%d job(s) to process", hb_list_count( work
->jobs
) );
93 while( !*work
->die
&& ( job
= hb_list_item( work
->jobs
, 0 ) ) )
95 hb_list_rem( work
->jobs
, job
);
96 hb_list_t
* passes
= hb_list_init();
98 // JSON jobs get special treatment. We want to perform the title
99 // scan for the JSON job automatically. This requires that we delay
100 // filling the job struct till we have performed the title scan
101 // because the default values for the job come from the title.
102 if (job
->json
!= NULL
)
104 hb_deep_log(1, "json job:\n%s", job
->json
);
106 // Perform title scan for json job
107 hb_json_job_scan(job
->h
, job
->json
);
109 // Expand json string to full job struct
110 hb_job_t
*new_job
= hb_json_to_job(job
->h
, job
->json
);
114 hb_list_close(&passes
);
115 *work
->error
= HB_ERROR_INIT
;
123 hb_job_setup_passes(job
->h
, job
, passes
);
126 int pass_count
, pass
;
127 pass_count
= hb_list_count(passes
);
128 for (pass
= 0; pass
< pass_count
&& !*work
->die
; pass
++)
130 job
= hb_list_item(passes
, pass
);
131 job
->die
= work
->die
;
132 job
->done_error
= work
->error
;
133 *(work
->current_job
) = job
;
134 InitWorkState(job
->h
, job
->pass_id
, pass
+ 1, pass_count
);
136 *(work
->current_job
) = NULL
;
138 // Clean up any incomplete jobs
139 for (; pass
< pass_count
; pass
++)
141 job
= hb_list_item(passes
, pass
);
144 hb_list_close(&passes
);
150 hb_work_object_t
* hb_get_work( hb_handle_t
*h
, int id
)
152 hb_work_object_t
* w
;
153 for( w
= hb_objects
; w
; w
= w
->next
)
157 hb_work_object_t
*wc
= malloc( sizeof(*w
) );
166 hb_work_object_t
* hb_codec_decoder(hb_handle_t
*h
, int codec
)
168 hb_work_object_t
* w
= NULL
;
169 if (codec
& HB_ACODEC_FF_MASK
)
171 w
= hb_get_work(h
, WORK_DECAVCODEC
);
172 w
->yield
= 1; // decoders yield to keep sync fifos more even
177 w
= hb_get_work(h
, WORK_DECLPCM
);
178 w
->yield
= 1; // decoders yield to keep sync fifos more even
186 hb_work_object_t
* hb_codec_encoder(hb_handle_t
*h
, int codec
)
188 if (codec
& HB_ACODEC_FF_MASK
)
190 return hb_get_work(h
, WORK_ENCAVCODEC_AUDIO
);
194 case HB_ACODEC_AC3
: return hb_get_work(h
, WORK_ENCAVCODEC_AUDIO
);
195 case HB_ACODEC_LAME
: return hb_get_work(h
, WORK_ENCLAME
);
196 case HB_ACODEC_VORBIS
: return hb_get_work(h
, WORK_ENCVORBIS
);
197 case HB_ACODEC_CA_AAC
: return hb_get_work(h
, WORK_ENC_CA_AAC
);
198 case HB_ACODEC_CA_HAAC
: return hb_get_work(h
, WORK_ENC_CA_HAAC
);
205 * Displays job parameters in the debug log.
206 * @param job Handle work hb_job_t.
208 void hb_display_job_info(hb_job_t
*job
)
211 hb_title_t
*title
= job
->title
;
213 hb_subtitle_t
*subtitle
;
215 hb_log("job configuration:");
216 hb_log( " * source");
218 hb_log( " + %s", title
->path
);
220 if( job
->pts_to_start
|| job
->pts_to_stop
)
223 int hr_start
, min_start
, hr_stop
, min_stop
;
224 float sec_start
, sec_stop
;
226 stop
= job
->pts_to_start
+ job
->pts_to_stop
;
228 hr_start
= job
->pts_to_start
/ (90000 * 60 * 60);
229 min_start
= job
->pts_to_start
/ (90000 * 60);
230 sec_start
= (float)job
->pts_to_start
/ 90000.0 - min_start
* 60;
233 hr_stop
= stop
/ (90000 * 60 * 60);
234 min_stop
= stop
/ (90000 * 60);
235 sec_stop
= (float)stop
/ 90000.0 - min_stop
* 60;
238 if (job
->pts_to_stop
)
240 hb_log(" + title %d, start %02d:%02d:%02.2f stop %02d:%02d:%02.2f",
242 hr_start
, min_start
, sec_start
,
243 hr_stop
, min_stop
, sec_stop
);
247 hb_log(" + title %d, start %02d:%02d:%02.2f",
249 hr_start
, min_start
, sec_start
);
252 else if( job
->frame_to_start
|| job
->frame_to_stop
)
254 hb_log( " + title %d, frames %d to %d", title
->index
,
255 job
->frame_to_start
, job
->frame_to_start
+ job
->frame_to_stop
);
259 hb_log( " + title %d, chapter(s) %d to %d", title
->index
,
260 job
->chapter_start
, job
->chapter_end
);
263 if( title
->container_name
!= NULL
)
264 hb_log( " + container: %s", title
->container_name
);
266 if( title
->data_rate
)
268 hb_log( " + data rate: %d kbps", title
->data_rate
/ 1000 );
271 hb_log( " * destination");
273 hb_log( " + %s", job
->file
);
275 hb_log(" + container: %s", hb_container_get_long_name(job
->mux
));
279 if (job
->mp4_optimize
)
280 hb_log(" + optimized for HTTP streaming (fast start)");
282 hb_log(" + compatibility atom for iPod 5G");
289 if( job
->chapter_markers
)
291 hb_log( " + chapter markers" );
294 hb_log(" * video track");
297 if (hb_qsv_decode_is_enabled(job
))
299 hb_log(" + decoder: %s",
300 hb_qsv_decode_get_codec_name(title
->video_codec_param
));
305 if (hb_hwd_enabled(job
->h
))
307 hb_log(" + decoder: %s (dxva2)", title
->video_codec_name
);
312 hb_log(" + decoder: %s", title
->video_codec_name
);
315 if( title
->video_bitrate
)
317 hb_log( " + bitrate %d kbps", title
->video_bitrate
/ 1000 );
320 // Filters can modify dimensions. So show them first.
321 if( hb_list_count( job
->list_filter
) )
323 hb_log(" + %s", hb_list_count( job
->list_filter
) > 1 ? "filters" : "filter" );
324 for( i
= 0; i
< hb_list_count( job
->list_filter
); i
++ )
326 hb_filter_object_t
* filter
= hb_list_item( job
->list_filter
, i
);
327 if( filter
->settings
&& *filter
->settings
)
328 hb_log(" + %s (%s)", filter
->name
, filter
->settings
);
330 hb_log(" + %s (default settings)", filter
->name
);
333 hb_filter_info_t info
;
334 filter
->info( filter
, &info
);
335 if( info
.human_readable_desc
[0] )
337 hb_log(" + %s", info
.human_readable_desc
);
343 if ( job
->grayscale
)
344 hb_log( " + grayscale mode" );
346 hb_log( " + Output geometry" );
347 hb_log( " + storage dimensions: %d x %d", job
->width
, job
->height
);
348 hb_log( " + pixel aspect ratio: %d : %d", job
->par
.num
, job
->par
.den
);
349 hb_log( " + display dimensions: %d x %d",
350 job
->width
* job
->par
.num
/ job
->par
.den
, job
->height
);
353 if( !job
->indepth_scan
)
356 hb_log(" + encoder: %s",
357 hb_video_encoder_get_long_name(job
->vcodec
));
359 if (job
->encoder_preset
&& *job
->encoder_preset
)
365 case HB_VCODEC_QSV_H264
:
366 hb_log(" + preset: %s", job
->encoder_preset
);
371 if (job
->encoder_tune
&& *job
->encoder_tune
)
377 hb_log(" + tune: %s", job
->encoder_tune
);
382 if (job
->encoder_options
!= NULL
&& *job
->encoder_options
&&
383 job
->vcodec
!= HB_VCODEC_THEORA
)
385 hb_log(" + options: %s", job
->encoder_options
);
387 if (job
->encoder_profile
&& *job
->encoder_profile
)
393 case HB_VCODEC_QSV_H264
:
394 hb_log(" + profile: %s", job
->encoder_profile
);
399 if (job
->encoder_level
&& *job
->encoder_level
)
404 case HB_VCODEC_QSV_H264
:
405 hb_log(" + level: %s", job
->encoder_level
);
411 if (job
->vquality
>= 0)
413 hb_log(" + quality: %.2f (%s)", job
->vquality
,
414 hb_video_quality_get_name(job
->vcodec
));
418 hb_log( " + bitrate: %d kbps, pass: %d", job
->vbitrate
, job
->pass_id
);
419 if(job
->pass_id
== HB_PASS_ENCODE_1ST
&& job
->fastfirstpass
== 1 &&
420 (job
->vcodec
== HB_VCODEC_X264
|| job
->vcodec
== HB_VCODEC_X265
))
422 hb_log( " + fast first pass" );
423 if (job
->vcodec
== HB_VCODEC_X264
)
425 hb_log( " + options: ref=1:8x8dct=0:me=dia:trellis=0" );
426 hb_log( " analyse=i4x4 (if originally enabled, else analyse=none)" );
427 hb_log( " subq=2 (if originally greater than 2, else subq unchanged)" );
432 if (job
->color_matrix_code
&& job
->vcodec
== HB_VCODEC_X264
)
434 // color matrix is set:
435 // 1) at the stream level (x264 only),
436 // 2) at the container level (mp4v2 only)
437 hb_log(" + custom color matrix: %s",
438 job
->color_matrix_code
== 1 ? "ITU Bt.601 (NTSC)" :
439 job
->color_matrix_code
== 2 ? "ITU Bt.601 (PAL)" :
440 job
->color_matrix_code
== 3 ? "ITU Bt.709 (HD)" : "Custom");
444 if( job
->indepth_scan
)
446 hb_log( " * Foreign Audio Search: %s%s%s",
447 job
->select_subtitle_config
.dest
== RENDERSUB
? "Render/Burn-in" : "Passthrough",
448 job
->select_subtitle_config
.force
? ", Forced Only" : "",
449 job
->select_subtitle_config
.default_track
? ", Default" : "" );
452 for( i
= 0; i
< hb_list_count( job
->list_subtitle
); i
++ )
454 subtitle
= hb_list_item( job
->list_subtitle
, i
);
458 if( job
->indepth_scan
)
460 hb_log( " + subtitle, %s (track %d, id 0x%x) %s [%s]",
461 subtitle
->lang
, subtitle
->track
, subtitle
->id
,
462 subtitle
->format
== PICTURESUB
? "Picture" : "Text",
463 hb_subsource_name( subtitle
->source
) );
465 else if( subtitle
->source
== SRTSUB
)
467 /* For SRT, print offset and charset too */
468 hb_log( " * subtitle track %d, %s (track %d, id 0x%x) Text [SRT] -> %s%s, offset: %"PRId64
", charset: %s",
469 subtitle
->out_track
, subtitle
->lang
, subtitle
->track
, subtitle
->id
,
470 subtitle
->config
.dest
== RENDERSUB
? "Render/Burn-in" : "Passthrough",
471 subtitle
->config
.default_track
? ", Default" : "",
472 subtitle
->config
.offset
, subtitle
->config
.src_codeset
);
476 hb_log( " * subtitle track %d, %s (track %d, id 0x%x) %s [%s] -> %s%s%s",
477 subtitle
->out_track
, subtitle
->lang
, subtitle
->track
, subtitle
->id
,
478 subtitle
->format
== PICTURESUB
? "Picture" : "Text",
479 hb_subsource_name( subtitle
->source
),
480 subtitle
->config
.dest
== RENDERSUB
? "Render/Burn-in" : "Passthrough",
481 subtitle
->config
.force
? ", Forced Only" : "",
482 subtitle
->config
.default_track
? ", Default" : "" );
487 if( !job
->indepth_scan
)
489 for( i
= 0; i
< hb_list_count( job
->list_audio
); i
++ )
491 audio
= hb_list_item( job
->list_audio
, i
);
493 hb_log( " * audio track %d", audio
->config
.out
.track
);
495 if( audio
->config
.out
.name
)
496 hb_log( " + name: %s", audio
->config
.out
.name
);
498 hb_log( " + decoder: %s (track %d, id 0x%x)", audio
->config
.lang
.description
, audio
->config
.in
.track
+ 1, audio
->id
);
500 if (audio
->config
.in
.bitrate
>= 1000)
501 hb_log(" + bitrate: %d kbps, samplerate: %d Hz",
502 audio
->config
.in
.bitrate
/ 1000,
503 audio
->config
.in
.samplerate
);
505 hb_log(" + samplerate: %d Hz",
506 audio
->config
.in
.samplerate
);
508 if( audio
->config
.out
.codec
& HB_ACODEC_PASS_FLAG
)
511 hb_audio_encoder_get_name(audio
->config
.out
.codec
));
515 hb_log(" + mixdown: %s",
516 hb_mixdown_get_name(audio
->config
.out
.mixdown
));
517 if( audio
->config
.out
.normalize_mix_level
!= 0 )
519 hb_log( " + normalized mixing levels" );
521 if( audio
->config
.out
.gain
!= 0.0 )
523 hb_log( " + gain: %.fdB", audio
->config
.out
.gain
);
525 if (audio
->config
.out
.dynamic_range_compression
> 0.0f
&&
526 hb_audio_can_apply_drc(audio
->config
.in
.codec
,
527 audio
->config
.in
.codec_param
,
528 audio
->config
.out
.codec
))
530 hb_log( " + dynamic range compression: %f", audio
->config
.out
.dynamic_range_compression
);
532 if (hb_audio_dither_is_supported(audio
->config
.out
.codec
))
534 hb_log(" + dither: %s",
535 hb_audio_dither_get_description(audio
->config
.out
.dither_method
));
537 hb_log(" + encoder: %s",
538 hb_audio_encoder_get_long_name(audio
->config
.out
.codec
));
539 if (audio
->config
.out
.bitrate
> 0)
541 hb_log(" + bitrate: %d kbps, samplerate: %d Hz",
542 audio
->config
.out
.bitrate
, audio
->config
.out
.samplerate
);
544 else if (audio
->config
.out
.quality
!= HB_INVALID_AUDIO_QUALITY
)
546 hb_log(" + quality: %.2f, samplerate: %d Hz",
547 audio
->config
.out
.quality
, audio
->config
.out
.samplerate
);
549 else if (audio
->config
.out
.samplerate
> 0)
551 hb_log(" + samplerate: %d Hz",
552 audio
->config
.out
.samplerate
);
554 if (audio
->config
.out
.compression_level
>= 0)
556 hb_log(" + compression level: %.2f",
557 audio
->config
.out
.compression_level
);
564 /* Corrects framerates when actual duration and frame count numbers are known. */
565 void correct_framerate( hb_job_t
* job
)
567 hb_interjob_t
* interjob
= hb_interjob_get( job
->h
);
569 if( ( job
->sequence_id
& 0xFFFFFF ) != ( interjob
->last_job
& 0xFFFFFF) )
570 return; // Interjob information is for a different encode.
572 // compute actual output vrate from first pass
573 interjob
->vrate
.den
= (int64_t)job
->vrate
.num
* interjob
->total_time
/
574 ((int64_t)interjob
->out_frame_count
* 90000);
575 interjob
->vrate
.num
= job
->vrate
.num
;
579 * Job initialization rountine.
581 * Creates work objects for synchronizer, video decoder, video renderer, video decoder, audio decoder, audio encoder, reader, muxer.
582 * Launches thread for each work object with work_loop.
583 * Loops while monitoring status of work threads and fifos.
584 * Exits loop when conversion is done and fifos are empty.
585 * Closes threads and frees fifos.
586 * @param job Handle work hb_job_t.
588 static void do_job(hb_job_t
*job
)
592 hb_interjob_t
*interjob
;
594 hb_work_object_t
*sync
;
595 hb_work_object_t
*muxer
;
596 hb_work_object_t
*reader
= hb_get_work(job
->h
, WORK_READER
);
599 hb_subtitle_t
*subtitle
;
600 unsigned int subtitle_highest
= 0;
601 unsigned int subtitle_lowest
= 0;
602 unsigned int subtitle_lowest_id
= 0;
603 unsigned int subtitle_forced_id
= 0;
604 unsigned int subtitle_forced_hits
= 0;
605 unsigned int subtitle_hit
= 0;
608 interjob
= hb_interjob_get( job
->h
);
610 if( job
->pass_id
== HB_PASS_ENCODE_2ND
)
612 correct_framerate( job
);
615 job
->list_work
= hb_list_init();
620 * Note: we delay hb_ocl_init until here, since they're no point it loading
621 * the library if we aren't going to use it. But we only call hb_ocl_close
622 * in hb_global_close, since un/reloading the library each run is wasteful.
624 if (job
->use_opencl
&& (hb_ocl_init() || hb_init_opencl_run_env(0, NULL
, "-I.")))
626 hb_log("work: failed to initialize OpenCL environment, using fallback");
627 hb_release_opencl_run_env();
632 // we're not (re-)using OpenCL here, we can release the environment
633 hb_release_opencl_run_env();
636 hb_log( "starting job" );
638 /* Look for the scanned subtitle in the existing subtitle list
639 * select_subtitle implies that we did a scan. */
640 if( !job
->indepth_scan
&& interjob
->select_subtitle
)
642 /* Disable forced subtitles if we didn't find any in the scan, so that
643 * we display normal subtitles instead. */
644 if( interjob
->select_subtitle
->config
.force
&&
645 interjob
->select_subtitle
->forced_hits
== 0 )
647 interjob
->select_subtitle
->config
.force
= 0;
649 for( i
= 0; i
< hb_list_count( job
->list_subtitle
); )
651 subtitle
= hb_list_item( job
->list_subtitle
, i
);
654 /* Remove the scanned subtitle from the list if
655 * it would result in:
656 * - an emty track (forced and no forced hits)
657 * - an identical, duplicate subtitle track:
658 * -> both (or neither) are forced
659 * -> subtitle is not forced but all its hits are forced */
660 if( ( interjob
->select_subtitle
->id
== subtitle
->id
) &&
661 ( ( subtitle
->config
.force
&&
662 interjob
->select_subtitle
->forced_hits
== 0 ) ||
663 ( subtitle
->config
.force
== interjob
->select_subtitle
->config
.force
) ||
664 ( !subtitle
->config
.force
&&
665 interjob
->select_subtitle
->hits
== interjob
->select_subtitle
->forced_hits
) ) )
667 hb_list_rem( job
->list_subtitle
, subtitle
);
671 /* Adjust output track number, in case we removed one.
672 * Output tracks sadly still need to be in sequential order.
673 * Note: out.track starts at 1, i starts at 0, and track 1 is interjob->select_subtitle */
674 subtitle
->out_track
= ++i
+ 1;
678 // avoid infinite loop is subtitle == NULL
683 /* Add the subtitle that we found on the subtitle scan pass.
685 * Make sure it's the first subtitle in the list so that it becomes the
686 * first burned subtitle (explicitly or after sanitizing) - which should
687 * ensure that it doesn't get dropped. */
688 interjob
->select_subtitle
->out_track
= 1;
689 if (job
->pass_id
== HB_PASS_ENCODE
||
690 job
->pass_id
== HB_PASS_ENCODE_2ND
)
692 // final pass, interjob->select_subtitle is no longer needed
693 hb_list_insert(job
->list_subtitle
, 0, interjob
->select_subtitle
);
694 interjob
->select_subtitle
= NULL
;
698 // this is not the final pass, so we need to copy it instead
699 hb_list_insert(job
->list_subtitle
, 0, hb_subtitle_copy(interjob
->select_subtitle
));
703 if ( !job
->indepth_scan
)
705 // Sanitize subtitles
706 uint8_t one_burned
= 0;
707 for( i
= 0; i
< hb_list_count( job
->list_subtitle
); )
709 subtitle
= hb_list_item( job
->list_subtitle
, i
);
710 if ( subtitle
->config
.dest
== RENDERSUB
)
714 if ( !hb_subtitle_can_pass(subtitle
->source
, job
->mux
) )
716 hb_log( "More than one subtitle burn-in requested, dropping track %d.", i
);
717 hb_list_rem( job
->list_subtitle
, subtitle
);
723 hb_log( "More than one subtitle burn-in requested. Changing track %d to soft subtitle.", i
);
724 subtitle
->config
.dest
= PASSTHRUSUB
;
727 else if ( !hb_subtitle_can_burn(subtitle
->source
) )
729 hb_log( "Subtitle burn-in requested and input track can not be rendered. Changing track %d to soft subtitle.", i
);
730 subtitle
->config
.dest
= PASSTHRUSUB
;
738 if ( subtitle
->config
.dest
== PASSTHRUSUB
&&
739 !hb_subtitle_can_pass(subtitle
->source
, job
->mux
) )
743 hb_log( "Subtitle pass-thru requested and input track is not compatible with container. Changing track %d to burned-in subtitle.", i
);
744 subtitle
->config
.dest
= RENDERSUB
;
745 subtitle
->config
.default_track
= 0;
750 hb_log( "Subtitle pass-thru requested and input track is not compatible with container. One track already burned, dropping track %d.", i
);
751 hb_list_rem( job
->list_subtitle
, subtitle
);
756 /* Adjust output track number, in case we removed one.
757 * Output tracks sadly still need to be in sequential order.
758 * Note: out.track starts at 1, i starts at 0 */
759 subtitle
->out_track
= ++i
;
763 // Add subtitle rendering filter
764 // Note that if the filter is already in the filter chain, this
765 // has no effect. Note also that this means the front-end is
766 // not required to add the subtitle rendering filter since
767 // we will always try to do it here.
768 hb_filter_object_t
*filter
= hb_filter_init(HB_FILTER_RENDER_SUB
);
769 hb_add_filter(job
, filter
, NULL
);
775 * XXX: mfxCoreInterface's CopyFrame doesn't work in old drivers, and our
776 * workaround is really slow. If we have validated CPU-based filters in
777 * the list and we can't use CopyFrame, disable QSV decoding until a
778 * better solution is implemented.
780 if (hb_qsv_copyframe_is_slow(job
->vcodec
))
782 if (job
->list_filter
!= NULL
)
785 for (i
= 0; i
< hb_list_count(job
->list_filter
) && !encode_only
; i
++)
787 hb_filter_object_t
*filter
= hb_list_item(job
->list_filter
, i
);
790 // validated, CPU-based filters
791 case HB_FILTER_ROTATE
:
792 case HB_FILTER_RENDER_SUB
:
796 // CPU-based deinterlace (validated)
797 case HB_FILTER_DEINTERLACE
:
798 if (filter
->settings
!= NULL
&&
799 strcasecmp(filter
->settings
, "qsv") != 0)
805 // other filters will be removed
812 hb_log("do_job: QSV: possible CopyFrame bug, using encode-only path");
813 if (hb_get_cpu_platform() >= HB_CPU_PLATFORM_INTEL_IVB
)
815 hb_log("do_job: QSV: please update your Intel graphics driver to version 9.18.10.3257 or later");
823 * When QSV is used for decoding, not all CPU-based filters are supported,
824 * so we need to do a little extra setup here.
826 if (hb_qsv_decode_is_enabled(job
))
829 int num_cpu_filters
= 0;
830 hb_filter_object_t
*filter
;
831 // default values for VPP filter
832 vpp_settings
[0] = job
->title
->geometry
.width
;
833 vpp_settings
[1] = job
->title
->geometry
.height
;
834 vpp_settings
[2] = job
->title
->crop
[0];
835 vpp_settings
[3] = job
->title
->crop
[1];
836 vpp_settings
[4] = job
->title
->crop
[2];
837 vpp_settings
[5] = job
->title
->crop
[3];
838 vpp_settings
[6] = 0; // deinterlace: off
839 if (job
->list_filter
!= NULL
&& hb_list_count(job
->list_filter
) > 0)
841 while (hb_list_count(job
->list_filter
) > num_cpu_filters
)
843 filter
= hb_list_item(job
->list_filter
, num_cpu_filters
);
846 // cropping and scaling always done via VPP filter
847 case HB_FILTER_CROP_SCALE
:
848 if (filter
->settings
== NULL
|| *filter
->settings
== '\0')
850 // VPP defaults were set above, so not a problem
851 // however, this should never happen, print an error
852 hb_error("do_job: '%s': no settings!", filter
->name
);
856 sscanf(filter
->settings
, "%d:%d:%d:%d:%d:%d",
857 &vpp_settings
[0], &vpp_settings
[1],
858 &vpp_settings
[2], &vpp_settings
[3],
859 &vpp_settings
[4], &vpp_settings
[5]);
861 // VPP crop/scale takes precedence over OpenCL scale too
864 hb_release_opencl_run_env();
867 hb_list_rem(job
->list_filter
, filter
);
868 hb_filter_close(&filter
);
871 // pick VPP or CPU deinterlace depending on settings
872 case HB_FILTER_DEINTERLACE
:
873 if (filter
->settings
== NULL
||
874 strcasecmp(filter
->settings
, "qsv") == 0)
876 // deinterlacing via VPP filter
878 hb_list_rem(job
->list_filter
, filter
);
879 hb_filter_close(&filter
);
888 // then, validated filters
889 case HB_FILTER_ROTATE
: // TODO: use Media SDK for this
890 case HB_FILTER_RENDER_SUB
:
894 // finally, drop all unsupported filters
896 hb_log("do_job: QSV: full path, removing unsupported filter '%s'",
898 hb_list_rem(job
->list_filter
, filter
);
899 hb_filter_close(&filter
);
903 if (num_cpu_filters
> 0)
905 // we need filters to copy to system memory and back
906 filter
= hb_filter_init(HB_FILTER_QSV_PRE
);
907 hb_add_filter(job
, filter
, NULL
);
908 filter
= hb_filter_init(HB_FILTER_QSV_POST
);
909 hb_add_filter(job
, filter
, NULL
);
911 if (vpp_settings
[0] != job
->title
->geometry
.width
||
912 vpp_settings
[1] != job
->title
->geometry
.height
||
913 vpp_settings
[2] >= 1 /* crop */ ||
914 vpp_settings
[3] >= 1 /* crop */ ||
915 vpp_settings
[4] >= 1 /* crop */ ||
916 vpp_settings
[5] >= 1 /* crop */ ||
917 vpp_settings
[6] >= 1 /* deinterlace */)
919 // we need the VPP filter
920 char *settings
= hb_strdup_printf("%d:%d:%d:%d:%d:%d_dei:%d",
928 filter
= hb_filter_init(HB_FILTER_QSV
);
929 hb_add_filter(job
, filter
, settings
);
938 * Check support for and enable DXVA2-accelerated when applicable; we need:
939 * - a compatible input bitstream (HB_DECODE_SUPPORT_DXVA2)
940 * - DXVA2-accelerated decoding enabled (job->use_hwd)
941 * - an AVFormatContext (title->opaque_priv) for now
943 if (title
->video_decode_support
& HB_DECODE_SUPPORT_DXVA2
)
945 hb_hwd_set_enable(job
->h
, job
->use_hwd
&& title
->opaque_priv
!= NULL
);
950 hb_hwd_set_enable(job
->h
, 0);
953 // Filters have an effect on settings.
954 // So initialize the filters and update the job.
955 if( job
->list_filter
&& hb_list_count( job
->list_filter
) )
957 hb_filter_init_t init
;
960 init
.pix_fmt
= AV_PIX_FMT_YUV420P
;
961 init
.geometry
.width
= title
->geometry
.width
;
962 init
.geometry
.height
= title
->geometry
.height
;
964 init
.geometry
.par
= job
->par
;
965 memcpy(init
.crop
, title
->crop
, sizeof(int[4]));
966 init
.vrate
= title
->vrate
;
968 for( i
= 0; i
< hb_list_count( job
->list_filter
); )
970 hb_filter_object_t
* filter
= hb_list_item( job
->list_filter
, i
);
971 if( filter
->init( filter
, &init
) )
973 hb_log( "Failure to initialise filter '%s', disabling",
975 hb_list_rem( job
->list_filter
, filter
);
976 hb_filter_close( &filter
);
981 job
->width
= init
.geometry
.width
;
982 job
->height
= init
.geometry
.height
;
983 job
->par
= init
.geometry
.par
;
984 memcpy(job
->crop
, init
.crop
, sizeof(int[4]));
985 job
->vrate
= init
.vrate
;
988 // Perform filter post_init which informs filters of final
989 // job configuration. e.g. rendersub filter needs to know the
990 // final crop dimensions.
991 for( i
= 0; i
< hb_list_count( job
->list_filter
); )
993 hb_filter_object_t
* filter
= hb_list_item( job
->list_filter
, i
);
994 if (filter
->post_init
!= NULL
&& filter
->post_init(filter
, job
))
996 hb_log( "Failure to initialise filter '%s', disabling",
998 hb_list_rem( job
->list_filter
, filter
);
999 hb_filter_close( &filter
);
1007 job
->width
= title
->geometry
.width
;
1008 job
->height
= title
->geometry
.height
;
1009 job
->par
= title
->geometry
.par
;
1010 memset(job
->crop
, 0, sizeof(int[4]));
1011 job
->vrate
= title
->vrate
;
1016 * MPEG-4 Part 2 stores the PAR num/den as unsigned 8-bit fields,
1017 * and libavcodec's encoder fails to initialize if we don't handle it.
1019 if (job
->vcodec
== HB_VCODEC_FFMPEG_MPEG4
)
1021 hb_limit_rational(&job
->par
.num
, &job
->par
.den
,
1022 job
->par
.num
, job
->par
.den
, 255);
1026 * The frame rate may affect the bitstream's time base, lose superfluous
1027 * factors for consistency (some encoders reduce fractions, some don't).
1029 hb_reduce(&job
->vrate
.num
, &job
->vrate
.den
,
1030 job
->vrate
.num
, job
->vrate
.den
);
1033 if (hb_qsv_decode_is_enabled(job
))
1035 job
->fifo_mpeg2
= hb_fifo_init( FIFO_MINI
, FIFO_MINI_WAKE
);
1036 job
->fifo_raw
= hb_fifo_init( FIFO_MINI
, FIFO_MINI_WAKE
);
1037 job
->fifo_sync
= hb_fifo_init( FIFO_MINI
, FIFO_MINI_WAKE
);
1038 job
->fifo_render
= hb_fifo_init( FIFO_MINI
, FIFO_MINI_WAKE
);
1039 job
->fifo_mpeg4
= hb_fifo_init( FIFO_MINI
, FIFO_MINI_WAKE
);
1044 job
->fifo_mpeg2
= hb_fifo_init( FIFO_LARGE
, FIFO_LARGE_WAKE
);
1045 job
->fifo_raw
= hb_fifo_init( FIFO_SMALL
, FIFO_SMALL_WAKE
);
1046 job
->fifo_sync
= hb_fifo_init( FIFO_SMALL
, FIFO_SMALL_WAKE
);
1047 job
->fifo_mpeg4
= hb_fifo_init( FIFO_LARGE
, FIFO_LARGE_WAKE
);
1048 job
->fifo_render
= NULL
; // Attached to filter chain
1051 /* Audio fifos must be initialized before sync */
1052 if (!job
->indepth_scan
)
1054 // apply Auto Passthru settings
1055 hb_autopassthru_apply_settings(job
);
1056 // sanitize audio settings
1057 for (i
= 0; i
< hb_list_count(job
->list_audio
);)
1059 audio
= hb_list_item(job
->list_audio
, i
);
1060 if (audio
->config
.out
.codec
== HB_ACODEC_AUTO_PASS
)
1062 // Auto Passthru should have been handled above
1063 // remove track to avoid a crash
1064 hb_log("Auto Passthru error, dropping track %d",
1065 audio
->config
.out
.track
);
1066 hb_list_rem(job
->list_audio
, audio
);
1070 if ((audio
->config
.out
.codec
& HB_ACODEC_PASS_FLAG
) &&
1071 !(audio
->config
.in
.codec
&
1072 audio
->config
.out
.codec
& HB_ACODEC_PASS_MASK
))
1074 hb_log("Passthru requested and input codec is not the same as output codec for track %d, dropping track",
1075 audio
->config
.out
.track
);
1076 hb_list_rem(job
->list_audio
, audio
);
1080 /* Adjust output track number, in case we removed one.
1081 * Output tracks sadly still need to be in sequential order.
1082 * Note: out.track starts at 1, i starts at 0 */
1083 audio
->config
.out
.track
= ++i
;
1086 int best_mixdown
= 0;
1087 int best_bitrate
= 0;
1088 int best_samplerate
= 0;
1090 for (i
= 0; i
< hb_list_count(job
->list_audio
); i
++)
1092 audio
= hb_list_item(job
->list_audio
, i
);
1094 /* set up the audio work structures */
1095 audio
->priv
.fifo_raw
= hb_fifo_init(FIFO_SMALL
, FIFO_SMALL_WAKE
);
1096 audio
->priv
.fifo_sync
= hb_fifo_init(FIFO_SMALL
, FIFO_SMALL_WAKE
);
1097 audio
->priv
.fifo_out
= hb_fifo_init(FIFO_LARGE
, FIFO_LARGE_WAKE
);
1098 audio
->priv
.fifo_in
= hb_fifo_init(FIFO_LARGE
, FIFO_LARGE_WAKE
);
1100 /* Passthru audio */
1101 if (audio
->config
.out
.codec
& HB_ACODEC_PASS_FLAG
)
1103 // Muxer needs these to be set correctly in order to
1104 // set audio track MP4 time base.
1105 audio
->config
.out
.samples_per_frame
=
1106 audio
->config
.in
.samples_per_frame
;
1107 audio
->config
.out
.samplerate
= audio
->config
.in
.samplerate
;
1111 /* Vorbis language information */
1112 if (audio
->config
.out
.codec
== HB_ACODEC_VORBIS
)
1113 audio
->priv
.config
.vorbis
.language
= audio
->config
.lang
.simple
;
1115 /* sense-check the requested samplerate */
1116 if (audio
->config
.out
.samplerate
<= 0)
1118 // if not specified, set to same as input
1119 audio
->config
.out
.samplerate
= audio
->config
.in
.samplerate
;
1122 hb_audio_samplerate_get_best(audio
->config
.out
.codec
,
1123 audio
->config
.out
.samplerate
,
1125 if (best_samplerate
!= audio
->config
.out
.samplerate
)
1127 hb_log("work: sanitizing track %d unsupported samplerate %d Hz to %s kHz",
1128 audio
->config
.out
.track
, audio
->config
.out
.samplerate
,
1129 hb_audio_samplerate_get_name(best_samplerate
));
1130 audio
->config
.out
.samplerate
= best_samplerate
;
1133 /* sense-check the requested mixdown */
1134 if (audio
->config
.out
.mixdown
<= HB_AMIXDOWN_NONE
)
1136 /* Mixdown not specified, set the default mixdown */
1137 audio
->config
.out
.mixdown
=
1138 hb_mixdown_get_default(audio
->config
.out
.codec
,
1139 audio
->config
.in
.channel_layout
);
1140 hb_log("work: mixdown not specified, track %d setting mixdown %s",
1141 audio
->config
.out
.track
,
1142 hb_mixdown_get_name(audio
->config
.out
.mixdown
));
1147 hb_mixdown_get_best(audio
->config
.out
.codec
,
1148 audio
->config
.in
.channel_layout
,
1149 audio
->config
.out
.mixdown
);
1150 if (audio
->config
.out
.mixdown
!= best_mixdown
)
1152 /* log the output mixdown */
1153 hb_log("work: sanitizing track %d mixdown %s to %s",
1154 audio
->config
.out
.track
,
1155 hb_mixdown_get_name(audio
->config
.out
.mixdown
),
1156 hb_mixdown_get_name(best_mixdown
));
1157 audio
->config
.out
.mixdown
= best_mixdown
;
1161 /* sense-check the requested compression level */
1162 if (audio
->config
.out
.compression_level
< 0)
1164 audio
->config
.out
.compression_level
=
1165 hb_audio_compression_get_default(audio
->config
.out
.codec
);
1166 if (audio
->config
.out
.compression_level
>= 0)
1168 hb_log("work: compression level not specified, track %d setting compression level %.2f",
1169 audio
->config
.out
.track
,
1170 audio
->config
.out
.compression_level
);
1175 float best_compression
=
1176 hb_audio_compression_get_best(audio
->config
.out
.codec
,
1177 audio
->config
.out
.compression_level
);
1178 if (best_compression
!= audio
->config
.out
.compression_level
)
1180 if (best_compression
== -1)
1182 hb_log("work: track %d, compression level not supported by codec",
1183 audio
->config
.out
.track
);
1187 hb_log("work: sanitizing track %d compression level %.2f to %.2f",
1188 audio
->config
.out
.track
,
1189 audio
->config
.out
.compression_level
,
1192 audio
->config
.out
.compression_level
= best_compression
;
1196 /* sense-check the requested quality */
1197 if (audio
->config
.out
.quality
!= HB_INVALID_AUDIO_QUALITY
)
1199 float best_quality
=
1200 hb_audio_quality_get_best(audio
->config
.out
.codec
,
1201 audio
->config
.out
.quality
);
1202 if (best_quality
!= audio
->config
.out
.quality
)
1204 if (best_quality
== HB_INVALID_AUDIO_QUALITY
)
1206 hb_log("work: track %d, quality mode not supported by codec",
1207 audio
->config
.out
.track
);
1211 hb_log("work: sanitizing track %d quality %.2f to %.2f",
1212 audio
->config
.out
.track
,
1213 audio
->config
.out
.quality
, best_quality
);
1215 audio
->config
.out
.quality
= best_quality
;
1219 /* sense-check the requested bitrate */
1220 if (audio
->config
.out
.quality
== HB_INVALID_AUDIO_QUALITY
)
1222 if (audio
->config
.out
.bitrate
<= 0)
1224 /* Bitrate not specified, set the default bitrate */
1225 audio
->config
.out
.bitrate
=
1226 hb_audio_bitrate_get_default(audio
->config
.out
.codec
,
1227 audio
->config
.out
.samplerate
,
1228 audio
->config
.out
.mixdown
);
1229 if (audio
->config
.out
.bitrate
> 0)
1231 hb_log("work: bitrate not specified, track %d setting bitrate %d Kbps",
1232 audio
->config
.out
.track
,
1233 audio
->config
.out
.bitrate
);
1239 hb_audio_bitrate_get_best(audio
->config
.out
.codec
,
1240 audio
->config
.out
.bitrate
,
1241 audio
->config
.out
.samplerate
,
1242 audio
->config
.out
.mixdown
);
1243 if (best_bitrate
> 0 &&
1244 best_bitrate
!= audio
->config
.out
.bitrate
)
1246 /* log the output bitrate */
1247 hb_log("work: sanitizing track %d bitrate %d to %d Kbps",
1248 audio
->config
.out
.track
,
1249 audio
->config
.out
.bitrate
, best_bitrate
);
1251 audio
->config
.out
.bitrate
= best_bitrate
;
1255 /* sense-check the requested dither */
1256 if (hb_audio_dither_is_supported(audio
->config
.out
.codec
))
1258 if (audio
->config
.out
.dither_method
==
1259 hb_audio_dither_get_default())
1261 /* "auto", enable with default settings */
1262 audio
->config
.out
.dither_method
=
1263 hb_audio_dither_get_default_method();
1266 else if (audio
->config
.out
.dither_method
!=
1267 hb_audio_dither_get_default())
1269 /* specific dither requested but dithering not supported */
1270 hb_log("work: track %d, dithering not supported by codec",
1271 audio
->config
.out
.track
);
1276 /* Synchronization */
1277 sync
= hb_sync_init( job
);
1280 if (title
->video_codec
== WORK_NONE
)
1282 hb_error("No video decoder set!");
1285 hb_list_add(job
->list_work
, (w
= hb_get_work(job
->h
, title
->video_codec
)));
1286 w
->yield
= 1; // decoders yield to keep sync fifos more even
1287 w
->codec_param
= title
->video_codec_param
;
1288 w
->fifo_in
= job
->fifo_mpeg2
;
1289 w
->fifo_out
= job
->fifo_raw
;
1291 for( i
= 0; i
< hb_list_count( job
->list_subtitle
); i
++ )
1293 subtitle
= hb_list_item( job
->list_subtitle
, i
);
1297 subtitle
->fifo_in
= hb_fifo_init( FIFO_SMALL
, FIFO_SMALL_WAKE
);
1298 // Must set capacity of the raw-FIFO to be set >= the maximum number of subtitle
1299 // lines that could be decoded prior to a video frame in order to prevent the following
1300 // deadlock condition:
1301 // 1. Subtitle decoder blocks trying to generate more subtitle lines than will fit in the FIFO.
1302 // 2. Blocks the processing of further subtitle packets read from the input stream.
1303 // 3. And that blocks the processing of any further video packets read from the input stream.
1304 // 4. And that blocks the sync work-object from running, which is needed to consume the subtitle lines in the raw-FIFO.
1305 // Since that number is unbounded, the FIFO must be made (effectively) unbounded in capacity.
1306 subtitle
->fifo_raw
= hb_fifo_init( FIFO_UNBOUNDED
, FIFO_UNBOUNDED_WAKE
);
1307 subtitle
->fifo_sync
= hb_fifo_init( FIFO_SMALL
, FIFO_SMALL_WAKE
);
1308 subtitle
->fifo_out
= hb_fifo_init( FIFO_SMALL
, FIFO_SMALL_WAKE
);
1310 w
= hb_get_work( job
->h
, subtitle
->codec
);
1311 w
->fifo_in
= subtitle
->fifo_in
;
1312 w
->fifo_out
= subtitle
->fifo_raw
;
1313 w
->subtitle
= subtitle
;
1314 hb_list_add( job
->list_work
, w
);
1318 /* Set up the video filter fifo pipeline */
1319 if( !job
->indepth_scan
)
1321 if( job
->list_filter
)
1323 int filter_count
= hb_list_count( job
->list_filter
);
1325 hb_fifo_t
* fifo_in
= job
->fifo_sync
;
1327 for( i
= 0; i
< filter_count
; i
++ )
1329 hb_filter_object_t
* filter
= hb_list_item( job
->list_filter
, i
);
1331 filter
->fifo_in
= fifo_in
;
1332 filter
->fifo_out
= hb_fifo_init( FIFO_MINI
, FIFO_MINI_WAKE
);
1333 fifo_in
= filter
->fifo_out
;
1335 job
->fifo_render
= fifo_in
;
1337 else if ( !job
->list_filter
)
1339 hb_log("work: Internal Error: no filters");
1340 job
->fifo_render
= NULL
;
1344 switch( job
->vcodec
)
1346 case HB_VCODEC_FFMPEG_MPEG4
:
1347 w
= hb_get_work( job
->h
, WORK_ENCAVCODEC
);
1348 w
->codec_param
= AV_CODEC_ID_MPEG4
;
1350 case HB_VCODEC_FFMPEG_MPEG2
:
1351 w
= hb_get_work( job
->h
, WORK_ENCAVCODEC
);
1352 w
->codec_param
= AV_CODEC_ID_MPEG2VIDEO
;
1354 case HB_VCODEC_FFMPEG_VP8
:
1355 w
= hb_get_work( job
->h
, WORK_ENCAVCODEC
);
1356 w
->codec_param
= AV_CODEC_ID_VP8
;
1358 case HB_VCODEC_X264
:
1359 w
= hb_get_work( job
->h
, WORK_ENCX264
);
1361 case HB_VCODEC_QSV_H264
:
1362 w
= hb_get_work( job
->h
, WORK_ENCQSV
);
1364 case HB_VCODEC_THEORA
:
1365 w
= hb_get_work( job
->h
, WORK_ENCTHEORA
);
1368 case HB_VCODEC_X265
:
1369 w
= hb_get_work( job
->h
, WORK_ENCX265
);
1373 // Handle case where there are no filters.
1374 // This really should never happen.
1375 if ( job
->fifo_render
)
1376 w
->fifo_in
= job
->fifo_render
;
1378 w
->fifo_in
= job
->fifo_sync
;
1380 w
->fifo_out
= job
->fifo_mpeg4
;
1381 w
->config
= &job
->config
;
1383 hb_list_add( job
->list_work
, w
);
1385 for( i
= 0; i
< hb_list_count( job
->list_audio
); i
++ )
1387 audio
= hb_list_item( job
->list_audio
, i
);
1390 * Audio Decoder Thread
1392 if ( audio
->priv
.fifo_in
)
1394 w
= hb_codec_decoder(job
->h
, audio
->config
.in
.codec
);
1397 hb_error("Invalid input codec: %d", audio
->config
.in
.codec
);
1398 *job
->done_error
= HB_ERROR_WRONG_INPUT
;
1402 w
->fifo_in
= audio
->priv
.fifo_in
;
1403 w
->fifo_out
= audio
->priv
.fifo_raw
;
1404 w
->config
= &audio
->priv
.config
;
1406 w
->codec_param
= audio
->config
.in
.codec_param
;
1408 hb_list_add( job
->list_work
, w
);
1412 * Audio Encoder Thread
1414 if ( !(audio
->config
.out
.codec
& HB_ACODEC_PASS_FLAG
) )
1417 * Add the encoder thread if not doing AC-3 pass through
1419 w
= hb_codec_encoder( job
->h
, audio
->config
.out
.codec
);
1422 hb_error("Invalid audio codec: %#x", audio
->config
.out
.codec
);
1424 *job
->done_error
= HB_ERROR_WRONG_INPUT
;
1428 w
->fifo_in
= audio
->priv
.fifo_sync
;
1429 w
->fifo_out
= audio
->priv
.fifo_out
;
1430 w
->config
= &audio
->priv
.config
;
1433 hb_list_add( job
->list_work
, w
);
1438 if( job
->chapter_markers
&& job
->chapter_start
== job
->chapter_end
)
1440 job
->chapter_markers
= 0;
1441 hb_log("work: only 1 chapter, disabling chapter markers");
1444 /* Display settings */
1445 hb_display_job_info( job
);
1447 /* Init read & write threads */
1448 if ( reader
->init( reader
, job
) )
1450 hb_error( "Failure to initialise thread '%s'", reader
->name
);
1451 *job
->done_error
= HB_ERROR_INIT
;
1455 reader
->done
= &job
->done
;
1456 reader
->thread
= hb_thread_init( reader
->name
, ReadLoop
, reader
, HB_NORMAL_PRIORITY
);
1460 if( job
->list_filter
&& !job
->indepth_scan
)
1462 int filter_count
= hb_list_count( job
->list_filter
);
1465 for( i
= 0; i
< filter_count
; i
++ )
1467 hb_filter_object_t
* filter
= hb_list_item( job
->list_filter
, i
);
1469 if( !filter
) continue;
1471 // Filters were initialized earlier, so we just need
1472 // to start the filter's thread
1473 filter
->done
= &job
->done
;
1474 filter
->thread
= hb_thread_init( filter
->name
, filter_loop
, filter
,
1479 /* Launch processing threads */
1480 for( i
= 0; i
< hb_list_count( job
->list_work
); i
++ )
1482 w
= hb_list_item( job
->list_work
, i
);
1483 w
->done
= &job
->done
;
1484 w
->thread_sleep_interval
= 10;
1485 if( w
->init( w
, job
) )
1487 hb_error( "Failure to initialise thread '%s'", w
->name
);
1488 *job
->done_error
= HB_ERROR_INIT
;
1492 w
->thread
= hb_thread_init( w
->name
, work_loop
, w
,
1496 if ( job
->indepth_scan
)
1500 sync
->done
= &job
->done
;
1504 sync
->done
= &job
->done
;
1505 sync
->thread_sleep_interval
= 10;
1506 if( sync
->init( w
, job
) )
1508 hb_error( "Failure to initialise thread '%s'", w
->name
);
1509 *job
->done_error
= HB_ERROR_INIT
;
1513 sync
->thread
= hb_thread_init( sync
->name
, work_loop
, sync
,
1516 // The muxer requires track information that's set up by the encoder
1517 // init routines so we have to init the muxer last.
1518 muxer
= hb_muxer_init( job
);
1522 hb_buffer_t
* buf_in
, * buf_out
= NULL
;
1524 while ( !*job
->die
&& !*w
->done
&& w
->status
!= HB_WORK_DONE
)
1526 buf_in
= hb_fifo_get_wait( w
->fifo_in
);
1527 if ( buf_in
== NULL
)
1533 hb_buffer_close( &buf_in
);
1539 w
->status
= w
->work( w
, &buf_in
, &buf_out
);
1543 hb_buffer_close( &buf_in
);
1545 if ( buf_out
&& w
->fifo_out
== NULL
)
1547 hb_buffer_close( &buf_out
);
1551 while ( !*job
->die
)
1553 if ( hb_fifo_full_wait( w
->fifo_out
) )
1555 hb_fifo_push( w
->fifo_out
, buf_out
);
1565 hb_buffer_close( &buf_out
);
1568 hb_handle_t
* h
= job
->h
;
1570 hb_get_state2( h
, &state
);
1572 hb_log("work: average encoding speed for job is %f fps", state
.param
.working
.rate_avg
);
1577 muxer
->close( muxer
);
1580 if( sync
->thread
!= NULL
)
1582 hb_thread_close( &sync
->thread
);
1583 sync
->close( sync
);
1589 /* Stop the write thread (thread_close will block until the muxer finishes) */
1592 // Close render filter pipeline
1593 if( job
->list_filter
)
1595 int filter_count
= hb_list_count( job
->list_filter
);
1598 for( i
= 0; i
< filter_count
; i
++ )
1600 hb_filter_object_t
* filter
= hb_list_item( job
->list_filter
, i
);
1602 if( !filter
) continue;
1604 if( filter
->thread
!= NULL
)
1606 hb_thread_close( &filter
->thread
);
1608 filter
->close( filter
);
1612 /* Close work objects */
1613 while( ( w
= hb_list_item( job
->list_work
, 0 ) ) )
1615 hb_list_rem( job
->list_work
, w
);
1616 if( w
->thread
!= NULL
)
1618 hb_thread_close( &w
->thread
);
1624 hb_list_close( &job
->list_work
);
1626 /* Stop the read thread */
1627 if( reader
->thread
!= NULL
)
1629 hb_thread_close( &reader
->thread
);
1630 reader
->close( reader
);
1635 hb_fifo_close( &job
->fifo_mpeg2
);
1636 hb_fifo_close( &job
->fifo_raw
);
1637 hb_fifo_close( &job
->fifo_sync
);
1638 hb_fifo_close( &job
->fifo_mpeg4
);
1640 for( i
= 0; i
< hb_list_count( job
->list_subtitle
); i
++ )
1642 subtitle
= hb_list_item( job
->list_subtitle
, i
);
1645 hb_fifo_close( &subtitle
->fifo_in
);
1646 hb_fifo_close( &subtitle
->fifo_raw
);
1647 hb_fifo_close( &subtitle
->fifo_sync
);
1648 hb_fifo_close( &subtitle
->fifo_out
);
1651 for( i
= 0; i
< hb_list_count( job
->list_audio
); i
++ )
1653 audio
= hb_list_item( job
->list_audio
, i
);
1654 if( audio
->priv
.fifo_in
!= NULL
)
1655 hb_fifo_close( &audio
->priv
.fifo_in
);
1656 if( audio
->priv
.fifo_raw
!= NULL
)
1657 hb_fifo_close( &audio
->priv
.fifo_raw
);
1658 if( audio
->priv
.fifo_sync
!= NULL
)
1659 hb_fifo_close( &audio
->priv
.fifo_sync
);
1660 if( audio
->priv
.fifo_out
!= NULL
)
1661 hb_fifo_close( &audio
->priv
.fifo_out
);
1664 if( job
->list_filter
)
1666 for( i
= 0; i
< hb_list_count( job
->list_filter
); i
++ )
1668 hb_filter_object_t
* filter
= hb_list_item( job
->list_filter
, i
);
1669 hb_fifo_close( &filter
->fifo_out
);
1673 if( job
->indepth_scan
)
1675 /* Before closing the title print out our subtitle stats if we need to
1676 * find the highest and lowest. */
1677 for( i
= 0; i
< hb_list_count( job
->list_subtitle
); i
++ )
1679 subtitle
= hb_list_item( job
->list_subtitle
, i
);
1681 hb_log( "Subtitle track %d (id 0x%x) '%s': %d hits (%d forced)",
1682 subtitle
->track
, subtitle
->id
, subtitle
->lang
,
1683 subtitle
->hits
, subtitle
->forced_hits
);
1685 if( subtitle
->hits
== 0 )
1688 if( subtitle_highest
< subtitle
->hits
)
1690 subtitle_highest
= subtitle
->hits
;
1693 if( subtitle_lowest
== 0 ||
1694 subtitle_lowest
> subtitle
->hits
)
1696 subtitle_lowest
= subtitle
->hits
;
1697 subtitle_lowest_id
= subtitle
->id
;
1700 // pick the track with fewest forced hits
1701 if( subtitle
->forced_hits
> 0 &&
1702 ( subtitle_forced_hits
== 0 ||
1703 subtitle_forced_hits
> subtitle
->forced_hits
) )
1705 subtitle_forced_id
= subtitle
->id
;
1706 subtitle_forced_hits
= subtitle
->forced_hits
;
1710 if( subtitle_forced_id
&& job
->select_subtitle_config
.force
)
1712 /* If there is a subtitle stream with forced subtitles and forced-only
1713 * is set, then select it in preference to the lowest. */
1714 subtitle_hit
= subtitle_forced_id
;
1715 hb_log( "Found a subtitle candidate with id 0x%x (contains forced subs)",
1718 else if( subtitle_lowest
> 0 &&
1719 subtitle_lowest
< ( subtitle_highest
* 0.1 ) )
1721 /* OK we have more than one, and the lowest is lower,
1722 * but how much lower to qualify for turning it on by
1725 * Let's say 10% as a default. */
1726 subtitle_hit
= subtitle_lowest_id
;
1727 hb_log( "Found a subtitle candidate with id 0x%x", subtitle_hit
);
1731 hb_log( "No candidate detected during subtitle scan" );
1734 for( i
= 0; i
< hb_list_count( job
->list_subtitle
); i
++ )
1736 subtitle
= hb_list_item( job
->list_subtitle
, i
);
1737 if( subtitle
->id
== subtitle_hit
)
1739 subtitle
->config
= job
->select_subtitle_config
;
1740 // Remove from list since we are taking ownership
1742 hb_list_rem( job
->list_subtitle
, subtitle
);
1743 interjob
->select_subtitle
= subtitle
;
1749 hb_buffer_pool_free();
1751 hb_job_close( &job
);
1754 static inline void copy_chapter( hb_buffer_t
* dst
, hb_buffer_t
* src
)
1756 // Propagate any chapter breaks for the worker if and only if the
1757 // output frame has the same time stamp as the input frame (any
1758 // worker that delays frames has to propagate the chapter marks itself
1759 // and workers that move chapter marks to a different time should set
1760 // 'src' to NULL so that this code won't generate spurious duplicates.)
1761 if( src
&& dst
&& src
->s
.start
== dst
->s
.start
)
1763 // restore log below to debug chapter mark propagation problems
1764 dst
->s
.new_chap
= src
->s
.new_chap
;
1769 * Performs the work object's specific work function.
1770 * Loops calling work function for associated work object. Sleeps when fifo is full.
1771 * Monitors work done indicator.
1772 * Exits loop when work indiactor is set.
1773 * @param _w Handle to work object.
1775 static void work_loop( void * _w
)
1777 hb_work_object_t
* w
= _w
;
1778 hb_buffer_t
* buf_in
= NULL
, * buf_out
= NULL
;
1780 while( !*w
->done
&& w
->status
!= HB_WORK_DONE
)
1782 buf_in
= hb_fifo_get_wait( w
->fifo_in
);
1783 if ( buf_in
== NULL
)
1789 hb_buffer_close( &buf_in
);
1793 // Invalidate buf_out so that if there is no output
1794 // we don't try to pass along junk.
1796 w
->status
= w
->work( w
, &buf_in
, &buf_out
);
1798 copy_chapter( buf_out
, buf_in
);
1802 hb_buffer_close( &buf_in
);
1804 if ( buf_out
&& w
->fifo_out
== NULL
)
1806 hb_buffer_close( &buf_out
);
1812 if ( hb_fifo_full_wait( w
->fifo_out
) )
1814 hb_fifo_push( w
->fifo_out
, buf_out
);
1827 hb_buffer_close( &buf_out
);
1830 // Consume data in incoming fifo till job complete so that
1831 // residual data does not stall the pipeline
1834 buf_in
= hb_fifo_get_wait( w
->fifo_in
);
1835 if ( buf_in
!= NULL
)
1836 hb_buffer_close( &buf_in
);
1841 * Performs the filter object's specific work function.
1842 * Loops calling work function for associated filter object.
1843 * Sleeps when fifo is full.
1844 * Monitors work done indicator.
1845 * Exits loop when work indiactor is set.
1846 * @param _w Handle to work object.
1848 static void filter_loop( void * _f
)
1850 hb_filter_object_t
* f
= _f
;
1851 hb_buffer_t
* buf_in
, * buf_out
= NULL
;
1853 while( !*f
->done
&& f
->status
!= HB_FILTER_DONE
)
1855 buf_in
= hb_fifo_get_wait( f
->fifo_in
);
1856 if ( buf_in
== NULL
)
1859 // Filters can drop buffers. Remember chapter information
1860 // so that it can be propagated to the next buffer
1861 if ( buf_in
->s
.new_chap
)
1863 f
->chapter_time
= buf_in
->s
.start
;
1864 f
->chapter_val
= buf_in
->s
.new_chap
;
1865 // don't let 'filter_loop' put a chapter mark on the wrong buffer
1866 buf_in
->s
.new_chap
= 0;
1872 hb_buffer_close( &buf_in
);
1880 hb_buffer_t
*last_buf_in
= buf_in
;
1883 f
->status
= f
->work( f
, &buf_in
, &buf_out
);
1886 if (f
->status
== HB_FILTER_DELAY
&&
1887 last_buf_in
->qsv_details
.filter_details
!= NULL
&& buf_out
== NULL
)
1889 hb_filter_private_t_qsv
*qsv_user
= buf_in
? buf_in
->qsv_details
.filter_details
: last_buf_in
->qsv_details
.filter_details
;
1890 qsv_user
->post
.status
= f
->status
;
1892 hb_lock(qsv_user
->post
.frame_completed_lock
);
1893 qsv_user
->post
.frame_go
= 1;
1894 hb_cond_broadcast(qsv_user
->post
.frame_completed
);
1895 hb_unlock(qsv_user
->post
.frame_completed_lock
);
1899 if ( buf_out
&& f
->chapter_val
&& f
->chapter_time
<= buf_out
->s
.start
)
1901 buf_out
->s
.new_chap
= f
->chapter_val
;
1907 hb_buffer_close( &buf_in
);
1909 if ( buf_out
&& f
->fifo_out
== NULL
)
1911 hb_buffer_close( &buf_out
);
1917 if ( hb_fifo_full_wait( f
->fifo_out
) )
1919 hb_fifo_push( f
->fifo_out
, buf_out
);
1928 hb_buffer_close( &buf_out
);
1931 // Consume data in incoming fifo till job complete so that
1932 // residual data does not stall the pipeline
1935 buf_in
= hb_fifo_get_wait( f
->fifo_in
);
1936 if ( buf_in
!= NULL
)
1937 hb_buffer_close( &buf_in
);