summaryrefslogtreecommitdiffstats
path: root/ext/theora
diff options
context:
space:
mode:
authorMichael Smith <msmith@xiph.org>2006-06-02 13:43:24 +0000
committerMichael Smith <msmith@xiph.org>2006-06-02 13:43:24 +0000
commit909d0a7f9a508e00acbae138a09e67c24b1bc719 (patch)
tree3c3eb91105f7068c56fa39a0ce10b0befe763b33 /ext/theora
parent3e2a2c461c952efafb04cc37b96ff1a2ac9a782d (diff)
downloadgst-plugins-bad-909d0a7f9a508e00acbae138a09e67c24b1bc719.tar.gz
gst-plugins-bad-909d0a7f9a508e00acbae138a09e67c24b1bc719.tar.bz2
gst-plugins-bad-909d0a7f9a508e00acbae138a09e67c24b1bc719.zip
ext/theora/theoradec.c: Theora 4:4:4 pixel format support.
Original commit message from CVS: * ext/theora/theoradec.c: (theora_dec_src_convert), (theora_handle_type_packet), (theora_handle_422_image), (theora_handle_444_image), (theora_handle_420_image), (theora_handle_data_packet): Theora 4:4:4 pixel format support.
Diffstat (limited to 'ext/theora')
-rw-r--r--ext/theora/theoradec.c95
1 files changed, 81 insertions, 14 deletions
diff --git a/ext/theora/theoradec.c b/ext/theora/theoradec.c
index 6657b7ec..c68ba41a 100644
--- a/ext/theora/theoradec.c
+++ b/ext/theora/theoradec.c
@@ -58,15 +58,12 @@ GST_ELEMENT_DETAILS ("Theora video decoder",
"Benjamin Otte <in7y118@public.uni-hamburg.de>, "
"Wim Taymans <wim@fluendo.com>, " "Michael Smith <msmith@fluendo,com>");
-/* TODO: Support for other pixel formats (4:4:4) as supported by the
- * theoraexp codebase
- */
static GstStaticPadTemplate theora_dec_src_factory =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw-yuv, "
- "format = (fourcc) { I420, YUY2 }, "
+ "format = (fourcc) { I420, YUY2, Y444 }, "
"framerate = (fraction) [0/1, MAX], "
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
);
@@ -714,11 +711,14 @@ theora_handle_type_packet (GstTheoraExpDec * dec, ogg_packet * packet)
* So, we convert to a widely-supported packed format.
*/
fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
- } else {
- /* TODO: Implement 4:4:4, check for reserved/invalid values,
- * post appropriate error message, ensure callers handle errors here
- * properly.
+ } else if (dec->info.pixel_fmt == TH_PF_444) {
+ dec->output_bpp = 24;
+ /* As for I420, we can't define the stride for this, so we need to memcpy,
+ * though at least this is a planar format...
*/
+ fourcc = GST_MAKE_FOURCC ('Y', '4', '4', '4');
+ } else {
+ GST_ERROR_OBJECT (dec, "Invalid pixel format %d", dec->info.pixel_fmt);
return GST_FLOW_ERROR;
}
@@ -895,7 +895,7 @@ theora_handle_422_image (GstTheoraExpDec * dec, th_ycbcr_buffer yuv,
*curdest = *src++;
curdest += 4;
}
- src_cr += yuv[1].ystride;
+ src_cr += yuv[2].ystride;
dest += stride;
}
@@ -920,6 +920,75 @@ no_buffer:
}
}
+/* Get buffer, populate with original data (we must memcpy to get things to
+ * have the expected strides, etc...), and push.
+ */
+static GstFlowReturn
+theora_handle_444_image (GstTheoraExpDec * dec, th_ycbcr_buffer yuv,
+ GstClockTime outtime)
+{
+ int i, plane;
+ gint width, height;
+ gint out_size;
+ gint stride;
+ GstBuffer *out;
+ GstFlowReturn result;
+
+ width = dec->width;
+ height = dec->height;
+
+ /* TODO: Check if we have any special alignment requirements for the planes,
+ * or for each line within a plane. */
+ stride = width;
+ out_size = stride * height * 3;
+
+ /* now copy over the area contained in offset_x,offset_y,
+ * frame_width, frame_height */
+ result =
+ gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE,
+ out_size, GST_PAD_CAPS (dec->srcpad), &out);
+ if (result != GST_FLOW_OK)
+ goto no_buffer;
+
+ {
+ guchar *dest, *src;
+
+ for (plane = 0; plane < 3; plane++) {
+ /* TODO: do we have to use something different here? */
+ dest = GST_BUFFER_DATA (out) + plane * stride * height;
+
+ src = yuv[plane].data + dec->offset_x +
+ dec->offset_y * yuv[plane].ystride;
+
+ for (i = 0; i < height; i++) {
+ memcpy (dest, src, width);
+
+ dest += stride;
+ src += yuv[plane].ystride;
+ }
+
+ }
+ }
+
+ /* FIXME, frame_nr not correct */
+ GST_BUFFER_OFFSET (out) = dec->frame_nr;
+ dec->frame_nr++;
+ GST_BUFFER_OFFSET_END (out) = dec->frame_nr;
+ GST_BUFFER_DURATION (out) =
+ gst_util_uint64_scale_int (GST_SECOND, dec->info.fps_denominator,
+ dec->info.fps_numerator);
+ GST_BUFFER_TIMESTAMP (out) = outtime;
+
+ return theora_dec_push (dec, out);
+
+no_buffer:
+ {
+ GST_DEBUG_OBJECT (dec, "could not get buffer, reason: %s",
+ gst_flow_get_name (result));
+ return result;
+ }
+}
+
/* Create a (planar, but with special alignment and stride requirements) 'I420'
* buffer, populate, push.
*/
@@ -988,9 +1057,6 @@ theora_handle_420_image (GstTheoraExpDec * dec, th_ycbcr_buffer yuv,
src_v = yuv[2].data + offset_v;
for (i = 0; i < cheight; i++) {
- /* TODO: This, like many other things, is broken for pixel formats other
- * than OC_PF_420
- */
memcpy (dest_u, src_u, cwidth);
memcpy (dest_v, src_v, cwidth);
@@ -1070,9 +1136,10 @@ theora_handle_data_packet (GstTheoraExpDec * dec, ogg_packet * packet,
result = theora_handle_420_image (dec, yuv, outtime);
} else if (dec->info.pixel_fmt == TH_PF_422) {
result = theora_handle_422_image (dec, yuv, outtime);
+ } else if (dec->info.pixel_fmt == TH_PF_444) {
+ result = theora_handle_444_image (dec, yuv, outtime);
} else {
- /* Should be unreachable */
- result = GST_FLOW_ERROR;
+ g_assert_not_reached ();
}
return result;