diff options
Diffstat (limited to 'libhb/common.c')
-rw-r--r-- | libhb/common.c | 742 |
1 files changed, 704 insertions, 38 deletions
diff --git a/libhb/common.c b/libhb/common.c index 821f17e76..80b526c2a 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -306,13 +306,13 @@ const char* hb_mixdown_get_short_name_from_mixdown(int amixdown) return ""; } -void hb_autopassthru_apply_settings( hb_job_t * job, hb_title_t * title ) +void hb_autopassthru_apply_settings( hb_job_t * job ) { int i, j, already_printed; hb_audio_t * audio; - for( i = 0, already_printed = 0; i < hb_list_count( title->list_audio ); ) + for( i = 0, already_printed = 0; i < hb_list_count( job->list_audio ); ) { - audio = hb_list_item( title->list_audio, i ); + audio = hb_list_item( job->list_audio, i ); if( audio->config.out.codec == HB_ACODEC_AUTO_PASS ) { if( !already_printed ) @@ -327,8 +327,8 @@ void hb_autopassthru_apply_settings( hb_job_t * job, hb_title_t * title ) { hb_log( "Auto Passthru: passthru not possible and no valid fallback specified, dropping track %d", audio->config.out.track ); - hb_list_rem( title->list_audio, audio ); - free( audio ); + hb_list_rem( job->list_audio, audio ); + hb_audio_close( &audio ); continue; } audio->config.out.samplerate = audio->config.in.samplerate; @@ -1157,7 +1157,7 @@ hb_list_t * hb_list_init() ********************************************************************** * Returns the number of items currently in the list *********************************************************************/ -int hb_list_count( hb_list_t * l ) +int hb_list_count( const hb_list_t * l ) { return l->items_count; } @@ -1252,7 +1252,7 @@ void hb_list_rem( hb_list_t * l, void * p ) * Returns item at position i, or NULL if there are not that many * items in the list *********************************************************************/ -void * hb_list_item( hb_list_t * l, int i ) +void * hb_list_item( const hb_list_t * l, int i ) { if( i < 0 || i >= l->items_count ) { @@ -1575,6 +1575,19 @@ void hb_register_error_handler( hb_error_handler_t * handler ) error_handler = handler; } +static void hb_update_str( char **dst, const char *src ) +{ + if ( dst ) + { + free( *dst ); + *dst = NULL; + if ( src ) + { + *dst = strdup( src ); + } + } +} + /********************************************************************** * hb_title_init ********************************************************************** @@ -1592,6 +1605,7 @@ hb_title_t * hb_title_init( char * path, int index ) t->list_chapter = hb_list_init(); t->list_subtitle = hb_list_init(); t->list_attachment = hb_list_init(); + t->metadata = hb_metadata_init(); strcat( t->path, path ); // default to decoding mpeg2 t->video_id = 0xE0; @@ -1616,65 +1630,252 @@ void hb_title_close( hb_title_t ** _t ) hb_subtitle_t * subtitle; hb_attachment_t * attachment; - while( ( audio = hb_list_item( t->list_audio, 0 ) ) ) - { - hb_list_rem( t->list_audio, audio ); - free( audio ); - } - hb_list_close( &t->list_audio ); - while( ( chapter = hb_list_item( t->list_chapter, 0 ) ) ) { hb_list_rem( t->list_chapter, chapter ); - free( chapter ); + hb_chapter_close( &chapter ); } hb_list_close( &t->list_chapter ); + while( ( audio = hb_list_item( t->list_audio, 0 ) ) ) + { + hb_list_rem( t->list_audio, audio ); + hb_audio_close( &audio ); + } + hb_list_close( &t->list_audio ); + while( ( subtitle = hb_list_item( t->list_subtitle, 0 ) ) ) { hb_list_rem( t->list_subtitle, subtitle ); - if ( subtitle->extradata ) - { - free( subtitle->extradata ); - subtitle->extradata = NULL; - } - free( subtitle ); + hb_subtitle_close( &subtitle ); } hb_list_close( &t->list_subtitle ); while( ( attachment = hb_list_item( t->list_attachment, 0 ) ) ) { hb_list_rem( t->list_attachment, attachment ); - if ( attachment->name ) + hb_attachment_close( &attachment ); + } + hb_list_close( &t->list_attachment ); + + hb_metadata_close( &t->metadata ); + + free( t->video_codec_name ); + free(t->container_name); + +#if defined(HB_TITLE_JOBS) + hb_job_close( &t->job ); +#endif + + free( t ); + *_t = NULL; +} + +/* + * Create a pristine job structure from a title + * title_index is 1 based + */ +hb_job_t * hb_job_init_by_index( hb_handle_t * h, int title_index ) +{ + hb_title_set_t *title_set = hb_get_title_set( h ); + hb_title_t * title = hb_list_item( title_set->list_title, + title_index - 1 ); + return hb_job_init( title ); +} + +hb_job_t * hb_job_init( hb_title_t * title ) +{ + hb_job_t * job; + + if ( title == NULL ) + return NULL; + + job = calloc( sizeof( hb_job_t ), 1 ); + + job->title = title; + + /* Set defaults settings */ + job->chapter_start = 1; + job->chapter_end = hb_list_count( title->list_chapter ); + job->list_chapter = hb_chapter_list_copy( title->list_chapter ); + + /* Autocrop by default. Gnark gnark */ + memcpy( job->crop, title->crop, 4 * sizeof( int ) ); + + /* Preserve a source's pixel aspect, if it's available. */ + if( title->pixel_aspect_width && title->pixel_aspect_height ) + { + job->anamorphic.par_width = title->pixel_aspect_width; + job->anamorphic.par_height = title->pixel_aspect_height; + } + + if( title->aspect != 0 && title->aspect != 1. && + !job->anamorphic.par_width && !job->anamorphic.par_height) + { + hb_reduce( &job->anamorphic.par_width, &job->anamorphic.par_height, + (int)(title->aspect * title->height + 0.5), title->width ); + } + + job->width = title->width - job->crop[2] - job->crop[3]; + hb_fix_aspect( job, HB_KEEP_WIDTH ); + if( job->height > title->height - job->crop[0] - job->crop[1] ) + { + job->height = title->height - job->crop[0] - job->crop[1]; + hb_fix_aspect( job, HB_KEEP_HEIGHT ); + } + + job->keep_ratio = 1; + + job->vcodec = HB_VCODEC_FFMPEG_MPEG4; + job->vquality = -1.0; + job->vbitrate = 1000; + job->pass = 0; + job->vrate = title->rate; + job->vrate_base = title->rate_base; + + job->mux = HB_MUX_MP4; + + job->list_audio = hb_list_init(); + job->list_subtitle = hb_list_init(); + job->list_filter = hb_list_init(); + + job->list_attachment = hb_attachment_list_copy( title->list_attachment ); + job->metadata = hb_metadata_copy( title->metadata ); + + return job; +} + +/** + * Clean up the job structure so that is is ready for setting up a new job. + * Should be called by front-ends after hb_add(). + */ +/********************************************************************** + * hb_job_reset + ********************************************************************** + * + *********************************************************************/ +void hb_job_reset( hb_job_t * job ) +{ + if ( job ) + { + hb_audio_t *audio; + hb_subtitle_t *subtitle; + hb_filter_object_t *filter; + hb_title_t * title = job->title; + + // clean up audio list + while( ( audio = hb_list_item( job->list_audio, 0 ) ) ) + { + hb_list_rem( job->list_audio, audio ); + hb_audio_close( &audio ); + } + + // clean up subtitle list + while( ( subtitle = hb_list_item( job->list_subtitle, 0 ) ) ) { - free( attachment->name ); - attachment->name = NULL; + hb_list_rem( job->list_subtitle, subtitle ); + hb_subtitle_close( &subtitle ); } - if ( attachment->data ) + + // clean up filter list + while( ( filter = hb_list_item( job->list_filter, 0 ) ) ) { - free( attachment->data ); - attachment->data = NULL; + hb_list_rem( job->list_filter, filter ); + hb_filter_close( &filter ); } - free( attachment ); + + hb_metadata_close( &job->metadata ); + job->metadata = hb_metadata_copy( title->metadata ); } - hb_list_close( &t->list_attachment ); +} - if( t->metadata ) +/********************************************************************** + * hb_job_close + ********************************************************************** + * + *********************************************************************/ +void hb_job_close( hb_job_t ** _j ) +{ + if (_j) { - if( t->metadata->coverart ) + hb_job_t * job = *_j; + + if (job) { - free( t->metadata->coverart ); + hb_chapter_t *chapter; + hb_audio_t *audio; + hb_subtitle_t *subtitle; + hb_filter_object_t *filter; + hb_attachment_t *attachment; + + free(job->file); + free(job->advanced_opts); + + // clean up chapter list + while( ( chapter = hb_list_item( job->list_chapter, 0 ) ) ) + { + hb_list_rem( job->list_chapter, chapter ); + hb_chapter_close( &chapter ); + } + hb_list_close( &job->list_chapter ); + + // clean up audio list + while( ( audio = hb_list_item( job->list_audio, 0 ) ) ) + { + hb_list_rem( job->list_audio, audio ); + hb_audio_close( &audio ); + } + hb_list_close( &job->list_audio ); + + // clean up subtitle list + while( ( subtitle = hb_list_item( job->list_subtitle, 0 ) ) ) + { + hb_list_rem( job->list_subtitle, subtitle ); + hb_subtitle_close( &subtitle ); + } + hb_list_close( &job->list_subtitle ); + + // clean up filter list + while( ( filter = hb_list_item( job->list_filter, 0 ) ) ) + { + hb_list_rem( job->list_filter, filter ); + hb_filter_close( &filter ); + } + hb_list_close( &job->list_filter ); + + // clean up attachment list + while( ( attachment = hb_list_item( job->list_attachment, 0 ) ) ) + { + hb_list_rem( job->list_attachment, attachment ); + hb_attachment_close( &attachment ); + } + hb_list_close( &job->list_attachment ); + + // clean up metadata + if ( job->metadata ) + { + hb_metadata_close( &job->metadata ); + } + free( job ); } - free( t->metadata ); + _j = NULL; } +} - if ( t->video_codec_name ) +void hb_job_set_file( hb_job_t *job, const char *file ) +{ + if ( job ) { - free( t->video_codec_name ); + hb_update_str( &job->file, file ); } +} - free( t ); - *_t = NULL; +void hb_job_set_advanced_opts( hb_job_t *job, const char *advanced_opts ) +{ + if ( job ) + { + hb_update_str( &job->advanced_opts, advanced_opts ); + } } hb_filter_object_t * hb_filter_copy( hb_filter_object_t * filter ) @@ -1689,6 +1890,30 @@ hb_filter_object_t * hb_filter_copy( hb_filter_object_t * filter ) return filter_copy; } +/********************************************************************** + * hb_filter_list_copy + ********************************************************************** + * + *********************************************************************/ +hb_list_t *hb_filter_list_copy(const hb_list_t *src) +{ + hb_list_t *list = hb_list_init(); + hb_filter_object_t *filter = NULL; + int i; + + if( src ) + { + for( i = 0; i < hb_list_count(src); i++ ) + { + if( ( filter = hb_list_item( src, i ) ) ) + { + hb_list_add( list, hb_filter_copy(filter) ); + } + } + } + return list; +} + /** * Gets a filter object with the given type * @param filter_id The type of filter to get. @@ -1759,6 +1984,93 @@ void hb_filter_close( hb_filter_object_t ** _f ) } /********************************************************************** + * hb_chapter_copy + ********************************************************************** + * + *********************************************************************/ +hb_chapter_t *hb_chapter_copy(const hb_chapter_t *src) +{ + hb_chapter_t *chap = NULL; + + if ( src ) + { + chap = calloc( 1, sizeof(*chap) ); + memcpy( chap, src, sizeof(*chap) ); + if ( src->title ) + { + chap->title = strdup( src->title ); + } + } + return chap; +} + +/********************************************************************** + * hb_chapter_list_copy + ********************************************************************** + * + *********************************************************************/ +hb_list_t *hb_chapter_list_copy(const hb_list_t *src) +{ + hb_list_t *list = hb_list_init(); + hb_chapter_t *chapter = NULL; + int i; + + if( src ) + { + for( i = 0; i < hb_list_count(src); i++ ) + { + if( ( chapter = hb_list_item( src, i ) ) ) + { + hb_list_add( list, hb_chapter_copy(chapter) ); + } + } + } + return list; +} + +/********************************************************************** + * hb_chapter_close + ********************************************************************** + * + *********************************************************************/ +void hb_chapter_close(hb_chapter_t **chap) +{ + if ( chap && *chap ) + { + free((*chap)->title); + free(*chap); + *chap = NULL; + } +} + +/********************************************************************** + * hb_chapter_set_title + ********************************************************************** + * + *********************************************************************/ +void hb_chapter_set_title( hb_chapter_t *chapter, const char *title ) +{ + if ( chapter ) + { + hb_update_str( &chapter->title, title ); + } +} + +/********************************************************************** + * hb_chapter_set_title_by_index + ********************************************************************** + * Applies information from the given job to the official job instance. + * @param job Handle to hb_job_t. + * @param chapter The chapter to apply the name to (1-based). + * @param titel to apply. + *********************************************************************/ +void hb_chapter_set_title_by_index( hb_job_t * job, int chapter_index, const char * title ) +{ + hb_chapter_t * chapter = hb_list_item( job->list_chapter, chapter_index - 1 ); + hb_chapter_set_title( chapter, title ); +} + +/********************************************************************** * hb_audio_copy ********************************************************************** * @@ -1771,11 +2083,54 @@ hb_audio_t *hb_audio_copy(const hb_audio_t *src) { audio = calloc(1, sizeof(*audio)); memcpy(audio, src, sizeof(*audio)); + if ( src->config.out.name ) + { + audio->config.out.name = strdup(src->config.out.name); + } } return audio; } /********************************************************************** + * hb_audio_list_copy + ********************************************************************** + * + *********************************************************************/ +hb_list_t *hb_audio_list_copy(const hb_list_t *src) +{ + hb_list_t *list = hb_list_init(); + hb_audio_t *audio = NULL; + int i; + + if( src ) + { + for( i = 0; i < hb_list_count(src); i++ ) + { + if( ( audio = hb_list_item( src, i ) ) ) + { + hb_list_add( list, hb_audio_copy(audio) ); + } + } + } + return list; +} + +/********************************************************************** + * hb_audio_close + ********************************************************************** + * + *********************************************************************/ +void hb_audio_close( hb_audio_t **audio ) +{ + if ( audio && *audio ) + { + free((*audio)->config.out.name); + free(*audio); + *audio = NULL; + } +} + +/********************************************************************** * hb_audio_new ********************************************************************** * @@ -1878,7 +2233,7 @@ int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg) } if (audiocfg->out.name && *audiocfg->out.name) { - audio->config.out.name = audiocfg->out.name; + audio->config.out.name = strdup(audiocfg->out.name); } hb_list_add(job->list_audio, audio); @@ -1918,6 +2273,45 @@ hb_subtitle_t *hb_subtitle_copy(const hb_subtitle_t *src) } /********************************************************************** + * hb_subtitle_list_copy + ********************************************************************** + * + *********************************************************************/ +hb_list_t *hb_subtitle_list_copy(const hb_list_t *src) +{ + hb_list_t *list = hb_list_init(); + hb_subtitle_t *subtitle = NULL; + int i; + + if( src ) + { + for( i = 0; i < hb_list_count(src); i++ ) + { + if( ( subtitle = hb_list_item( src, i ) ) ) + { + hb_list_add( list, hb_subtitle_copy(subtitle) ); + } + } + } + return list; +} + +/********************************************************************** + * hb_subtitle_close + ********************************************************************** + * + *********************************************************************/ +void hb_subtitle_close( hb_subtitle_t **sub ) +{ + if ( sub && *sub ) + { + free ((*sub)->extradata); + free(*sub); + *sub = NULL; + } +} + +/********************************************************************** * hb_subtitle_add ********************************************************************** * @@ -2026,6 +2420,238 @@ int hb_subtitle_can_pass( int source, int mux ) } } +/********************************************************************** + * hb_metadata_init + ********************************************************************** + * + *********************************************************************/ +hb_metadata_t *hb_metadata_init() +{ + hb_metadata_t *metadata = calloc( 1, sizeof(*metadata) ); + return metadata; +} + +/********************************************************************** + * hb_metadata_copy + ********************************************************************** + * + *********************************************************************/ +hb_metadata_t *hb_metadata_copy( const hb_metadata_t *src ) +{ + hb_metadata_t *metadata = NULL; + + if ( src ) + { + metadata = calloc( 1, sizeof(*metadata) ); + if ( src->name ) + { + metadata->name = strdup(src->name); + } + if ( src->artist ) + { + metadata->artist = strdup(src->artist); + } + if ( src->album_artist ) + { + metadata->album_artist = strdup(src->album_artist); + } + if ( src->composer ) + { + metadata->composer = strdup(src->composer); + } + if ( src->release_date ) + { + metadata->release_date = strdup(src->release_date); + } + if ( src->comment ) + { + metadata->comment = strdup(src->comment); + } + if ( src->album ) + { + metadata->album = strdup(src->album); + } + if ( src->genre ) + { + metadata->genre = strdup(src->genre); + } + if ( src->description ) + { + metadata->description = strdup(src->description); + } + if ( src->long_description ) + { + metadata->long_description = strdup(src->long_description); + } + if ( src->list_coverart ) + { + int ii; + for ( ii = 0; ii < hb_list_count( src->list_coverart ); ii++ ) + { + hb_coverart_t *art = hb_list_item( src->list_coverart, ii ); + hb_metadata_add_coverart( + metadata, art->data, art->size, art->type ); + } + } + } + return metadata; +} + +/********************************************************************** + * hb_metadata_close + ********************************************************************** + * + *********************************************************************/ +void hb_metadata_close( hb_metadata_t **_m ) +{ + if ( _m && *_m ) + { + hb_metadata_t *m = *_m; + hb_coverart_t *art; + + free( m->name ); + free( m->artist ); + free( m->composer ); + free( m->release_date ); + free( m->comment ); + free( m->album ); + free( m->album_artist ); + free( m->genre ); + free( m->description ); + free( m->long_description ); + + if ( m->list_coverart ) + { + while( ( art = hb_list_item( m->list_coverart, 0 ) ) ) + { + hb_list_rem( m->list_coverart, art ); + free( art->data ); + free( art ); + } + hb_list_close( &m->list_coverart ); + } + + free( m ); + *_m = NULL; + } +} + +/********************************************************************** + * hb_metadata_set_* + ********************************************************************** + * + *********************************************************************/ +void hb_metadata_set_name( hb_metadata_t *metadata, const char *name ) +{ + if ( metadata ) + { + hb_update_str( &metadata->name, name ); + } +} + +void hb_metadata_set_artist( hb_metadata_t *metadata, const char *artist ) +{ + if ( metadata ) + { + hb_update_str( &metadata->artist, artist ); + } +} + +void hb_metadata_set_composer( hb_metadata_t *metadata, const char *composer ) +{ + if ( metadata ) + { + hb_update_str( &metadata->composer, composer ); + } +} + +void hb_metadata_set_release_date( hb_metadata_t *metadata, const char *release_date ) +{ + if ( metadata ) + { + hb_update_str( &metadata->release_date, release_date ); + } +} + +void hb_metadata_set_comment( hb_metadata_t *metadata, const char *comment ) +{ + if ( metadata ) + { + hb_update_str( &metadata->comment, comment ); + } +} + +void hb_metadata_set_genre( hb_metadata_t *metadata, const char *genre ) +{ + if ( metadata ) + { + hb_update_str( &metadata->genre, genre ); + } +} + +void hb_metadata_set_album( hb_metadata_t *metadata, const char *album ) +{ + if ( metadata ) + { + hb_update_str( &metadata->album, album ); + } +} + +void hb_metadata_set_album_artist( hb_metadata_t *metadata, const char *album_artist ) +{ + if ( metadata ) + { + hb_update_str( &metadata->album_artist, album_artist ); + } +} + +void hb_metadata_set_description( hb_metadata_t *metadata, const char *description ) +{ + if ( metadata ) + { + hb_update_str( &metadata->description, description ); + } +} + +void hb_metadata_set_long_description( hb_metadata_t *metadata, const char *long_description ) +{ + if ( metadata ) + { + hb_update_str( &metadata->long_description, long_description ); + } +} + +void hb_metadata_add_coverart( hb_metadata_t *metadata, const uint8_t *data, int size, int type ) +{ + if ( metadata ) + { + if ( metadata->list_coverart == NULL ) + { + metadata->list_coverart = hb_list_init(); + } + hb_coverart_t *art = calloc( 1, sizeof(hb_coverart_t) ); + art->data = malloc( size ); + memcpy( art->data, data, size ); + art->size = size; + art->type = type; + hb_list_add( metadata->list_coverart, art ); + } +} + +void hb_metadata_rem_coverart( hb_metadata_t *metadata, int idx ) +{ + if ( metadata ) + { + hb_coverart_t *art = hb_list_item( metadata->list_coverart, idx ); + if ( art ) + { + hb_list_rem( metadata->list_coverart, art ); + free( art->data ); + free( art ); + } + } +} + char * hb_strdup_printf( const char * fmt, ... ) { int len; @@ -2119,6 +2745,46 @@ hb_attachment_t *hb_attachment_copy(const hb_attachment_t *src) } /********************************************************************** + * hb_attachment_list_copy + ********************************************************************** + * + *********************************************************************/ +hb_list_t *hb_attachment_list_copy(const hb_list_t *src) +{ + hb_list_t *list = hb_list_init(); + hb_attachment_t *attachment = NULL; + int i; + + if( src ) + { + for( i = 0; i < hb_list_count(src); i++ ) + { + if( ( attachment = hb_list_item( src, i ) ) ) + { + hb_list_add( list, hb_attachment_copy(attachment) ); + } + } + } + return list; +} + +/********************************************************************** + * hb_attachment_close + ********************************************************************** + * + *********************************************************************/ +void hb_attachment_close( hb_attachment_t **attachment ) +{ + if ( attachment && *attachment ) + { + free((*attachment)->data); + free((*attachment)->name); + free(*attachment); + *attachment = NULL; + } +} + +/********************************************************************** * hb_yuv2rgb ********************************************************************** * Converts a YCrCb pixel to an RGB pixel. |