a52dec: Use a debug category, Output timestamps correctly
authorJan Schmidt <thaytan@mad.scientist.com>
Thu, 1 Apr 2004 11:48:27 +0000 (11:48 +0000)
committerJan Schmidt <thaytan@mad.scientist.com>
Thu, 1 Apr 2004 11:48:27 +0000 (11:48 +0000)
Original commit message from CVS:
a52dec:   Use a debug category, Output timestamps correctly
Emit tag info, Handle events, tell liba52dec about cpu
capabilities so it can use MMX etc.
dvdec:    Fix a crasher accessing invalid memory
dvdnavsrc:Some support for byte-format seeking.
Small fixes for still frames and menu button overlays
mpeg2dec: Use a debug category. Adjust the report level of several items to
LOG. Call mpeg2_custom_fbuf to mark our buffers as 'custom buffers'
so it doesn't lose the GstBuffer pointer
navseek:  Add the navseek debug element for seeking back and forth in a
video stream using arrow keys.
mpeg2subt:Pretty much a complete rewrite. Now a loopbased element. May still
require work to properly synchronise subtitle buffers.
mpegdemux:
dvddemux: Don't attempt to create subbuffers of size 0
Reduce a couple of error outputs to warnings.
y4mencode:Output the y4m frame header correctly

ChangeLog
ext/a52dec/gsta52dec.c
ext/a52dec/gsta52dec.h
ext/dvdnav/dvdnavsrc.c
ext/mpeg2dec/gstmpeg2dec.c
gst/mpegstream/gstdvddemux.c
gst/mpegstream/gstmpegdemux.c

index 53ff97d..7621d47 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,60 @@
+2004-04-01  Jan Schmidt  <thaytan@mad.scientist.com>
+
+       * ext/a52dec/gsta52dec.c: (gst_a52dec_get_type), (gst_a52dec_init),
+       (gst_a52dec_push), (gst_a52dec_handle_event),
+       (gst_a52dec_update_streaminfo), (gst_a52dec_loop),
+       (gst_a52dec_change_state):
+       * ext/a52dec/gsta52dec.h:
+         Use a debug category, Output timestamps correctly
+         Emit tag info, Handle events, tell liba52dec about cpu
+         capabilities so it can use MMX etc.
+       * ext/dv/gstdvdec.c: (gst_dvdec_loop), (gst_dvdec_change_state):
+         Fix a crasher accessing invalid memory
+       * ext/dvdnav/dvdnavsrc.c: (dvdnavsrc_init),
+       (dvdnavsrc_update_highlight), (dvdnavsrc_loop),
+       (dvdnavsrc_get_event_mask), (dvdnav_handle_navigation_event),
+       (dvdnavsrc_event), (dvdnavsrc_get_formats), (dvdnavsrc_convert),
+       (dvdnavsrc_query):
+         Some support for byte-format seeking.
+         Small fixes for still frames and menu button overlays
+       * ext/mpeg2dec/gstmpeg2dec.c: (gst_mpeg2dec_get_type),
+       (gst_mpeg2dec_alloc_buffer):
+         Use a debug category. Adjust the report level of several items to
+         LOG. Call mpeg2_custom_fbuf to mark our buffers as 'custom buffers'
+         so it doesn't lose the GstBuffer pointer
+       * gst/debug/Makefile.am:
+       * gst/debug/gstdebug.c: (plugin_init):
+       * gst/debug/gstnavseek.c: (gst_navseek_get_type),
+       (gst_navseek_base_init), (gst_navseek_class_init),
+       (gst_navseek_init), (gst_navseek_seek),
+       (gst_navseek_handle_src_event), (gst_navseek_set_property),
+       (gst_navseek_get_property), (gst_navseek_chain),
+       (gst_navseek_plugin_init):
+       * gst/debug/gstnavseek.h:
+         Add the navseek debug element for seeking back and forth in a 
+         video stream using arrow keys.
+       * gst/mpeg2sub/gstmpeg2subt.c: (gst_mpeg2subt_get_type),
+       (gst_mpeg2subt_base_init), (gst_mpeg2subt_class_init),
+       (gst_mpeg2subt_init), (gst_mpeg2subt_finalize),
+       (gst_mpeg2subt_getcaps_video), (gst_mpeg2subt_link_video),
+       (gst_mpeg2subt_handle_video), (gst_mpeg2subt_src_event),
+       (gst_mpeg2subt_parse_header), (gst_get_nibble),
+       (gst_setup_palette), (gst_get_rle_code), (gst_draw_rle_line),
+       (gst_merge_uv_data), (gst_mpeg2subt_merge_title),
+       (gst_update_still_frame), (gst_mpeg2subt_handle_subtitle),
+       (gst_mpeg2subt_handle_dvd_event), (gst_mpeg2subt_loop):
+       * gst/mpeg2sub/gstmpeg2subt.h:
+         Pretty much a complete rewrite. Now a loopbased element. May still
+         require work to properly synchronise subtitle buffers.
+       * gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_process_private),
+       (gst_dvd_demux_send_subbuffer):
+       * gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_send_subbuffer):
+         Don't attempt to create subbuffers of size 0
+         Reduce a couple of error outputs to warnings.
+       * gst/y4m/gsty4mencode.c: (gst_y4mencode_sinkconnect),
+       (gst_y4mencode_chain):
+       Output the y4m frame header correctly.
+
 2004-04-01  Thomas Vander Stichele  <thomas at apestaart dot org>
 
        * gst/adder/gstadder.c: (gst_adder_get_type), (gst_adder_loop):
