]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/ffv1.c
utvideodec: Support UQRA and UQRG
[ffmpeg] / libavcodec / ffv1.c
index d37230c6c15c5c6c9eb32a68b781f2c7a69134bf..89d27bbca1bc5dd491a27716996e86ce3c3d1fae 100644 (file)
  * FF Video Codec 1 (a lossless codec)
  */
 
-#include "libavutil/avassert.h"
+#include "libavutil/attributes.h"
+
 #include "avcodec.h"
-#include "get_bits.h"
 #include "put_bits.h"
 #include "rangecoder.h"
-#include "golomb.h"
 #include "mathops.h"
 #include "ffv1.h"
 
@@ -130,7 +129,7 @@ const uint8_t ffv1_ver2_state[256] = {
 };
 
 
-int ffv1_common_init(AVCodecContext *avctx)
+av_cold int ffv1_common_init(AVCodecContext *avctx)
 {
     FFV1Context *s = avctx->priv_data;
 
@@ -140,10 +139,6 @@ int ffv1_common_init(AVCodecContext *avctx)
     if (!avctx->width || !avctx->height)
         return AVERROR_INVALIDDATA;
 
-    avcodec_get_frame_defaults(&s->picture);
-
-    ff_dsputil_init(&s->dsp, avctx);
-
     s->width  = avctx->width;
     s->height = avctx->height;
 
@@ -163,7 +158,7 @@ int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs)
     for (j = 0; j < f->plane_count; j++) {
         PlaneContext *const p = &fs->plane[j];
 
-        if (fs->ac) {
+        if (fs->ac != AC_GOLOMB_RICE) {
             if (!p->state)
                 p->state = av_malloc(CONTEXT_SIZE * p->context_count *
                                      sizeof(uint8_t));
@@ -177,7 +172,7 @@ int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs)
         }
     }
 
-    if (fs->ac > 1) {
+    if (fs->ac == AC_RANGE_CUSTOM_TAB) {
         //FIXME only redo if state_transition changed
         for (j = 1; j < 256; j++) {
             fs->c.one_state[j]        = f->state_transition[j];
@@ -190,18 +185,25 @@ int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs)
 
 av_cold int ffv1_init_slice_contexts(FFV1Context *f)
 {
-    int i;
+    int i, j;
 
     f->slice_count = f->num_h_slices * f->num_v_slices;
+    if (f->slice_count <= 0) {
+        av_log(f->avctx, AV_LOG_ERROR, "Invalid number of slices\n");
+        return AVERROR(EINVAL);
+    }
 
     for (i = 0; i < f->slice_count; i++) {
-        FFV1Context *fs = av_mallocz(sizeof(*fs));
         int sx          = i % f->num_h_slices;
         int sy          = i / f->num_h_slices;
         int sxs         = f->avctx->width  *  sx      / f->num_h_slices;
         int sxe         = f->avctx->width  * (sx + 1) / f->num_h_slices;
         int sys         = f->avctx->height *  sy      / f->num_v_slices;
         int sye         = f->avctx->height * (sy + 1) / f->num_v_slices;
+        FFV1Context *fs = av_mallocz(sizeof(*fs));
+        if (!fs)
+            goto memfail;
+
         f->slice_context[i] = fs;
         memcpy(fs, f, sizeof(*fs));
         memset(fs->rc_stat2, 0, sizeof(fs->rc_stat2));
@@ -213,10 +215,19 @@ av_cold int ffv1_init_slice_contexts(FFV1Context *f)
 
         fs->sample_buffer = av_malloc(3 * MAX_PLANES * (fs->width + 6) *
                                       sizeof(*fs->sample_buffer));
-        if (!fs->sample_buffer)
-            return AVERROR(ENOMEM);
+        if (!fs->sample_buffer) {
+            av_free(fs);
+            goto memfail;
+        }
     }
     return 0;
+
+memfail:
+    for (j = 0; j < i; j++) {
+        av_free(f->slice_context[j]->sample_buffer);
+        av_free(f->slice_context[j]);
+    }
+    return AVERROR(ENOMEM);
 }
 
 int ffv1_allocate_initial_states(FFV1Context *f)
@@ -244,7 +255,7 @@ void ffv1_clear_slice_state(FFV1Context *f, FFV1Context *fs)
         p->interlace_bit_state[0] = 128;
         p->interlace_bit_state[1] = 128;
 
-        if (fs->ac) {
+        if (fs->ac != AC_GOLOMB_RICE) {
             if (f->initial_states[p->quant_table_index]) {
                 memcpy(p->state, f->initial_states[p->quant_table_index],
                        CONTEXT_SIZE * p->context_count);
@@ -266,11 +277,6 @@ av_cold int ffv1_close(AVCodecContext *avctx)
     FFV1Context *s = avctx->priv_data;
     int i, j;
 
-    if (avctx->codec->decode && s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-    if (avctx->codec->decode && s->last_picture.data[0])
-        avctx->release_buffer(avctx, &s->last_picture);
-
     for (j = 0; j < s->slice_count; j++) {
         FFV1Context *fs = s->slice_context[j];
         for (i = 0; i < s->plane_count; i++) {