WinGui: Fix another instance of the Caliburn vs Json.net sillyness where objects...
[HandBrake.git] / libhb / work.c
blob8a58519eed2617df74ffd2a27e85a135c5035564
1 /* work.c
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
8 */
10 #include "hb.h"
11 #include "libavformat/avformat.h"
12 #include "openclwrapper.h"
13 #include "opencl.h"
15 #ifdef USE_QSV
16 #include "qsv_common.h"
17 #include "qsv_filter_pp.h"
18 #endif
20 typedef struct
22 hb_list_t * jobs;
23 hb_job_t ** current_job;
24 hb_error_code * error;
25 volatile int * die;
27 } hb_work_t;
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
36 #define FIFO_LARGE 32
37 #define FIFO_LARGE_WAKE 16
38 #define FIFO_SMALL 16
39 #define FIFO_SMALL_WAKE 15
40 #define FIFO_MINI 4
41 #define FIFO_MINI_WAKE 3
43 /**
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 );
53 work->jobs = jobs;
54 work->current_job = job;
55 work->die = die;
56 work->error = error;
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)
63 hb_state_t state;
65 state.state = HB_STATE_WORKING;
66 #define p state.param.working
67 p.pass_id = pass_id;
68 p.pass = pass;
69 p.pass_count = pass_count;
70 p.progress = 0.0;
71 p.rate_cur = 0.0;
72 p.rate_avg = 0.0;
73 p.hours = -1;
74 p.minutes = -1;
75 p.seconds = -1;
76 #undef p
78 hb_set_state( h, &state );
82 /**
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;
89 hb_job_t * job;
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);
111 if (new_job == NULL)
113 hb_job_close(&job);
114 hb_list_close(&passes);
115 *work->error = HB_ERROR_INIT;
116 *work->die = 1;
117 break;
119 new_job->h = job->h;
120 hb_job_close(&job);
121 job = new_job;
123 hb_job_setup_passes(job->h, job, passes);
124 hb_job_close(&job);
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);
135 do_job( job );
136 *(work->current_job) = NULL;
138 // Clean up any incomplete jobs
139 for (; pass < pass_count; pass++)
141 job = hb_list_item(passes, pass);
142 hb_job_close(&job);
144 hb_list_close(&passes);
147 free( work );
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 )
155 if( w->id == id )
157 hb_work_object_t *wc = malloc( sizeof(*w) );
158 *wc = *w;
159 wc->h = h;
160 return wc;
163 return NULL;
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
174 switch (codec)
176 case HB_ACODEC_LPCM:
177 w = hb_get_work(h, WORK_DECLPCM);
178 w->yield = 1; // decoders yield to keep sync fifos more even
179 break;
180 default:
181 break;
183 return w;
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);
192 switch (codec)
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);
199 default: break;
201 return NULL;
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)
210 int i;
211 hb_title_t *title = job->title;
212 hb_audio_t *audio;
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 )
222 int64_t 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;
231 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;
236 min_stop %= 60;
238 if (job->pts_to_stop)
240 hb_log(" + title %d, start %02d:%02d:%02.2f stop %02d:%02d:%02.2f",
241 title->index,
242 hr_start, min_start, sec_start,
243 hr_stop, min_stop, sec_stop);
245 else
247 hb_log(" + title %d, start %02d:%02d:%02.2f",
248 title->index,
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 );
257 else
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));
276 switch (job->mux)
278 case HB_MUX_AV_MP4:
279 if (job->mp4_optimize)
280 hb_log(" + optimized for HTTP streaming (fast start)");
281 if (job->ipod_atom)
282 hb_log(" + compatibility atom for iPod 5G");
283 break;
285 default:
286 break;
289 if( job->chapter_markers )
291 hb_log( " + chapter markers" );
294 hb_log(" * video track");
296 #ifdef USE_QSV
297 if (hb_qsv_decode_is_enabled(job))
299 hb_log(" + decoder: %s",
300 hb_qsv_decode_get_codec_name(title->video_codec_param));
302 else
303 #endif
304 #ifdef USE_HWD
305 if (hb_hwd_enabled(job->h))
307 hb_log(" + decoder: %s (dxva2)", title->video_codec_name);
309 else
310 #endif
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);
329 else
330 hb_log(" + %s (default settings)", filter->name);
331 if( filter->info )
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 )
355 /* Video encoder */
356 hb_log(" + encoder: %s",
357 hb_video_encoder_get_long_name(job->vcodec));
359 if (job->encoder_preset && *job->encoder_preset)
361 switch (job->vcodec)
363 case HB_VCODEC_X264:
364 case HB_VCODEC_X265:
365 case HB_VCODEC_QSV_H264:
366 hb_log(" + preset: %s", job->encoder_preset);
367 default:
368 break;
371 if (job->encoder_tune && *job->encoder_tune)
373 switch (job->vcodec)
375 case HB_VCODEC_X264:
376 case HB_VCODEC_X265:
377 hb_log(" + tune: %s", job->encoder_tune);
378 default:
379 break;
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)
389 switch (job->vcodec)
391 case HB_VCODEC_X264:
392 case HB_VCODEC_X265:
393 case HB_VCODEC_QSV_H264:
394 hb_log(" + profile: %s", job->encoder_profile);
395 default:
396 break;
399 if (job->encoder_level && *job->encoder_level)
401 switch (job->vcodec)
403 case HB_VCODEC_X264:
404 case HB_VCODEC_QSV_H264:
405 hb_log(" + level: %s", job->encoder_level);
406 default:
407 break;
411 if (job->vquality >= 0)
413 hb_log(" + quality: %.2f (%s)", job->vquality,
414 hb_video_quality_get_name(job->vcodec));
416 else
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 );
456 if( subtitle )
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 );
474 else
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);
504 else
505 hb_log(" + samplerate: %d Hz",
506 audio->config.in.samplerate);
508 if( audio->config.out.codec & HB_ACODEC_PASS_FLAG )
510 hb_log(" + %s",
511 hb_audio_encoder_get_name(audio->config.out.codec));
513 else
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.
580 * Initializes fifos.
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)
590 int i;
591 hb_title_t *title;
592 hb_interjob_t *interjob;
593 hb_work_object_t *w;
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);
598 hb_audio_t *audio;
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;
607 title = job->title;
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();
618 * OpenCL
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();
628 job->use_opencl = 0;
630 else
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 );
652 if( subtitle )
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 );
668 free( subtitle );
669 continue;
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;
676 else
678 // avoid infinite loop is subtitle == NULL
679 i++;
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;
696 else
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 )
712 if ( one_burned )
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 );
718 free( subtitle );
719 continue;
721 else
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;
732 else
734 one_burned = 1;
738 if ( subtitle->config.dest == PASSTHRUSUB &&
739 !hb_subtitle_can_pass(subtitle->source, job->mux) )
741 if ( !one_burned )
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;
746 one_burned = 1;
748 else
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 );
752 free( subtitle );
753 continue;
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;
761 if (one_burned)
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);
773 #ifdef USE_QSV
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)
784 int encode_only = 0;
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);
788 switch (filter->id)
790 // validated, CPU-based filters
791 case HB_FILTER_ROTATE:
792 case HB_FILTER_RENDER_SUB:
793 encode_only = 1;
794 break;
796 // CPU-based deinterlace (validated)
797 case HB_FILTER_DEINTERLACE:
798 if (filter->settings != NULL &&
799 strcasecmp(filter->settings, "qsv") != 0)
801 encode_only = 1;
803 break;
805 // other filters will be removed
806 default:
807 break;
810 if (encode_only)
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");
817 job->qsv.decode = 0;
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))
828 int vpp_settings[7];
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);
844 switch (filter->id)
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);
854 else
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
862 if (job->use_opencl)
864 hb_release_opencl_run_env();
865 job->use_opencl = 0;
867 hb_list_rem(job->list_filter, filter);
868 hb_filter_close(&filter);
869 break;
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
877 vpp_settings[6] = 1;
878 hb_list_rem(job->list_filter, filter);
879 hb_filter_close(&filter);
881 else
883 // validated
884 num_cpu_filters++;
886 break;
888 // then, validated filters
889 case HB_FILTER_ROTATE: // TODO: use Media SDK for this
890 case HB_FILTER_RENDER_SUB:
891 num_cpu_filters++;
892 break;
894 // finally, drop all unsupported filters
895 default:
896 hb_log("do_job: QSV: full path, removing unsupported filter '%s'",
897 filter->name);
898 hb_list_rem(job->list_filter, filter);
899 hb_filter_close(&filter);
900 break;
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",
921 vpp_settings[0],
922 vpp_settings[1],
923 vpp_settings[2],
924 vpp_settings[3],
925 vpp_settings[4],
926 vpp_settings[5],
927 vpp_settings[6]);
928 filter = hb_filter_init(HB_FILTER_QSV);
929 hb_add_filter(job, filter, settings);
930 free(settings);
934 #endif
936 #ifdef USE_HWD
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);
947 else
948 #endif
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;
959 init.job = job;
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;
967 init.cfr = 0;
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",
974 filter->name );
975 hb_list_rem( job->list_filter, filter );
976 hb_filter_close( &filter );
977 continue;
979 i++;
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;
986 job->cfr = init.cfr;
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",
997 filter->name );
998 hb_list_rem( job->list_filter, filter );
999 hb_filter_close( &filter );
1000 continue;
1002 i++;
1005 else
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;
1012 job->cfr = 0;
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);
1032 #ifdef USE_QSV
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 );
1041 else
1042 #endif
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);
1067 free(audio);
1068 continue;
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);
1077 free(audio);
1078 continue;
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;
1108 continue;
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;
1121 best_samplerate =
1122 hb_audio_samplerate_get_best(audio->config.out.codec,
1123 audio->config.out.samplerate,
1124 NULL);
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));
1144 else
1146 best_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);
1173 else
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);
1185 else
1187 hb_log("work: sanitizing track %d compression level %.2f to %.2f",
1188 audio->config.out.track,
1189 audio->config.out.compression_level,
1190 best_compression);
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);
1209 else
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);
1236 else
1238 best_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 );
1279 /* Video decoder */
1280 if (title->video_codec == WORK_NONE)
1282 hb_error("No video decoder set!");
1283 goto cleanup;
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 );
1295 if( subtitle )
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 );
1324 int i;
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;
1343 /* Video encoder */
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;
1349 break;
1350 case HB_VCODEC_FFMPEG_MPEG2:
1351 w = hb_get_work( job->h, WORK_ENCAVCODEC );
1352 w->codec_param = AV_CODEC_ID_MPEG2VIDEO;
1353 break;
1354 case HB_VCODEC_FFMPEG_VP8:
1355 w = hb_get_work( job->h, WORK_ENCAVCODEC );
1356 w->codec_param = AV_CODEC_ID_VP8;
1357 break;
1358 case HB_VCODEC_X264:
1359 w = hb_get_work( job->h, WORK_ENCX264 );
1360 break;
1361 case HB_VCODEC_QSV_H264:
1362 w = hb_get_work( job->h, WORK_ENCQSV );
1363 break;
1364 case HB_VCODEC_THEORA:
1365 w = hb_get_work( job->h, WORK_ENCTHEORA );
1366 break;
1367 #ifdef USE_X265
1368 case HB_VCODEC_X265:
1369 w = hb_get_work( job->h, WORK_ENCX265 );
1370 break;
1371 #endif
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;
1377 else
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);
1395 if (w == NULL)
1397 hb_error("Invalid input codec: %d", audio->config.in.codec);
1398 *job->done_error = HB_ERROR_WRONG_INPUT;
1399 *job->die = 1;
1400 goto cleanup;
1402 w->fifo_in = audio->priv.fifo_in;
1403 w->fifo_out = audio->priv.fifo_raw;
1404 w->config = &audio->priv.config;
1405 w->audio = audio;
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);
1420 if (w == NULL)
1422 hb_error("Invalid audio codec: %#x", audio->config.out.codec);
1423 w = NULL;
1424 *job->done_error = HB_ERROR_WRONG_INPUT;
1425 *job->die = 1;
1426 goto cleanup;
1428 w->fifo_in = audio->priv.fifo_sync;
1429 w->fifo_out = audio->priv.fifo_out;
1430 w->config = &audio->priv.config;
1431 w->audio = audio;
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;
1452 *job->die = 1;
1453 goto cleanup;
1455 reader->done = &job->done;
1456 reader->thread = hb_thread_init( reader->name, ReadLoop, reader, HB_NORMAL_PRIORITY );
1458 job->done = 0;
1460 if( job->list_filter && !job->indepth_scan )
1462 int filter_count = hb_list_count( job->list_filter );
1463 int i;
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,
1475 HB_LOW_PRIORITY );
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;
1489 *job->die = 1;
1490 goto cleanup;
1492 w->thread = hb_thread_init( w->name, work_loop, w,
1493 HB_LOW_PRIORITY );
1496 if ( job->indepth_scan )
1498 muxer = NULL;
1499 w = sync;
1500 sync->done = &job->done;
1502 else
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;
1510 *job->die = 1;
1511 goto cleanup;
1513 sync->thread = hb_thread_init( sync->name, work_loop, sync,
1514 HB_LOW_PRIORITY );
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 );
1519 w = muxer;
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 )
1528 continue;
1529 if ( *job->die )
1531 if( buf_in )
1533 hb_buffer_close( &buf_in );
1535 break;
1538 buf_out = NULL;
1539 w->status = w->work( w, &buf_in, &buf_out );
1541 if( buf_in )
1543 hb_buffer_close( &buf_in );
1545 if ( buf_out && w->fifo_out == NULL )
1547 hb_buffer_close( &buf_out );
1549 if( buf_out )
1551 while ( !*job->die )
1553 if ( hb_fifo_full_wait( w->fifo_out ) )
1555 hb_fifo_push( w->fifo_out, buf_out );
1556 buf_out = NULL;
1557 break;
1563 if ( buf_out )
1565 hb_buffer_close( &buf_out );
1568 hb_handle_t * h = job->h;
1569 hb_state_t state;
1570 hb_get_state2( h, &state );
1572 hb_log("work: average encoding speed for job is %f fps", state.param.working.rate_avg);
1574 job->done = 1;
1575 if( muxer != NULL )
1577 muxer->close( muxer );
1578 free( muxer );
1580 if( sync->thread != NULL )
1582 hb_thread_close( &sync->thread );
1583 sync->close( sync );
1585 free( sync );
1588 cleanup:
1589 /* Stop the write thread (thread_close will block until the muxer finishes) */
1590 job->done = 1;
1592 // Close render filter pipeline
1593 if( job->list_filter )
1595 int filter_count = hb_list_count( job->list_filter );
1596 int i;
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 );
1619 w->close( w );
1621 free( w );
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 );
1632 free( reader );
1634 /* Close fifos */
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 );
1643 if( subtitle )
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 )
1686 continue;
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)",
1716 subtitle_hit );
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
1723 * default?
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 );
1729 else
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
1741 // of the subtitle.
1742 hb_list_rem( job->list_subtitle, subtitle );
1743 interjob->select_subtitle = subtitle;
1744 break;
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 )
1784 continue;
1785 if ( *w->done )
1787 if( buf_in )
1789 hb_buffer_close( &buf_in );
1791 break;
1793 // Invalidate buf_out so that if there is no output
1794 // we don't try to pass along junk.
1795 buf_out = NULL;
1796 w->status = w->work( w, &buf_in, &buf_out );
1798 copy_chapter( buf_out, buf_in );
1800 if( buf_in )
1802 hb_buffer_close( &buf_in );
1804 if ( buf_out && w->fifo_out == NULL )
1806 hb_buffer_close( &buf_out );
1808 if( buf_out )
1810 while ( !*w->done )
1812 if ( hb_fifo_full_wait( w->fifo_out ) )
1814 hb_fifo_push( w->fifo_out, buf_out );
1815 buf_out = NULL;
1816 break;
1820 if (w->yield)
1822 hb_yield();
1825 if ( 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
1832 while( !*w->done )
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 )
1857 continue;
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;
1868 if ( *f->done )
1870 if( buf_in )
1872 hb_buffer_close( &buf_in );
1874 break;
1877 buf_out = NULL;
1879 #ifdef USE_QSV
1880 hb_buffer_t *last_buf_in = buf_in;
1881 #endif
1883 f->status = f->work( f, &buf_in, &buf_out );
1885 #ifdef USE_QSV
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);
1898 #endif
1899 if ( buf_out && f->chapter_val && f->chapter_time <= buf_out->s.start )
1901 buf_out->s.new_chap = f->chapter_val;
1902 f->chapter_val = 0;
1905 if( buf_in )
1907 hb_buffer_close( &buf_in );
1909 if ( buf_out && f->fifo_out == NULL )
1911 hb_buffer_close( &buf_out );
1913 if( buf_out )
1915 while ( !*f->done )
1917 if ( hb_fifo_full_wait( f->fifo_out ) )
1919 hb_fifo_push( f->fifo_out, buf_out );
1920 buf_out = NULL;
1921 break;
1926 if ( 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
1933 while( !*f->done )
1935 buf_in = hb_fifo_get_wait( f->fifo_in );
1936 if ( buf_in != NULL )
1937 hb_buffer_close( &buf_in );