~kaozilon/totem/test

« back to all changes in this revision

Viewing changes to src/totem-video-thumbnailer.c

  • Committer: Bazaar Package Importer
  • Author(s): Sjoerd Simons, Josselin Mouette, Sjoerd Simons, Emilio Pozuelo Monfort
  • Date: 2009-04-19 17:28:51 UTC
  • mfrom: (1.2.52 upstream) (5.1.1 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090419172851-epoqimnq62akn294
Tags: 2.26.1-1
[ Josselin Mouette ]
* totem-plugins depends on python-gdbm. Closes: #523582.

[ Sjoerd Simons ]
* New upstream release (2.26.1)
* debian/patches/02_flv.patch: Dropped, fixed upstream
* debian/patches/04_tracker_build.patch: Dropped, fixed upstream
* debian/patches/01_fake_keypresses.patch: Updated and simplified
* debian/patches/70_bbc_plugin.patch: Updated
* debian/patches/90_autotools.patch: Updated

[ Emilio Pozuelo Monfort ]
* Recommend gnome-codec-install rather than gnome-app-install.
  Closes: #523052.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include <glib/gstdio.h>
31
31
#include <gtk/gtk.h>
32
32
#include <glib/gi18n.h>
 
33
#include <cairo.h>
33
34
 
34
35
#include <unistd.h>
35
36
#include <string.h>
 
37
#include <math.h>
36
38
#include <stdlib.h>
 
39
#include <fcntl.h>
37
40
#include <sys/types.h>
38
41
#include <sys/stat.h>
39
42
#include "bacon-video-widget.h"
 
43
#include "video-utils.h"
40
44
#include "totem-resources.h"
41
45
 
42
46
/* #define THUMB_DEBUG */
47
51
#define PROGRESS_DEBUG(format...) { if (verbose != FALSE) g_message (format); }
48
52
#endif
49
53
 
 
54
/* The main() function controls progress in the first and last 10% */
 
55
#define PRINT_PROGRESS(p) { if (print_progress) g_printf ("%f%% complete\n", p); }
 
56
#define MIN_PROGRESS 10.0
 
57
#define MAX_PROGRESS 90.0
 
58
 
50
59
#define BORING_IMAGE_VARIANCE 256.0             /* Tweak this if necessary */
 
60
#define GALLERY_MIN 3                           /* minimum number of screenshots in a gallery */
 
61
#define GALLERY_MAX 30                          /* maximum number of screenshots in a gallery */
 
62
#define GALLERY_HEADER_HEIGHT 66                /* header height (in pixels) for the gallery */
51
63
 
52
64
static gboolean jpeg_output = FALSE;
53
65
static gboolean output_size = 128;
54
66
static gboolean time_limit = TRUE;
55
67
static gboolean verbose = FALSE;
 
68
static gboolean print_progress = FALSE;
56
69
static gboolean g_fatal_warnings = FALSE;
 
70
static gint gallery = -1;
57
71
static gint64 second_index = -1;
58
72
static char **filenames = NULL;
59
73
 
255
269
        return (variance > BORING_IMAGE_VARIANCE);
256
270
}
257
271
 
258
 
static void
259
 
save_pixbuf (GdkPixbuf *pixbuf, const char *path,
260
 
             const char *video_path, int size, gboolean is_still)
 
272
static GdkPixbuf *
 
