ext/mpeg2dec/gstmpeg2dec.*: Don't treat STATE_INVALID as fatal error; throw an error only after five consecutive deco...

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).
This commit is contained in:
Tim-Philipp Müller 2006-02-27 14:49:05 +00:00
parent 9d6d85d89d
commit 6438094695
3 changed files with 39 additions and 4 deletions

View file

@ -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> 2006-02-26 Tim-Philipp Müller <tim at centricular dot net>
* ext/dvdnav/dvdnavsrc.h: * ext/dvdnav/dvdnavsrc.h:

View file

@ -75,6 +75,11 @@ enum
/* FILL ME */ /* 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 can't use fractions in static pad templates, so
* we do something manual... * we do something manual...
@ -290,6 +295,8 @@ gst_mpeg2dec_init (GstMpeg2dec * mpeg2dec)
gst_element_add_pad (GST_ELEMENT (mpeg2dec), mpeg2dec->userdatapad); gst_element_add_pad (GST_ELEMENT (mpeg2dec), mpeg2dec->userdatapad);
#endif #endif
mpeg2dec->error_count = 0;
/* initialize the mpeg2dec acceleration */ /* initialize the mpeg2dec acceleration */
} }
@ -321,6 +328,7 @@ gst_mpeg2dec_reset (GstMpeg2dec * mpeg2dec)
mpeg2dec->need_sequence = TRUE; mpeg2dec->need_sequence = TRUE;
mpeg2dec->next_time = 0; mpeg2dec->next_time = 0;
mpeg2dec->offset = 0; mpeg2dec->offset = 0;
mpeg2dec->error_count = 0;
mpeg2_reset (mpeg2dec->decoder, 1); mpeg2_reset (mpeg2dec->decoder, 1);
} }
@ -920,13 +928,21 @@ gst_mpeg2dec_chain (GstPad * pad, GstBuffer * buf)
break; break;
/* error */ /* error */
case STATE_INVALID: 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; goto exit;
default: default:
GST_ERROR_OBJECT (mpeg2dec, "Unknown libmpeg2 state %d, FIXME", state); 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 * 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; return ret;
exit: exit:
gst_buffer_unref (buf);
return GST_FLOW_OK;
exit_error:
GST_ELEMENT_ERROR (mpeg2dec, STREAM, DECODE, (NULL), (NULL));
gst_buffer_unref (buf); gst_buffer_unref (buf);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }

View file

@ -75,7 +75,7 @@ struct _GstMpeg2dec {
gboolean closed; gboolean closed;
gboolean have_fbuf; gboolean have_fbuf;
GstBuffer *buffers[GST_MPEG2DEC_NUM_BUFS]; GstBuffer *buffers[GST_MPEG2DEC_NUM_BUFS];
DiscontState discont_state; DiscontState discont_state;
@ -96,7 +96,7 @@ struct _GstMpeg2dec {
gint64 total_frames; gint64 total_frames;
gint64 frame_period; gint64 frame_period;
guint64 offset; guint64 offset;
gint fps_n; gint fps_n;
gint fps_d; gint fps_d;
gboolean need_sequence; gboolean need_sequence;
@ -105,6 +105,8 @@ struct _GstMpeg2dec {
GstIndex *index; GstIndex *index;
gint index_id; gint index_id;
gint error_count;
}; };
struct _GstMpeg2decClass { struct _GstMpeg2decClass {