index 7db4ac2..9c626b0 100644 (file)
@@ -39,6 +39,8 @@ static GstElementDetails gst_a52dec_details = {
   "David I. Lehn <dlehn@users.sourceforge.net>",
 };
 
+GST_DEBUG_CATEGORY_STATIC (a52dec_debug);
+#define GST_CAT_DEFAULT (a52dec_debug)
 
 /* A52Dec signals and args */
 enum
@@ -109,6 +111,9 @@ gst_a52dec_get_type (void)
 
     a52dec_type =
         g_type_register_static (GST_TYPE_ELEMENT, "GstA52Dec", &a52dec_info, 0);
+
+    GST_DEBUG_CATEGORY_INIT (a52dec_debug, "a52dec", 0,
+        "AC3/A52 software decoder");
   }
   return a52dec_type;
 }
@@ -161,6 +166,7 @@ gst_a52dec_init (GstA52Dec * a52dec)
   gst_pad_use_explicit_caps (a52dec->srcpad);
   gst_element_add_pad (GST_ELEMENT (a52dec), a52dec->srcpad);
 
+  GST_FLAG_SET (GST_ELEMENT (a52dec), GST_ELEMENT_EVENT_AWARE);
   a52dec->dynamic_range_compression = FALSE;
 }
 
@@ -307,7 +313,7 @@ gst_a52dec_channels (int flags)
 
 static int
 gst_a52dec_push (GstPad * srcpad, int flags, sample_t * _samples,
-    gint64 timestamp)
+    GstClockTime timestamp)
 {
   GstBuffer *buf;
   int chans;
@@ -369,34 +375,32 @@ gst_a52dec_handle_event (GstA52Dec * a52dec)
     return;
   }
 
+  GST_LOG ("Handling event of type %d timestamp %llu", GST_EVENT_TYPE (event),
+      GST_EVENT_TIMESTAMP (event));
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_DISCONTINUOUS:
+    case GST_EVENT_FLUSH:
       gst_bytestream_flush_fast (a52dec->bs, remaining);
+      break;
     default:
-      gst_pad_event_default (a52dec->sinkpad, event);
       break;
   }
+  gst_pad_event_default (a52dec->sinkpad, event);
 }
 
-#if 0
 static void
 gst_a52dec_update_streaminfo (GstA52Dec * a52dec)
 {
-  GstProps *props;
-  GstPropsEntry *entry;
-
-  props = gst_props_empty_new ();
+  GstTagList *taglist;
 
-  entry = gst_props_entry_new ("bitrate", GST_PROPS_INT (a52dec->bit_rate));
-  gst_props_add_entry (props, (GstPropsEntry *) entry);
+  taglist = gst_tag_list_new ();
 
-  gst_caps_unref (a52dec->streaminfo);
+  gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND,
+      GST_TAG_BITRATE, (guint) a52dec->bit_rate, NULL);
 