273
scale_pixbuf (GdkPixbuf *pixbuf, int size, gboolean is_still)
261
274
{
 
275
        GdkPixbuf *result;
262
276
        int width, height;
263
 
        GdkPixbuf *small, *with_holes;
264
 
        GError *err = NULL;
265
 
        char *a_width, *a_height;
266
 
 
267
 
        height = gdk_pixbuf_get_height (pixbuf);
268
 
        width = gdk_pixbuf_get_width (pixbuf);
269
 
 
270
 
        if (size <= 256)
271
 
        {
 
277
 
 
278
        if (size <= 256) {
272
279
                int d_width, d_height;
 
280
                GdkPixbuf *small;
273
281
 
274
282
                height = gdk_pixbuf_get_height (pixbuf);
275
283
                width = gdk_pixbuf_get_width (pixbuf);
276
284
 
277
 
                if (width > height)
278
 
                {
 
285
                if (width > height) {
279
286
                        d_width = size;
280
287
                        d_height = size * height / width;
281
288
                } else {
283
290
                        d_width = size * width / height;
284
291
                }
285
292
 
286
 
                small = gdk_pixbuf_scale_simple (pixbuf, d_width, d_height,
287
 
                                GDK_INTERP_TILES);
 
293
                small = gdk_pixbuf_scale_simple (pixbuf, d_width, d_height, GDK_INTERP_TILES);
288
294
 
289
295
                if (is_still == FALSE) {
290
 
                        with_holes = add_holes_to_pixbuf_small (small,
291
 
                                        d_width, d_height);
292
 
                        g_return_if_fail (with_holes != NULL);
 
296
                        result = add_holes_to_pixbuf_small (small, d_width, d_height);
 
297
                        g_return_val_if_fail (result != NULL, NULL);
293
298
                        g_object_unref (small);
294
299
                } else {
295
 
                        with_holes = small;
 
300
                        result = small;
296
301
                }
297
302
        } else {
298
 
                with_holes = add_holes_to_pixbuf_large (pixbuf, size);
299
 
                g_return_if_fail (with_holes != NULL);
300
 
        }
301
 
 
302
 
        a_width = g_strdup_printf ("%d", width);
303
 
        a_height = g_strdup_printf ("%d", height);
304
 
 
305
 
        if (gdk_pixbuf_save (with_holes, path,
306
 
                                jpeg_output ? "jpeg" : "png", &err,
307
 
                                "tEXt::Thumb::Image::Width", a_width,
308
 
                                "tEXt::Thumb::Image::Height", a_height,
309
 
                                NULL) == FALSE)
310
 
        {
311
 
                g_free (a_width);
312
 
                g_free (a_height);
313
 
 
314
 
                if (err != NULL)
315
 
                {
 
303
                result = add_holes_to_pixbuf_large (pixbuf, size);
 
304
                g_return_val_if_fail (result != NULL, NULL);
 
305
        }
 
306
 
 
307
        return result;
 
308
}
 
309
 
 
310
static void
 
311
save_pixbuf (GdkPixbuf *pixbuf, const char *path,
 
312
             const char *video_path, int size, gboolean is_still)
 
313
{
 
314
        int width, height;
 
315
        GdkPixbuf *with_holes;
 
316
        GError *err = NULL;
 
317
        gboolean ret;
 
318
 
 
319
        height = gdk_pixbuf_get_height (pixbuf);
 
320
        width = gdk_pixbuf_get_width (pixbuf);
 
321
 
 
322
        /* If we're outputting a gallery, don't scale the pixbuf or add borders */
 
323
        if (gallery == -1)
 
324
                with_holes = scale_pixbuf (pixbuf, size, is_still);
 
325
        else
 
326
                with_holes = g_object_ref (pixbuf);
 
327
 
 
328
 
 
329
        if (jpeg_output == FALSE) {
 
330
                char *a_width, *a_height;
 
331
 
 
332
                a_width = g_strdup_printf ("%d", width);
 
333
                a_height = g_strdup_printf ("%d", height);
 
334
 
 
335
                ret = gdk_pixbuf_save (with_holes, path, "png", &err,
 
336
                                       "tEXt::Thumb::Image::Width", a_width,
 
337
                                       "tEXt::Thumb::Image::Height", a_height,
 
338
                                       NULL);
 
339
        } else {
 
340
                ret = gdk_pixbuf_save (with_holes, path, "jpeg", &err, NULL);
 
341
        }
 
342
 
 
343
        if (ret == FALSE) {
 
344
                if (err != NULL) {
316
345
                        g_print ("totem-video-thumbnailer couldn't write the thumbnail '%s' for video '%s': %s\n", path, video_path, err->message);
317
346
                        g_error_free (err);
318
347
                } else {
462
491
        }
463
492
}
464
493
 
 
494
static GdkPixbuf *
 
495
cairo_surface_to_pixbuf (cairo_surface_t *surface)
 
496
{
 
497
        gint stride, width, height, x, y;
 
498
        guchar *data, *output, *output_pixel;
 
499
 
 
500
        /* This doesn't deal with alpha --- it simply converts the 4-byte Cairo ARGB
 
501
         * format to the 3-byte GdkPixbuf packed RGB format. */
 
502
        g_assert (cairo_image_surface_get_format (surface) == CAIRO_FORMAT_RGB24);
 
503
 
 
504
        stride = cairo_image_surface_get_stride (surface);
 
505
        width = cairo_image_surface_get_width (surface);
 
506
        height = cairo_image_surface_get_height (surface);
 
507
        data = cairo_image_surface_get_data (surface);
 
508
 
 
509
        output = g_malloc (stride * height);
 
510
        output_pixel = output;
 
511
 
 
512
        for (y = 0; y < height; y++) {
 
513
                guint32 *row = (guint32*) (data + y * stride);
 
514
 
 
515
                for (x = 0; x < width; x++) {
 
516
                        output_pixel[0] = (row[x] & 0x00ff0000) >> 16;
 
517
                        output_pixel[1] = (row[x] & 0x0000ff00) >> 8;
 
518
                        output_pixel[2] = (row[x] & 0x000000ff);
 
519
 
 
520
                        output_pixel += 3;
 
521
                }
 
522
        }
 
523
 
 
524
        return gdk_pixbuf_new_from_data (output, GDK_COLORSPACE_RGB, FALSE, 8,
 
525
                                         width, height, width * 3,
 
526
                                         (GdkPixbufDestroyNotify) g_free, NULL);
 
527
}
 
528
 
 
529
 
 
530
static GdkPixbuf *
 
531
create_gallery (BaconVideoWidget *bvw, const char *input, const char *output)
 
532
{
 
533
        GdkPixbuf *screenshot, *pixbuf = NULL;
 
534
        cairo_t *cr;
 
535
        cairo_surface_t *surface;
 
536
        PangoLayout *layout;
 
537
        PangoFontDescription *font_desc;
 
538
        gint64 stream_length, screenshot_interval, pos;
 
539
        guint columns, rows, current_column, current_row, x, y;
 
540
        gint screenshot_width, screenshot_height = 0, x_padding = 0, y_padding = 0;
 
541
        gfloat scale = 1.0;
 
542
        gchar *header_text, *duration_text, *filename;
 
543
 
 
544
        /* Calculate how many screenshots we're going to take */
 
545
        stream_length = bacon_video_widget_get_stream_length (bvw) / 1000;
 
546
 
 
547
        /* As a default, we have one screenshot per minute of stream,
 
548
         * but adjusted so we don't have any gaps in the resulting gallery. */
 
549
        if (gallery == 0) {
 
550
                gallery = stream_length / 60;
 
551
 
 
552
                while (gallery % 3 != 0 &&
 
553
                       gallery % 4 != 0 &&
 
554
                       gallery % 5 != 0) {
 
555
                        gallery++;
 
556
                }
 
557
        }
 
558
 
 
559
        if (gallery < GALLERY_MIN)
 
560
                gallery = GALLERY_MIN;
 
561
        if (gallery > GALLERY_MAX)
 
562
                gallery = GALLERY_MAX;
 
563
        screenshot_interval = stream_length / gallery;
 
564
 
 
565
        PROGRESS_DEBUG ("Producing gallery of %u screenshots, taken at %" G_GINT64_FORMAT " second intervals throughout a %" G_GINT64_FORMAT " second-long stream.",
 
566
                        gallery, screenshot_interval, stream_length);
 
567
 
 
568
        /* Calculate how to arrange the screenshots so we don't get ones orphaned on the last row.
 
569
         * At this point, only deal with arrangements of 3, 4 or 5 columns. */
 
570
        y = G_MAXUINT;
 
571
        for (x = 3; x <= 5; x++) {
 
572
                if (gallery % x == 0 || x - gallery % x < y) {
 
573
                        y = x - gallery % x;
 
574
                        columns = x;
 
575
 
 
576
                        /* Have we found an optimal solution already? */
 
577
                        if (y == x)
 
578
                                break;
 
579
                }
 
580
        }
 
581
 
 
582
        rows = ceil ((gfloat) gallery / (gfloat) columns);
 
583
 
 
584
        PROGRESS_DEBUG ("Outputting as %u rows and %u columns.", rows, columns);
 
585
 
 
586
        /* Take the screenshots and composite them into a pixbuf */
 
587
        current_column = current_row = x = y = 0;
 
588
        for (pos = screenshot_interval; pos <= stream_length; pos += screenshot_interval) {
 
589
                screenshot = capture_frame_at_time (bvw, input, output, pos);
 
590
 
 
591
                if (pixbuf == NULL) {
 
592
                        screenshot_width = gdk_pixbuf_get_width (screenshot);
 
593
                        screenshot_height = gdk_pixbuf_get_height (screenshot);
 
594
 
 
595
                        /* Calculate a scaling factor so that screenshot_width -> output_size */
 
596
                        scale = (float) output_size / (float) screenshot_width;
 
597
 
 
598
                        x_padding = x = MAX (output_size * 0.05, 1);
 
599
                        y_padding = y = MAX (scale * screenshot_height * 0.05, 1);
 
600
 
 
601
                        PROGRESS_DEBUG ("Scaling each screenshot by %f.", scale);
 
602
 
 
603
                        /* Create our massive pixbuf */
 
604
                        pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
 
605
                                                 columns * output_size + (columns + 1) * x_padding,
 
606
                                                 (guint) (rows * scale * screenshot_height + (rows + 1) * y_padding));
 
607
                        gdk_pixbuf_fill (pixbuf, 0x000000ff);
 
608
 
 
609
                        PROGRESS_DEBUG ("Created output pixbuf (%ux%u).", gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf));
 
610
                }
 
611
 
 
612
                /* Composite the screenshot into our gallery */
 
613
                gdk_pixbuf_composite (screenshot, pixbuf,
 
614
                                      x, y, output_size, scale * screenshot_height,
 
615
                                      (gdouble) x, (gdouble) y, scale, scale,
 
616
                                      GDK_INTERP_BILINEAR, 255);
 
617
                g_object_unref (screenshot);
 
618
 
 
619
                PROGRESS_DEBUG ("Composited screenshot from %" G_GINT64_FORMAT " seconds (address %u) at (%u,%u).",
 
620
                                pos, GPOINTER_TO_UINT (screenshot), x, y);
 
621
 
 
622
                /* We print progress in the range 10% (MIN_PROGRESS) to 50% (MAX_PROGRESS - MIN_PROGRESS) / 2.0 */
 
623
                PRINT_PROGRESS (MIN_PROGRESS + (current_row * columns + current_column) * (((MAX_PROGRESS - MIN_PROGRESS) / gallery) / 2.0));
 
624
 
 
625
                current_column = (current_column + 1) % columns;
 
626
                x += output_size + x_padding;
 
627
                if (current_column == 0) {
 
628
                        x = x_padding;
 
629
                        y += scale * screenshot_height + y_padding;
 
630
                        current_row++;
 
631
                }
 
632
        }
 
633
 
 
634
        PROGRESS_DEBUG ("Converting pixbuf to a Cairo surface.");
 
635
 
 
636
        /* Load the pixbuf into a Cairo surface and overlay the text. The height is the height of
 
637
         * the gallery plus the necessary height for 3 lines of header (at ~18px each), plus some
 
638
         * extra padding. */
 
639
        surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, gdk_pixbuf_get_width (pixbuf),
 
640
                                              gdk_pixbuf_get_height (pixbuf) + GALLERY_HEADER_HEIGHT + y_padding);
 
641
        cr = cairo_create (surface);
 
642
        cairo_surface_destroy (surface);
 
643
 
 
644
        /* First, copy across the gallery pixbuf */
 
645
        gdk_cairo_set_source_pixbuf (cr, pixbuf, 0.0, GALLERY_HEADER_HEIGHT + y_padding);
 
646
        cairo_rectangle (cr, 0.0, GALLERY_HEADER_HEIGHT + y_padding, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf));
 
647
        cairo_fill (cr);
 
648
        g_object_unref (pixbuf);
 
649
 
 
650
        /* Build the header information */
 
651
        duration_text = totem_time_to_string (stream_length * 1000);
 
652
        filename = NULL;
 
653
        if (strstr (input, "://")) {
 
654
                char *local;
 
655
                local = g_filename_from_uri (input, NULL, NULL);
 
656
                filename = g_path_get_basename (local);
 
657
                g_free (local);
 
658
        }
 
659
        if (filename == NULL)
 
660
                filename = g_path_get_basename (input);
 
661
 
 
662
        /* Translators: The first string is "Filename" (as translated); the second is an actual filename.
 
663
                        The third string is "Resolution" (as translated); the fourth and fifth are screenshot height and width, respectively.
 
664
                        The sixth string is "Duration" (as translated); the seventh is the movie duration in words. */
 
665
        header_text = g_strdup_printf (_("<b>%s</b>: %s\n<b>%s</b>: %d\303\227%d\n<b>%s</b>: %s"),
 
666
                                       _("Filename"),
 
667
                                       filename,
 
668
                                       _("Resolution"),
 
669
                                       screenshot_width,
 
670
                                       screenshot_height,
 
671
                                       _("Duration"),
 
672
                                       duration_text);
 
673
        g_free (duration_text);
 
674
        g_free (filename);
 
675
 
 
676
        PROGRESS_DEBUG ("Writing header text with Pango.");
 
677
 
 
678
        /* Write out some header information */
 
679
        layout = pango_cairo_create_layout (cr);
 
680
        font_desc = pango_font_description_from_string ("Sans 18px");
 
681
        pango_layout_set_font_description (layout, font_desc);
 
682
        pango_font_description_free (font_desc);
 
683
 
 
684
        pango_layout_set_markup (layout, header_text, -1);
 
685
        g_free (header_text);
 
686
 
 
687
        cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
 
688
        cairo_move_to (cr, (gdouble) x_padding, (gdouble) y_padding);
 
689
        pango_cairo_show_layout (cr, layout);
 
690
 
 
691
        /* Go through each screenshot and write its timestamp */
 
692
        current_column = current_row = 0;
 
693
        x = x_padding + output_size;
 
694
        y = y_padding * 2 + GALLERY_HEADER_HEIGHT + scale * screenshot_height;
 
695
 
 
696
        font_desc = pango_font_description_from_string ("Sans 10px");
 
697
        pango_layout_set_font_description (layout, font_desc);
 
698
        pango_font_description_free (font_desc);
 
699
 
 
700
        PROGRESS_DEBUG ("Writing screenshot timestamps with Pango.");
 
701
 
 
702
        for (pos = screenshot_interval; pos <= stream_length; pos += screenshot_interval) {
 
703
                gchar *timestamp_text;
 
704
                gint layout_width, layout_height;
 
705
 
 
706
                timestamp_text = totem_time_to_string (pos * 1000);
 
707
 
 
708
                pango_layout_set_text (layout, timestamp_text, -1);
 
709
                pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
 
710
 
 
711
                /* Display the timestamp in the bottom-right corner of the current screenshot */
 
712
                cairo_move_to (cr, x - layout_width - 0.02 * output_size, y - layout_height - 0.02 * scale * screenshot_height);
 
713
 
 
714
                /* We have to stroke the text so it's visible against screenshots of the same
 
715
                 * foreground color. */
 
716
                pango_cairo_layout_path (cr, layout);
 
717
                cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
 
718
                cairo_stroke_preserve (cr);
 
719
                cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
 
720
                cairo_fill (cr);
 
721
 
 
722
                PROGRESS_DEBUG ("Writing timestamp \"%s\" at (%f,%f).", timestamp_text,
 
723
                                x - layout_width - 0.02 * output_size,
 
724
                                y - layout_height - 0.02 * scale * screenshot_height);
 
725
 
 
726
                /* We print progress in the range 50% (MAX_PROGRESS - MIN_PROGRESS) / 2.0) to 90% (MAX_PROGRESS) */
 
727
                PRINT_PROGRESS (MIN_PROGRESS + (MAX_PROGRESS - MIN_PROGRESS) / 2.0 + (current_row * columns + current_column) * (((MAX_PROGRESS - MIN_PROGRESS) / gallery) / 2.0));
 
728
 
 
729
                g_free (timestamp_text);
 
730
 
 
731
                current_column = (current_column + 1) % columns;
 
732
                x += output_size + x_padding;
 
733
                if (current_column == 0) {
 
734
                        x = x_padding + output_size;
 
735
                        y += scale * screenshot_height + y_padding;
 
736
                        current_row++;
 
737
                }
 
738
        }
 
739
 
 
740
        g_object_unref (layout);
 
741
 
 
742
        PROGRESS_DEBUG ("Converting Cairo surface back to pixbuf.");
 
743
 
 
744
        /* Create a new pixbuf from the Cairo context */
 
745
        pixbuf = cairo_surface_to_pixbuf (cairo_get_target (cr));
 
746
        cairo_destroy (cr);
 
747
 
 
748
        return pixbuf;
 
749
}
 
