/*********************************************************************** * hb_reader_init *********************************************************************** * **********************************************************************/ hb_thread_t * hb_reader_init( hb_job_t * job ) { hb_reader_t * r; r = calloc( sizeof( hb_reader_t ), 1 ); r->job = job; r->title = job->title; r->die = job->die; r->sequence = 0; r->st_slots = 4; r->stream_timing = calloc( sizeof(stream_timing_t), r->st_slots ); r->stream_timing[0].id = r->title->video_id; r->stream_timing[0].average = 90000. * (double)job->vrate_base / (double)job->vrate; r->stream_timing[0].last = -r->stream_timing[0].average; r->stream_timing[0].valid = 1; r->stream_timing[1].id = -1; if ( !job->pts_to_start ) r->start_found = 1; return hb_thread_init( "reader", ReaderFunc, r, HB_NORMAL_PRIORITY ); }
/*********************************************************************** * hb_reader_init *********************************************************************** * **********************************************************************/ hb_thread_t * hb_reader_init( hb_job_t * job ) { hb_reader_t * r; r = calloc( sizeof( hb_reader_t ), 1 ); r->job = job; r->title = job->title; r->die = job->die; r->sequence = 0; r->st_slots = 4; r->stream_timing = calloc( sizeof(stream_timing_t), r->st_slots ); r->stream_timing[0].id = r->title->video_id; r->stream_timing[0].average = 90000. * (double)job->vrate_base / (double)job->vrate; r->stream_timing[0].last = -r->stream_timing[0].average; r->stream_timing[0].valid = 1; r->stream_timing[1].id = -1; if ( !job->pts_to_start ) r->start_found = 1; else { // The frame at the actual start time may not be an i-frame // so can't be decoded without starting a little early. // sync.c will drop early frames. r->pts_to_start = MAX(0, job->pts_to_start - 180000); } return hb_thread_init( "reader", ReaderFunc, r, HB_NORMAL_PRIORITY ); }
hb_thread_t * hb_scan_init( hb_handle_t * handle, volatile int * die, const char * path, int title_index, hb_title_set_t * title_set, int preview_count, int store_previews, uint64_t min_duration ) { hb_scan_t * data = calloc( sizeof( hb_scan_t ), 1 ); data->h = handle; data->die = die; data->path = strdup( path ); data->title_index = title_index; data->title_set = title_set; data->preview_count = preview_count; data->store_previews = store_previews; data->min_title_duration = min_duration; // Initialize scan state hb_state_t state; #define p state.param.scanning state.state = HB_STATE_SCANNING; p.title_cur = 1; p.title_count = 1; p.preview_cur = 0; p.preview_count = 1; p.progress = 0.0; #undef p hb_set_state(handle, &state); return hb_thread_init( "scan", ScanFunc, data, HB_NORMAL_PRIORITY ); }
int taskset_thread_spawn( taskset_t *ts, int thr_idx, const char *descr, thread_func_t *func, int priority ) { ts->task_threads[thr_idx] = hb_thread_init( descr, func, taskset_thread_args( ts, thr_idx ), priority); return( ts->task_threads[thr_idx] != NULL ); }
hb_thread_t * hb_update_init( int * build, char * version ) { hb_update_t * data = calloc( sizeof( hb_update_t ), 1 ); data->build = build; data->version = version; return hb_thread_init( "update", UpdateFunc, data, HB_NORMAL_PRIORITY ); }
/** * Allocates work object and launches work thread with work_func. * @param jobs Handle to hb_list_t. * @param die Handle to user inititated exit indicator. * @param error Handle to error indicator. */ hb_thread_t * hb_work_init( hb_list_t * jobs, volatile int * die, int * error, hb_job_t ** job ) { hb_work_t * work = calloc( sizeof( hb_work_t ), 1 ); work->jobs = jobs; work->current_job = job; work->die = die; work->error = error; return hb_thread_init( "work", work_func, work, HB_LOW_PRIORITY ); }
hb_thread_t * hb_scan_init( hb_handle_t * handle, volatile int * die, const char * path, int title_index, hb_list_t * list_title, int preview_count, int store_previews, uint64_t min_duration ) { hb_scan_t * data = calloc( sizeof( hb_scan_t ), 1 ); data->h = handle; data->die = die; data->path = strdup( path ); data->title_index = title_index; data->list_title = list_title; data->preview_count = preview_count; data->store_previews = store_previews; data->min_title_duration = min_duration; return hb_thread_init( "scan", ScanFunc, data, HB_NORMAL_PRIORITY ); }
hb_work_object_t * hb_muxer_init( hb_job_t * job ) { hb_title_t * title = job->title; int i; hb_mux_t * mux = calloc( sizeof( hb_mux_t ), 1 ); hb_work_object_t * w; hb_work_object_t * muxer; mux->mutex = hb_lock_init(); // set up to interleave track data in blocks of 1 video frame time. // (the best case for buffering and playout latency). The container- // specific muxers can reblock this into bigger chunks if necessary. mux->interleave = 90000. * (double)job->vrate_base / (double)job->vrate; mux->pts = mux->interleave; /* Get a real muxer */ if( job->pass == 0 || job->pass == 2) { switch( job->mux ) { case HB_MUX_MP4: mux->m = hb_mux_mp4_init( job ); break; case HB_MUX_MKV: mux->m = hb_mux_mkv_init( job ); break; default: hb_error( "No muxer selected, exiting" ); *job->die = 1; return NULL; } /* Create file, write headers */ if( mux->m ) { mux->m->init( mux->m ); } } /* Initialize the work objects that will receive fifo data */ muxer = hb_get_work( WORK_MUX ); muxer->private_data = calloc( sizeof( hb_work_private_t ), 1 ); muxer->private_data->job = job; muxer->private_data->mux = mux; mux->ref++; muxer->private_data->track = mux->ntracks; muxer->fifo_in = job->fifo_mpeg4; add_mux_track( mux, job->mux_data, 1 ); muxer->done = &muxer->private_data->mux->done; for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { hb_audio_t *audio = hb_list_item( title->list_audio, i ); w = hb_get_work( WORK_MUX ); w->private_data = calloc( sizeof( hb_work_private_t ), 1 ); w->private_data->job = job; w->private_data->mux = mux; mux->ref++; w->private_data->track = mux->ntracks; w->fifo_in = audio->priv.fifo_out; add_mux_track( mux, audio->priv.mux_data, 1 ); w->done = &job->done; hb_list_add( job->list_work, w ); w->thread = hb_thread_init( w->name, mux_loop, w, HB_NORMAL_PRIORITY ); } for( i = 0; i < hb_list_count( title->list_subtitle ); i++ ) { hb_subtitle_t *subtitle = hb_list_item( title->list_subtitle, i ); if (subtitle->config.dest != PASSTHRUSUB) continue; w = hb_get_work( WORK_MUX ); w->private_data = calloc( sizeof( hb_work_private_t ), 1 ); w->private_data->job = job; w->private_data->mux = mux; mux->ref++; w->private_data->track = mux->ntracks; w->fifo_in = subtitle->fifo_out; add_mux_track( mux, subtitle->mux_data, 0 ); w->done = &job->done; hb_list_add( job->list_work, w ); w->thread = hb_thread_init( w->name, mux_loop, w, HB_NORMAL_PRIORITY ); } return muxer; }
hb_filter_private_t * hb_rotate_init( int pix_fmt, int width, int height, char * settings ) { if( pix_fmt != PIX_FMT_YUV420P ) { return 0; } hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) ); pv->pix_fmt = pix_fmt; pv->width[0] = width; pv->height[0] = height; pv->width[1] = pv->width[2] = width >> 1; pv->height[1] = pv->height[2] = height >> 1; pv->buf_out = hb_video_buffer_init( width, height ); pv->buf_settings = hb_buffer_init( 0 ); pv->mode = MODE_DEFAULT; pv->ref_stride[0] = pv->width[0]; pv->ref_stride[1] = pv->width[1]; pv->ref_stride[2] = pv->width[2]; if( settings ) { sscanf( settings, "%d", &pv->mode ); } pv->cpu_count = hb_get_cpu_count(); /* * Create threads and locks. */ pv->rotate_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count ); pv->rotate_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count ); pv->rotate_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count ); pv->rotate_arguments = malloc( sizeof( rotate_arguments_t ) * pv->cpu_count ); int i; for( i = 0; i < pv->cpu_count; i++ ) { rotate_thread_arg_t *thread_args; thread_args = malloc( sizeof( rotate_thread_arg_t ) ); if( thread_args ) { thread_args->pv = pv; thread_args->segment = i; pv->rotate_begin_lock[i] = hb_lock_init(); pv->rotate_complete_lock[i] = hb_lock_init(); /* * Important to start off with the threads locked waiting * on input. */ hb_lock( pv->rotate_begin_lock[i] ); pv->rotate_arguments[i].stop = 0; pv->rotate_arguments[i].dst = NULL; pv->rotate_threads[i] = hb_thread_init( "rotate_filter_segment", rotate_filter_thread, thread_args, HB_NORMAL_PRIORITY ); } else { hb_error( "rotate could not create threads" ); } } return pv; }