mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
theora: Don't always round to even width/height
Previously, the code always rounded to even sizes. Now it only ensures that pic_x and pic_y are multiples of 2 if the output format requires it. Also inlcudes fixes to take pic_x/y into account properly when copying the buffer. https://bugzilla.gnome.org/show_bug.cgi?id=594729
This commit is contained in:
parent
0ac35d8555
commit
a3e92d3078
1 changed files with 25 additions and 19 deletions
|
@ -909,16 +909,25 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dec->crop) {
|
if (dec->crop) {
|
||||||
/* add black borders to make width/height/offsets even. we need this because
|
|
||||||
* we cannot express an offset to the peer plugin. */
|
|
||||||
dec->width = GST_ROUND_UP_2 (dec->info.pic_width + (dec->info.pic_x & 1));
|
|
||||||
dec->height = GST_ROUND_UP_2 (dec->info.pic_height + (dec->info.pic_y & 1));
|
|
||||||
dec->offset_x = dec->info.pic_x & ~1;
|
|
||||||
dec->offset_y = dec->info.pic_y & ~1;
|
|
||||||
} else {
|
|
||||||
/* no cropping, use the encoded dimensions */
|
|
||||||
dec->width = dec->info.pic_width;
|
dec->width = dec->info.pic_width;
|
||||||
dec->height = dec->info.pic_height;
|
dec->height = dec->info.pic_height;
|
||||||
|
dec->offset_x = dec->info.pic_x;
|
||||||
|
dec->offset_y = dec->info.pic_y;
|
||||||
|
/* Ensure correct offsets in chroma for formats that need it
|
||||||
|
* by rounding the offset. libtheora will add proper pixels,
|
||||||
|
* so no need to handle them ourselves. */
|
||||||
|
if (dec->offset_x & 1 && dec->info.pixel_fmt != TH_PF_444) {
|
||||||
|
dec->offset_x--;
|
||||||
|
dec->width++;
|
||||||
|
}
|
||||||
|
if (dec->offset_y & 1 && dec->info.pixel_fmt == TH_PF_420) {
|
||||||
|
dec->offset_y--;
|
||||||
|
dec->height++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* no cropping, use the encoded dimensions */
|
||||||
|
dec->width = dec->info.frame_width;
|
||||||
|
dec->height = dec->info.frame_height;
|
||||||
dec->offset_x = 0;
|
dec->offset_x = 0;
|
||||||
dec->offset_y = 0;
|
dec->offset_y = 0;
|
||||||
}
|
}
|
||||||
|
@ -1176,7 +1185,7 @@ theora_handle_422_image (GstTheoraDec * dec, th_ycbcr_buffer buf,
|
||||||
GstBuffer ** out)
|
GstBuffer ** out)
|
||||||
{
|
{
|
||||||
gint width = dec->width;
|
gint width = dec->width;
|
||||||
gint uvwidth = dec->width / 2;
|
gint uvwidth = GST_ROUND_UP_2 (dec->width) / 2;
|
||||||
gint height = dec->height;
|
gint height = dec->height;
|
||||||
gint out_size;
|
gint out_size;
|
||||||
gint ystride, uvstride;
|
gint ystride, uvstride;
|
||||||
|
@ -1198,21 +1207,21 @@ theora_handle_422_image (GstTheoraDec * dec, th_ycbcr_buffer buf,
|
||||||
|
|
||||||
dst = GST_BUFFER_DATA (*out);
|
dst = GST_BUFFER_DATA (*out);
|
||||||
|
|
||||||
src = buf[0].data;
|
src = buf[0].data + dec->offset_x + dec->offset_y * buf[0].stride;
|
||||||
for (i = 0; i < height; i++) {
|
for (i = 0; i < height; i++) {
|
||||||
memcpy (dst, src, width);
|
memcpy (dst, src, width);
|
||||||
src += buf[0].stride;
|
src += buf[0].stride;
|
||||||
dst += ystride;
|
dst += ystride;
|
||||||
}
|
}
|
||||||
|
|
||||||
src = buf[1].data;
|
src = buf[1].data + dec->offset_x / 2 + dec->offset_y * buf[1].stride;
|
||||||
for (i = 0; i < height; i++) {
|
for (i = 0; i < height; i++) {
|
||||||
memcpy (dst, src, uvwidth);
|
memcpy (dst, src, uvwidth);
|
||||||
src += buf[1].stride;
|
src += buf[1].stride;
|
||||||
dst += uvstride;
|
dst += uvstride;
|
||||||
}
|
}
|
||||||
|
|
||||||
src = buf[2].data;
|
src = buf[2].data + dec->offset_x / 2 + dec->offset_y * buf[2].stride;
|
||||||
for (i = 0; i < height; i++) {
|
for (i = 0; i < height; i++) {
|
||||||
memcpy (dst, src, uvwidth);
|
memcpy (dst, src, uvwidth);
|
||||||
src += buf[2].stride;
|
src += buf[2].stride;
|
||||||
|
@ -1234,8 +1243,8 @@ theora_handle_420_image (GstTheoraDec * dec, th_ycbcr_buffer buf,
|
||||||
{
|
{
|
||||||
gint width = dec->width;
|
gint width = dec->width;
|
||||||
gint height = dec->height;
|
gint height = dec->height;
|
||||||
gint cwidth = width / 2;
|
gint cwidth = GST_ROUND_UP_2 (width) / 2;
|
||||||
gint cheight = height / 2;
|
gint cheight = GST_ROUND_UP_2 (height) / 2;
|
||||||
gint out_size;
|
gint out_size;
|
||||||
gint stride_y, stride_uv;
|
gint stride_y, stride_uv;
|
||||||
GstFlowReturn result;
|
GstFlowReturn result;
|
||||||
|
@ -1269,7 +1278,6 @@ theora_handle_420_image (GstTheoraDec * dec, th_ycbcr_buffer buf,
|
||||||
guchar *dest_y, *src_y;
|
guchar *dest_y, *src_y;
|
||||||
guchar *dest_u, *src_u;
|
guchar *dest_u, *src_u;
|
||||||
guchar *dest_v, *src_v;
|
guchar *dest_v, *src_v;
|
||||||
gint offset;
|
|
||||||
|
|
||||||
dest_y = GST_BUFFER_DATA (*out);
|
dest_y = GST_BUFFER_DATA (*out);
|
||||||
dest_u = dest_y + stride_y * GST_ROUND_UP_2 (height);
|
dest_u = dest_y + stride_y * GST_ROUND_UP_2 (height);
|
||||||
|
@ -1290,10 +1298,8 @@ theora_handle_420_image (GstTheoraDec * dec, th_ycbcr_buffer buf,
|
||||||
src_y += buf[0].stride;
|
src_y += buf[0].stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = dec->offset_x / 2 + dec->offset_y / 2 * buf[1].stride;
|
src_u = buf[1].data + dec->offset_x / 2 + dec->offset_y / 2 * buf[1].stride;
|
||||||
|
src_v = buf[2].data + dec->offset_x / 2 + dec->offset_y / 2 * buf[2].stride;
|
||||||
src_u = buf[1].data + offset;
|
|
||||||
src_v = buf[2].data + offset;
|
|
||||||
|
|
||||||
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