Merge commit '86bfcfcf2364bc837b7bb582c66a8a15a332414f'
[ffmpeg.git] / libavcodec / ffv1enc.c
index dd52329..2fe51c3 100644 (file)
@@ -33,7 +33,7 @@
 #include "libavutil/timer.h"
 #include "avcodec.h"
 #include "internal.h"
-#include "get_bits.h"
+#include "put_bits.h"
 #include "dsputil.h"
 #include "rangecoder.h"
 #include "golomb.h"
@@ -245,7 +245,7 @@ static inline void put_vlc_symbol(PutBitContext *pb, VlcState *const state,
         i += i;
     }
 
-    av_assert2(k<=13);
+    av_assert2(k <= 13);
 
 #if 0 // JPEG LS
     if (k == 0 && 2 * state->drift <= -state->count)
@@ -277,12 +277,12 @@ static av_always_inline int encode_line(FFV1Context *s, int w,
     if (s->ac) {
         if (c->bytestream_end - c->bytestream < w * 20) {
             av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     } else {
         if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) < w * 4) {
             av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
@@ -395,16 +395,18 @@ static void encode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h, int
     int x, y, p, i;
     const int ring_size = s->avctx->context_model ? 3 : 2;
     int16_t *sample[4][3];
-    int lbd    = s->avctx->bits_per_raw_sample <= 8;
-    int bits   = s->avctx->bits_per_raw_sample > 0 ? s->avctx->bits_per_raw_sample : 8;
+    int lbd    = s->bits_per_raw_sample <= 8;
+    int bits   = s->bits_per_raw_sample > 0 ? s->bits_per_raw_sample : 8;
     int offset = 1 << bits;
+
     s->run_index = 0;
 
-    memset(s->sample_buffer, 0, ring_size * 4 * (w + 6) * sizeof(*s->sample_buffer));
+    memset(s->sample_buffer, 0, ring_size * MAX_PLANES *
+                                (w + 6) * sizeof(*s->sample_buffer));
 
     for (y = 0; y < h; y++) {
         for (i = 0; i < ring_size; i++)
-            for (p = 0; p < 4; p++)
+            for (p = 0; p < MAX_PLANES; p++)
                 sample[p][i]= s->sample_buffer + p*ring_size*(w+6) + ((h+i-y)%ring_size)*(w+6) + 3;
 
         for (x = 0; x < w; x++) {
@@ -436,9 +438,9 @@ static void encode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h, int
             sample[p][0][-1] = sample[p][1][0  ];
             sample[p][1][ w] = sample[p][1][w-1];
             if (lbd)
-                encode_line(s, w, sample[p], (p+1)/2, 9);
+                encode_line(s, w, sample[p], (p + 1) / 2, 9);
             else
-                encode_line(s, w, sample[p], (p+1)/2, bits+1);
+                encode_line(s, w, sample[p], (p + 1) / 2, bits + 1);
         }
     }
 }
@@ -513,7 +515,7 @@ static void write_header(FFV1Context *f)
     }
 }
 
-static int write_extra_header(FFV1Context *f)
+static int write_extradata(FFV1Context *f)
 {
     RangeCoder *const c = &f->c;
     uint8_t state[CONTEXT_SIZE];
@@ -524,8 +526,9 @@ static int write_extra_header(FFV1Context *f)
     memset(state2, 128, sizeof(state2));
     memset(state, 128, sizeof(state));
 
-    f->avctx->extradata = av_malloc(f->avctx->extradata_size = 10000 +
-                                    (11 * 11 * 5 * 5 * 5 + 11 * 11 * 11) * 32);
+    f->avctx->extradata_size = 10000 + 4 +
+                                    (11 * 11 * 5 * 5 * 5 + 11 * 11 * 11) * 32;
+    f->avctx->extradata = av_malloc(f->avctx->extradata_size);
     ff_init_range_encoder(c, f->avctx->extradata, f->avctx->extradata_size);
     ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
 
@@ -535,10 +538,12 @@ static int write_extra_header(FFV1Context *f)
             f->minor_version = 2;
         put_symbol(c, state, f->minor_version, 0);
     }
