|
|
@ -33,6 +33,7 @@ |
|
|
|
#include "avcodec.h" |
|
|
|
#include "avcodec.h" |
|
|
|
#include "get_bits.h" |
|
|
|
#include "get_bits.h" |
|
|
|
#include "huffyuv.h" |
|
|
|
#include "huffyuv.h" |
|
|
|
|
|
|
|
#include "huffyuvdsp.h" |
|
|
|
#include "thread.h" |
|
|
|
#include "thread.h" |
|
|
|
#include "libavutil/pixdesc.h" |
|
|
|
#include "libavutil/pixdesc.h" |
|
|
|
|
|
|
|
|
|
|
@ -265,6 +266,7 @@ static av_cold int decode_init(AVCodecContext *avctx) |
|
|
|
{ |
|
|
|
{ |
|
|
|
HYuvContext *s = avctx->priv_data; |
|
|
|
HYuvContext *s = avctx->priv_data; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ff_huffyuvdsp_init(&s->hdsp); |
|
|
|
memset(s->vlc, 0, 4 * sizeof(VLC)); |
|
|
|
memset(s->vlc, 0, 4 * sizeof(VLC)); |
|
|
|
|
|
|
|
|
|
|
|
s->interlaced = avctx->height > 288; |
|
|
|
s->interlaced = avctx->height > 288; |
|
|
@ -746,7 +748,7 @@ static void draw_slice(HYuvContext *s, AVFrame *frame, int y) |
|
|
|
static int left_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, int w, int acc) |
|
|
|
static int left_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, int w, int acc) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (s->bps <= 8) { |
|
|
|
if (s->bps <= 8) { |
|
|
|
return s->dsp.add_hfyu_left_prediction(dst, src, w, acc); |
|
|
|
return s->hdsp.add_hfyu_left_pred(dst, src, w, acc); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return s->llviddsp.add_hfyu_left_prediction_int16(( uint16_t *)dst, (const uint16_t *)src, s->n-1, w, acc); |
|
|
|
return s->llviddsp.add_hfyu_left_prediction_int16(( uint16_t *)dst, (const uint16_t *)src, s->n-1, w, acc); |
|
|
|
} |
|
|
|
} |
|
|
@ -755,7 +757,7 @@ static int left_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, int |
|
|
|
static void add_bytes(HYuvContext *s, uint8_t *dst, uint8_t *src, int w) |
|
|
|
static void add_bytes(HYuvContext *s, uint8_t *dst, uint8_t *src, int w) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (s->bps <= 8) { |
|
|
|
if (s->bps <= 8) { |
|
|
|
s->dsp.add_bytes(dst, src, w); |
|
|
|
s->hdsp.add_bytes(dst, src, w); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
s->llviddsp.add_int16((uint16_t*)dst, (const uint16_t*)src, s->n - 1, w); |
|
|
|
s->llviddsp.add_int16((uint16_t*)dst, (const uint16_t*)src, s->n - 1, w); |
|
|
|
} |
|
|
|
} |
|
|
@ -764,7 +766,7 @@ static void add_bytes(HYuvContext *s, uint8_t *dst, uint8_t *src, int w) |
|
|
|
static void add_median_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, const uint8_t *diff, int w, int *left, int *left_top) |
|
|
|
static void add_median_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, const uint8_t *diff, int w, int *left, int *left_top) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (s->bps <= 8) { |
|
|
|
if (s->bps <= 8) { |
|
|
|
s->dsp.add_hfyu_median_prediction(dst, src, diff, w, left, left_top); |
|
|
|
s->hdsp.add_hfyu_median_pred(dst, src, diff, w, left, left_top); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
s->llviddsp.add_hfyu_median_prediction_int16((uint16_t *)dst, (const uint16_t *)src, (const uint16_t *)diff, s->n-1, w, left, left_top); |
|
|
|
s->llviddsp.add_hfyu_median_prediction_int16((uint16_t *)dst, (const uint16_t *)src, (const uint16_t *)diff, s->n-1, w, left, left_top); |
|
|
|
} |
|
|
|
} |
|
|
@ -903,10 +905,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
|
|
|
case LEFT: |
|
|
|
case LEFT: |
|
|
|
case PLANE: |
|
|
|
case PLANE: |
|
|
|
decode_422_bitstream(s, width-2); |
|
|
|
decode_422_bitstream(s, width-2); |
|
|
|
lefty = s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); |
|
|
|
lefty = s->hdsp.add_hfyu_left_pred(p->data[0] + 2, s->temp[0], width - 2, lefty); |
|
|
|
if (!(s->flags&CODEC_FLAG_GRAY)) { |
|
|
|
if (!(s->flags&CODEC_FLAG_GRAY)) { |
|
|
|
leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2 - 1, leftu); |
|
|
|
leftu = s->hdsp.add_hfyu_left_pred(p->data[1] + 1, s->temp[1], width2 - 1, leftu); |
|
|
|
leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + 1, s->temp[2], width2 - 1, leftv); |
|
|
|
leftv = s->hdsp.add_hfyu_left_pred(p->data[2] + 1, s->temp[2], width2 - 1, leftv); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (cy = y = 1; y < s->height; y++, cy++) { |
|
|
|
for (cy = y = 1; y < s->height; y++, cy++) { |
|
|
@ -917,10 +919,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
|
|
|
|
|
|
|
|
|
|
|
ydst = p->data[0] + p->linesize[0] * y; |
|
|
|
ydst = p->data[0] + p->linesize[0] * y; |
|
|
|
|
|
|
|
|
|
|
|
lefty = s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty); |
|
|
|
lefty = s->hdsp.add_hfyu_left_pred(ydst, s->temp[0], width, lefty); |
|
|
|
if (s->predictor == PLANE) { |
|
|
|
if (s->predictor == PLANE) { |
|
|
|
if (y > s->interlaced) |
|
|
|
if (y > s->interlaced) |
|
|
|
s->dsp.add_bytes(ydst, ydst - fake_ystride, width); |
|
|
|
s->hdsp.add_bytes(ydst, ydst - fake_ystride, width); |
|
|
|
} |
|
|
|
} |
|
|
|
y++; |
|
|
|
y++; |
|
|
|
if (y >= s->height) break; |
|
|
|
if (y >= s->height) break; |
|
|
@ -933,17 +935,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
|
|
|
vdst = p->data[2] + p->linesize[2]*cy; |
|
|
|
vdst = p->data[2] + p->linesize[2]*cy; |
|
|
|
|
|
|
|
|
|
|
|
decode_422_bitstream(s, width); |
|
|
|
decode_422_bitstream(s, width); |
|
|
|
lefty = s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty); |
|
|
|
lefty = s->hdsp.add_hfyu_left_pred(ydst, s->temp[0], width, lefty); |
|
|
|
if (!(s->flags & CODEC_FLAG_GRAY)) { |
|
|
|
if (!(s->flags & CODEC_FLAG_GRAY)) { |
|
|
|
leftu= s->dsp.add_hfyu_left_prediction(udst, s->temp[1], width2, leftu); |
|
|
|
leftu = s->hdsp.add_hfyu_left_pred(udst, s->temp[1], width2, leftu); |
|
|
|
leftv= s->dsp.add_hfyu_left_prediction(vdst, s->temp[2], width2, leftv); |
|
|
|
leftv = s->hdsp.add_hfyu_left_pred(vdst, s->temp[2], width2, leftv); |
|
|
|
} |
|
|
|
} |
|
|
|
if (s->predictor == PLANE) { |
|
|
|
if (s->predictor == PLANE) { |
|
|
|
if (cy > s->interlaced) { |
|
|
|
if (cy > s->interlaced) { |
|
|
|
s->dsp.add_bytes(ydst, ydst - fake_ystride, width); |
|
|
|
s->hdsp.add_bytes(ydst, ydst - fake_ystride, width); |
|
|
|
if (!(s->flags & CODEC_FLAG_GRAY)) { |
|
|
|
if (!(s->flags & CODEC_FLAG_GRAY)) { |
|
|
|
s->dsp.add_bytes(udst, udst - fake_ustride, width2); |
|
|
|
s->hdsp.add_bytes(udst, udst - fake_ustride, width2); |
|
|
|
s->dsp.add_bytes(vdst, vdst - fake_vstride, width2); |
|
|
|
s->hdsp.add_bytes(vdst, vdst - fake_vstride, width2); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -954,10 +956,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
|
|
|
case MEDIAN: |
|
|
|
case MEDIAN: |
|
|
|
/* first line except first 2 pixels is left predicted */ |
|
|
|
/* first line except first 2 pixels is left predicted */ |
|
|
|
decode_422_bitstream(s, width - 2); |
|
|
|
decode_422_bitstream(s, width - 2); |
|
|
|
lefty= s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width - 2, lefty); |
|
|
|
lefty = s->hdsp.add_hfyu_left_pred(p->data[0] + 2, s->temp[0], width - 2, lefty); |
|
|
|
if (!(s->flags & CODEC_FLAG_GRAY)) { |
|
|
|
if (!(s->flags & CODEC_FLAG_GRAY)) { |
|
|
|
leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2 - 1, leftu); |
|
|
|
leftu = s->hdsp.add_hfyu_left_pred(p->data[1] + 1, s->temp[1], width2 - 1, leftu); |
|
|
|
leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + 1, s->temp[2], width2 - 1, leftv); |
|
|
|
leftv = s->hdsp.add_hfyu_left_pred(p->data[2] + 1, s->temp[2], width2 - 1, leftv); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
cy = y = 1; |
|
|
|
cy = y = 1; |
|
|
@ -965,31 +967,31 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
|
|
|
/* second line is left predicted for interlaced case */ |
|
|
|
/* second line is left predicted for interlaced case */ |
|
|
|
if (s->interlaced) { |
|
|
|
if (s->interlaced) { |
|
|
|
decode_422_bitstream(s, width); |
|
|
|
decode_422_bitstream(s, width); |
|
|
|
lefty = s->dsp.add_hfyu_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty); |
|
|
|
lefty = s->hdsp.add_hfyu_left_pred(p->data[0] + p->linesize[0], s->temp[0], width, lefty); |
|
|
|
if (!(s->flags & CODEC_FLAG_GRAY)) { |
|
|
|
if (!(s->flags & CODEC_FLAG_GRAY)) { |
|
|
|
leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu); |
|
|
|
leftu = s->hdsp.add_hfyu_left_pred(p->data[1] + p->linesize[2], s->temp[1], width2, leftu); |
|
|
|
leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv); |
|
|
|
leftv = s->hdsp.add_hfyu_left_pred(p->data[2] + p->linesize[1], s->temp[2], width2, leftv); |
|
|
|
} |
|
|
|
} |
|
|
|
y++; cy++; |
|
|
|
y++; cy++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* next 4 pixels are left predicted too */ |
|
|
|
/* next 4 pixels are left predicted too */ |
|
|
|
decode_422_bitstream(s, 4); |
|
|
|
decode_422_bitstream(s, 4); |
|
|
|
lefty = s->dsp.add_hfyu_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty); |
|
|
|
lefty = s->hdsp.add_hfyu_left_pred(p->data[0] + fake_ystride, s->temp[0], 4, lefty); |
|
|
|
if (!(s->flags&CODEC_FLAG_GRAY)) { |
|
|
|
if (!(s->flags&CODEC_FLAG_GRAY)) { |
|
|
|
leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu); |
|
|
|
leftu = s->hdsp.add_hfyu_left_pred(p->data[1] + fake_ustride, s->temp[1], 2, leftu); |
|
|
|
leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv); |
|
|
|
leftv = s->hdsp.add_hfyu_left_pred(p->data[2] + fake_vstride, s->temp[2], 2, leftv); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* next line except the first 4 pixels is median predicted */ |
|
|
|
/* next line except the first 4 pixels is median predicted */ |
|
|
|
lefttopy = p->data[0][3]; |
|
|
|
lefttopy = p->data[0][3]; |
|
|
|
decode_422_bitstream(s, width - 4); |
|
|
|
decode_422_bitstream(s, width - 4); |
|
|
|
s->dsp.add_hfyu_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy); |
|
|
|
s->hdsp.add_hfyu_median_pred(p->data[0] + fake_ystride + 4, p->data[0] + 4, s->temp[0], width - 4, &lefty, &lefttopy); |
|
|
|
if (!(s->flags&CODEC_FLAG_GRAY)) { |
|
|
|
if (!(s->flags&CODEC_FLAG_GRAY)) { |
|
|
|
lefttopu = p->data[1][1]; |
|
|
|
lefttopu = p->data[1][1]; |
|
|
|
lefttopv = p->data[2][1]; |
|
|
|
lefttopv = p->data[2][1]; |
|
|
|
s->dsp.add_hfyu_median_prediction(p->data[1] + fake_ustride+2, p->data[1] + 2, s->temp[1], width2 - 2, &leftu, &lefttopu); |
|
|
|
s->hdsp.add_hfyu_median_pred(p->data[1] + fake_ustride + 2, p->data[1] + 2, s->temp[1], width2 - 2, &leftu, &lefttopu); |
|
|
|
s->dsp.add_hfyu_median_prediction(p->data[2] + fake_vstride+2, p->data[2] + 2, s->temp[2], width2 - 2, &leftv, &lefttopv); |
|
|
|
s->hdsp.add_hfyu_median_pred(p->data[2] + fake_vstride + 2, p->data[2] + 2, s->temp[2], width2 - 2, &leftv, &lefttopv); |
|
|
|
} |
|
|
|
} |
|
|
|
y++; cy++; |
|
|
|
y++; cy++; |
|
|
|
|
|
|
|
|
|
|
@ -1000,7 +1002,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
|
|
|
while (2 * cy > y) { |
|
|
|
while (2 * cy > y) { |
|
|
|
decode_gray_bitstream(s, width); |
|
|
|
decode_gray_bitstream(s, width); |
|
|
|
ydst = p->data[0] + p->linesize[0] * y; |
|
|
|
ydst = p->data[0] + p->linesize[0] * y; |
|
|
|
s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); |
|
|
|
s->hdsp.add_hfyu_median_pred(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); |
|
|
|
y++; |
|
|
|
y++; |
|
|
|
} |
|
|
|
} |
|
|
|
if (y >= height) break; |
|
|
|
if (y >= height) break; |
|
|
@ -1013,10 +1015,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
|
|
|
udst = p->data[1] + p->linesize[1] * cy; |
|
|
|
udst = p->data[1] + p->linesize[1] * cy; |
|
|
|
vdst = p->data[2] + p->linesize[2] * cy; |
|
|
|
vdst = p->data[2] + p->linesize[2] * cy; |
|
|
|
|
|
|
|
|
|
|
|
s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); |
|
|
|
s->hdsp.add_hfyu_median_pred(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); |
|
|
|
if (!(s->flags & CODEC_FLAG_GRAY)) { |
|
|
|
if (!(s->flags & CODEC_FLAG_GRAY)) { |
|
|
|
s->dsp.add_hfyu_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu); |
|
|
|
s->hdsp.add_hfyu_median_pred(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu); |
|
|
|
s->dsp.add_hfyu_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv); |
|
|
|
s->hdsp.add_hfyu_median_pred(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1047,17 +1049,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
|
|
|
case LEFT: |
|
|
|
case LEFT: |
|
|
|
case PLANE: |
|
|
|
case PLANE: |
|
|
|
decode_bgr_bitstream(s, width - 1); |
|
|
|
decode_bgr_bitstream(s, width - 1); |
|
|
|
s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width - 1, &leftr, &leftg, &leftb, &lefta); |
|
|
|
s->hdsp.add_hfyu_left_pred_bgr32(p->data[0] + last_line + 4, s->temp[0], width - 1, &leftr, &leftg, &leftb, &lefta); |
|
|
|
|
|
|
|
|
|
|
|
for (y = s->height - 2; y >= 0; y--) { //Yes it is stored upside down.
|
|
|
|
for (y = s->height - 2; y >= 0; y--) { //Yes it is stored upside down.
|
|
|
|
decode_bgr_bitstream(s, width); |
|
|
|
decode_bgr_bitstream(s, width); |
|
|
|
|
|
|
|
|
|
|
|
s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb, &lefta); |
|
|
|
s->hdsp.add_hfyu_left_pred_bgr32(p->data[0] + p->linesize[0] * y, s->temp[0], width, &leftr, &leftg, &leftb, &lefta); |
|
|
|
if (s->predictor == PLANE) { |
|
|
|
if (s->predictor == PLANE) { |
|
|
|
if (s->bitstream_bpp != 32) lefta = 0; |
|
|
|
if (s->bitstream_bpp != 32) lefta = 0; |
|
|
|
if ((y & s->interlaced) == 0 && |
|
|
|
if ((y & s->interlaced) == 0 && |
|
|
|
y < s->height - 1 - s->interlaced) { |
|
|
|
y < s->height - 1 - s->interlaced) { |
|
|
|
s->dsp.add_bytes(p->data[0] + p->linesize[0] * y, |
|
|
|
s->hdsp.add_bytes(p->data[0] + p->linesize[0] * y, |
|
|
|
p->data[0] + p->linesize[0] * y + |
|
|
|
p->data[0] + p->linesize[0] * y + |
|
|
|
fake_ystride, fake_ystride); |
|
|
|
fake_ystride, fake_ystride); |
|
|
|
} |
|
|
|
} |
|
|
|