mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
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.
This commit is contained in:
parent
3e2a2c461c
commit
909d0a7f9a
2 changed files with 89 additions and 14 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2006-06-02 Michael Smith <msmith@fluendo.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2006-06-02 Thomas Vander Stichele <thomas at apestaart dot org>
|
2006-06-02 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||||
|
|
||||||
* gst/gdp/gstgdppay.c: (gst_gdp_pay_class_init),
|
* gst/gdp/gstgdppay.c: (gst_gdp_pay_class_init),
|
||||||
|
|
|
@ -58,15 +58,12 @@ GST_ELEMENT_DETAILS ("Theora video decoder",
|
||||||
"Benjamin Otte <in7y118@public.uni-hamburg.de>, "
|
"Benjamin Otte <in7y118@public.uni-hamburg.de>, "
|
||||||
"Wim Taymans <wim@fluendo.com>, " "Michael Smith <msmith@fluendo,com>");
|
"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 =
|
static GstStaticPadTemplate theora_dec_src_factory =
|
||||||
GST_STATIC_PAD_TEMPLATE ("src",
|
GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("video/x-raw-yuv, "
|
GST_STATIC_CAPS ("video/x-raw-yuv, "
|
||||||
"format = (fourcc) { I420, YUY2 }, "
|
"format = (fourcc) { I420, YUY2, Y444 }, "
|
||||||
"framerate = (fraction) [0/1, MAX], "
|
"framerate = (fraction) [0/1, MAX], "
|
||||||
"width = (int) [ 1, MAX ], " "height = (int) [ 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.
|
* So, we convert to a widely-supported packed format.
|
||||||
*/
|
*/
|
||||||
fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
|
fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
|
||||||
} else {
|
} else if (dec->info.pixel_fmt == TH_PF_444) {
|
||||||
/* TODO: Implement 4:4:4, check for reserved/invalid values,
|
dec->output_bpp = 24;
|
||||||
* post appropriate error message, ensure callers handle errors here
|
/* As for I420, we can't define the stride for this, so we need to memcpy,
|
||||||
* properly.
|
* 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;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,7 +895,7 @@ theora_handle_422_image (GstTheoraExpDec * dec, th_ycbcr_buffer yuv,
|
||||||
*curdest = *src++;
|
*curdest = *src++;
|
||||||
curdest += 4;
|
curdest += 4;
|
||||||
}
|
}
|
||||||
src_cr += yuv[1].ystride;
|
src_cr += yuv[2].ystride;
|
||||||
|
|
||||||
dest += stride;
|
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'
|
/* Create a (planar, but with special alignment and stride requirements) 'I420'
|
||||||
* buffer, populate, push.
|
* buffer, populate, push.
|
||||||
*/
|
*/
|
||||||
|
@ -988,9 +1057,6 @@ theora_handle_420_image (GstTheoraExpDec * dec, th_ycbcr_buffer yuv,
|
||||||
src_v = yuv[2].data + offset_v;
|
src_v = yuv[2].data + offset_v;
|
||||||
|
|
||||||
for (i = 0; i < cheight; i++) {
|
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_u, src_u, cwidth);
|
||||||
memcpy (dest_v, src_v, 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);
|
result = theora_handle_420_image (dec, yuv, outtime);
|
||||||
} else if (dec->info.pixel_fmt == TH_PF_422) {
|
} else if (dec->info.pixel_fmt == TH_PF_422) {
|
||||||
result = theora_handle_422_image (dec, yuv, outtime);
|
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 {
|
} else {
|
||||||
/* Should be unreachable */
|
g_assert_not_reached ();
|
||||||
result = GST_FLOW_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Reference in a new issue