+
     put_symbol(c, state, f->ac, 0);
     if (f->ac > 1)
         for (i = 1; i < 256; i++)
             put_symbol(c, state, f->state_transition[i] - c->one_state[i], 1);
+
     put_symbol(c, state, f->colorspace, 0); // YUV cs type
     put_symbol(c, state, f->bits_per_raw_sample, 0);
     put_rac(c, state, f->chroma_planes);
@@ -599,7 +604,7 @@ static int sort_stt(FFV1Context *s, uint8_t stt[256])
 
                 double size0 = COST2(i,  i) + COST2(i2, i2);
                 double sizeX = COST2(i, i2) + COST2(i2, i);
-                if (sizeX < size0 && i != 128 && i2 != 128) {
+                if (size0 - sizeX > size0*(1e-14) && i != 128 && i2 != 128) {
                     int j;
                     FFSWAP(int, stt[i], stt[i2]);
                     FFSWAP(int, s->rc_stat[i][0], s->rc_stat[i2][0]);
@@ -631,9 +636,9 @@ static int sort_stt(FFV1Context *s, uint8_t stt[256])
 
 static av_cold int encode_init(AVCodecContext *avctx)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
     FFV1Context *s = avctx->priv_data;
-    int i, j, k, m;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    int i, j, k, m, ret;
 
     ffv1_common_init(avctx);
 
@@ -689,7 +694,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
         }
         if (!s->ac) {
             av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample of more than 8 needs -coder 1 currently\n");
-            return AVERROR_INVALIDDATA;
+            return AVERROR(ENOSYS);
         }
         s->version = FFMAX(s->version, 1);
     case AV_PIX_FMT_GRAY8:
@@ -736,7 +741,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "format not supported\n");
-        return AVERROR_INVALIDDATA;
+        return AVERROR(ENOSYS);
     }
     if (s->transparency) {
         av_log(avctx, AV_LOG_WARNING, "Storing alpha plane, this will require a recent FFV1 decoder to playback!\n");
@@ -785,8 +790,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
         p->context_count     = s->context_count[p->quant_table_index];
     }
 
-    if (ffv1_allocate_initial_states(s) < 0)
-        return AVERROR(ENOMEM);
+    if ((ret = ffv1_allocate_initial_states(s)) < 0)
+        return ret;
 
     avctx->coded_frame = &s->picture;
     if (!s->transparency)
@@ -817,7 +822,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
                     if (next == p) {
                         av_log(avctx, AV_LOG_ERROR,
                                "2Pass file invalid at %d %d [%s]\n", j, i, p);
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                     p = next;
                 }