750
 
465
751
static const GOptionEntry entries[] = {
466
752
        { "jpeg", 'j',  0, G_OPTION_ARG_NONE, &jpeg_output, "Output the thumbnail as a JPEG instead of PNG", NULL },
467
 
        { "size", 's', 0, G_OPTION_ARG_INT, &output_size, "Size of the thumbnail in pixels", NULL },
 
753
        { "size", 's', 0, G_OPTION_ARG_INT, &output_size, "Size of the thumbnail in pixels (with --gallery sets the size of individual screenshots)", NULL },
468
754
        { "no-limit", 'l', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &time_limit, "Don't limit the thumbnailing time to 30 seconds", NULL },
469
755
        { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Output debug information", NULL },
470
 
        { "time", 't', 0, G_OPTION_ARG_INT64, &second_index, "Choose this time (in seconds) as the thumbnail", NULL },
471
 
        {"g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL},
 
756
        { "time", 't', 0, G_OPTION_ARG_INT64, &second_index, "Choose this time (in seconds) as the thumbnail (can't be used with --gallery)", NULL },
 
757
        { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL },
 
758
        { "gallery", 'g', 0, G_OPTION_ARG_INT, &gallery, "Output a gallery of the given number (0 is default) of screenshots (can't be used with --time)", NULL },
 
759
        { "print-progress", 'p', 0, G_OPTION_ARG_NONE, &print_progress, "Only print progress updates (can't be used with --verbose)", NULL },
472
760
        { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, "[FILE...]" },
473
761
        { NULL }
474
762
};
505
793
                return 1;
506
794
        }
507
795
 
 
796
        if (print_progress) {
 
797
                fcntl (fileno (stdout), F_SETFL, O_NONBLOCK);
 
798
                setbuf (stdout, NULL);
 
799
        }
 
800
 
508
801
        if (g_fatal_warnings) {
509
802
                GLogLevelFlags fatal_mask;
510
803
 
513
806
                g_log_set_always_fatal (fatal_mask);
514
807
        }
515
808
 
516
 
        if (filenames == NULL || g_strv_length (filenames) != 2) {
 
809
        if (filenames == NULL || g_strv_length (filenames) != 2 ||
 
810
            (second_index != -1 && gallery != -1) ||
 
811
            (print_progress == TRUE && verbose == TRUE)) {
517
812
                char *help;
518
813
                help = g_option_context_get_help (context, FALSE, NULL);
519
814
                g_print ("%s", help);
524
819
        output = filenames[1];
525
820
 
526
821
        PROGRESS_DEBUG("Initialised libraries, about to create video widget");
 
822
        PRINT_PROGRESS (2.0);
527
823
 
528
824
        bvw = BACON_VIDEO_WIDGET (bacon_video_widget_new (-1, -1, BVW_USE_TYPE_CAPTURE, &err));
529
825
        if (err != NULL) {
539
835
                          &data);
540
836
 
541
837
        PROGRESS_DEBUG("Video widget created");
 
838
        PRINT_PROGRESS (6.0);
542
839
 
543
840
        if (time_limit != FALSE)
544
841
                totem_resources_monitor_start (input, 0);
555
852
 
556
853
        PROGRESS_DEBUG("Opened video file: '%s'", input);
557
854
        PROGRESS_DEBUG("About to play file");
 
855
        PRINT_PROGRESS (8.0);
558
856
 
559
857
        bacon_video_widget_play (bvw, &err);
560
858
        if (err != NULL) {
564
862
                exit (1);
565
863
        }
566
864
        PROGRESS_DEBUG("Started playing file");
 
865
        PRINT_PROGRESS (10.0);
567
866
 
568
 
        /* If the user has told us to use a frame at a specific second 
569
 
         * into the video, just use that frame no matter how boring it
570
 
         * is */
571
 
        if(second_index != -1)
572
 
                pixbuf = capture_frame_at_time (bvw, input, output, second_index);
573
 
        else
574
 
                pixbuf = capture_interesting_frame (bvw, input, output);
 
867
        if (gallery == -1) {
 
868
                /* If the user has told us to use a frame at a specific second 
 
869
                 * into the video, just use that frame no matter how boring it
 
870
                 * is */
 
871
                if (second_index != -1)
 
872
                        pixbuf = capture_frame_at_time (bvw, input, output, second_index);
 
873
                else
 
874
                        pixbuf = capture_interesting_frame (bvw, input, output);
 
875
                PRINT_PROGRESS (90.0);
 
876
        } else {
 
877
                /* We're producing a gallery of screenshots from throughout the file */
 
878
                pixbuf = create_gallery (bvw, input, output);
 
879
        }
575
880
 
576
881
        /* Cleanup */
577
882
        bacon_video_widget_close (bvw);
578
883
        totem_resources_monitor_stop ();
579
884
        gtk_widget_destroy (GTK_WIDGET (bvw));
 
885
        PRINT_PROGRESS (92.0);
580
886
 
581
887
        if (pixbuf == NULL) {
582
888
                g_print ("totem-video-thumbnailer couldn't get a picture from "
587
893
        PROGRESS_DEBUG("Saving captured screenshot");
588
894
        save_pixbuf (pixbuf, output, input, output_size, FALSE);
589
895
        g_object_unref (pixbuf);
 
896
        PRINT_PROGRESS (100.0);
590
897
 
591
898
        return 0;
592
899
}