summaryrefslogtreecommitdiffstats
path: root/ext/dv/gstdvdec.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2006-02-28 10:22:11 +0000
committerWim Taymans <wim.taymans@gmail.com>2006-02-28 10:22:11 +0000
commite6d71f7bea1bce119edc5311a0aa634a5daa7bd5 (patch)
tree860358efc48fecb5c864b6863633487631c8b6b6 /ext/dv/gstdvdec.c
parent86ddc6d513b81b6fca8896151a87a06560261f75 (diff)
docs/plugins/: Added dvdec and dvdemux to docs.
Original commit message from CVS: * docs/plugins/Makefile.am: * docs/plugins/gst-plugins-good-plugins-docs.sgml: * docs/plugins/gst-plugins-good-plugins-sections.txt: Added dvdec and dvdemux to docs. * ext/dv/gstdvdec.c: (gst_dvdec_base_init), (gst_dvdec_chain): Added docs. Check frame sizes so we don't crash when don't have enough data. Send nice error messages on error. * ext/dv/gstdvdemux.c: (gst_dvdemux_base_init), (gst_dvdemux_class_init), (gst_dvdemux_init), (gst_dvdemux_finalize), (gst_dvdemux_reset), (gst_dvdemux_src_convert), (gst_dvdemux_sink_convert), (gst_dvdemux_src_query), (gst_dvdemux_sink_query), (gst_dvdemux_push_event), (gst_dvdemux_handle_sink_event), (gst_dvdemux_convert_src_pair), (gst_dvdemux_convert_sink_pair), (gst_dvdemux_convert_src_to_sink), (gst_dvdemux_handle_push_seek), (gst_dvdemux_do_seek), (gst_dvdemux_handle_pull_seek), (gst_dvdemux_handle_src_event), (gst_dvdemux_demux_audio), (gst_dvdemux_demux_video), (gst_dvdemux_demux_frame), (gst_dvdemux_flush), (gst_dvdemux_chain), (gst_dvdemux_loop), (gst_dvdemux_sink_activate_push), (gst_dvdemux_sink_activate_pull), (gst_dvdemux_sink_activate), (gst_dvdemux_change_state): * ext/dv/gstdvdemux.h: Added docs. Implement pull mode. Fix memleaks. Reduce memcpy for the video demuxing.
Diffstat (limited to 'ext/dv/gstdvdec.c')
-rw-r--r--ext/dv/gstdvdec.c68
1 files changed, 61 insertions, 7 deletions
diff --git a/ext/dv/gstdvdec.c b/ext/dv/gstdvdec.c
index 85ccf884..4458f3a5 100644
--- a/ext/dv/gstdvdec.c
+++ b/ext/dv/gstdvdec.c
@@ -18,6 +18,30 @@
* Boston, MA 02111-1307, USA.
*/
+/**
+ * SECTION:element-dvdec
+ *
+ * <refsect2>
+ * <para>
+ * dvdec decodes DV video into raw video. The element expects a full DV frame
+ * as input, which is 120000 bytes for NTSC and 144000 for PAL video.
+ * </para>
+ * <para>
+ * This element can perform simple frame dropping with the drop-factor
+ * property. Setting this property to a value N > 1 will only decode every
+ * Nth frame.
+ * </para>
+ * <title>Example launch line</title>
+ * <para>
+ * <programlisting>
+ * gst-launch filesrc location=test.dv ! dvdemux name=demux ! dvdec ! xvimagesink
+ * </programlisting>
+ * This pipeline decodes and renders the raw DV stream to a videosink.
+ * </para>
+ * Last reviewed on 2006-02-28 (0.10.3)
+ * </refsect2>
+ */
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -33,6 +57,9 @@ GST_ELEMENT_DETAILS ("DV (smpte314) decoder plugin",
"Uses libdv to decode DV video (libdv.sourceforge.net)",
"Erik Walthinsen <omega@cse.ogi.edu>," "Wim Taymans <wim@fluendo.com>");
+/* sizes of one input buffer */
+#define NTSC_BUFFER 120000
+#define PAL_BUFFER 144000
#define DV_DEFAULT_QUALITY DV_QUALITY_BEST
#define DV_DEFAULT_DECODE_NTH 1
@@ -265,12 +292,25 @@ gst_dvdec_chain (GstPad * pad, GstBuffer * buf)
gint outframe_pitches[3];
GstBuffer *outbuf;
GstFlowReturn ret = GST_FLOW_OK;
+ guint length;
dvdec = GST_DVDEC (gst_pad_get_parent (pad));
inframe = GST_BUFFER_DATA (buf);
- if (dv_parse_header (dvdec->decoder, inframe) < 0)
- g_assert_not_reached ();
+ /* buffer should be at least the size of one NTSC frame, this should
+ * be enough to decode the header. */
+ if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < NTSC_BUFFER))
+ goto wrong_size;
+
+ if (G_UNLIKELY (dv_parse_header (dvdec->decoder, inframe) < 0))
+ goto parse_header_error;
+
+ /* check the buffer is of right size after we know if we are
+ * dealing with PAL or NTSC */
+ length = (dvdec->PAL ? PAL_BUFFER : NTSC_BUFFER);
+ if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < length))
+ goto wrong_size;
+
dv_parse_packs (dvdec->decoder, inframe);
if (dvdec->video_offset % dvdec->drop_factor != 0)
@@ -280,7 +320,7 @@ gst_dvdec_chain (GstPad * pad, GstBuffer * buf)
gst_pad_alloc_buffer_and_set_caps (dvdec->srcpad, 0,
(720 * dvdec->height) * dvdec->bpp,
GST_PAD_CAPS (dvdec->srcpad), &outbuf);
- if (ret != GST_FLOW_OK)
+ if (G_UNLIKELY (ret != GST_FLOW_OK))
goto no_buffer;
outframe = GST_BUFFER_DATA (outbuf);
@@ -306,19 +346,33 @@ gst_dvdec_chain (GstPad * pad, GstBuffer * buf)
ret = gst_pad_push (dvdec->srcpad, outbuf);
skip:
- gst_buffer_unref (buf);
dvdec->video_offset++;
+
+done:
+ gst_buffer_unref (buf);
gst_object_unref (dvdec);
return ret;
/* ERRORS */
+wrong_size:
+ {
+ GST_ELEMENT_ERROR (dvdec, STREAM, DECODE,
+ (NULL), ("Input buffer too small"));
+ ret = GST_FLOW_ERROR;
+ goto done;
+ }
+parse_header_error:
+ {
+ GST_ELEMENT_ERROR (dvdec, STREAM, DECODE,
+ (NULL), ("Error parsing DV header"));
+ ret = GST_FLOW_ERROR;
+ goto done;
+ }
no_buffer:
{
GST_DEBUG_OBJECT (dvdec, "could not allocate buffer");
- gst_buffer_unref (buf);
- gst_object_unref (dvdec);
- return ret;
+ goto done;
}
}