return;
widget = GHB_WIDGET(ud->builder, "sourcetoolbutton");
- gtk_widget_set_sensitive(widget, FALSE);
+ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-stop");
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Stop Scan");
+ gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Stop Scan");
+ //gtk_widget_set_sensitive(widget, FALSE);
+
action = GHB_ACTION(ud->builder, "source_action");
gtk_action_set_sensitive(action, FALSE);
action = GHB_ACTION(ud->builder, "source_single_action");
if (filename != NULL)
{
last_scan_file = g_strdup(filename);
- ghb_settings_set_string(ud->settings, "source", filename);
+ ghb_settings_set_string(ud->settings, "scan_source", filename);
if (update_source_label(ud, filename, TRUE))
{
gchar *path;
gint preview_count;
show_scan_progress(ud);
- path = ghb_settings_get_string( ud->settings, "source");
+ path = ghb_settings_get_string( ud->settings, "scan_source");
prune_logs(ud);
preview_count = ghb_settings_get_int(ud->settings, "preview_count");
GtkWidget *dialog;
gchar *sourcename;
- sourcename = ghb_settings_get_string(ud->settings, "source");
+ sourcename = ghb_settings_get_string(ud->settings, "scan_source");
dialog = GHB_WIDGET(ud->builder, "source_dialog");
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), sourcename);
g_free(sourcename);
gboolean checkbutton_active;
g_debug("source_browse_clicked_cb ()");
- sourcename = ghb_settings_get_string(ud->settings, "source");
+ sourcename = ghb_settings_get_string(ud->settings, "scan_source");
checkbutton_active = FALSE;
if (g_file_test(sourcename, G_FILE_TEST_IS_DIR))
{
G_MODULE_EXPORT void
source_button_clicked_cb(GtkButton *button, signal_user_data_t *ud)
{
- do_source_dialog(button, FALSE, ud);
+ ghb_status_t status;
+ ghb_get_status(&status);
+ if (status.scan.state & GHB_STATE_SCANNING)
+ {
+ ghb_backend_scan_stop();
+ }
+ else
+ {
+ do_source_dialog(button, FALSE, ud);
+ }
}
G_MODULE_EXPORT void
const gchar *filename;
gchar *sourcename;
- sourcename = ghb_settings_get_string(ud->settings, "source");
+ sourcename = ghb_settings_get_string(ud->settings, "scan_source");
filename = gtk_action_get_name(action);
ghb_do_scan(ud, filename, 0, TRUE);
if (strcmp(sourcename, filename) != 0)
rate_s = g_strdup_printf("%.6g", rate_f);
return rate_s;
}
+
+static void
+update_title_duration(signal_user_data_t *ud)
+{
+ gint ti;
+ gint hh, mm, ss, start, end;
+ gchar *text;
+ GtkWidget *widget;
+
+ ti = ghb_settings_combo_int(ud->settings, "title");
+ widget = GHB_WIDGET (ud->builder, "title_duration");
+
+ start = ghb_settings_get_int(ud->settings, "start_chapter");
+ end = ghb_settings_get_int(ud->settings, "end_chapter");
+ ghb_part_duration(ti, start, end, &hh, &mm, &ss);
+ text = g_strdup_printf("%02d:%02d:%02d", hh, mm, ss);
+ gtk_label_set_text (GTK_LABEL(widget), text);
+ g_free(text);
+}
+
static void
show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
{
GtkWidget *widget;
gchar *text;
- ud->dont_clear_presets = TRUE;
- widget = GHB_WIDGET (ud->builder, "title_duration");
- if (tinfo->duration != 0)
+ ghb_settings_set_string(ud->settings, "source", tinfo->path);
+ if (tinfo->type == HB_STREAM_TYPE)
{
- text = g_strdup_printf ("%02d:%02d:%02d", tinfo->hours,
- tinfo->minutes, tinfo->seconds);
- }
- else
- {
- text = g_strdup_printf ("Unknown");
+ GtkWidget *widget = GHB_WIDGET (ud->builder, "source_title");
+ if (tinfo->name != NULL && tinfo->name[0] != 0)
+ {
+ gtk_label_set_text (GTK_LABEL(widget), tinfo->name);
+ ghb_settings_set_string(ud->settings, "volume_label", tinfo->name);
+ set_destination(ud);
+ }
+ else
+ {
+ gchar *label = "No Title Found";
+ gtk_label_set_text (GTK_LABEL(widget), label);
+ ghb_settings_set_string(ud->settings, "volume_label", label);
+ }
}
- gtk_label_set_text (GTK_LABEL(widget), text);
- g_free(text);
+ ud->dont_clear_presets = TRUE;
+ update_title_duration(ud);
widget = GHB_WIDGET (ud->builder, "source_dimensions");
text = g_strdup_printf ("%d x %d", tinfo->width, tinfo->height);
gtk_label_set_text (GTK_LABEL(widget), text);
{
gtk_widget_show(widget);
}
+ update_title_duration(ud);
}
G_MODULE_EXPORT void
{
gtk_widget_show(widget);
}
+ update_title_duration(ud);
}
G_MODULE_EXPORT void
GtkAction *action;
widget = GHB_WIDGET(ud->builder, "sourcetoolbutton");
- gtk_widget_set_sensitive(widget, TRUE);
+ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-source");
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Source");
+ gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Choose Video Source");
+
action = GHB_ACTION(ud->builder, "source_action");
gtk_action_set_sensitive(action, TRUE);
action = GHB_ACTION(ud->builder, "source_single_action");
gtk_action_set_sensitive(action, TRUE);
- source = ghb_settings_get_string(ud->settings, "source");
+ source = ghb_settings_get_string(ud->settings, "scan_source");
update_source_label(ud, source, FALSE);
scan_prog = GTK_PROGRESS_BAR(GHB_WIDGET (ud->builder, "scan_prog"));
update_source_label(ud, device, TRUE);
gint preview_count;
preview_count = ghb_settings_get_int(ud->settings, "preview_count");
- ghb_settings_set_string(ud->settings, "source", device);
+ ghb_settings_set_string(ud->settings, "scan_source", device);
start_scan(ud, device, 0, preview_count);
}
}
{
ghb_hb_cleanup(TRUE);
prune_logs(ud);
- ghb_settings_set_string(ud->settings, "source", "/dev/null");
+ ghb_settings_set_string(ud->settings, "scan_source", "/dev/null");
start_scan(ud, "/dev/null", 0, 1);
}
}
update_source_label(ud, device, TRUE);
gint preview_count;
preview_count = ghb_settings_get_int(ud->settings, "preview_count");
- ghb_settings_set_string(ud->settings, "source", device);
+ ghb_settings_set_string(ud->settings, "scan_source", device);
start_scan(ud, device, 0, preview_count);
}
}
{
ghb_hb_cleanup(TRUE);
prune_logs(ud);
- ghb_settings_set_string(ud->settings, "source", "/dev/null");
+ ghb_settings_set_string(ud->settings, "scan_source", "/dev/null");
start_scan(ud, "/dev/null", 0, 1);
}
}
<child>
<object class="GtkVBox" id="vbox16">
<property name="visible">True</property>
- <property name="spacing">6</property>
+ <property name="spacing">2</property>
<child>
<object class="GtkHBox" id="hbox54">
<property name="visible">True</property>
</packing>
</child>
<child>
- <object class="GtkAlignment" id="alignment65">
+ <object class="GtkAlignment" id="alignment72">
<property name="visible">True</property>
+ <property name="top_padding">6</property>
<property name="left_padding">6</property>
- <property name="bottom_padding">6</property>
<child>
- <object class="GtkHBox" id="hbox5">
+ <object class="GtkHBox" id="hbox8">
<property name="visible">True</property>
<property name="spacing">4</property>
<child>
<property name="position">1</property>
</packing>
</child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment65">
+ <property name="visible">True</property>
+ <property name="left_padding">6</property>
+ <property name="bottom_padding">6</property>
+ <child>
+ <object class="GtkHBox" id="hbox5">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
<child>
<object class="GtkAlignment" id="chapter_box">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">0</property>
<property name="xscale">0</property>
- <property name="left_padding">8</property>
+ <property name="left_padding">0</property>
<child>
<object class="GtkHBox" id="hbox4">
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
</object>
<object class="GtkFileChooserDialog" id="source_dialog">
<property name="border_width">5</property>
<property name="modal">True</property>
+ <property name="action">GTK_FILE_CHOOSER_ACTION_OPEN</property>
<property name="type_hint">dialog</property>
<property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property>
</child>
<child>
<object class="GtkCheckButton" id="source_folder_flag">
- <property name="label" translatable="yes">Open VIDEO_TS folder</property>
+ <property name="label" translatable="yes">Open folder (DVD or batch)</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
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,
}
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;
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)
{
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));
tinfo->duration = title->duration;
tinfo->angle_count = title->angle_count;
+ tinfo->path = title->path;
+ tinfo->name = title->name;
+ tinfo->type = title->type;
return TRUE;
}
typedef struct
{
+ gchar *path;
+ gchar *name;
+ gint index;
+ gint type;
gint width;
gint height;
gint crop[4];
void ghb_get_status(ghb_status_t *status);
void ghb_track_status(void);
void ghb_backend_scan(const gchar *path, gint titleindex, gint preview_count);
+void ghb_backend_scan_stop();
void ghb_backend_queue_scan(const gchar *path, gint titleindex);
gboolean ghb_get_title_info(ghb_title_info_t *tinfo, gint titleindex);
void ghb_par_init(signal_user_data_t *ud);
void ghb_set_scale(signal_user_data_t *ud, gint mode);
GValue* ghb_get_chapters(gint titleindex);
void ghb_get_chapter_duration(gint ti, gint ii, gint *hh, gint *mm, gint *ss);
+void ghb_part_duration(gint tt, gint sc, gint ec, gint *hh, gint *mm, gint *ss);
gint ghb_get_best_mix(gint titleindex, gint track, gint acodec, gint mix);
gboolean ghb_ac3_in_audio_list(const GValue *audio_list);
gboolean ghb_audio_is_passthru(gint acodec);
G_BEGIN_DECLS
-/* VOID:STRING,STRING (marshalers.list:1) */
+/* VOID:STRING,STRING (/home/jstebbins/Source/HandBrake.batch/build.dbg/../gtk/src/marshalers.list:1) */
extern void ghb_marshal_VOID__STRING_STRING (GClosure *closure,
GValue *return_value,
guint n_param_values,
gpointer invocation_hint,
gpointer marshal_data);
-/* BOOLEAN:BOXED (marshalers.list:2) */
+/* BOOLEAN:BOXED (/home/jstebbins/Source/HandBrake.batch/build.dbg/../gtk/src/marshalers.list:2) */
extern void ghb_marshal_BOOLEAN__BOXED (GClosure *closure,
GValue *return_value,
guint n_param_values,
ghb_ui_update(ud, "hbfd", ghb_int64_value(0));
}
gval = ghb_settings_get_value(ud->settings, "default_source");
- ghb_settings_set_value (ud->settings, "source", gval);
+ ghb_settings_set_value (ud->settings, "scan_source", gval);
str = ghb_settings_get_string(ud->settings, "destination_dir");
ghb_ui_update(ud, "dest_dir", ghb_string_value(str));
--- /dev/null
+/* $Id: dvd.c,v 1.12 2005/11/25 15:05:25 titer Exp $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#include "hb.h"
+#include "lang.h"
+
+struct hb_batch_s
+{
+ char * path;
+ hb_list_t * list_file;
+};
+
+/***********************************************************************
+ * hb_batch_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+hb_batch_t * hb_batch_init( char * path )
+{
+ hb_batch_t * d;
+ struct stat sb;
+ DIR * dir;
+ struct dirent * entry;
+ char * filename;
+
+ if ( stat( path, &sb ) )
+ return NULL;
+
+ if ( !S_ISDIR( sb.st_mode ) )
+ return NULL;
+
+ dir = opendir( path );
+ if ( dir == NULL )
+ return NULL;
+
+ d = calloc( sizeof( hb_batch_t ), 1 );
+ d->list_file = hb_list_init();
+
+ while ( (entry = readdir( dir ) ) )
+ {
+ filename = hb_strdup_printf( "%s" DIR_SEP_STR "%s", path, entry->d_name );
+ if ( stat( filename, &sb ) )
+ {
+ free( filename );
+ continue;
+ }
+
+ if ( !S_ISREG( sb.st_mode ) )
+ {
+ free( filename );
+ continue;
+ }
+
+ hb_list_add( d->list_file, filename );
+ }
+
+ if ( hb_list_count( d->list_file ) == 0 )
+ {
+ hb_list_close( &d->list_file );
+ free( d );
+ return NULL;
+ }
+
+ d->path = strdup( path );
+
+ return d;
+}
+
+/***********************************************************************
+ * hb_batch_title_count
+ **********************************************************************/
+int hb_batch_title_count( hb_batch_t * d )
+{
+ return hb_list_count( d->list_file );
+}
+
+/***********************************************************************
+ * hb_batch_title_scan
+ **********************************************************************/
+hb_title_t * hb_batch_title_scan( hb_batch_t * d, int t )
+{
+
+ hb_title_t * title;
+ char * filename;
+ hb_stream_t * stream;
+
+ if ( t < 1 )
+ return NULL;
+
+ filename = hb_list_item( d->list_file, t-1 );
+ if ( filename == NULL )
+ return NULL;
+
+ stream = hb_stream_open( filename, 0 );
+ if ( stream == NULL )
+ return NULL;
+
+ title = hb_stream_title_scan( stream );
+ title->index = t;
+ hb_stream_close( &stream );
+
+ return title;
+}
+
+/***********************************************************************
+ * hb_batch_close
+ ***********************************************************************
+ * Closes and frees everything
+ **********************************************************************/
+void hb_batch_close( hb_batch_t ** _d )
+{
+ hb_batch_t * d = *_d;
+ char * filename;
+
+ while ( ( filename = hb_list_item( d->list_file, 0 ) ) )
+ {
+ hb_list_rem( d->list_file, filename );
+ free( filename );
+ }
+ hb_list_close( &d->list_file );
+ free( d->path );
+ free( d );
+ *_d = NULL;
+}
+
**********************************************************************
*
*********************************************************************/
-hb_title_t * hb_title_init( char * dvd, int index )
+hb_title_t * hb_title_init( char * path, int index )
{
hb_title_t * t;
t->list_audio = hb_list_init();
t->list_chapter = hb_list_init();
t->list_subtitle = hb_list_init();
- strcat( t->dvd, dvd );
+ strcat( t->path, path );
// default to decoding mpeg2
t->video_id = 0xE0;
t->video_codec = WORK_DECMPEG2;
}
return retval;
}
+
+char * hb_strdup_printf( char * fmt, ... )
+{
+ int len;
+ va_list ap;
+ int size = 256;
+ char * str;
+ char * tmp;
+
+ str = malloc( size );
+ if ( str == NULL )
+ return NULL;
+
+ while (1)
+ {
+ /* Try to print in the allocated space. */
+ va_start( ap, fmt );
+ len = vsnprintf( str, size, fmt, ap );
+ va_end( ap );
+
+ /* If that worked, return the string. */
+ if ( len > -1 && len < size )
+ {
+ return str;
+ }
+
+ /* Else try again with more space. */
+ if ( len > -1 ) /* glibc 2.1 */
+ size = len + 1; /* precisely what is needed */
+ else /* glibc 2.0 */
+ size *= 2; /* twice the old size */
+ tmp = realloc( str, size );
+ if ( tmp == NULL )
+ {
+ free( str );
+ return NULL;
+ }
+ else
+ str = tmp;
+ }
+}
+
struct hb_title_s
{
- char dvd[1024];
+ enum { HB_DVD_TYPE, HB_STREAM_TYPE } type;
+ char path[1024];
char name[1024];
int index;
int vts;
extern void hb_register_error_handler( hb_error_handler_t * handler );
+char * hb_strdup_printf( char * fmt, ... );
+
#endif
MP4FileHandle input_file;
hb_deep_log( 2, "Got an MP4 input, read the metadata");
- input_file = MP4Read( title->dvd, 0 );
+ input_file = MP4Read( title->path, 0 );
if( input_file != MP4_INVALID_FILE_HANDLE )
{
hb_log( "scan: scanning title %d", t );
title = hb_title_init( d->path, t );
+ title->type = HB_DVD_TYPE;
+
if( DVDUDFVolumeInfo( d->reader, title->name, sizeof( title->name ),
unused, sizeof( unused ) ) )
{
hb_log( "scan: scanning title %d", t );
title = hb_title_init( d->path, t );
+ title->type = HB_DVD_TYPE;
if (dvdnav_get_title_string(d->dvdnav, &name) == DVDNAV_STATUS_OK)
{
strncpy( title->name, name, sizeof( title->name ) );
/* For MacGui active queue
increments each time the scan thread completes*/
int scanCount;
+ volatile int scan_die;
/* Stash of persistent data between jobs, for stuff
like correcting frame count and framerate estimates
{
hb_title_t * title;
+ h->scan_die = 0;
+
/* Clean up from previous scan */
hb_remove_previews( h );
while( ( title = hb_list_item( h->list_title, 0 ) ) )
}
hb_log( "hb_scan: path=%s, title_index=%d", path, title_index );
- h->scan_thread = hb_scan_init( h, path, title_index, h->list_title,
- preview_count, store_previews );
+ h->scan_thread = hb_scan_init( h, &h->scan_die, path, title_index,
+ h->list_title, preview_count,
+ store_previews );
}
/**
}
/**
+ * Stops the conversion process.
+ * @param h Handle to hb_handle_t.
+ */
+void hb_scan_stop( hb_handle_t * h )
+{
+ h->scan_die = 1;
+
+ h->job_count = hb_count(h);
+ h->job_count_permanent = 0;
+
+ hb_resume( h );
+}
+
+/**
* Returns the state of the conversion process.
* @param h Handle to hb_handle_t.
* @param s Handle to hb_state_t which to copy the state data.
{
hb_thread_close( &h->scan_thread );
- hb_log( "libhb: scan thread found %d valid title(s)",
- hb_list_count( h->list_title ) );
+ if ( h->scan_die )
+ {
+ hb_title_t * title;
+
+ hb_remove_previews( h );
+ while( ( title = hb_list_item( h->list_title, 0 ) ) )
+ {
+ hb_list_rem( h->list_title, title );
+ hb_title_close( &title );
+ }
+
+ hb_log( "hb_scan: canceled" );
+ }
+ else
+ {
+ hb_log( "libhb: scan thread found %d valid title(s)",
+ hb_list_count( h->list_title ) );
+ }
hb_lock( h->state_lock );
h->state.state = HB_STATE_SCANDONE; //originally state.state
hb_unlock( h->state_lock );
void hb_scan( hb_handle_t *, const char * path,
int title_index, int preview_count,
int store_previews );
+void hb_scan_stop( hb_handle_t * );
/* hb_get_titles()
Returns the list of valid titles detected by the latest scan. */
* Threads: update.c, scan.c, work.c, reader.c, muxcommon.c
**********************************************************************/
hb_thread_t * hb_update_init( int * build, char * version );
-hb_thread_t * hb_scan_init( hb_handle_t *, const char * path,
- int title_index, hb_list_t * list_title,
- int preview_count, int store_previews );
+hb_thread_t * hb_scan_init( hb_handle_t *, volatile int * die,
+ const char * path, int title_index,
+ hb_list_t * list_title, int preview_count,
+ int store_previews );
hb_thread_t * hb_work_init( hb_list_t * jobs, int cpu_count,
volatile int * die, int * error, hb_job_t ** job );
hb_thread_t * hb_reader_init( hb_job_t * );
extern void decmetadata( hb_title_t *title );
/***********************************************************************
+ * batch.c
+ **********************************************************************/
+typedef struct hb_batch_s hb_batch_t;
+
+hb_batch_t * hb_batch_init( char * path );
+void hb_batch_close( hb_batch_t ** _d );
+int hb_batch_title_count( hb_batch_t * d );
+hb_title_t * hb_batch_title_scan( hb_batch_t * d, int t );
+
+/***********************************************************************
* dvd.c
**********************************************************************/
typedef union hb_dvd_s hb_dvd_t;
#ifndef HB_PORTS_H
#define HB_PORTS_H
+#if defined(_WIN32)
+#define DIR_SEP_STR "\\"
+#else
+#define DIR_SEP_STR "/"
+#endif
+
/************************************************************************
* Utils
***********************************************************************/
int chapter = -1;
int chapter_end = r->job->chapter_end;
- if( !( r->dvd = hb_dvd_init( r->title->dvd ) ) )
+ if ( r->title->type == HB_DVD_TYPE )
{
- if ( !( r->stream = hb_stream_open( r->title->dvd, r->title ) ) )
- {
- return;
- }
+ if ( !( r->dvd = hb_dvd_init( r->title->path ) ) )
+ return;
+ }
+ else if ( r->title->type == HB_STREAM_TYPE )
+ {
+ if ( !( r->stream = hb_stream_open( r->title->path, r->title ) ) )
+ return;
+ }
+ else
+ {
+ // Unknown type, should never happen
+ return;
}
if (r->dvd)
typedef struct
{
- hb_handle_t * h;
+ hb_handle_t * h;
+ volatile int * die;
- char * path;
- int title_index;
- hb_list_t * list_title;
+ char * path;
+ int title_index;
+ hb_list_t * list_title;
- hb_dvd_t * dvd;
- hb_stream_t * stream;
+ hb_dvd_t * dvd;
+ hb_stream_t * stream;
+ hb_batch_t * batch;
- int preview_count;
- int store_previews;
+ int preview_count;
+ int store_previews;
} hb_scan_t;
return arstr;
}
-hb_thread_t * hb_scan_init( hb_handle_t * handle, const char * path,
- int title_index, hb_list_t * list_title,
- int preview_count, int store_previews )
+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 )
{
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;
}
}
}
+ else if ( ( data->batch = hb_batch_init( data->path ) ) )
+ {
+ /* Scan all titles */
+ for( i = 0; i < hb_batch_title_count( data->batch ); i++ )
+ {
+ hb_title_t * title;
+
+ title = hb_batch_title_scan( data->batch, i + 1 );
+ if ( title != NULL )
+ {
+ hb_list_add( data->list_title, title );
+ }
+ }
+ }
else if ( (data->stream = hb_stream_open( data->path, 0 ) ) != NULL )
{
hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) );
hb_state_t state;
hb_audio_t * audio;
+ if ( *data->die )
+ {
+ goto finish;
+ }
title = hb_list_item( data->list_title, i );
#define p state.param.scanning
job->mux = HB_MUX_MP4;
}
+finish:
+
if( data->dvd )
{
hb_dvd_close( &data->dvd );
{
hb_stream_close(&data->stream);
}
+ if( data->batch )
+ {
+ hb_batch_close( &data->batch );
+ }
free( data->path );
free( data );
_data = NULL;
if (data->dvd)
{
- hb_dvd_start( data->dvd, title, 1 );
- title->angle_count = hb_dvd_angle_count( data->dvd );
- hb_log( "scan: title angle(s) %d", title->angle_count );
+ hb_dvd_start( data->dvd, title, 1 );
+ title->angle_count = hb_dvd_angle_count( data->dvd );
+ hb_log( "scan: title angle(s) %d", title->angle_count );
+ }
+ else if (data->batch)
+ {
+ data->stream = hb_stream_open( title->path, title );
}
for( i = 0; i < data->preview_count; i++ )
FILE * file_preview;
char filename[1024];
+ if ( *data->die )
+ {
+ return 0;
+ }
if (data->dvd)
{
if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / ( data->preview_count + 1.0 ) ) )
hb_buffer_close( &vid_buf );
}
+ if ( data->batch && data->stream )
+ {
+ hb_stream_close( &data->stream );
+ }
+
if ( npreviews )
{
// use the most common frame info for our final title dimensions
// 'Barebones Title'
hb_title_t *aTitle = hb_title_init( stream->path, 0 );
+ aTitle->type = HB_STREAM_TYPE;
aTitle->index = 1;
// Copy part of the stream path to the title name
// 'Barebones Title'
hb_title_t *title = hb_title_init( stream->path, 0 );
+ title->type = HB_STREAM_TYPE;
title->index = 1;
// Copy part of the stream path to the title name
hb_log("job configuration:");
hb_log( " * source");
- hb_log( " + %s", title->dvd );
+ hb_log( " + %s", title->path );
hb_log( " + title %d, chapter(s) %d to %d", title->index,
job->chapter_start, job->chapter_end );
- (void) performScan:(NSString *) scanPath scanTitleNum: (int) scanTitleNum;
- (IBAction) showNewScan: (id) sender;
+
+- (IBAction) cancelScanning:(id)sender;
+
- (void) updateUI: (NSTimer *) timer;
- (void) enableUI: (bool) enable;
hb_state_t s;
hb_get_state( fHandle, &s );
- if (s.state == HB_STATE_SCANNING && ([ident isEqualToString: StartEncodingIdentifier] || [ident isEqualToString: AddToQueueIdentifier]))
- return NO;
-
+ if (s.state == HB_STATE_SCANNING)
+ {
+
+ if ([ident isEqualToString: ChooseSourceIdentifier])
+ {
+ [toolbarItem setImage: [NSImage imageNamed: @"Stop"]];
+ [toolbarItem setLabel: @"Cancel Scan"];
+ [toolbarItem setPaletteLabel: @"Cancel Scanning"];
+ [toolbarItem setToolTip: @"Cancel Scanning Source"];
+ return YES;
+ }
+
+ if ([ident isEqualToString: StartEncodingIdentifier] || [ident isEqualToString: AddToQueueIdentifier])
+ return NO;
+ }
+ else
+ {
+ if ([ident isEqualToString: ChooseSourceIdentifier])
+ {
+ [toolbarItem setImage: [NSImage imageNamed: @"Source"]];
+ [toolbarItem setLabel: @"Source"];
+ [toolbarItem setPaletteLabel: @"Source"];
+ [toolbarItem setToolTip: @"Choose Video Source"];
+ return YES;
+ }
+ }
+
hb_get_state2( fQueueEncodeLibhb, &s );
if (s.state == HB_STATE_WORKING || s.state == HB_STATE_MUXING)
/*Opens the source browse window, called from Open Source widgets */
- (IBAction) browseSources: (id) sender
{
+
+ hb_state_t s;
+ hb_get_state( fHandle, &s );
+ if (s.state == HB_STATE_SCANNING)
+ {
+ [self cancelScanning:nil];
+ return;
+ }
+
+
NSOpenPanel * panel;
panel = [NSOpenPanel openPanel];
if ([[scanPath lastPathComponent] isEqualToString: @"VIDEO_TS"])
{
/* If VIDEO_TS Folder is chosen, choose its parent folder for the source display name
- we have to use the title->dvd value so we get the proper name of the volume if a physical dvd is the source*/
+ we have to use the title->path value so we get the proper name of the volume if a physical dvd is the source*/
displayTitlescanSourceName = [[scanPath stringByDeletingLastPathComponent] lastPathComponent];
}
else
}
}
+- (IBAction) cancelScanning:(id)sender
+{
+ hb_scan_stop(fHandle);
+}
+
- (IBAction) showNewScan:(id)sender
{
hb_list_t * list;
}
[fSrcTitlePopUp addItemWithTitle: [NSString
- stringWithFormat: @"%d - %02dh%02dm%02ds",
- title->index, title->hours, title->minutes,
+ stringWithFormat: @"%s %d - %02dh%02dm%02ds",
+ title->name,title->index, title->hours, title->minutes,
title->seconds]];
}
- // Select the longuest title
- [fSrcTitlePopUp selectItemAtIndex: indxpri];
+ /* if we are a stream, select the first title */
+ if (title->type == HB_STREAM_TYPE)
+ {
+ [fSrcTitlePopUp selectItemAtIndex: 0];
+ }
+ else
+ {
+ /* if not then select the longest title (dvd) */
+ [fSrcTitlePopUp selectItemAtIndex: indxpri];
+ }
[self titlePopUpChanged:nil];
SuccessfulScan = YES;
[queueFileJob setObject:[NSNumber numberWithInt:2] forKey:@"Status"];
/* Source and Destination Information */
- [queueFileJob setObject:[NSString stringWithUTF8String: title->dvd] forKey:@"SourcePath"];
+ [queueFileJob setObject:[NSString stringWithUTF8String: title->path] forKey:@"SourcePath"];
[queueFileJob setObject:[fSrcDVD2Field stringValue] forKey:@"SourceName"];
[queueFileJob setObject:[NSNumber numberWithInt:title->index] forKey:@"TitleNumber"];
[queueFileJob setObject:[NSNumber numberWithInt:[fSrcAnglePopUp indexOfSelectedItem] + 1] forKey:@"TitleAngle"];
hb_title_t * title = (hb_title_t*)
hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
+ /* If we are a stream type, grok the output file name from title->name upon title change */
+ if (title->type == HB_STREAM_TYPE)
+ {
+ /* we set the default name according to the new title->name */
+ [fDstFile2Field setStringValue: [NSString stringWithFormat:
+ @"%@/%@.%@", [[fDstFile2Field stringValue] stringByDeletingLastPathComponent],
+ [NSString stringWithUTF8String: title->name],
+ [[fDstFile2Field stringValue] pathExtension]]];
+ /* If we have more than one title and are stream then we have a batch, change the source to read out the parent folder also */
+ if ( hb_list_count( list ) > 1 )
+ {
+ [fSrcDVD2Field setStringValue:[NSString stringWithFormat:@"%@/%@", browsedSourceDisplayName,[NSString stringWithUTF8String: title->name]]];
+ }
+ }
+
+
/* If Auto Naming is on. We create an output filename of dvd name - title number */
if( [[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultAutoNaming"] > 0 && ( hb_list_count( list ) > 1 ) )
{
int i;
fprintf( stderr, "+ title %d:\n", title->index );
- fprintf( stderr, " + vts %d, ttn %d, cells %d->%d (%d blocks)\n",
- title->vts, title->ttn, title->cell_start, title->cell_end,
- title->block_count );
+ if ( title->type == HB_STREAM_TYPE )
+ {
+ fprintf( stderr, " + stream: %s\n", title->path );
+ }
+ else if ( title->type == HB_DVD_TYPE )
+ {
+ fprintf( stderr, " + vts %d, ttn %d, cells %d->%d (%d blocks)\n",
+ title->vts, title->ttn, title->cell_start, title->cell_end,
+ title->block_count );
+ }
if (dvdnav)
fprintf( stderr, " + angle(s) %d\n", title->angle_count );
fprintf( stderr, " + duration: %02d:%02d:%02d\n",