X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Flagarith.c;h=e9b00982d3e024ae2abff98ea11bebdfbef176c6;hb=a536a4e4bc52d05f59869761337452fb1f1977f6;hp=665bd963b9c64efd0f0314ec096bdcfe44eb982f;hpb=36ef5369ee9b336febc2c270f8718cec4476cb85;p=ffmpeg diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index 665bd963b9c..e9b00982d3e 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -25,11 +25,14 @@ * @author Nathan Caldwell */ +#include + #include "avcodec.h" #include "get_bits.h" #include "mathops.h" -#include "dsputil.h" +#include "huffyuvdsp.h" #include "lagarithrac.h" +#include "thread.h" enum LagarithFrameType { FRAME_RAW = 1, /**< uncompressed */ @@ -47,11 +50,11 @@ enum LagarithFrameType { typedef struct LagarithContext { AVCodecContext *avctx; - AVFrame picture; - DSPContext dsp; + HuffYUVDSPContext hdsp; int zeros; /**< number of consecutive zero bytes encountered */ int zeros_rem; /**< number of zero bytes remaining to output */ uint8_t *rgb_planes; + int rgb_planes_allocated; int rgb_stride; } LagarithContext; @@ -197,8 +200,8 @@ static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb) } /* Comment from reference source: * if (b & 0x80 == 0) { // order of operations is 'wrong'; it has been left this way - * // since the compression change is negligable and fixing it - * // breaks backwards compatibilty + * // since the compression change is negligible and fixing it + * // breaks backwards compatibility * b =- (signed int)b; * b &= 0xFF; * } else { @@ -222,7 +225,7 @@ static void add_lag_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *diff, int w, int *left, int *left_top) { - /* This is almost identical to add_hfyu_median_prediction in dsputil.h. + /* This is almost identical to add_hfyu_median_pred in huffyuvdsp.h. * However the &0xFF on the gradient predictor yealds incorrect output * for lagarith. */ @@ -248,9 +251,11 @@ static void lag_pred_line(LagarithContext *l, uint8_t *buf, int L, TL; if (!line) { + int i, align_width = (width - 1) & ~31; /* Left prediction only for first line */ - L = l->dsp.add_hfyu_left_prediction(buf + 1, buf + 1, - width - 1, buf[0]); + L = l->hdsp.add_hfyu_left_pred(buf + 1, buf + 1, align_width, buf[0]); + for (i = align_width + 1; i < width; i++) + buf[i] += buf[i - 1]; } else { /* Left pixel is actually prev_row[width] */ L = buf[width - stride - 1]; @@ -258,7 +263,7 @@ static void lag_pred_line(LagarithContext *l, uint8_t *buf, if (line == 1) { /* Second line, left predict first pixel, the rest of the line is median predicted * NOTE: In the case of RGB this pixel is top predicted */ - TL = l->avctx->pix_fmt == PIX_FMT_YUV420P ? buf[-stride] : L; + TL = l->avctx->pix_fmt == AV_PIX_FMT_YUV420P ? buf[-stride] : L; } else { /* Top left is 2 rows back, last pixel */ TL = buf[width - (2 * stride) - 1]; @@ -276,11 +281,18 @@ static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf, int L, TL; if (!line) { + int i, align_width; if (is_luma) { buf++; width--; } - l->dsp.add_hfyu_left_prediction(buf + 1, buf + 1, width - 1, buf[0]); + + align_width = (width - 1) & ~31; + l->hdsp.add_hfyu_left_pred(buf + 1, buf + 1, align_width, buf[0]); + + for (i = align_width + 1; i < width; i++) + buf[i] += buf[i - 1]; + return; } if (line == 1) { @@ -293,14 +305,16 @@ static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf, L += buf[i]; buf[i] = L; } - buf += HEAD; - width -= HEAD; + for (; i < width; i++) { + L = mid_pred(L & 0xFF, buf[i - stride], (L + buf[i - stride] - TL) & 0xFF) + buf[i]; + TL = buf[i - stride]; + buf[i] = L; + } } else { TL = buf[width - (2 * stride) - 1]; L = buf[width - stride - 1]; + l->hdsp.add_hfyu_median_pred(buf, buf - stride, buf, width, &L, &TL); } - l->dsp.add_hfyu_median_prediction(buf, buf - stride, buf, width, - &L, &TL); } static int lag_decode_line(LagarithContext *l, lag_rac *rac, @@ -360,6 +374,11 @@ static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst, output_zeros: if (l->zeros_rem) { count = FFMIN(l->zeros_rem, width - i); + if (end - dst < count) { + av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n"); + return AVERROR_INVALIDDATA; + } + memset(dst, 0, count); l->zeros_rem -= count; dst += count; @@ -430,7 +449,7 @@ static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst, if (read > length) av_log(l->avctx, AV_LOG_WARNING, - "Output more bytes than length (%d of %d)\n", read, + "Output more bytes than length (%d of %"PRIu32")\n", read, length); } else if (esc_count < 8) { esc_count -= 4; @@ -466,7 +485,7 @@ static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst, return -1; } - if (l->avctx->pix_fmt != PIX_FMT_YUV422P) { + if (l->avctx->pix_fmt != AV_PIX_FMT_YUV422P) { for (i = 0; i < height; i++) { lag_pred_line(l, dst, width, stride, i); dst += stride; @@ -491,24 +510,19 @@ static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst, * @return number of consumed bytes on success or negative if decode fails */ static int lag_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, AVPacket *avpkt) + void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; LagarithContext *l = avctx->priv_data; - AVFrame *const p = &l->picture; + ThreadFrame frame = { .f = data }; + AVFrame *const p = data; uint8_t frametype = 0; uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9; uint32_t offs[4]; uint8_t *srcs[4], *dst; int i, j, planes = 3; - AVFrame *picture = data; - - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 0; p->key_frame = 1; frametype = buf[0]; @@ -518,9 +532,9 @@ static int lag_decode_frame(AVCodecContext *avctx, switch (frametype) { case FRAME_SOLID_RGBA: - avctx->pix_fmt = PIX_FMT_RGB32; + avctx->pix_fmt = AV_PIX_FMT_RGB32; - if (avctx->get_buffer(avctx, p) < 0) { + if (ff_thread_get_buffer(avctx, &frame, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -533,16 +547,16 @@ static int lag_decode_frame(AVCodecContext *avctx, } break; case FRAME_ARITH_RGBA: - avctx->pix_fmt = PIX_FMT_RGB32; + avctx->pix_fmt = AV_PIX_FMT_RGB32; planes = 4; offset_ry += 4; offs[3] = AV_RL32(buf + 9); case FRAME_ARITH_RGB24: case FRAME_U_RGB24: if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24) - avctx->pix_fmt = PIX_FMT_RGB24; + avctx->pix_fmt = AV_PIX_FMT_RGB24; - if (avctx->get_buffer(avctx, p) < 0) { + if (ff_thread_get_buffer(avctx, &frame, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -551,13 +565,12 @@ static int lag_decode_frame(AVCodecContext *avctx, offs[1] = offset_gu; offs[2] = offset_ry; + l->rgb_stride = FFALIGN(avctx->width, 16); + av_fast_malloc(&l->rgb_planes, &l->rgb_planes_allocated, + l->rgb_stride * avctx->height * planes + 1); if (!l->rgb_planes) { - l->rgb_stride = FFALIGN(avctx->width, 16); - l->rgb_planes = av_malloc(l->rgb_stride * avctx->height * planes + 1); - if (!l->rgb_planes) { - av_log(avctx, AV_LOG_ERROR, "cannot allocate temporary buffer\n"); - return AVERROR(ENOMEM); - } + av_log(avctx, AV_LOG_ERROR, "cannot allocate temporary buffer\n"); + return AVERROR(ENOMEM); } for (i = 0; i < planes; i++) srcs[i] = l->rgb_planes + (i + 1) * l->rgb_stride * avctx->height - l->rgb_stride; @@ -600,9 +613,9 @@ static int lag_decode_frame(AVCodecContext *avctx, } break; case FRAME_ARITH_YUY2: - avctx->pix_fmt = PIX_FMT_YUV422P; + avctx->pix_fmt = AV_PIX_FMT_YUV422P; - if (avctx->get_buffer(avctx, p) < 0) { + if (ff_thread_get_buffer(avctx, &frame, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -626,9 +639,9 @@ static int lag_decode_frame(AVCodecContext *avctx, buf + offset_bv, buf_size - offset_bv); break; case FRAME_ARITH_YV12: - avctx->pix_fmt = PIX_FMT_YUV420P; + avctx->pix_fmt = AV_PIX_FMT_YUV420P; - if (avctx->get_buffer(avctx, p) < 0) { + if (ff_thread_get_buffer(avctx, &frame, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -653,12 +666,11 @@ static int lag_decode_frame(AVCodecContext *avctx, break; default: av_log(avctx, AV_LOG_ERROR, - "Unsupported Lagarith frame type: %#x\n", frametype); + "Unsupported Lagarith frame type: %#"PRIx8"\n", frametype); return -1; } - *picture = *p; - *data_size = sizeof(AVFrame); + *got_frame = 1; return buf_size; } @@ -668,7 +680,7 @@ static av_cold int lag_decode_init(AVCodecContext *avctx) LagarithContext *l = avctx->priv_data; l->avctx = avctx; - ff_dsputil_init(&l->dsp, avctx); + ff_huffyuvdsp_init(&l->hdsp); return 0; } @@ -677,8 +689,6 @@ static av_cold int lag_decode_end(AVCodecContext *avctx) { LagarithContext *l = avctx->priv_data; - if (l->picture.data[0]) - avctx->release_buffer(avctx, &l->picture); av_freep(&l->rgb_planes); return 0; @@ -686,12 +696,12 @@ static av_cold int lag_decode_end(AVCodecContext *avctx) AVCodec ff_lagarith_decoder = { .name = "lagarith", + .long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_LAGARITH, .priv_data_size = sizeof(LagarithContext), .init = lag_decode_init, .close = lag_decode_end, .decode = lag_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"), + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, };