@@ -851,42 +856,59 @@ static av_cold int encode_init(AVCodecContext *avctx)
         find_best_state(best_state, s->state_transition);
 
         for (i = 0; i < s->quant_table_count; i++) {
-            for (j = 0; j < s->context_count[i]; j++)
-                for (k = 0; k < 32; k++) {
+            for (k = 0; k < 32; k++) {
+                double a=0, b=0;
+                int jp = 0;
+                for (j = 0; j < s->context_count[i]; j++) {
                     double p = 128;
-                    if (s->rc_stat2[i][j][k][0] + s->rc_stat2[i][j][k][1]) {
-                        p = 256.0 * s->rc_stat2[i][j][k][1] /
-                            (s->rc_stat2[i][j][k][0] + s->rc_stat2[i][j][k][1]);
+                    if (s->rc_stat2[i][j][k][0] + s->rc_stat2[i][j][k][1] > 200 && j || a+b > 200) {
+                        if (a+b)
+                            p = 256.0 * b / (a + b);
+                        s->initial_states[i][jp][k] =
+                            best_state[av_clip(round(p), 1, 255)][av_clip((a + b) / gob_count, 0, 255)];
+                        for(jp++; jp<j; jp++)
+                            s->initial_states[i][jp][k] = s->initial_states[i][jp-1][k];
+                        a=b=0;
+                    }
+                    a += s->rc_stat2[i][j][k][0];
+                    b += s->rc_stat2[i][j][k][1];
+                    if (a+b) {
+                        p = 256.0 * b / (a + b);
                     }
                     s->initial_states[i][j][k] =
-                        best_state[av_clip(round(p), 1, 255)][av_clip((s->rc_stat2[i][j][k][0] +
-                                                                       s->rc_stat2[i][j][k][1]) /
-                                                                      gob_count, 0, 255)];
+                        best_state[av_clip(round(p), 1, 255)][av_clip((a + b) / gob_count, 0, 255)];
                 }
+            }
         }
     }
 
     if (s->version > 1) {
-        for (s->num_v_slices = 2; s->num_v_slices < 9; s->num_v_slices++) {
+        s->num_v_slices = (avctx->width > 352 || avctx->height > 288 || !avctx->slices) ? 2 : 1;
+        for (; s->num_v_slices < 9; s->num_v_slices++) {
             for (s->num_h_slices = s->num_v_slices; s->num_h_slices < 2*s->num_v_slices; s->num_h_slices++) {
                 if (avctx->slices == s->num_h_slices * s->num_v_slices && avctx->slices <= 64 || !avctx->slices)
                     goto slices_ok;
             }
         }
-        av_log(avctx, AV_LOG_ERROR, "Unsupported number %d of slices requested, please specify a supported number with -slices (ex:4,6,9,12,16, ...)\n", avctx->slices);
-        return -1;
-        slices_ok:
-        write_extra_header(s);
+        av_log(avctx, AV_LOG_ERROR,
+               "Unsupported number %d of slices requested, please specify a "
+               "supported number with -slices (ex:4,6,9,12,16, ...)\n",
+               avctx->slices);
+        return AVERROR(ENOSYS);
+slices_ok:
+        write_extradata(s);
     }
 
-    if (ffv1_init_slice_contexts(s) < 0)
-        return -1;
-    if (ffv1_init_slices_state(s) < 0)
-        return -1;
+    if ((ret = ffv1_init_slice_contexts(s)) < 0)
+        return ret;
+    if ((ret = ffv1_init_slices_state(s)) < 0)
+        return ret;
 
 #define STATS_OUT_SIZE 1024 * 1024 * 6
     if (avctx->flags & CODEC_FLAG_PASS1) {
         avctx->stats_out = av_mallocz(STATS_OUT_SIZE);
+        if (!avctx->stats_out)
+            return AVERROR(ENOMEM);
         for (i = 0; i < s->quant_table_count; i++)
             for (j = 0; j < s->slice_count; j++) {
                 FFV1Context *sf = s->slice_context[j];
@@ -916,8 +938,10 @@ static void encode_slice_header(FFV1Context *f, FFV1Context *fs)
         put_symbol(c, state, f->plane[j].quant_table_index, 0);
         av_assert0(f->plane[j].quant_table_index == f->avctx->context_model);
     }
-    if (!f->picture.interlaced_frame) put_symbol(c, state, 3, 0);
-    else                             put_symbol(c, state, 1 + !f->picture.top_field_first, 0);
+    if (!f->picture.interlaced_frame)
+        put_symbol(c, state, 3, 0);
+    else
+        put_symbol(c, state, 1 + !f->picture.top_field_first, 0);
     put_symbol(c, state, f->picture.sample_aspect_ratio.num, 0);
     put_symbol(c, state, f->picture.sample_aspect_ratio.den, 0);
 }
@@ -940,9 +964,11 @@ static int encode_slice(AVCodecContext *c, void *arg)
     }
     if (!fs->ac) {
         if (f->version > 2)
-            put_rac(&fs->c, (uint8_t[]) {129}, 0);
-        fs->ac_byte_count = f->version > 2 || (!x&&!y) ? ff_rac_terminate(&fs->c) : 0;
-        init_put_bits(&fs->pb, fs->c.bytestream_start + fs->ac_byte_count, fs->c.bytestream_end - fs->c.bytestream_start - fs->ac_byte_count);
+            put_rac(&fs->c, (uint8_t[]) { 129 }, 0);
+        fs->ac_byte_count = f->version > 2 || (!x && !y) ? ff_rac_terminate(&fs->c) : 0;
+        init_put_bits(&fs->pb,
+                      fs->c.bytestream_start + fs->ac_byte_count,
+                      fs->c.bytestream_end - fs->c.bytestream_start - fs->ac_byte_count);
     }
 
     if (f->colorspace == 0) {
@@ -1024,12 +1050,12 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         int bytes;
 
         if (fs->ac) {
-            uint8_t state=129;
+            uint8_t state = 129;
             put_rac(&fs->c, &state, 0);
             bytes = ff_rac_terminate(&fs->c);
         } else {
             flush_put_bits(&fs->pb); // FIXME: nicer padding
-            bytes = fs->ac_byte_count + (put_bits_count(&fs->pb) + 7)/8;
+            bytes = fs->ac_byte_count + (put_bits_count(&fs->pb) + 7) / 8;
         }
         if (i > 0 || f->version > 2) {
             av_assert0(bytes < pkt->size / f->slice_count);
@@ -1042,7 +1068,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
             unsigned v;
             buf_p[bytes++] = 0;
             v = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, buf_p, bytes);
-            AV_WL32(buf_p + bytes, v); bytes += 4;
+            AV_WL32(buf_p + bytes, v);
+            bytes += 4;
         }
         buf_p += bytes;
     }
