Commit 9a173575 authored by Kostya Shishkov's avatar Kostya Shishkov Committed by Ronald S. Bultje

utvideo: account for coupled lines in YUV420 format

Luma slices in YUV420 colourspace should have height in multiple of two since
they have the same line of chrominance data corresponding to pair of them.
Signed-off-by: 's avatarRonald S. Bultje <rsbultje@gmail.com>
parent 8370e426
...@@ -113,6 +113,7 @@ static int decode_plane(UtvideoContext *c, int plane_no, ...@@ -113,6 +113,7 @@ static int decode_plane(UtvideoContext *c, int plane_no,
VLC vlc; VLC vlc;
GetBitContext gb; GetBitContext gb;
int prev; int prev;
const int cmask = ~(!plane_no && c->avctx->pix_fmt == PIX_FMT_YUV420P);
if (build_huff(src, &vlc)) { if (build_huff(src, &vlc)) {
av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
...@@ -128,7 +129,7 @@ static int decode_plane(UtvideoContext *c, int plane_no, ...@@ -128,7 +129,7 @@ static int decode_plane(UtvideoContext *c, int plane_no,
int slice_data_start, slice_data_end, slice_size; int slice_data_start, slice_data_end, slice_size;
sstart = send; sstart = send;
send = height * (slice + 1) / c->slices; send = (height * (slice + 1) / c->slices) & cmask;
dest = dst + sstart * stride; dest = dst + sstart * stride;
// slice offset and size validation was done earlier // slice offset and size validation was done earlier
...@@ -204,16 +205,17 @@ static void restore_rgb_planes(uint8_t *src, int step, int stride, int width, in ...@@ -204,16 +205,17 @@ static void restore_rgb_planes(uint8_t *src, int step, int stride, int width, in
} }
static void restore_median(uint8_t *src, int step, int stride, static void restore_median(uint8_t *src, int step, int stride,
int width, int height, int slices) int width, int height, int slices, int rmode)
{ {
int i, j, slice; int i, j, slice;
int A, B, C; int A, B, C;
uint8_t *bsrc; uint8_t *bsrc;
int slice_start, slice_height; int slice_start, slice_height;
const int cmask = ~rmode;
for (slice = 0; slice < slices; slice++) { for (slice = 0; slice < slices; slice++) {
slice_start = (slice * height) / slices; slice_start = ((slice * height) / slices) & cmask;
slice_height = ((slice + 1) * height) / slices - slice_start; slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start;
bsrc = src + slice_start * stride; bsrc = src + slice_start * stride;
...@@ -337,7 +339,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac ...@@ -337,7 +339,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
if (c->frame_pred == PRED_MEDIAN) if (c->frame_pred == PRED_MEDIAN)
restore_median(c->pic.data[0] + rgb_order[i], c->planes, restore_median(c->pic.data[0] + rgb_order[i], c->planes,
c->pic.linesize[0], avctx->width, avctx->height, c->pic.linesize[0], avctx->width, avctx->height,
c->slices); c->slices, 0);
} }
restore_rgb_planes(c->pic.data[0], c->planes, c->pic.linesize[0], restore_rgb_planes(c->pic.data[0], c->planes, c->pic.linesize[0],
avctx->width, avctx->height); avctx->width, avctx->height);
...@@ -353,7 +355,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac ...@@ -353,7 +355,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
if (c->frame_pred == PRED_MEDIAN) if (c->frame_pred == PRED_MEDIAN)
restore_median(c->pic.data[i], 1, c->pic.linesize[i], restore_median(c->pic.data[i], 1, c->pic.linesize[i],
avctx->width >> !!i, avctx->height >> !!i, avctx->width >> !!i, avctx->height >> !!i,
c->slices); c->slices, !i);
} }
break; break;
case PIX_FMT_YUV422P: case PIX_FMT_YUV422P:
...@@ -366,7 +368,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac ...@@ -366,7 +368,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
return ret; return ret;
if (c->frame_pred == PRED_MEDIAN) if (c->frame_pred == PRED_MEDIAN)
restore_median(c->pic.data[i], 1, c->pic.linesize[i], restore_median(c->pic.data[i], 1, c->pic.linesize[i],
avctx->width >> !!i, avctx->height, c->slices); avctx->width >> !!i, avctx->height, c->slices, 0);
} }
break; break;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment