Browse code

ffv1enc: store 2pass statistics at the end

This reduces their size from O(n) to O(1)

Fixes Ticket3078

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2013/11/03 06:27:32
Showing 1 changed files
... ...
@@ -1068,6 +1068,51 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
1068 1068
     int64_t maxsize =   FF_MIN_BUFFER_SIZE
1069 1069
                       + avctx->width*avctx->height*35LL*4;
1070 1070
 
1071
+    if(!pict) {
1072
+        if (avctx->flags & CODEC_FLAG_PASS1) {
1073
+            int j, k, m;
1074
+            char *p   = avctx->stats_out;
1075
+            char *end = p + STATS_OUT_SIZE;
1076
+
1077
+            memset(f->rc_stat, 0, sizeof(f->rc_stat));
1078
+            for (i = 0; i < f->quant_table_count; i++)
1079
+                memset(f->rc_stat2[i], 0, f->context_count[i] * sizeof(*f->rc_stat2[i]));
1080
+
1081
+            for (j = 0; j < f->slice_count; j++) {
1082
+                FFV1Context *fs = f->slice_context[j];
1083
+                for (i = 0; i < 256; i++) {
1084
+                    f->rc_stat[i][0] += fs->rc_stat[i][0];
1085
+                    f->rc_stat[i][1] += fs->rc_stat[i][1];
1086
+                }
1087
+                for (i = 0; i < f->quant_table_count; i++) {
1088
+                    for (k = 0; k < f->context_count[i]; k++)
1089
+                        for (m = 0; m < 32; m++) {
1090
+                            f->rc_stat2[i][k][m][0] += fs->rc_stat2[i][k][m][0];
1091
+                            f->rc_stat2[i][k][m][1] += fs->rc_stat2[i][k][m][1];
1092
+                        }
1093
+                }
1094
+            }
1095
+
1096
+            for (j = 0; j < 256; j++) {
1097
+                snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ",
1098
+                        f->rc_stat[j][0], f->rc_stat[j][1]);
1099
+                p += strlen(p);
1100
+            }
1101
+            snprintf(p, end - p, "\n");
1102
+
1103
+            for (i = 0; i < f->quant_table_count; i++) {
1104
+                for (j = 0; j < f->context_count[i]; j++)
1105
+                    for (m = 0; m < 32; m++) {
1106
+                        snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ",
1107
+                                f->rc_stat2[i][j][m][0], f->rc_stat2[i][j][m][1]);
1108
+                        p += strlen(p);
1109
+                    }
1110
+            }
1111
+            snprintf(p, end - p, "%d\n", f->gob_count);
1112
+        }
1113
+        return 0;
1114
+    }
1115
+
1071 1116
     if (f->version > 3)
1072 1117
         maxsize = FF_MIN_BUFFER_SIZE + avctx->width*avctx->height*3LL*4;
1073 1118
 
... ...
@@ -1139,47 +1184,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
1139 1139
         buf_p += bytes;
1140 1140
     }
1141 1141
 
1142
-    if ((avctx->flags & CODEC_FLAG_PASS1) && (f->picture_number & 31) == 0) {
1143
-        int j, k, m;
1144
-        char *p   = avctx->stats_out;
1145
-        char *end = p + STATS_OUT_SIZE;
1146
-
1147
-        memset(f->rc_stat, 0, sizeof(f->rc_stat));
1148
-        for (i = 0; i < f->quant_table_count; i++)
1149
-            memset(f->rc_stat2[i], 0, f->context_count[i] * sizeof(*f->rc_stat2[i]));
1150
-
1151
-        for (j = 0; j < f->slice_count; j++) {
1152
-            FFV1Context *fs = f->slice_context[j];
1153
-            for (i = 0; i < 256; i++) {
1154
-                f->rc_stat[i][0] += fs->rc_stat[i][0];
1155
-                f->rc_stat[i][1] += fs->rc_stat[i][1];
1156
-            }
1157
-            for (i = 0; i < f->quant_table_count; i++) {
1158
-                for (k = 0; k < f->context_count[i]; k++)
1159
-                    for (m = 0; m < 32; m++) {
1160
-                        f->rc_stat2[i][k][m][0] += fs->rc_stat2[i][k][m][0];
1161
-                        f->rc_stat2[i][k][m][1] += fs->rc_stat2[i][k][m][1];
1162
-                    }
1163
-            }
1164
-        }
1165
-
1166
-        for (j = 0; j < 256; j++) {
1167
-            snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ",
1168
-                     f->rc_stat[j][0], f->rc_stat[j][1]);
1169
-            p += strlen(p);
1170
-        }
1171
-        snprintf(p, end - p, "\n");
1172
-
1173
-        for (i = 0; i < f->quant_table_count; i++) {
1174
-            for (j = 0; j < f->context_count[i]; j++)
1175
-                for (m = 0; m < 32; m++) {
1176
-                    snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ",
1177
-                             f->rc_stat2[i][j][m][0], f->rc_stat2[i][j][m][1]);
1178
-                    p += strlen(p);
1179
-                }
1180
-        }
1181
-        snprintf(p, end - p, "%d\n", f->gob_count);
1182
-    } else if (avctx->flags & CODEC_FLAG_PASS1)
1142
+    if (avctx->flags & CODEC_FLAG_PASS1)
1183 1143
         avctx->stats_out[0] = '\0';
1184 1144
 
1185 1145
     f->picture_number++;
... ...
@@ -1220,7 +1225,7 @@ AVCodec ff_ffv1_encoder = {
1220 1220
     .init           = encode_init,
1221 1221
     .encode2        = encode_frame,
1222 1222
     .close          = ffv1_close,
1223
-    .capabilities   = CODEC_CAP_SLICE_THREADS,
1223
+    .capabilities   = CODEC_CAP_SLICE_THREADS | CODEC_CAP_DELAY,
1224 1224
     .pix_fmts       = (const enum AVPixelFormat[]) {
1225 1225
         AV_PIX_FMT_YUV420P,   AV_PIX_FMT_YUVA420P,  AV_PIX_FMT_YUVA422P,  AV_PIX_FMT_YUV444P,
1226 1226
         AV_PIX_FMT_YUVA444P,  AV_PIX_FMT_YUV440P,   AV_PIX_FMT_YUV422P,   AV_PIX_FMT_YUV411P,