@@ -1101,8 +1128,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 #define OFFSET(x) offsetof(FFV1Context, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "slicecrc",        "Protect slices with CRCs",               OFFSET(ec),              AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE},
-{NULL}
+    { "slicecrc", "Protect slices with CRCs", OFFSET(ec), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE },
+    { NULL }
 };
 
 static const AVClass class = {
@@ -1113,7 +1140,7 @@ static const AVClass class = {
 };
 
 static const AVCodecDefault ffv1_defaults[] = {
-    { "coder",                "-1" },
+    { "coder", "-1" },
     { NULL },
 };
 
@@ -1124,19 +1151,20 @@ AVCodec ff_ffv1_encoder = {
     .priv_data_size = sizeof(FFV1Context),
     .init           = encode_init,
     .encode2        = encode_frame,
-    .close          = ffv1_common_end,
+    .close          = ffv1_close,
     .capabilities   = CODEC_CAP_SLICE_THREADS,
-    .defaults       = ffv1_defaults,
     .pix_fmts       = (const enum AVPixelFormat[]) {
-        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV444P,
-        AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P,
-        AV_PIX_FMT_YUV410P, AV_PIX_FMT_0RGB32, AV_PIX_FMT_RGB32, AV_PIX_FMT_YUV420P16,
-        AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV422P9,
-        AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
-        AV_PIX_FMT_GRAY16, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10,
-        AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14,
+        AV_PIX_FMT_YUV420P,   AV_PIX_FMT_YUVA420P,  AV_PIX_FMT_YUVA422P,  AV_PIX_FMT_YUV444P,
+        AV_PIX_FMT_YUVA444P,  AV_PIX_FMT_YUV440P,   AV_PIX_FMT_YUV422P,   AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_YUV410P,   AV_PIX_FMT_0RGB32,    AV_PIX_FMT_RGB32,     AV_PIX_FMT_YUV420P16,
+        AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUV444P9,  AV_PIX_FMT_YUV422P9,
+        AV_PIX_FMT_YUV420P9,  AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
+        AV_PIX_FMT_GRAY16,    AV_PIX_FMT_GRAY8,     AV_PIX_FMT_GBRP9,     AV_PIX_FMT_GBRP10,
+        AV_PIX_FMT_GBRP12,    AV_PIX_FMT_GBRP14,
         AV_PIX_FMT_NONE
+
     },
     .long_name      = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
+    .defaults       = ffv1_defaults,
     .priv_class     = &class,
 };