OSDN Git Service

forgot to checkin the new icon for picutre settings
[handbrake-jp/handbrake-jp-git.git] / gtk / src / hb-backend.c
index 3bc95e3..5318882 100644 (file)
@@ -31,6 +31,7 @@
 #include "hb-backend.h"
 #include "settings.h"
 #include "callbacks.h"
+#include "preview.h"
 #include "values.h"
 #include "lang.h"
 
@@ -63,6 +64,18 @@ static const gchar *index_str[] =
        "10",
 };
 
+static options_map_t d_logging_opts[] =
+{
+       {"0", "0", 0, "0"},
+       {"1", "1", 1, "1"},
+       {"2", "2", 2, "2"},
+};
+combo_opts_t logging_opts =
+{
+       sizeof(d_logging_opts)/sizeof(options_map_t),
+       d_logging_opts
+};
+
 static options_map_t d_container_opts[] =
 {
        {"MKV", "mkv", HB_MUX_MKV, "mkv"},
@@ -144,10 +157,11 @@ combo_opts_t direct_opts =
 
 static options_map_t d_me_opts[] =
 {
-       {"Diamond",              "dia", 0, "dia"},
-       {"Hexagon",              "hex", 1, "hex"},
-       {"Uneven Multi-Hexagon", "umh", 2, "umh"},
-       {"Exhaustive",           "esa", 3, "esa"},
+       {"Diamond",              "dia",  0, "dia"},
+       {"Hexagon",              "hex",  1, "hex"},
+       {"Uneven Multi-Hexagon", "umh",  2, "umh"},
+       {"Exhaustive",           "esa",  3, "esa"},
+       {"Hadamard Exhaustive",  "tesa", 4, "tesa"},
 };
 combo_opts_t me_opts =
 {
@@ -224,6 +238,7 @@ typedef struct
 
 combo_name_map_t combo_name_map[] =
 {
+       {"LoggingLevel", &logging_opts},
        {"FileFormat", &container_opts},
        {"PictureDeinterlace", &deint_opts},
        {"tweak_PictureDeinterlace", &deint_opts},
@@ -840,6 +855,15 @@ static hb_handle_t * h_queue = NULL;
 
 extern void hb_get_tempory_directory(hb_handle_t *h, char path[512]);
 
+gchar*
+ghb_get_tmp_dir()
+{
+       char dir[512];
+
+       hb_get_tempory_directory(h_scan, dir);
+       return g_strdup(dir);
+}
+
 void
 ghb_hb_cleanup(gboolean partial)
 {
@@ -1733,6 +1757,7 @@ ghb_update_ui_combo_box(GtkBuilder *builder, const gchar *name, gint user_data,
                subtitle_opts_set(builder, "Subtitles", user_data);
                title_opts_set(builder, "title");
                audio_track_opts_set(builder, "AudioTrack", user_data);
+               generic_opts_set(builder, "LoggingLevel", &logging_opts);
                generic_opts_set(builder, "FileFormat", &container_opts);
                generic_opts_set(builder, "PictureDeinterlace", &deint_opts);
                generic_opts_set(builder, "tweak_PictureDeinterlace", &deint_opts);
@@ -1968,11 +1993,8 @@ ghb_set_default_bitrate_opts(GtkBuilder *builder, gint last_rate)
 static ghb_status_t hb_status;
 
 void
-ghb_backend_init(GtkBuilder *builder, gint debug, gint update)
+ghb_combo_init(GtkBuilder *builder)
 {
-    /* Init libhb */
-    h_scan = hb_init( debug, update );
-    h_queue = hb_init( debug, 0 );
        // Set up the list model for the combos
        init_ui_combo_boxes(builder);
        // Populate all the combos
@@ -1980,6 +2002,14 @@ ghb_backend_init(GtkBuilder *builder, gint debug, gint update)
 }
 
 void
+ghb_backend_init(gint debug)
+{
+    /* Init libhb */
+    h_scan = hb_init( debug, 0 );
+    h_queue = hb_init( debug, 0 );
+}
+
+void
 ghb_backend_close()
 {
        hb_close(&h_queue);
@@ -1987,58 +2017,58 @@ ghb_backend_close()
 }
 
 void
-ghb_backend_scan(const gchar *path, gint titleindex)
+ghb_backend_scan(const gchar *path, gint titleindex, gint preview_count)
 {
-    hb_scan( h_scan, path, titleindex );
-       hb_status.state |= GHB_STATE_SCANNING;
+    hb_scan( h_scan, path, titleindex, preview_count, 1 );
+       hb_status.scan.state |= GHB_STATE_SCANNING;
        // initialize count and cur to something that won't cause FPE
        // when computing progress
-       hb_status.title_count = 1;
-       hb_status.title_cur = 0;
+       hb_status.scan.title_count = 1;
+       hb_status.scan.title_cur = 0;
 }
 
 void
 ghb_backend_queue_scan(const gchar *path, gint titlenum)
 {
        g_debug("ghb_backend_queue_scan()");
-       hb_scan( h_queue, path, titlenum );
-       hb_status.queue_state |= GHB_STATE_SCANNING;
+       hb_scan( h_queue, path, titlenum, 10, 0 );
+       hb_status.queue.state |= GHB_STATE_SCANNING;
 }
 
 gint
-ghb_get_state()
+ghb_get_scan_state()
 {
-       return hb_status.state;
+       return hb_status.scan.state;
 }
 
 gint
 ghb_get_queue_state()
 {
-       return hb_status.queue_state;
+       return hb_status.queue.state;
 }
 
 void
-ghb_clear_state(gint state)
+ghb_clear_scan_state(gint state)
 {
-       hb_status.state &= ~state;
+       hb_status.scan.state &= ~state;
 }
 
 void
 ghb_clear_queue_state(gint state)
 {
-       hb_status.queue_state &= ~state;
+       hb_status.queue.state &= ~state;
 }
 
 void
-ghb_set_state(gint state)
+ghb_set_scan_state(gint state)
 {
-       hb_status.state |= state;
+       hb_status.scan.state |= state;
 }
 
 void
 ghb_set_queue_state(gint state)
 {
-       hb_status.queue_state |= state;
+       hb_status.queue.state |= state;
 }
 
 void
@@ -2050,66 +2080,125 @@ ghb_get_status(ghb_status_t *status)
 void 
 ghb_track_status()
 {
-    hb_state_t s;
+    hb_state_t s_scan;
     hb_state_t s_queue;
 
        if (h_scan == NULL) return;
-    hb_get_state( h_scan, &s );
-       switch( s.state )
+    hb_get_state( h_scan, &s_scan );
+       switch( s_scan.state )
     {
-#define p s.param.scanning
+#define p s_scan.param.scanning
         case HB_STATE_SCANNING:
                {
-                       hb_status.state |= GHB_STATE_SCANNING;
-                       hb_status.title_count = p.title_count;
-                       hb_status.title_cur = p.title_cur;
+                       hb_status.scan.state |= GHB_STATE_SCANNING;
+                       hb_status.scan.title_count = p.title_count;
+                       hb_status.scan.title_cur = p.title_cur;
                } break;
 #undef p
 
         case HB_STATE_SCANDONE:
         {
-                       hb_status.state &= ~GHB_STATE_SCANNING;
-                       hb_status.state |= GHB_STATE_SCANDONE;
+                       hb_status.scan.state &= ~GHB_STATE_SCANNING;
+                       hb_status.scan.state |= GHB_STATE_SCANDONE;
         } break;
 
+#define p s_scan.param.working
+        case HB_STATE_WORKING:
+                       hb_status.scan.state |= GHB_STATE_WORKING;
+                       hb_status.scan.state &= ~GHB_STATE_PAUSED;
+                       hb_status.scan.job_cur = p.job_cur;
+                       hb_status.scan.job_count = p.job_count;
+                       hb_status.scan.progress = p.progress;
+                       hb_status.scan.rate_cur = p.rate_cur;
+                       hb_status.scan.rate_avg = p.rate_avg;
+                       hb_status.scan.hours = p.hours;
+                       hb_status.scan.minutes = p.minutes;
+                       hb_status.scan.seconds = p.seconds;
+                       hb_status.scan.unique_id = p.sequence_id & 0xFFFFFF;
+            break;
+#undef p
+
+        case HB_STATE_PAUSED:
+                       hb_status.scan.state |= GHB_STATE_PAUSED;
+            break;
+                               
+        case HB_STATE_MUXING:
+        {
+                       hb_status.scan.state |= GHB_STATE_MUXING;
+        } break;
+
+#define p s_scan.param.workdone
+        case HB_STATE_WORKDONE:
+               {
+            hb_job_t *job;
+
+                       hb_status.scan.state |= GHB_STATE_WORKDONE;
+                       hb_status.scan.state &= ~GHB_STATE_MUXING;
+                       hb_status.scan.state &= ~GHB_STATE_PAUSED;
+                       hb_status.scan.state &= ~GHB_STATE_WORKING;
+                       switch (p.error)
+                       {
+                       case HB_ERROR_NONE:
+                               hb_status.scan.error = GHB_ERROR_NONE;
+                               break;
+                       case HB_ERROR_CANCELED:
+                               hb_status.scan.error = GHB_ERROR_CANCELED;
+                               break;
+                       default:
+                               hb_status.scan.error = GHB_ERROR_FAIL;
+                               break;
+                       }
+                       // Delete all remaining jobs of this encode.
+                       // An encode can be composed of multiple associated jobs.
+                       // When a job is stopped, libhb removes it from the job list,
+                       // but does not remove other jobs that may be associated with it.
+                       // Associated jobs are taged in the sequence id.
+            while ((job = hb_job(h_scan, 0)) != NULL) 
+                hb_rem( h_scan, job );
+               } break;
+#undef p
     }
     hb_get_state( h_queue, &s_queue );
        switch( s_queue.state )
     {
+#define p s_queue.param.scanning
         case HB_STATE_SCANNING:
                {
-                       hb_status.queue_state |= GHB_STATE_SCANNING;
+                       hb_status.queue.state |= GHB_STATE_SCANNING;
+                       hb_status.queue.title_count = p.title_count;
+                       hb_status.queue.title_cur = p.title_cur;
                } break;
+#undef p
 
         case HB_STATE_SCANDONE:
         {
-                       hb_status.queue_state &= ~GHB_STATE_SCANNING;
-                       hb_status.queue_state |= GHB_STATE_SCANDONE;
+                       hb_status.queue.state &= ~GHB_STATE_SCANNING;
+                       hb_status.queue.state |= GHB_STATE_SCANDONE;
         } break;
 
 #define p s_queue.param.working
         case HB_STATE_WORKING:
-                       hb_status.queue_state |= GHB_STATE_WORKING;
-                       hb_status.queue_state &= ~GHB_STATE_PAUSED;
-                       hb_status.job_cur = p.job_cur;
-                       hb_status.job_count = p.job_count;
-                       hb_status.progress = p.progress;
-                       hb_status.rate_cur = p.rate_cur;
-                       hb_status.rate_avg = p.rate_avg;
-                       hb_status.hours = p.hours;
-                       hb_status.minutes = p.minutes;
-                       hb_status.seconds = p.seconds;
-                       hb_status.unique_id = p.sequence_id & 0xFFFFFF;
+                       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;
+                       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;
 #undef p
 
         case HB_STATE_PAUSED:
-                       hb_status.queue_state |= GHB_STATE_PAUSED;
+                       hb_status.queue.state |= GHB_STATE_PAUSED;
             break;
                                
         case HB_STATE_MUXING:
         {
-                       hb_status.queue_state |= GHB_STATE_MUXING;
+                       hb_status.queue.state |= GHB_STATE_MUXING;
         } break;
 
 #define p s_queue.param.workdone
@@ -2117,20 +2206,22 @@ ghb_track_status()
                {
             hb_job_t *job;
 
-                       hb_status.queue_state |= GHB_STATE_WORKDONE;
-                       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_WORKDONE;
+                       hb_status.queue.state &= ~GHB_STATE_MUXING;
+                       hb_status.queue.state &= ~GHB_STATE_PAUSED;
+                       hb_status.queue.state &= ~GHB_STATE_WORKING;
                        switch (p.error)
                        {
                        case HB_ERROR_NONE:
-                               hb_status.error = GHB_ERROR_NONE;
+                               hb_status.queue.error = GHB_ERROR_NONE;
+                               break;
                        case HB_ERROR_CANCELED:
-                               hb_status.error = GHB_ERROR_CANCELED;
+                               hb_status.queue.error = GHB_ERROR_CANCELED;
+                               break;
                        default:
-                               hb_status.error = GHB_ERROR_FAIL;
+                               hb_status.queue.error = GHB_ERROR_FAIL;
+                               break;
                        }
-                       hb_status.error = p.error;
                        // Delete all remaining jobs of this encode.
                        // An encode can be composed of multiple associated jobs.
                        // When a job is stopped, libhb removes it from the job list,
@@ -2320,8 +2411,8 @@ ghb_set_scale(signal_user_data_t *ud, gint mode)
        {
                width = crop_width;
                height = crop_height;
-               max_width = 0; //crop_width;
-               max_height = 0; //crop_height;
+               max_width = 0;
+               max_height = 0;
        }
        else
        {
@@ -2864,8 +2955,8 @@ ghb_validate_vquality(GValue *settings)
        return TRUE;
 }
 
-void
-ghb_add_job(GValue *js, gint unique_id)
+static void
+add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
 {
        hb_list_t  * list;
        hb_title_t * title;
@@ -2880,19 +2971,15 @@ ghb_add_job(GValue *js, gint unique_id)
        gchar *denoise_str = NULL;
        gchar *dest_str = NULL;
 
-       g_debug("ghb_add_job()\n");
-       if (h_queue == NULL) return;
-       list = hb_get_titles( h_queue );
+       g_debug("add_job()\n");
+       if (h == NULL) return;
+       list = hb_get_titles( h );
        if( !hb_list_count( list ) )
        {
                /* No valid title, stop right there */
                return;
        }
 
-       // Since I'm doing a scan of the single title I want just prior 
-       // to adding the job, there is only the one title to choose from.
-       //gint titleindex = ghb_settings_get_int(js, "title");
-    gint titleindex = 0;
     title = hb_list_item( list, titleindex );
        if (title == NULL) return;
 
@@ -2900,6 +2987,14 @@ ghb_add_job(GValue *js, gint unique_id)
        job   = title->job;
        if (job == NULL) return;
 
+       job->start_at_preview = ghb_settings_get_int(js, "start_frame") + 1;
+       if (job->start_at_preview)
+       {
+g_message("duration %d", ghb_settings_get_int(js, "live_duration"));
+               job->seek_points = ghb_settings_get_int(js, "preview_count");
+               job->pts_to_stop = ghb_settings_get_int(js, "live_duration") * 90000LL;
+       }
+
        tweaks = ghb_settings_get_boolean(js, "allow_tweaks");
        job->mux = ghb_settings_combo_int(js, "FileFormat");
        if (job->mux == HB_MUX_MP4)
@@ -2912,42 +3007,45 @@ ghb_add_job(GValue *js, gint unique_id)
                job->largeFileSize = FALSE;
                job->mp4_optimize = FALSE;
        }
-       gint chapter_start, chapter_end;
-       chapter_start = ghb_settings_get_int(js, "start_chapter");
-       chapter_end = ghb_settings_get_int(js, "end_chapter");
-       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 );
-
-       job->chapter_markers = ghb_settings_get_boolean(js, "ChapterMarkers");
-       if ( job->chapter_markers )
+       if (!job->start_at_preview)
        {
-               GValue *chapters;
-               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++)
+               gint chapter_start, chapter_end;
+               chapter_start = ghb_settings_get_int(js, "start_chapter");
+               chapter_end = ghb_settings_get_int(js, "end_chapter");
+               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 );
+
+               job->chapter_markers = ghb_settings_get_boolean(js, "ChapterMarkers");
+               if ( job->chapter_markers )
                {
-                       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); 
-                       }
-                       if (name == NULL)
+                       GValue *chapters;
+                       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++)
                        {
-                               name = g_strdup_printf ("Chapter %2d", 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); 
+                               }
+                               if (name == NULL)
+                               {
+                                       name = g_strdup_printf ("Chapter %2d", chap);
+                               }
+                               chapter_s = hb_list_item( job->title->list_chapter, chap - 1);
+                               strncpy(chapter_s->title, name, 1023);
+                               chapter_s->title[1023] = '\0';
+                               g_free(name);
                        }
-                       chapter_s = hb_list_item( job->title->list_chapter, chap - 1);
-                       strncpy(chapter_s->title, name, 1023);
-                       chapter_s->title[1023] = '\0';
-                       g_free(name);
                }
        }
        job->crop[0] = ghb_settings_get_int(js, "PictureTopCrop");
@@ -3138,6 +3236,7 @@ ghb_add_job(GValue *js, gint unique_id)
                        }
                        else
                        {
+printf("switching to faac\n");
                                audio.out.codec = HB_ACODEC_FAAC;
                        }
                }
