]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/aic.c
network: Use ff_neterrno instead of AVERROR(errno) for poll errors
[ffmpeg] / libavcodec / aic.c
index e46c00349a5b45d0bee94f256fcc0c95a89c5f8c..de9d7de91bee5f67ae3fcd92a23519e9c61263a5 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <inttypes.h>
+
 #include "avcodec.h"
+#include "bitstream.h"
 #include "bytestream.h"
-#include "dsputil.h"
-#include "internal.h"
-#include "get_bits.h"
 #include "golomb.h"
+#include "internal.h"
+#include "idctdsp.h"
+#include "thread.h"
 #include "unary.h"
 
 #define AIC_HDR_SIZE    24
@@ -130,14 +133,14 @@ static const uint8_t aic_c_ext_scan[192] = {
     177, 184, 176, 169, 162, 161, 168, 160,
 };
 
-static const uint8_t *aic_scan[NUM_BANDS] = {
+static const uint8_t * const aic_scan[NUM_BANDS] = {
     aic_y_scan, aic_c_scan, aic_y_ext_scan, aic_c_ext_scan
 };
 
 typedef struct AICContext {
     AVCodecContext *avctx;
     AVFrame        *frame;
-    DSPContext     dsp;
+    IDCTDSPContext idsp;
     ScanTable      scantable;
 
     int            num_x_slices;
@@ -169,7 +172,7 @@ static int aic_decode_header(AICContext *ctx, const uint8_t *src, int size)
     width      = AV_RB16(src + 6);
     height     = AV_RB16(src + 8);
     if (frame_size > size) {
-        av_log(ctx->avctx, AV_LOG_ERROR, "Frame size should be %d got %d\n",
+        av_log(ctx->avctx, AV_LOG_ERROR, "Frame size should be %"PRIu32" got %d\n",
                frame_size, size);
         return AVERROR_INVALIDDATA;
     }
@@ -188,14 +191,14 @@ static int aic_decode_header(AICContext *ctx, const uint8_t *src, int size)
 #define GET_CODE(val, type, add_bits)                         \
     do {                                                      \
         if (type)                                             \
-            val = get_ue_golomb(gb);                          \
+            val = get_ue_golomb(bc);                          \
         else                                                  \
-            val = get_unary(gb, 1, 31);                       \
+            val = get_unary(bc, 1, 31);                       \
         if (add_bits)                                         \
-            val = (val << add_bits) + get_bits(gb, add_bits); \
+            val = (val << add_bits) + bitstream_read(bc, add_bits); \
     } while (0)
 
-static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst,
+static int aic_decode_coeffs(BitstreamContext *bc, int16_t *dst,
                              int band, int slice_width, int force_chroma)
 {
     int has_skips, coeff_type, coeff_bits, skip_type, skip_bits;
@@ -203,24 +206,26 @@ static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst,
     const uint8_t *scan = aic_scan[band | force_chroma];
     int mb, idx, val;
 
-    has_skips  = get_bits1(gb);
-    coeff_type = get_bits1(gb);
-    coeff_bits = get_bits(gb, 3);
+    has_skips  = bitstream_read_bit(bc);
+    coeff_type = bitstream_read_bit(bc);
+    coeff_bits = bitstream_read(bc, 3);
 
     if (has_skips) {
-        skip_type = get_bits1(gb);
-        skip_bits = get_bits(gb, 3);
+        skip_type = bitstream_read_bit(bc);
+        skip_bits = bitstream_read(bc, 3);
 
         for (mb = 0; mb < slice_width; mb++) {
             idx = -1;
             do {
                 GET_CODE(val, skip_type, skip_bits);
+                if (val < 0)
+                    return AVERROR_INVALIDDATA;
                 idx += val + 1;
                 if (idx >= num_coeffs)
                     break;
                 GET_CODE(val, coeff_type, coeff_bits);
                 val++;
-                if (val >= 0x10000)
+                if (val >= 0x10000 || val < 0)
                     return AVERROR_INVALIDDATA;
                 dst[scan[idx]] = val;
             } while (idx < num_coeffs - 1);
@@ -230,7 +235,7 @@ static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst,
         for (mb = 0; mb < slice_width; mb++) {
             for (idx = 0; idx < num_coeffs; idx++) {
                 GET_CODE(val, coeff_type, coeff_bits);
-                if (val >= 0x10000)
+                if (val >= 0x10000 || val < 0)
                     return AVERROR_INVALIDDATA;
                 dst[scan[idx]] = val;
             }
@@ -298,7 +303,7 @@ static void unquant_block(int16_t *block, int q)
 static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
                             const uint8_t *src, int src_size)
 {
-    GetBitContext gb;
+    BitstreamContext bc;
     int ret, i, mb, blk;
     int slice_width = FFMIN(ctx->slice_width, ctx->mb_width - mb_x);
     uint8_t *Y, *C[2];
@@ -313,12 +318,12 @@ static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
     for (i = 0; i < 2; i++)
         C[i] = ctx->frame->data[i + 1] + mb_x * 8
                + mb_y * 8 * ctx->frame->linesize[i + 1];
-    init_get_bits(&gb, src, src_size * 8);
+    bitstream_init8(&bc, src, src_size);
 
     memset(ctx->slice_data, 0,
            sizeof(*ctx->slice_data) * slice_width * AIC_BAND_COEFFS);
     for (i = 0; i < NUM_BANDS; i++)
-        if ((ret = aic_decode_coeffs(&gb, ctx->data_ptr[i],
+        if ((ret = aic_decode_coeffs(&bc, ctx->data_ptr[i],
                                      i, slice_width,
                                      !ctx->interlaced)) < 0)
             return ret;
@@ -332,16 +337,15 @@ static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
                 recombine_block_il(ctx->block, ctx->scantable.permutated,
                                    &base_y, &ext_y, blk);
             unquant_block(ctx->block, ctx->quant);
-            ctx->dsp.idct(ctx->block);
+            ctx->idsp.idct(ctx->block);
 
             if (!ctx->interlaced) {
                 dst = Y + (blk >> 1) * 8 * ystride + (blk & 1) * 8;
-                ctx->dsp.put_signed_pixels_clamped(ctx->block, dst,
-                                                   ystride);
+                ctx->idsp.put_signed_pixels_clamped(ctx->block, dst, ystride);
             } else {
                 dst = Y + (blk & 1) * 8 + (blk >> 1) * ystride;
-                ctx->dsp.put_signed_pixels_clamped(ctx->block, dst,
-                                                   ystride * 2);
+                ctx->idsp.put_signed_pixels_clamped(ctx->block, dst,
+                                                    ystride * 2);
             }
         }
         Y += 16;
@@ -350,9 +354,9 @@ static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
             recombine_block(ctx->block, ctx->scantable.permutated,
                             &base_c, &ext_c);
             unquant_block(ctx->block, ctx->quant);
-            ctx->dsp.idct(ctx->block);
-            ctx->dsp.put_signed_pixels_clamped(ctx->block, C[blk],
-                                               ctx->frame->linesize[blk + 1]);
+            ctx->idsp.idct(ctx->block);
+            ctx->idsp.put_signed_pixels_clamped(ctx->block, C[blk],
+                                                ctx->frame->linesize[blk + 1]);
             C[blk] += 8;
         }
     }
@@ -370,6 +374,7 @@ static int aic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     uint32_t off;
     int x, y, ret;
     int slice_size;
+    ThreadFrame frame = { .f = data };
 
     ctx->frame            = data;
     ctx->frame->pict_type = AV_PICTURE_TYPE_I;
@@ -382,10 +387,13 @@ static int aic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    if ((ret = aic_decode_header(ctx, buf, buf_size)) < 0)
+    ret = aic_decode_header(ctx, buf, buf_size);
+    if (ret < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid header\n");
         return ret;
+    }
 
-    if ((ret = ff_get_buffer(avctx, ctx->frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
         return ret;
 
     bytestream2_init(&gb, buf + AIC_HDR_SIZE,
@@ -395,13 +403,17 @@ static int aic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         for (x = 0; x < ctx->mb_width; x += ctx->slice_width) {
             slice_size = bytestream2_get_le16(&gb) * 4;
             if (slice_size + off > buf_size || !slice_size) {
-                av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n");
+                av_log(avctx, AV_LOG_ERROR,
+                       "Incorrect slice size %d at %d.%d\n", slice_size, x, y);
                 return AVERROR_INVALIDDATA;
             }
 
-            if ((ret = aic_decode_slice(ctx, x, y,
-                                        buf + off, slice_size)) < 0)
+            ret = aic_decode_slice(ctx, x, y, buf + off, slice_size);
+            if (ret < 0) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Error decoding slice at %d.%d\n", x, y);
                 return ret;
+            }
 
             off += slice_size;
         }
@@ -422,19 +434,19 @@ static av_cold int aic_decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-    ff_dsputil_init(&ctx->dsp, avctx);
+    ff_idctdsp_init(&ctx->idsp, avctx);
 
     for (i = 0; i < 64; i++)
         scan[i] = i;
-    ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, scan);
+    ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable, scan);
 
     ctx->mb_width  = FFALIGN(avctx->width,  16) >> 4;
     ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
 
-    ctx->num_x_slices = 16;
-    ctx->slice_width  = ctx->mb_width / 16;
+    ctx->num_x_slices = (ctx->mb_width + 15) >> 4;
+    ctx->slice_width  = 16;
     for (i = 1; i < 32; i++) {
-        if (!(ctx->mb_width % i) && (ctx->mb_width / i < 32)) {
+        if (!(ctx->mb_width % i) && (ctx->mb_width / i <= 32)) {
             ctx->slice_width  = ctx->mb_width / i;
             ctx->num_x_slices = i;
             break;
@@ -467,12 +479,14 @@ static av_cold int aic_decode_close(AVCodecContext *avctx)
 
 AVCodec ff_aic_decoder = {
     .name           = "aic",
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple Intermediate Codec"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_AIC,
     .priv_data_size = sizeof(AICContext),
     .init           = aic_decode_init,
     .close          = aic_decode_close,
     .decode         = aic_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Apple Intermediate Codec")
+    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .init_thread_copy = ONLY_IF_THREADS_ENABLED(aic_decode_init),
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };