ext/mpeg2dec/gstmpeg2dec.*: Don't treat STATE_INVALID as fatal error; throw an error...
authorTim-Philipp Müller <tim@centricular.net>
Mon, 27 Feb 2006 14:49:05 +0000 (14:49 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Mon, 27 Feb 2006 14:49:05 +0000 (14:49 +0000)
Original commit message from CVS:
Reviewed by: Tim-Philipp Müller  <tim at centricular dot net>
* ext/mpeg2dec/gstmpeg2dec.c: (gst_mpeg2dec_init),
(gst_mpeg2dec_reset), (gst_mpeg2dec_chain):
* ext/mpeg2dec/gstmpeg2dec.h:
Don't treat STATE_INVALID as fatal error; throw an error
only after five consecutive decoding errors. Makes decoding
mpeg streams more robust and fixes playback of joined clips
(#300682).

ChangeLog
ext/mpeg2dec/gstmpeg2dec.c
ext/mpeg2dec/gstmpeg2dec.h

index 9dec8601e0794b976bbf82317cec7ad4522d3c43..d5597de129b268a5713f2da2bf5225b98c3ac81c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2006-02-27  Luca Ognibene  <luogni at tin dot it>
+
+       Reviewed by: Tim-Philipp Müller  <tim at centricular dot net>
+
+       * ext/mpeg2dec/gstmpeg2dec.c: (gst_mpeg2dec_init),
+       (gst_mpeg2dec_reset), (gst_mpeg2dec_chain):
+       * ext/mpeg2dec/gstmpeg2dec.h:
+         Don't treat STATE_INVALID as fatal error; throw an error
+         only after five consecutive decoding errors. Makes decoding
+         mpeg streams more robust and fixes playback of joined clips
+         (#300682).
+
 2006-02-26  Tim-Philipp Müller  <tim at centricular dot net>
 
        * ext/dvdnav/dvdnavsrc.h:
index 12d0c03f7c381d6c3f89b33e9b6515f2211b1726..f8133792d6e624e8baa95a5b1bedaa43e3d65d34 100644 (file)
@@ -75,6 +75,11 @@ enum
       /* FILL ME */
 };
 
+/* error out after receiving MAX_ERROR_COUNT STATE_INVALID return value
+ * from mpeg2_parse. -1 means never error out
+ */
+#define MAX_ERROR_COUNT (5)
+
 /*
  * We can't use fractions in static pad templates, so
  * we do something manual...
@@ -290,6 +295,8 @@ gst_mpeg2dec_init (GstMpeg2dec * mpeg2dec)
   gst_element_add_pad (GST_ELEMENT (mpeg2dec), mpeg2dec->userdatapad);
 #endif
 
+  mpeg2dec->error_count = 0;
+
   /* initialize the mpeg2dec acceleration */
 }
 
@@ -321,6 +328,7 @@ gst_mpeg2dec_reset (GstMpeg2dec * mpeg2dec)
   mpeg2dec->need_sequence = TRUE;
   mpeg2dec->next_time = 0;
   mpeg2dec->offset = 0;
+  mpeg2dec->error_count = 0;
   mpeg2_reset (mpeg2dec->decoder, 1);
 }
 
@@ -920,13 +928,21 @@ gst_mpeg2dec_chain (GstPad * pad, GstBuffer * buf)
         break;
         /* error */
       case STATE_INVALID:
-        GST_WARNING_OBJECT (mpeg2dec, "Decoding error");
+        mpeg2dec->error_count++;
+        GST_WARNING_OBJECT (mpeg2dec, "Decoding error #%d",
+            mpeg2dec->error_count);
+        if (mpeg2dec->error_count >= MAX_ERROR_COUNT && MAX_ERROR_COUNT > 0) {
+          GST_WARNING_OBJECT (mpeg2dec, "Too many decoding errors");
+          goto exit_error;
+        }
         goto exit;
       default:
         GST_ERROR_OBJECT (mpeg2dec, "Unknown libmpeg2 state %d, FIXME", state);
-        break;
+        goto exit;
     }
 
+    mpeg2dec->error_count = 0;
+
     /*
      * FIXME: should pass more information such as state the user data is from
      */
@@ -949,6 +965,11 @@ gst_mpeg2dec_chain (GstPad * pad, GstBuffer * buf)
   return ret;
 
 exit:
+  gst_buffer_unref (buf);
+  return GST_FLOW_OK;
+
+exit_error:
+  GST_ELEMENT_ERROR (mpeg2dec, STREAM, DECODE, (NULL), (NULL));
   gst_buffer_unref (buf);
   return GST_FLOW_ERROR;
 }
index 1bcc5e442944035597aa70cecc80cefbfd8fb2ef..d4959669a777593e99c5fd40ac5d1a5aa97932f7 100644 (file)
@@ -75,7 +75,7 @@ struct _GstMpeg2dec {
   gboolean       closed;
   gboolean       have_fbuf;
 
-  GstBuffer  *buffers[GST_MPEG2DEC_NUM_BUFS];
+  GstBuffer     *buffers[GST_MPEG2DEC_NUM_BUFS];
 
   DiscontState   discont_state;
 
@@ -96,7 +96,7 @@ struct _GstMpeg2dec {
   gint64         total_frames;
   gint64         frame_period;
   
-  guint64  offset;
+  guint64        offset;
   gint           fps_n;
   gint           fps_d;
   gboolean       need_sequence;
@@ -105,6 +105,8 @@ struct _GstMpeg2dec {
 
   GstIndex      *index;
   gint           index_id;
+  
+  gint           error_count;
 };
 
 struct _GstMpeg2decClass {