-  a52dec->streaminfo = gst_caps_new ("a52dec_streaminfo",
-      "application/x-gst-streaminfo", props);
-  g_object_notify (G_OBJECT (a52dec), "streaminfo");
+  gst_element_found_tags_for_pad (GST_ELEMENT (a52dec),
+      GST_PAD (a52dec->srcpad), a52dec->current_ts, taglist);
 }
-#endif
 
 static void
 gst_a52dec_loop (GstElement * element)
@@ -408,27 +412,31 @@ gst_a52dec_loop (GstElement * element)
   GstBuffer *buf;
   guint32 got_bytes;
   gboolean need_reneg;
-  GstClockTime timestamp;
+  GstClockTime timestamp = 0;
 
   a52dec = GST_A52DEC (element);
 
   /* find and read header */
-  while (1) {
-    got_bytes = gst_bytestream_peek_bytes (a52dec->bs, &data, 7);
-    if (got_bytes < 7) {
-      gst_a52dec_handle_event (a52dec);
-      return;
+  do {
+    gint skipped_bytes = 0;
+
+    while (skipped_bytes < 3840) {
+      got_bytes = gst_bytestream_peek_bytes (a52dec->bs, &data, 7);
+      if (got_bytes < 7) {
+        gst_a52dec_handle_event (a52dec);
+        return;
+      }
+      length = a52_syncinfo (data, &flags, &sample_rate, &bit_rate);
+      if (length == 0) {
+        /* slide window to next 7 bytesa */
+        gst_bytestream_flush_fast (a52dec->bs, 1);
+        skipped_bytes++;
+        GST_LOG ("Skipped");
+      } else
+        break;
     }
-    length = a52_syncinfo (data, &flags, &sample_rate, &bit_rate);
-    if (length == 0) {
-      /* slide window to next 7 bytesa */
-      gst_bytestream_flush_fast (a52dec->bs, 1);
-    } else
-      break;
-
-    /* FIXME this can potentially be an infinite loop, we might
-     * have to insert a yield operation here */
   }
+  while (0);
 
   need_reneg = FALSE;
 
@@ -441,6 +449,7 @@ gst_a52dec_loop (GstElement * element)
 
   if (bit_rate != a52dec->bit_rate) {
     a52dec->bit_rate = bit_rate;
+    gst_a52dec_update_streaminfo (a52dec);
   }
 
   /* read the header + rest of frame */
@@ -451,10 +460,12 @@ gst_a52dec_loop (GstElement * element)
   }
   data = GST_BUFFER_DATA (buf);
   timestamp = gst_bytestream_get_timestamp (a52dec->bs);
-  if (timestamp == a52dec->last_ts) {
-    timestamp = a52dec->current_ts;
-  } else {
-    a52dec->last_ts = timestamp;
+  if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
+    if (timestamp == a52dec->last_ts) {
+      timestamp = a52dec->current_ts;
+    } else {
+      a52dec->last_ts = timestamp;
+    }
   }
 
   /* process */
@@ -462,7 +473,7 @@ gst_a52dec_loop (GstElement * element)
   a52dec->level = 1;
 
   if (a52_frame (a52dec->state, data, &flags, &a52dec->level, a52dec->bias)) {
-    g_warning ("a52dec: a52_frame error\n");
+    GST_WARNING ("a52_frame error");
     goto end;
   }
 
@@ -486,17 +497,21 @@ gst_a52dec_loop (GstElement * element)
 
   for (i = 0; i < 6; i++) {
     if (a52_block (a52dec->state)) {
-      g_warning ("a52dec a52_block error %d\n", i);
+      GST_WARNING ("a52_block error %d", i);
       continue;
     }
     /* push on */
+
     if (gst_a52dec_push (a52dec->srcpad, a52dec->using_channels,
             a52dec->samples, timestamp)) {
-      g_warning ("a52dec push error\n");
+      GST_WARNING ("a52dec push error");
     } else {
-      timestamp += sizeof (int16_t) * 256 * GST_SECOND / a52dec->sample_rate;
+
+      if (i % 2)
+        timestamp += 256 * GST_SECOND / a52dec->sample_rate;
     }
   }
+
   a52dec->current_ts = timestamp;
 
 end:
@@ -507,13 +522,23 @@ static GstElementStateReturn
 gst_a52dec_change_state (GstElement * element)
 {
   GstA52Dec *a52dec = GST_A52DEC (element);
+  GstCPUFlags cpuflags;
+  uint32_t a52_cpuflags = 0;
 
   switch (GST_STATE_TRANSITION (element)) {
     case GST_STATE_NULL_TO_READY:
+      a52dec->bs = gst_bytestream_new (a52dec->sinkpad);
+      cpuflags = gst_cpu_get_flags ();
+      if (cpuflags & GST_CPU_FLAG_MMX)
+        a52_cpuflags |= MM_ACCEL_X86_MMX;
+      if (cpuflags & GST_CPU_FLAG_3DNOW)
+        a52_cpuflags |= MM_ACCEL_X86_3DNOW;
+      if (cpuflags & GST_CPU_FLAG_MMXEXT)
+        a52_cpuflags |= MM_ACCEL_X86_MMXEXT;
+
+      a52dec->state = a52_init (a52_cpuflags);
       break;
     case GST_STATE_READY_TO_PAUSED:
-      a52dec->bs = gst_bytestream_new (a52dec->sinkpad);
-      a52dec->state = a52_init (0);     /* mm_accel()); */
       a52dec->samples = a52_samples (a52dec->state);
       a52dec->bit_rate = -1;
       a52dec->sample_rate = -1;
@@ -523,8 +548,11 @@ gst_a52dec_change_state (GstElement * element)
       a52dec->using_channels = A52_CHANNEL;
       a52dec->level = 1;
       a52dec->bias = 384;
-      a52dec->last_ts = -1;
+      a52dec->last_ts = 0;
       a52dec->current_ts = 0;
+      a52dec->last_timestamp = 0;
+      a52dec->last_diff = 0;
+
       break;
     case GST_STATE_PAUSED_TO_PLAYING:
       break;
@@ -534,10 +562,10 @@ gst_a52dec_change_state (GstElement * element)
       gst_bytestream_destroy (a52dec->bs);
       a52dec->bs = NULL;
       a52dec->samples = NULL;
-      a52_free (a52dec->state);
-      a52dec->state = NULL;
       break;
     case GST_STATE_READY_TO_NULL:
+      a52_free (a52dec->state);
+      a52dec->state = NULL;
       break;
     default:
       break;
index 1796965..eecbed5 100644 (file)
@@ -62,6 +62,9 @@ struct _GstA52Dec {
 
   GstClockTime last_ts;
   GstClockTime current_ts;
+
+  GstClockTime last_timestamp;
+  GstClockTimeDiff last_diff;
 };
 
 struct _GstA52DecClass {
index 5b508cb..f45b6bc 100644 (file)
@@ -39,6 +39,8 @@
 GST_DEBUG_CATEGORY_STATIC (dvdnavsrc_debug);
 #define GST_CAT_DEFAULT (dvdnavsrc_debug)
 
+/* Size of a DVD sector, used for sector-byte format conversions */
+#define DVD_SECTOR_SIZE 2048
 
 #define CLOCK_BASE 9LL
 #define CLOCK_FREQ CLOCK_BASE * 10000
@@ -96,7 +98,7 @@ typedef enum
 DVDNavSrcPauseMode;
 
 /* Interval of time to sleep during pauses. */
-#define DVDNAVSRC_PAUSE_INTERVAL (GST_SECOND / 5)
+#define DVDNAVSRC_PAUSE_INTERVAL (GST_SECOND / 20)
 
 /* The DVD domain types. */
 typedef enum
@@ -229,6 +231,9 @@ static const GstFormat *dvdnavsrc_get_formats (GstPad * pad);
 static gboolean dvdnavsrc_query (GstPad * pad,
     GstQueryType type, GstFormat * format, gint64 * value);
 static const GstQueryType *dvdnavsrc_get_query_types (GstPad * pad);
+static gboolean dvdnavsrc_convert (GstPad * pad,
+    GstFormat src_format, gint64 src_value,
+    GstFormat * dest_format, gint64 * dest_value);
 
 static gboolean dvdnavsrc_close (DVDNavSrc * src);
 static gboolean dvdnavsrc_open (DVDNavSrc * src);
@@ -361,7 +366,7 @@ dvdnavsrc_init (DVDNavSrc * src)
 
   gst_pad_set_event_function (src->srcpad, dvdnavsrc_event);
   gst_pad_set_event_mask_function (src->srcpad, dvdnavsrc_get_event_mask);
-  /*gst_pad_set_convert_function (src->srcpad, dvdnavsrc_convert); */
+  gst_pad_set_convert_function (src->srcpad, dvdnavsrc_convert);
   gst_pad_set_query_function (src->srcpad, dvdnavsrc_query);
   gst_pad_set_query_type_function (src->srcpad, dvdnavsrc_get_query_types);
   gst_pad_set_formats_function (src->srcpad, dvdnavsrc_get_formats);
@@ -809,7 +814,7 @@ dvdnavsrc_set_domain (DVDNavSrc * src)
 static void
 dvdnavsrc_update_highlight (DVDNavSrc * src)
 {
-  int button;
+  int button = 0;
   pci_t *pci;
   dvdnav_highlight_area_t area;
   GstEvent *event;
@@ -817,11 +822,16 @@ dvdnavsrc_update_highlight (DVDNavSrc * src)
   DVDNAV_CALL (dvdnav_get_current_highlight, (src->dvdnav, &button), src);
 
   pci = dvdnav_get_current_nav_pci (src->dvdnav);
-  if (button > pci->hli.hl_gi.btn_ns) {
+  if ((button > pci->hli.hl_gi.btn_ns) || (button < 0)) {
     /* button is out of the range of possible buttons. */
     button = 0;
   }
 
+  if (!pci->hli.hl_gi.hli_ss) {
+    /* Not in menu */
+    button = 0;
+  }
+
   if (button == 0) {
     if (src->button != 0) {
       src->button = 0;
@@ -856,6 +866,7 @@ dvdnavsrc_update_highlight (DVDNavSrc * src)
 
     src->button = button;
 
+    GST_DEBUG ("Sending dvd-spu-highlight for button %d", button);
     gst_pad_push (src->srcpad, GST_DATA (event));
   }
 }
@@ -1307,13 +1318,14 @@ dvdnavsrc_loop (GstElement * element)
 
           /* We just saw a still frame. Start a pause now. */
           if (info->length == 0xff) {
-            GST_INFO_OBJECT (src, "starting unlimed pause");
+            GST_INFO_OBJECT (src, "starting unlimited pause");
             src->pause_mode = DVDNAVSRC_PAUSE_UNLIMITED;
           } else {
-            GST_INFO_OBJECT (src, "starting limited pause: %d seconds",
-                info->length);
             src->pause_mode = DVDNAVSRC_PAUSE_LIMITED;
             src->pause_end = current_time + info->length * GST_SECOND;
+            GST_INFO_OBJECT (src,
+                "starting limited pause: %d seconds at %llu until %llu",
+                info->length, current_time, src->pause_end);
           }
 
           /* For the moment, send the first empty event to let
@@ -1328,6 +1340,8 @@ dvdnavsrc_loop (GstElement * element)
 
         if (src->pause_mode == DVDNAVSRC_PAUSE_UNLIMITED ||
             current_time < src->pause_end) {
+          GstEvent *event;
+
           /* We are in pause mode. Make this element sleep for a
              fraction of a second. */
           if (current_time + DVDNAVSRC_PAUSE_INTERVAL > src->pause_end) {
@@ -1336,10 +1350,13 @@ dvdnavsrc_loop (GstElement * element)
             gst_element_wait (GST_ELEMENT (src),
                 current_time + DVDNAVSRC_PAUSE_INTERVAL);
           }
-
           /* Send an empty event to keep the pipeline going. */
           /* FIXME: Use an interrupt/filler event here. */
-          send_data = GST_DATA (gst_event_new (GST_EVENT_EMPTY));
+          event = gst_event_new (GST_EVENT_EMPTY);
+          send_data = GST_DATA (event);
+          GST_EVENT_TIMESTAMP (event) =
+              gst_element_get_time (GST_ELEMENT (src));
+
           break;
         } else {
           /* We reached the end of the pause. */
@@ -1595,12 +1612,7 @@ dvdnavsrc_get_event_mask (GstPad * pad)
   static const GstEventMask masks[] = {
     {GST_EVENT_SEEK, GST_SEEK_METHOD_SET |
           GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH},
-    /*
-       {GST_EVENT_SEEK_SEGMENT, GST_SEEK_METHOD_SET | 
-       GST_SEEK_METHOD_CUR | 
-       GST_SEEK_METHOD_END | 
-       GST_SEEK_FLAG_FLUSH },
-     */
+    {GST_EVENT_FLUSH, 0},
     {GST_EVENT_NAVIGATION, GST_EVENT_FLAG_NONE},
     {0,}
   };
@@ -1629,6 +1641,8 @@ dvdnav_handle_navigation_event (DVDNavSrc * src, GstEvent * event)
 
     dvdnav_mouse_select (src->dvdnav,
         dvdnav_get_current_nav_pci (src->dvdnav), (int) x, (int) y);
+
+    dvdnavsrc_update_highlight (src);
   } else if (strcmp (event_type, "mouse-button-release") == 0) {
     double x, y;
 
@@ -1667,6 +1681,24 @@ dvdnavsrc_event (GstPad * pad, GstEvent * event)
       offset = GST_EVENT_SEEK_OFFSET (event);
 
       switch (format) {
+        case GST_FORMAT_BYTES:
+          switch (GST_EVENT_SEEK_METHOD (event)) {
+            case GST_SEEK_METHOD_SET:
+              origin = SEEK_SET;
+              break;
+            case GST_SEEK_METHOD_CUR:
+              origin = SEEK_CUR;
+              break;
+            case GST_SEEK_METHOD_END:
+              origin = SEEK_END;
+              break;
+            default:
+              goto error;
+          }
+          if (dvdnav_sector_search (src->dvdnav, (offset / DVD_SECTOR_SIZE),
+                  origin) != DVDNAV_STATUS_OK) {
+            goto error;
+          }
         default:
           if (format == sector_format) {
             switch (GST_EVENT_SEEK_METHOD (event)) {
@@ -1770,6 +1802,7 @@ dvdnavsrc_event (GstPad * pad, GstEvent * event)
     }
     case GST_EVENT_NAVIGATION:
       res = dvdnav_handle_navigation_event (src, event);
+      break;
     case GST_EVENT_FLUSH:
       src->need_flush = TRUE;
       break;
@@ -1791,9 +1824,9 @@ dvdnavsrc_get_formats (GstPad * pad)
 {
   int i;
   static GstFormat formats[] = {
+    GST_FORMAT_BYTES,
     /*
        GST_FORMAT_TIME,
-       GST_FORMAT_BYTES,
        GST_FORMAT_DEFAULT,
      */
     0,                          /* filled later */
@@ -1817,7 +1850,6 @@ dvdnavsrc_get_formats (GstPad * pad)
   return formats;
 }
 
-#if 0
 static gboolean
 dvdnavsrc_convert (GstPad * pad,
     GstFormat src_format, gint64 src_value,
@@ -1831,97 +1863,20 @@ dvdnavsrc_convert (GstPad * pad,
     return FALSE;
 
   switch (src_format) {
-    case GST_FORMAT_TIME:
-      switch (*dest_format) {
-        case GST_FORMAT_BYTES:
-          src_value <<= 2;      /* 4 bytes per sample */
-        case GST_FORMAT_DEFAULT:
-          *dest_value = src_value * 44100 / GST_SECOND;
-          break;
-        default:
-          if (*dest_format == track_format || *dest_format == sector_format) {
-            gint sector =
-                (src_value * 44100) / ((CD_FRAMESIZE_RAW >> 2) * GST_SECOND);
-
-            if (*dest_format == sector_format) {
-              *dest_value = sector;
-            } else {
-              *dest_value = cdda_sector_gettrack (src->d, sector) - 1;
-            }
-          } else
-            return FALSE;
-          break;
-      }
-      break;
     case GST_FORMAT_BYTES:
-      src_value >>= 2;
-    case GST_FORMAT_DEFAULT:
-      switch (*dest_format) {
-        case GST_FORMAT_BYTES:
-          *dest_value = src_value * 4;
-          break;
-        case GST_FORMAT_TIME:
-          *dest_value = src_value * GST_SECOND / 44100;
-          break;
-        default:
-          if (*dest_format == track_format || *dest_format == sector_format) {
-            gint sector = src_value / (CD_FRAMESIZE_RAW >> 2);
-
-            if (*dest_format == track_format) {
-              *dest_value = cdda_sector_gettrack (src->d, sector) - 1;
-            } else {
-              *dest_value = sector;
-            }
-          } else
-            return FALSE;
-          break;
-      }
-      break;
+      if (*dest_format == sector_format) {
+        *dest_value = src_value / DVD_SECTOR_SIZE;
+      } else
+        return FALSE;
     default:
-    {
-      gint sector;
-
-      if (src_format == track_format) {
-        /* some sanity checks */
-        if (src_value < 0 || src_value > src->d->tracks)
-          return FALSE;
-
-        sector = cdda_track_firstsector (src->d, src_value + 1);
-      } else if (src_format == sector_format) {
-        sector = src_value;
+      if ((src_format == sector_format) && (*dest_format == GST_FORMAT_BYTES)) {
+        *dest_value = src_value * DVD_SECTOR_SIZE;
       } else
         return FALSE;
-
-      switch (*dest_format) {
-        case GST_FORMAT_TIME:
-          *dest_value = ((CD_FRAMESIZE_RAW >> 2) * sector * GST_SECOND) / 44100;
-          break;
-        case GST_FORMAT_BYTES:
-          sector <<= 2;
-        case GST_FORMAT_DEFAULT:
-          *dest_value = (CD_FRAMESIZE_RAW >> 2) * sector;
-          break;
-        default:
-          if (*dest_format == sector_format) {
-            *dest_value = sector;
-          } else if (*dest_format == track_format) {
-            /* if we go past the last sector, make sure to report the
-               last track */
-            if (sector > src->last_sector)
-              *dest_value = cdda_sector_gettrack (src->d, src->last_sector);
-            else
-              *dest_value = cdda_sector_gettrack (src->d, sector) - 1;
-          } else
-            return FALSE;
-          break;
-      }
-      break;
-    }
   }
 
   return TRUE;
 }
-#endif
 
 static const GstQueryType *
 dvdnavsrc_get_query_types (GstPad * pad)
@@ -1959,6 +1914,11 @@ dvdnavsrc_query (GstPad * pad, GstQueryType type,
           res = FALSE;
         }
         *value = len;
+      } else if (*format == GST_FORMAT_BYTES) {
+        if (dvdnav_get_position (src->dvdnav, &pos, &len) != DVDNAV_STATUS_OK) {
+          res = FALSE;
+        }
+        *value = len * DVD_SECTOR_SIZE;
       } else if (*format == title_format) {
         if (dvdnav_get_number_of_titles (src->dvdnav, &titles)
             != DVDNAV_STATUS_OK) {
index baa60fd..a8f6ac9 100644 (file)
@@ -40,6 +40,8 @@ typedef gint mpeg2_state_t;
 #endif
 
 GST_DEBUG_CATEGORY_EXTERN (GST_CAT_SEEK);
+GST_DEBUG_CATEGORY_STATIC (mpeg2dec_debug);
+#define GST_CAT_DEFAULT (mpeg2dec_debug)
 
 /* elementfactory information */
 static GstElementDetails gst_mpeg2dec_details = {
@@ -148,6 +150,10 @@ gst_mpeg2dec_get_type (void)
         g_type_register_static (GST_TYPE_ELEMENT, "GstMpeg2dec", &mpeg2dec_info,
         0);
   }
+
+  GST_DEBUG_CATEGORY_INIT (mpeg2dec_debug, "mpeg2dec", 0,
+      "MPEG2 decoder element");
+
   return mpeg2dec_type;
 }
 
@@ -318,6 +324,8 @@ gst_mpeg2dec_alloc_buffer (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info,
   }
 
   gst_buffer_ref (outbuf);
+
+  mpeg2_custom_fbuf (mpeg2dec->decoder, 1);
   mpeg2_set_buf (mpeg2dec->decoder, buf, outbuf);
 
   picture = info->current_picture;
@@ -471,6 +479,7 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
           gst_index_commit (mpeg2dec->index, mpeg2dec->index_id);
         }
       default:
+        GST_DEBUG ("Got event of type %d on sink pad", GST_EVENT_TYPE (event));
         gst_pad_event_default (pad, event);
         return;
     }
@@ -496,17 +505,17 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
     mpeg2_pts (mpeg2dec->decoder, mpeg_pts);
 #endif
   } else {
-    GST_DEBUG ("no pts");
+    GST_LOG ("no pts");
   }
 
-  GST_DEBUG ("calling _buffer");
+  GST_LOG ("calling mpeg2_buffer");
   mpeg2_buffer (mpeg2dec->decoder, data, end);
-  GST_DEBUG ("calling _buffer done");
+  GST_LOG ("calling mpeg2_buffer done");
 
   while (!done) {
     gboolean slice = FALSE;
 
-    GST_DEBUG ("calling parse");
+    GST_LOG ("calling parse");
     state = mpeg2_parse (mpeg2dec->decoder);
     GST_DEBUG ("parse state %d", state);
     switch (state) {
@@ -644,7 +653,6 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
           mpeg2dec->next_time +=
               (mpeg2dec->frame_period * picture->nb_fields) >> 1;
 
-
           GST_DEBUG ("picture: %s %s fields:%d off:%" G_GINT64_FORMAT " ts:%"
               G_GINT64_FORMAT,
               (picture->flags & PIC_FLAG_TOP_FIELD_FIRST ? "tff " : "    "),
@@ -659,7 +667,6 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
                 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (outbuf), 0);
           }
 
-
           if (picture->flags & PIC_FLAG_SKIP ||
               !GST_PAD_IS_USABLE (mpeg2dec->srcpad) ||
               mpeg2dec->discont_state != MPEG2DEC_DISC_NONE ||
@@ -670,7 +677,10 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
             GST_BUFFER_DURATION (outbuf) = mpeg2dec->frame_period;
             gst_pad_push (mpeg2dec->srcpad, GST_DATA (outbuf));
           }
+        } else if (info->display_fbuf && !info->display_fbuf->id) {
+          GST_WARNING ("Got a frame from libmpeg2, but it has no buffer");
         }
+
         if (info->discard_fbuf && info->discard_fbuf->id) {
           gst_buffer_unref ((GstBuffer *) info->discard_fbuf->id);
         }
index 98926e3..daf8643 100644 (file)
@@ -672,7 +672,7 @@ gst_dvd_demux_process_private (GstMPEGDemux * mpeg_demux,
         headerlen += 1;
         datalen -= 1;
       } else {
-        GST_ERROR_OBJECT (dvd_demux,
+        GST_WARNING_OBJECT (dvd_demux,
             "unknown DVD (private 1) id 0x%02x", ps_id_code);
       }
       break;
@@ -696,8 +696,8 @@ gst_dvd_demux_process_private (GstMPEGDemux * mpeg_demux,
           break;
 
         default:
-          GST_ERROR_OBJECT (dvd_demux,
-              "unknown DVD (private 1) id 0x%02x", ps_id_code);
+          GST_WARNING_OBJECT (dvd_demux,
+              "unknown DVD (private 2) id 0x%02x", ps_id_code);
           break;
       }
       break;
@@ -780,7 +780,7 @@ gst_dvd_demux_send_subbuffer (GstMPEGDemux * mpeg_demux,
       break;
   }
 
-  if (outpad != NULL && cur_nr == outstream->number) {
+  if (outpad != NULL && cur_nr == outstream->number && (size > 0)) {
     GstBuffer *outbuf;
 
     /* We have a packet of the current stream. Send it to the
index b63d7cd..b364040 100644 (file)
@@ -902,7 +902,7 @@ gst_mpeg_demux_send_subbuffer (GstMPEGDemux * mpeg_demux,
         GST_BUFFER_OFFSET (buffer), GST_FORMAT_TIME, timestamp, 0);
   }
 
-  if (!GST_PAD_IS_USABLE (outstream->pad)) {
+  if (!GST_PAD_IS_USABLE (outstream->pad) || (size == 0)) {
     return;
   }