-Subproject commit 46dfcea233cf6df83e3771d8a8066e87d614f893
+Subproject commit 9e5bbd508588961696e70c38e764492e0312ec4c
GstElementClass *gstelement_class;
GstBaseSrcClass *gstbasesrc_class;
GstAudioSrcClass *gstaudiosrc_class;
- GstBaseAudioSrcClass *gstbaseaudiosrc_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
gstbasesrc_class = (GstBaseSrcClass *) klass;
gstaudiosrc_class = (GstAudioSrcClass *) klass;
- gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
gobject_class->finalize = gst_alsasrc_finalize;
gobject_class->get_property = gst_alsasrc_get_property;
}
static GstFlowReturn
+vorbis_dec_handle_header_buffer (GstVorbisDec * vd, GstBuffer * buffer)
+{
+ ogg_packet *packet;
+ ogg_packet_wrapper packet_wrapper;
+
+ gst_ogg_packet_wrapper_from_buffer (&packet_wrapper, buffer);
+ packet = gst_ogg_packet_from_wrapper (&packet_wrapper);
+
+ return vorbis_handle_header_packet (vd, packet);
+}
+
+
+#define MIN_NUM_HEADERS 3
+static GstFlowReturn
+vorbis_dec_handle_header_caps (GstVorbisDec * vd, GstBuffer * buffer)
+{
+ GstFlowReturn result = GST_FLOW_OK;
+ GstCaps *caps = GST_PAD_CAPS (vd->sinkpad);
+ GstStructure *s = gst_caps_get_structure (caps, 0);
+ const GValue *array = gst_structure_get_value (s, "streamheader");
+
+ if (array && (gst_value_array_get_size (array) >= MIN_NUM_HEADERS)) {
+ const GValue *value = NULL;
+ GstBuffer *buf = NULL;
+
+ /* initial header */
+ value = gst_value_array_get_value (array, 0);
+ buf = gst_value_get_buffer (value);
+ if (!buf)
+ goto null_buffer;
+ result = vorbis_dec_handle_header_buffer (vd, buf);
+
+ /* comment header */
+ if (result == GST_FLOW_OK) {
+ value = gst_value_array_get_value (array, 1);
+ buf = gst_value_get_buffer (value);
+ if (!buf)
+ goto null_buffer;
+ result = vorbis_dec_handle_header_buffer (vd, buf);
+ }
+
+ /* bitstream codebook header */
+ if (result == GST_FLOW_OK) {
+ value = gst_value_array_get_value (array, 2);
+ buf = gst_value_get_buffer (value);
+ if (!buf)
+ goto null_buffer;
+ result = vorbis_dec_handle_header_buffer (vd, buf);
+ }
+ } else
+ goto array_error;
+
+done:
+ return (result != GST_FLOW_OK ? GST_FLOW_NOT_NEGOTIATED : GST_FLOW_OK);
+
+array_error:
+ {
+ GST_WARNING_OBJECT (vd, "streamheader array not found");
+ result = GST_FLOW_ERROR;
+ goto done;
+ }
+
+null_buffer:
+ {
+ GST_WARNING_OBJECT (vd, "streamheader with null buffer received");
+ result = GST_FLOW_ERROR;
+ goto done;
+ }
+}
+
+static GstFlowReturn
vorbis_dec_decode_buffer (GstVorbisDec * vd, GstBuffer * buffer)
{
ogg_packet *packet;
} else {
GstClockTime timestamp, duration;
+ /* try to find header in caps so we can initialize the decoder */
+ if (!vd->initialized) {
+ result = vorbis_dec_handle_header_caps (vd, buffer);
+ if (result != GST_FLOW_OK)
+ goto invalid_caps_header;
+ }
+
timestamp = GST_BUFFER_TIMESTAMP (buffer);
duration = GST_BUFFER_DURATION (buffer);
vd->discont = TRUE;
goto done;
}
+
+invalid_caps_header:
+ {
+ GST_ELEMENT_ERROR (vd, STREAM, DECODE, (NULL),
+ ("invalid streamheader in caps"));
+ goto done;
+ }
}
/*
* Returns: TRUE if @caps was parsed correctly.
*/
gboolean
-gst_video_format_parse_caps (GstCaps * caps, GstVideoFormat * format,
+gst_video_format_parse_caps (const GstCaps * caps, GstVideoFormat * format,
int *width, int *height)
{
GstStructure *structure;
}
/**
+ * gst_video_get_size_from_caps:
+ * @caps: a pointer to #GstCaps
+ * @size: a pointer to a gint that will be assigned the size (in bytes) of a video frame with the given caps
+ *
+ * Calculates the total number of bytes in the raw video format for the given
+ * caps. This number should be used when allocating a buffer for raw video.
+ *
+ * Since: 0.10.34
+ *
+ * Returns: %TRUE if the size could be calculated from the caps
+ */
+gboolean
+gst_video_get_size_from_caps (const GstCaps * caps, gint * size)
+{
+ GstVideoFormat format = 0;
+ gint width = 0, height = 0;
+
+ g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
+ g_return_val_if_fail (size != NULL, FALSE);
+
+ if (gst_video_format_parse_caps (caps, &format, &width, &height) == FALSE) {
+ GST_WARNING ("Could not parse caps: %" GST_PTR_FORMAT, caps);
+ return FALSE;
+ }
+
+ *size = gst_video_format_get_size (format, width, height);
+ return TRUE;
+}
+
+/**
* gst_video_format_convert:
* @format: a #GstVideoFormat
* @width: the width of video
guint video_par_n, guint video_par_d,
guint display_par_n, guint display_par_d);
-gboolean gst_video_format_parse_caps (GstCaps *caps, GstVideoFormat *format,
- int *width, int *height);
+gboolean gst_video_format_parse_caps (const GstCaps *caps,
+ GstVideoFormat *format, int *width, int *height);
gboolean gst_video_format_parse_caps_interlaced (GstCaps *caps, gboolean *interlaced);
gboolean gst_video_parse_caps_framerate (GstCaps *caps,
int *fps_n, int *fps_d);
int gst_video_format_get_component_offset (GstVideoFormat format, int component,
int width, int height);
int gst_video_format_get_size (GstVideoFormat format, int width, int height);
+gboolean gst_video_get_size_from_caps (const GstCaps * caps, gint * size);
gboolean gst_video_format_convert (GstVideoFormat format, int width, int height,
int fps_n, int fps_d,
GstFormat src_format, gint64 src_value,
GST_END_TEST;
+GST_START_TEST (test_video_size_from_caps)
+{
+ gint size;
+ guint32 fourcc = GST_MAKE_FOURCC ('Y', 'V', '1', '2');
+ GstCaps *caps = gst_caps_new_simple ("video/x-raw-yuv",
+ "format", GST_TYPE_FOURCC, fourcc,
+ "width", G_TYPE_INT, 640,
+ "height", G_TYPE_INT, 480,
+ "framerate", GST_TYPE_FRACTION, 25, 1,
+ NULL);
+
+ fail_unless (gst_video_get_size_from_caps (caps, &size));
+ fail_unless (size ==
+ gst_video_format_get_size (gst_video_format_from_fourcc (fourcc), 640,
+ 480));
+ fail_unless (size == (640 * 480 * 12 / 8));
+
+ gst_caps_unref (caps);
+}
+
+GST_END_TEST;
+
static Suite *
video_suite (void)
{
tcase_add_test (tc_chain, test_events);
tcase_add_test (tc_chain, test_convert_frame);
tcase_add_test (tc_chain, test_convert_frame_async);
+ tcase_add_test (tc_chain, test_video_size_from_caps);
return s;
}