@@ -3269,7 +3368,7 @@ ghb_add_job(GValue *js, gint unique_id)
                 * Add the pre-scan job
                 */
                job->sequence_id = (unique_id & 0xFFFFFF) | (sub_id++ << 24);
-               hb_add( h_queue, job );
+               hb_add( h, job );
                //if (job->x264opts != NULL)
                //      g_free(job->x264opts);
 
@@ -3322,7 +3421,7 @@ ghb_add_job(GValue *js, gint unique_id)
                        job->x264opts = x264opts;
                }
                job->sequence_id = (unique_id & 0xFFFFFF) | (sub_id++ << 24);
-               hb_add( h_queue, job );
+               hb_add( h, job );
                //if (job->x264opts != NULL)
                //      g_free(job->x264opts);
 
@@ -3337,7 +3436,7 @@ ghb_add_job(GValue *js, gint unique_id)
                job->indepth_scan = 0;
                job->x264opts = x264opts2;
                job->sequence_id = (unique_id & 0xFFFFFF) | (sub_id++ << 24);
-               hb_add( h_queue, job );
+               hb_add( h, job );
                //if (job->x264opts != NULL)
                //      g_free(job->x264opts);
        }
@@ -3346,7 +3445,7 @@ ghb_add_job(GValue *js, gint unique_id)
                job->indepth_scan = 0;
                job->pass = 0;
                job->sequence_id = (unique_id & 0xFFFFFF) | (sub_id++ << 24);
