mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
lagarith: add YUY2 decoding support
Unlike other variants, for YUY2 we need to use different prediction: * on line 0 for luma we should left predict starting from the second pixel * on line 1 we should left predict first 4 pixels for luma and 2 for chroma * median prediction employed here is taken directly from HuffYUV
This commit is contained in:
parent
58637a0b24
commit
464e9ab011
@ -269,6 +269,40 @@ static void lag_pred_line(LagarithContext *l, uint8_t *buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf,
|
||||||
|
int width, int stride, int line,
|
||||||
|
int is_luma)
|
||||||
|
{
|
||||||
|
int L, TL;
|
||||||
|
|
||||||
|
if (!line) {
|
||||||
|
if (is_luma) {
|
||||||
|
buf++;
|
||||||
|
width--;
|
||||||
|
}
|
||||||
|
l->dsp.add_hfyu_left_prediction(buf + 1, buf + 1, width - 1, buf[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (line == 1) {
|
||||||
|
const int HEAD = is_luma ? 4 : 2;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
L = buf[width - stride - 1];
|
||||||
|
TL = buf[HEAD - stride - 1];
|
||||||
|
for (i = 0; i < HEAD; i++) {
|
||||||
|
L += buf[i];
|
||||||
|
buf[i] = L;
|
||||||
|
}
|
||||||
|
buf += HEAD;
|
||||||
|
width -= HEAD;
|
||||||
|
} else {
|
||||||
|
TL = buf[width - (2 * stride) - 1];
|
||||||
|
L = buf[width - stride - 1];
|
||||||
|
}
|
||||||
|
l->dsp.add_hfyu_median_prediction(buf, buf - stride, buf, width,
|
||||||
|
&L, &TL);
|
||||||
|
}
|
||||||
|
|
||||||
static int lag_decode_line(LagarithContext *l, lag_rac *rac,
|
static int lag_decode_line(LagarithContext *l, lag_rac *rac,
|
||||||
uint8_t *dst, int width, int stride,
|
uint8_t *dst, int width, int stride,
|
||||||
int esc_count)
|
int esc_count)
|
||||||
@ -432,9 +466,17 @@ static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < height; i++) {
|
if (l->avctx->pix_fmt != PIX_FMT_YUV422P) {
|
||||||
lag_pred_line(l, dst, width, stride, i);
|
for (i = 0; i < height; i++) {
|
||||||
dst += stride;
|
lag_pred_line(l, dst, width, stride, i);
|
||||||
|
dst += stride;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < height; i++) {
|
||||||
|
lag_pred_line_yuy2(l, dst, width, stride, i,
|
||||||
|
width == l->avctx->width);
|
||||||
|
dst += stride;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -557,6 +599,32 @@ static int lag_decode_frame(AVCodecContext *avctx,
|
|||||||
srcs[i] += l->rgb_stride;
|
srcs[i] += l->rgb_stride;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case FRAME_ARITH_YUY2:
|
||||||
|
avctx->pix_fmt = PIX_FMT_YUV422P;
|
||||||
|
|
||||||
|
if (avctx->get_buffer(avctx, p) < 0) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset_ry >= buf_size ||
|
||||||
|
offset_gu >= buf_size ||
|
||||||
|
offset_bv >= buf_size) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR,
|
||||||
|
"Invalid frame offsets\n");
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
|
||||||
|
p->linesize[0], buf + offset_ry,
|
||||||
|
buf_size - offset_ry);
|
||||||
|
lag_decode_arith_plane(l, p->data[2], avctx->width / 2,
|
||||||
|
avctx->height, p->linesize[2],
|
||||||
|
buf + offset_gu, buf_size - offset_gu);
|
||||||
|
lag_decode_arith_plane(l, p->data[1], avctx->width / 2,
|
||||||
|
avctx->height, p->linesize[1],
|
||||||
|
buf + offset_bv, buf_size - offset_bv);
|
||||||
|
break;
|
||||||
case FRAME_ARITH_YV12:
|
case FRAME_ARITH_YV12:
|
||||||
avctx->pix_fmt = PIX_FMT_YUV420P;
|
avctx->pix_fmt = PIX_FMT_YUV420P;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user