X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=gtk%2Fsrc%2Fhb-backend.c;h=fb76aa7c2fd702df4949f4a104a3256126bf5df3;hb=9460d9624a5cf24126bc39605bc47d43330fcdf4;hp=bb41aa4ccc21d01b3b8dd33e6ed2209311de96d1;hpb=578e887b6832b5c2971ab96bd34d5e0d8d13e6d3;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c index bb41aa4c..fb76aa7c 100644 --- a/gtk/src/hb-backend.c +++ b/gtk/src/hb-backend.c @@ -70,6 +70,18 @@ index_str_init(gint max_index) } } +static options_map_t d_point_to_point_opts[] = +{ + {"Chapters:", "chapter", 0, "0"}, + {"Seconds:", "time", 1, "1"}, + {"Frames:", "frame", 2, "2"}, +}; +combo_opts_t point_to_point_opts = +{ + sizeof(d_point_to_point_opts)/sizeof(options_map_t), + d_point_to_point_opts +}; + static options_map_t d_when_complete_opts[] = { {"Do Nothing", "nothing", 0, "0"}, @@ -359,6 +371,7 @@ typedef struct combo_name_map_t combo_name_map[] = { + {"PtoPType", &point_to_point_opts}, {"WhenComplete", &when_complete_opts}, {"PicturePAR", &par_opts}, {"PictureModulus", &alignment_opts}, @@ -926,6 +939,33 @@ lookup_audio_rate_option(const GValue *rate) return result; } +gint +ghb_find_closest_audio_bitrate(gint codec, gint rate) +{ + gint ii; + gint low = 32; + gint high = 768; + gint result; + + if (codec == HB_ACODEC_FAAC) + high = 160; + + result = high; + for (ii = 0; ii < hb_audio_bitrates_count; ii++) + { + if (hb_audio_bitrates[ii].rate < low) + continue; + if (hb_audio_bitrates[ii].rate > high) + break; + if (rate <= hb_audio_bitrates[ii].rate) + { + result = hb_audio_bitrates[ii].rate; + break; + } + } + return result; +} + static gint lookup_audio_bitrate_int(const GValue *rate) { @@ -1017,8 +1057,8 @@ lookup_audio_lang_option(const GValue *rate) return result; } -static GValue* -get_acodec_value(gint val) +GValue* +ghb_lookup_acodec_value(gint val) { GValue *value = NULL; gint ii; @@ -1732,14 +1772,32 @@ title_opts_set(GtkBuilder *builder, const gchar *name) for (ii = 0; ii < count; ii++) { title = (hb_title_t*)hb_list_item(list, ii); - if (title->duration != 0) + if (title->type == HB_STREAM_TYPE) { - titles[ii] = g_strdup_printf ("%d - %02dh%02dm%02ds", - title->index, title->hours, title->minutes, title->seconds); + if (title->duration != 0) + { + titles[ii] = g_strdup_printf ("%d - %02dh%02dm%02ds - %s", + title->index, title->hours, title->minutes, title->seconds, + title->name); + } + else + { + titles[ii] = g_strdup_printf ("%d - %s", + title->index, title->name); + } } else { - titles[ii] = g_strdup_printf ("%d - Unknown Length", title->index); + if (title->duration != 0) + { + titles[ii] = g_strdup_printf ("%d - %02dh%02dm%02ds", + title->index, title->hours, title->minutes, title->seconds); + } + else + { + titles[ii] = g_strdup_printf ("%d - Unknown Length", + title->index); + } } gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, @@ -2007,56 +2065,79 @@ ghb_get_source_audio_lang(gint titleindex, gint track) return lang; } +static gboolean* +get_track_used(gint acodec, GHashTable *track_indices, gint count) +{ + gboolean *used; + + used = g_hash_table_lookup(track_indices, &acodec); + if (used == NULL) + { + gint *key; + + used = g_malloc0(count * sizeof(gboolean)); + key = g_malloc(sizeof(gint)); + *key = acodec; + g_hash_table_insert(track_indices, key, used); + } + return used; +} + gint ghb_find_audio_track( gint titleindex, const gchar *lang, gint acodec, + gint fallback_acodec, GHashTable *track_indices) { hb_list_t * list; hb_title_t * title; - hb_audio_config_t * audio; + hb_audio_config_t * audio; gint ii; gint count = 0; gint track = -1; gint max_chan = 0; gboolean *used; + gboolean *passthru_used; + gint try_acodec; + gint passthru_acodec; + gboolean passthru; g_debug("find_audio_track ()\n"); if (h_scan == NULL) return -1; list = hb_get_titles( h_scan ); - title = (hb_title_t*)hb_list_item( list, titleindex ); + title = (hb_title_t*)hb_list_item( list, titleindex ); if (title != NULL) { count = hb_list_count( title->list_audio ); } if (count > 10) count = 10; - used = g_hash_table_lookup(track_indices, &acodec); - if (used == NULL) - { - used = g_malloc0(count * sizeof(gboolean)); - g_hash_table_insert(track_indices, &acodec, used); - } // Try to find an item that matches the preferred language and // the passthru codec type - if (acodec & (HB_ACODEC_AC3 | HB_ACODEC_DCA)) + passthru = (acodec & (HB_ACODEC_AC3 | HB_ACODEC_DCA)) != 0; + if (passthru) { for (ii = 0; ii < count; ii++) { gint channels; + audio = (hb_audio_config_t*)hb_list_audio_config_item( + title->list_audio, ii ); + passthru_acodec = (HB_ACODEC_AC3 | HB_ACODEC_DCA) & audio->in.codec; + // Is the source track use a passthru capable codec? + if (passthru_acodec == 0) + continue; + used = get_track_used(passthru_acodec, track_indices, count); + // Has the track already been used with this codec? if (used[ii]) continue; - audio = (hb_audio_config_t*)hb_list_audio_config_item( - title->list_audio, ii ); channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( audio->in.channel_layout); // Find a track that is not visually impaired or dirctor's // commentary, and has the highest channel count. - if ((audio->in.codec & acodec) && - (audio->lang.type < 2) && + if ((audio->lang.type < 2) && ((strcmp(lang, audio->lang.iso639_2) == 0) || (strcmp(lang, "und") == 0))) { @@ -2067,6 +2148,11 @@ ghb_find_audio_track( } } } + try_acodec = fallback_acodec; + } + else + { + try_acodec = acodec; } if (track > -1) { @@ -2074,12 +2160,22 @@ ghb_find_audio_track( return track; } // Try to find an item that matches the preferred language + used = get_track_used(try_acodec, track_indices, count); for (ii = 0; ii < count; ii++) { + // Has the track already been used with this codec? if (used[ii]) continue; - audio = (hb_audio_config_t*)hb_list_audio_config_item( - title->list_audio, ii ); + audio = (hb_audio_config_t*)hb_list_audio_config_item( + title->list_audio, ii ); + passthru_acodec = (HB_ACODEC_AC3 | HB_ACODEC_DCA) & audio->in.codec; + if (passthru_acodec && passthru) + { + passthru_used = get_track_used(passthru_acodec, track_indices, count); + // Has the track already been used with this codec for passthru? + if (passthru_used[ii]) + continue; + } // Find a track that is not visually impaired or dirctor's commentary if ((audio->lang.type < 2) && ((strcmp(lang, audio->lang.iso639_2) == 0) || @@ -2096,23 +2192,28 @@ ghb_find_audio_track( } // Try to fine an item that does not match the preferred language and // matches the passthru codec type - if (acodec & (HB_ACODEC_AC3 | HB_ACODEC_DCA)) + if (passthru) { for (ii = 0; ii < count; ii++) { gint channels; + audio = (hb_audio_config_t*)hb_list_audio_config_item( + title->list_audio, ii ); + passthru_acodec = (HB_ACODEC_AC3 | HB_ACODEC_DCA) & audio->in.codec; + // Is the source track use a passthru capable codec? + if (passthru_acodec == 0) + continue; + used = get_track_used(passthru_acodec, track_indices, count); + // Has the track already been used with this codec? if (used[ii]) continue; - audio = (hb_audio_config_t*)hb_list_audio_config_item( - title->list_audio, ii ); channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( audio->in.channel_layout); // Find a track that is not visually impaired or dirctor's // commentary, and has the highest channel count. - if ((audio->in.codec & acodec) && - (audio->lang.type < 2)) + if (audio->lang.type < 2) { if (channels > max_chan) { @@ -2121,6 +2222,11 @@ ghb_find_audio_track( } } } + try_acodec = fallback_acodec; + } + else + { + try_acodec = acodec; } if (track > -1) { @@ -2128,12 +2234,22 @@ ghb_find_audio_track( return track; } // Try to fine an item that does not match the preferred language + used = get_track_used(try_acodec, track_indices, count); for (ii = 0; ii < count; ii++) { + // Has the track already been used with this codec? if (used[ii]) continue; - audio = (hb_audio_config_t*)hb_list_audio_config_item( + audio = (hb_audio_config_t*)hb_list_audio_config_item( title->list_audio, ii ); + passthru_acodec = (HB_ACODEC_AC3 | HB_ACODEC_DCA) & audio->in.codec; + if (passthru_acodec && passthru) + { + passthru_used = get_track_used(passthru_acodec, track_indices, count); + // Has the track already been used with this codec for passthru? + if (passthru_used[ii]) + continue; + } // Find a track that is not visually impaired or dirctor's commentary if (audio->lang.type < 2) { @@ -2149,8 +2265,17 @@ ghb_find_audio_track( // Last ditch, anything goes for (ii = 0; ii < count; ii++) { - audio = (hb_audio_config_t*)hb_list_audio_config_item( - title->list_audio, ii ); + audio = (hb_audio_config_t*)hb_list_audio_config_item( + title->list_audio, ii ); + passthru_acodec = (HB_ACODEC_AC3 | HB_ACODEC_DCA) & audio->in.codec; + if (passthru_acodec && passthru) + { + passthru_used = get_track_used(passthru_acodec, track_indices, count); + // Has the track already been used with this codec for passthru? + if (passthru_used[ii]) + continue; + } + // Has the track already been used with this codec? if (!used[ii]) { track = ii; @@ -2479,6 +2604,7 @@ ghb_update_ui_combo_box( audio_track_opts_set(ud->builder, "AudioTrack", user_data); subtitle_track_opts_set(ud->builder, "SubtitleTrack", user_data); generic_opts_set(ud->builder, "VideoQualityGranularity", &vqual_granularity_opts); + generic_opts_set(ud->builder, "PtoPType", &point_to_point_opts); generic_opts_set(ud->builder, "WhenComplete", &when_complete_opts); generic_opts_set(ud->builder, "PicturePAR", &par_opts); generic_opts_set(ud->builder, "PictureModulus", &alignment_opts); @@ -2573,6 +2699,44 @@ ghb_build_x264opts_string(GValue *settings) } void +ghb_part_duration(gint tt, gint sc, gint ec, gint *hh, gint *mm, gint *ss) +{ + hb_list_t * list; + hb_title_t * title; + hb_chapter_t * chapter; + gint count, c; + gint64 duration; + + *hh = *mm = *ss = 0; + if (h_scan == NULL) return; + list = hb_get_titles( h_scan ); + title = (hb_title_t*)hb_list_item( list, tt ); + if (title == NULL) return; + + *hh = title->hours; + *mm = title->minutes; + *ss = title->seconds; + + count = hb_list_count(title->list_chapter); + if (sc > count) sc = count; + if (ec > count) ec = count; + + if (sc == 1 && ec == count) + return; + + duration = 0; + for (c = sc; c <= ec; c++) + { + chapter = hb_list_item(title->list_chapter, c-1); + duration += chapter->duration; + } + + *hh = duration / 90000 / 3600; + *mm = ((duration / 90000) % 3600) / 60; + *ss = (duration / 90000) % 60; +} + +void ghb_get_chapter_duration(gint ti, gint ii, gint *hh, gint *mm, gint *ss) { hb_list_t * list; @@ -2787,6 +2951,11 @@ ghb_backend_close() hb_close(&h_scan); } +void ghb_backend_scan_stop() +{ + hb_scan_stop( h_scan ); +} + void ghb_backend_scan(const gchar *path, gint titleindex, gint preview_count) { @@ -2951,6 +3120,22 @@ ghb_track_status() case HB_STATE_WORKING: hb_status.queue.state |= GHB_STATE_WORKING; hb_status.queue.state &= ~GHB_STATE_PAUSED; + hb_status.queue.state &= ~GHB_STATE_SEARCHING; + hb_status.queue.job_cur = p.job_cur; + hb_status.queue.job_count = p.job_count; + hb_status.queue.progress = p.progress; + hb_status.queue.rate_cur = p.rate_cur; + hb_status.queue.rate_avg = p.rate_avg; + hb_status.queue.hours = p.hours; + hb_status.queue.minutes = p.minutes; + hb_status.queue.seconds = p.seconds; + hb_status.queue.unique_id = p.sequence_id & 0xFFFFFF; + break; + + case HB_STATE_SEARCHING: + hb_status.queue.state |= GHB_STATE_SEARCHING; + hb_status.queue.state &= ~GHB_STATE_WORKING; + hb_status.queue.state &= ~GHB_STATE_PAUSED; hb_status.queue.job_cur = p.job_cur; hb_status.queue.job_count = p.job_count; hb_status.queue.progress = p.progress; @@ -2981,6 +3166,7 @@ ghb_track_status() hb_status.queue.state &= ~GHB_STATE_MUXING; hb_status.queue.state &= ~GHB_STATE_PAUSED; hb_status.queue.state &= ~GHB_STATE_WORKING; + hb_status.queue.state &= ~GHB_STATE_SEARCHING; switch (p.error) { case HB_ERROR_NONE: @@ -3019,8 +3205,9 @@ ghb_get_title_info(ghb_title_info_t *tinfo, gint titleindex) return FALSE; } - title = hb_list_item( list, titleindex ); + title = hb_list_item( list, titleindex ); if (title == NULL) return FALSE; // Bad titleindex + tinfo->index = titleindex; tinfo->width = title->width; tinfo->height = title->height; memcpy(tinfo->crop, title->crop, 4 * sizeof(int)); @@ -3041,6 +3228,9 @@ ghb_get_title_info(ghb_title_info_t *tinfo, gint titleindex) tinfo->duration = title->duration; tinfo->angle_count = title->angle_count; + tinfo->path = title->path; + tinfo->name = title->name; + tinfo->type = title->type; return TRUE; } @@ -3144,6 +3334,7 @@ ghb_set_scale(signal_user_data_t *ud, gint mode) static gboolean busy = FALSE; g_debug("ghb_set_scale ()\n"); + picture_settings_deps(ud); if (h_scan == NULL) return; list = hb_get_titles( h_scan ); if( !hb_list_count( list ) ) @@ -3159,7 +3350,6 @@ ghb_set_scale(signal_user_data_t *ud, gint mode) job = title->job; if (job == NULL) return; - picture_settings_deps(ud); if (busy) return; busy = TRUE; @@ -3865,7 +4055,7 @@ ghb_validate_audio(signal_user_data_t *ud) { codec = HB_ACODEC_FAAC; } - value = get_acodec_value(codec); + value = ghb_lookup_acodec_value(codec); ghb_settings_take_value(asettings, "AudioEncoder", value); } gchar *a_unsup = NULL; @@ -3902,7 +4092,7 @@ ghb_validate_audio(signal_user_data_t *ud) return FALSE; } g_free(message); - value = get_acodec_value(codec); + value = ghb_lookup_acodec_value(codec); ghb_settings_take_value(asettings, "AudioEncoder", value); } gint mix = ghb_settings_combo_int (asettings, "AudioMixdown"); @@ -4081,13 +4271,42 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) } if (!job->start_at_preview) { - gint chapter_start, chapter_end; - chapter_start = ghb_settings_get_int(js, "start_chapter"); - chapter_end = ghb_settings_get_int(js, "end_chapter"); + gint start, end; gint num_chapters = hb_list_count(title->list_chapter); - job->chapter_start = MIN( num_chapters, chapter_start ); - job->chapter_end = MAX( job->chapter_start, chapter_end ); + gint duration = title->duration / 90000; + job->chapter_start = 1; + job->chapter_end = num_chapters; + + if (ghb_settings_combo_int(js, "PtoPType") == 0) + { + start = ghb_settings_get_int(js, "start_point"); + end = ghb_settings_get_int(js, "end_point"); + job->chapter_start = MIN( num_chapters, start ); + job->chapter_end = MAX( job->chapter_start, end ); + } + if (ghb_settings_combo_int(js, "PtoPType") == 1) + { + job->chapter_start = 1; + job->chapter_end = num_chapters; + start = ghb_settings_get_int(js, "start_point"); + end = ghb_settings_get_int(js, "end_point"); + job->pts_to_start = (int64_t)MIN(duration-1, start) * 90000; + job->pts_to_stop = (int64_t)MAX(start+1, end) * 90000 - + job->pts_to_start; + } + if (ghb_settings_combo_int(js, "PtoPType") == 2) + { + job->chapter_start = 1; + job->chapter_end = num_chapters; + start = ghb_settings_get_int(js, "start_point"); + end = ghb_settings_get_int(js, "end_point"); + gint64 max_frames; + max_frames = (gint64)duration * title->rate / title->rate_base; + job->frame_to_start = (int64_t)MIN(max_frames-1, start-1); + job->frame_to_stop = (int64_t)MAX(start, end-1) - + job->frame_to_start; + } job->chapter_markers = ghb_settings_get_boolean(js, "ChapterMarkers"); if (job->chapter_start == job->chapter_end) job->chapter_markers = 0; @@ -4097,25 +4316,22 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) GValue *chapter; gint chap; gint count; - + chapters = ghb_settings_get_value(js, "chapter_list"); count = ghb_array_len(chapters); - for(chap = chapter_start; chap <= chapter_end; chap++) + for(chap = 0; chap < count; chap++) { hb_chapter_t * chapter_s; gchar *name; - + name = NULL; - if (chap-1 < count) - { - chapter = ghb_array_get_nth(chapters, chap-1); - name = ghb_value_string(chapter); - } + chapter = ghb_array_get_nth(chapters, chap); + name = ghb_value_string(chapter); if (name == NULL) { - name = g_strdup_printf ("Chapter %2d", chap); + name = g_strdup_printf ("Chapter %2d", chap+1); } - chapter_s = hb_list_item( job->title->list_chapter, chap - 1); + chapter_s = hb_list_item( job->title->list_chapter, chap); strncpy(chapter_s->title, name, 1023); chapter_s->title[1023] = '\0'; g_free(name);