-               hb_add( h_queue, job );
+               hb_add( h, job );
                //if (job->x264opts != NULL)
                //      g_free(job->x264opts);
        }
@@ -3359,6 +3458,23 @@ ghb_add_job(GValue *js, gint unique_id)
 }
 
 void
+ghb_add_job(GValue *js, gint unique_id)
+{
+       // Since I'm doing a scan of the single title I want just prior 
+       // to adding the job, there is only the one title to choose from.
+       add_job(h_queue, js, unique_id, 0);
+}
+
+void
+ghb_add_live_job(GValue *js, gint unique_id)
+{
+       // Since I'm doing a scan of the single title I want just prior 
+       // to adding the job, there is only the one title to choose from.
+       gint titleindex = ghb_settings_combo_int(js, "title");
+       add_job(h_scan, js, unique_id, titleindex);
+}
+
+void
 ghb_remove_job(gint unique_id)
 {
     hb_job_t * job;
@@ -3388,6 +3504,18 @@ ghb_stop_queue()
 }
 
 void
+ghb_start_live_encode()
+{
+       hb_start( h_scan );
+}
+
+void
+ghb_stop_live_encode()
+{
+       hb_stop( h_scan );
+}
+
+void
 ghb_pause_queue()
 {
     hb_state_t s;
@@ -3410,12 +3538,16 @@ GdkPixbuf*
 ghb_get_preview_image(
        gint titleindex, 
        gint index, 
-       GValue *settings, 
-       gboolean borders)
+       signal_user_data_t *ud,
+       gboolean borders,
+       gint *out_width,
+       gint *out_height)
 {
+       GValue *settings;
        hb_title_t *title;
        hb_list_t  *list;
        
+       settings = ud->settings;
        list = hb_get_titles( h_scan );
        if( !hb_list_count( list ) )
        {
@@ -3537,27 +3669,37 @@ ghb_get_preview_image(
        if (anamorphic)
        {
                hb_set_anamorphic_size( title->job, &width, &height, &par_width, &par_height );
-               if (par_width > par_height)
-                       dstWidth = dstWidth * par_width / par_height;
-               else
-                       dstHeight = dstHeight * par_height / par_width;
+               ghb_par_scale(ud, &dstWidth, &dstHeight, par_width, par_height);
+       }
+       else
+       {
+               ghb_par_scale(ud, &dstWidth, &dstHeight, 1, 1);
        }
+       *out_width = dstWidth;
+       *out_height = dstHeight;
        if (ghb_settings_get_boolean(settings, "reduce_hd_preview"))
        {
-               gdouble factor = 1.0;
+               GdkScreen *ss;
+               gint s_w, s_h;
+               gint num, den;
+
+               ss = gdk_screen_get_default();
+               s_w = gdk_screen_get_width(ss);
+               s_h = gdk_screen_get_height(ss);
+               num = dstWidth * par_width;
+               den = dstHeight * par_height;
 
-               if (dstHeight > RED_HEIGHT)
+               if (dstWidth > s_w * 80 / 100)
                {
-                       factor = RED_HEIGHT / (gdouble)dstHeight;
+                       dstWidth = s_w * 80 / 100;
+                       dstHeight = dstWidth * den / num;
                }
-               if (dstWidth * factor > RED_WIDTH)
+               if (dstHeight > s_h * 80 / 100)
                {
-                       factor = RED_WIDTH / (gdouble)dstWidth;
+                       dstHeight = s_h * 80 / 100;
+                       dstWidth = dstHeight * num / den;
                }
-               dstHeight = dstHeight * factor + 0.5;
-               dstWidth = dstWidth * factor + 0.5;
        }
-       
        g_debug("scaled %d x %d\n", dstWidth, dstHeight);
        GdkPixbuf *scaled_preview;
        scaled_preview = gdk_pixbuf_scale_simple(preview, dstWidth, dstHeight, GDK_INTERP_HYPER);