mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
ext/theora/theoradec.c: Don't screw up the 1 Chroma for 1 luma sample situation when we have an odd offset/width by a...
Original commit message from CVS: * ext/theora/theoradec.c: (theora_get_formats), (theora_dec_src_convert), (theora_dec_sink_convert), (theora_dec_src_query), (theora_dec_src_event), (theora_dec_event), (theora_dec_chain): Don't screw up the 1 Chroma for 1 luma sample situation when we have an odd offset/width by adding a black border in those cases.
This commit is contained in:
parent
9523130954
commit
13eaab891d
2 changed files with 35 additions and 16 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2004-07-28 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* ext/theora/theoradec.c: (theora_get_formats),
|
||||||
|
(theora_dec_src_convert), (theora_dec_sink_convert),
|
||||||
|
(theora_dec_src_query), (theora_dec_src_event), (theora_dec_event),
|
||||||
|
(theora_dec_chain):
|
||||||
|
Don't screw up the 1 Chroma for 1 luma sample situation when we
|
||||||
|
have an odd offset/width by adding a black border in those cases.
|
||||||
|
|
||||||
2004-07-28 Wim Taymans <wim@fluendo.com>
|
2004-07-28 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* ext/theora/theoradec.c: (theora_get_formats),
|
* ext/theora/theoradec.c: (theora_get_formats),
|
||||||
|
|
|
@ -58,6 +58,8 @@ struct _GstTheoraDec
|
||||||
guint64 granulepos;
|
guint64 granulepos;
|
||||||
|
|
||||||
gboolean need_keyframe;
|
gboolean need_keyframe;
|
||||||
|
gint width, height;
|
||||||
|
gint offset_x, offset_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstTheoraDecClass
|
struct _GstTheoraDecClass
|
||||||
|
@ -563,6 +565,18 @@ theora_dec_chain (GstPad * pad, GstData * data)
|
||||||
dec->info.frame_width, dec->info.frame_height,
|
dec->info.frame_width, dec->info.frame_height,
|
||||||
dec->info.offset_x, dec->info.offset_y);
|
dec->info.offset_x, dec->info.offset_y);
|
||||||
|
|
||||||
|
/* add black borders to make width/height/offsets even. we need this because
|
||||||
|
* we cannot express an offset to the peer plugin. */
|
||||||
|
dec->width =
|
||||||
|
ROUND_UP_2 (dec->info.frame_width + (dec->info.offset_x & 1));
|
||||||
|
dec->height =
|
||||||
|
ROUND_UP_2 (dec->info.frame_height + (dec->info.offset_y & 1));
|
||||||
|
dec->offset_x = dec->info.offset_x & ~1;
|
||||||
|
dec->offset_y = dec->info.offset_y & ~1;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (dec, "after fixup frame dimension %dx%d, offset %d:%d",
|
||||||
|
dec->width, dec->height, dec->offset_x, dec->offset_y);
|
||||||
|
|
||||||
/* done */
|
/* done */
|
||||||
theora_decode_init (&dec->state, &dec->info);
|
theora_decode_init (&dec->state, &dec->info);
|
||||||
caps = gst_caps_new_simple ("video/x-raw-yuv",
|
caps = gst_caps_new_simple ("video/x-raw-yuv",
|
||||||
|
@ -570,8 +584,8 @@ theora_dec_chain (GstPad * pad, GstData * data)
|
||||||
"framerate", G_TYPE_DOUBLE,
|
"framerate", G_TYPE_DOUBLE,
|
||||||
((gdouble) dec->info.fps_numerator) / dec->info.fps_denominator,
|
((gdouble) dec->info.fps_numerator) / dec->info.fps_denominator,
|
||||||
"pixel-aspect-ratio", GST_TYPE_FRACTION, par_num, par_den,
|
"pixel-aspect-ratio", GST_TYPE_FRACTION, par_num, par_den,
|
||||||
"width", G_TYPE_INT, dec->info.frame_width, "height", G_TYPE_INT,
|
"width", G_TYPE_INT, dec->width, "height", G_TYPE_INT,
|
||||||
dec->info.frame_height, NULL);
|
dec->height, NULL);
|
||||||
gst_pad_set_explicit_caps (dec->srcpad, caps);
|
gst_pad_set_explicit_caps (dec->srcpad, caps);
|
||||||
gst_caps_free (caps);
|
gst_caps_free (caps);
|
||||||
}
|
}
|
||||||
|
@ -612,8 +626,10 @@ theora_dec_chain (GstPad * pad, GstData * data)
|
||||||
g_return_if_fail (yuv.y_width == dec->info.width);
|
g_return_if_fail (yuv.y_width == dec->info.width);
|
||||||
g_return_if_fail (yuv.y_height == dec->info.height);
|
g_return_if_fail (yuv.y_height == dec->info.height);
|
||||||
|
|
||||||
width = dec->info.frame_width;
|
width = dec->width;
|
||||||
height = dec->info.frame_height;
|
height = dec->height;
|
||||||
|
cwidth = width / 2;
|
||||||
|
cheight = height / 2;
|
||||||
|
|
||||||
/* should get the stride from the caps, for now we round up to the nearest
|
/* should get the stride from the caps, for now we round up to the nearest
|
||||||
* multiple of 4 because some element needs it. chroma needs special
|
* multiple of 4 because some element needs it. chroma needs special
|
||||||
|
@ -621,10 +637,6 @@ theora_dec_chain (GstPad * pad, GstData * data)
|
||||||
stride_y = ROUND_UP_4 (width);
|
stride_y = ROUND_UP_4 (width);
|
||||||
stride_uv = ROUND_UP_8 (width) / 2;
|
stride_uv = ROUND_UP_8 (width) / 2;
|
||||||
|
|
||||||
/* for odd offsets we need to copy one extra line/column of chroma samples */
|
|
||||||
cwidth = width / 2 + (dec->info.offset_x & 1);
|
|
||||||
cheight = height / 2 + (dec->info.offset_y & 1);
|
|
||||||
|
|
||||||
out_size = stride_y * height + stride_uv * cheight * 2;
|
out_size = stride_y * height + stride_uv * cheight * 2;
|
||||||
|
|
||||||
/* now copy over the area contained in offset_x,offset_y,
|
/* now copy over the area contained in offset_x,offset_y,
|
||||||
|
@ -635,6 +647,8 @@ theora_dec_chain (GstPad * pad, GstData * data)
|
||||||
* complicated and gstreamer doesn't support all the needed caps to do this
|
* complicated and gstreamer doesn't support all the needed caps to do this
|
||||||
* correctly. For example, when we have an odd offset, we should only combine
|
* correctly. For example, when we have an odd offset, we should only combine
|
||||||
* 1 row/column of luma samples with on chroma sample in colorspace conversion.
|
* 1 row/column of luma samples with on chroma sample in colorspace conversion.
|
||||||
|
* We compensate for this by adding a block border around the image when the
|
||||||
|
* offset of size is odd (see above).
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
guint8 *dest_y, *src_y;
|
guint8 *dest_y, *src_y;
|
||||||
|
@ -643,9 +657,9 @@ theora_dec_chain (GstPad * pad, GstData * data)
|
||||||
|
|
||||||
dest_y = GST_BUFFER_DATA (out);
|
dest_y = GST_BUFFER_DATA (out);
|
||||||
dest_u = dest_y + stride_y * height;
|
dest_u = dest_y + stride_y * height;
|
||||||
dest_v = dest_u + stride_uv * height / 2;
|
dest_v = dest_u + stride_uv * cheight;
|
||||||
|
|
||||||
src_y = yuv.y + dec->info.offset_x + dec->info.offset_y * yuv.y_stride;
|
src_y = yuv.y + dec->offset_x + dec->offset_y * yuv.y_stride;
|
||||||
|
|
||||||
for (i = 0; i < height; i++) {
|
for (i = 0; i < height; i++) {
|
||||||
memcpy (dest_y, src_y, width);
|
memcpy (dest_y, src_y, width);
|
||||||
|
@ -654,12 +668,8 @@ theora_dec_chain (GstPad * pad, GstData * data)
|
||||||
src_y += yuv.y_stride;
|
src_y += yuv.y_stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
src_u =
|
src_u = yuv.u + dec->offset_x / 2 + dec->offset_y / 2 * yuv.uv_stride;
|
||||||
yuv.u + dec->info.offset_x / 2 +
|
src_v = yuv.v + dec->offset_x / 2 + dec->offset_y / 2 * yuv.uv_stride;
|
||||||
dec->info.offset_y / 2 * yuv.uv_stride;
|
|
||||||
src_v =
|
|
||||||
yuv.v + dec->info.offset_x / 2 +
|
|
||||||
dec->info.offset_y / 2 * yuv.uv_stride;
|
|
||||||
|
|
||||||
for (i = 0; i < cheight; i++) {
|
for (i = 0; i < cheight; i++) {
|
||||||
memcpy (dest_u, src_u, cwidth);
|
memcpy (dest_u, src_u, cwidth);
|
||||||
|
|
Loading…
Reference in a new issue