avcodec/cinepakenc: fixes and improvements
[ffmpeg.git] / libavcodec / cinepakenc.c
1 /*
2  * Cinepak encoder (c) 2011 Tomas Härdin
3  * http://titan.codemill.se/~tomhar/cinepakenc.patch
4  *
5  * Fixes and improvements, vintage decoders compatibility
6  *  (c) 2013, 2014 Rl, Aetey Global Technologies AB
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 and/or sell copies of the Software, and to permit persons to whom the
13 Software is furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 OTHER DEALINGS IN THE SOFTWARE.
25
26  * TODO:
27  * - optimize: color space conversion, ...
28  * - implement options to set the min/max number of strips?
29  * MAYBE:
30  * - "optimally" split the frame into several non-regular areas
31  *   using a separate codebook pair for each area and approximating
32  *   the area by several rectangular strips (generally not full width ones)
33  *   (use quadtree splitting? a simple fixed-granularity grid?)
34  *
35  *
36  * version 2014-01-21 Rl
37  * - believe it or not, now we get even smaller files, with better quality
38  *   (which means I missed an optimization earlier :)
39  *
40  * version 2014-01-20 Rl
41  * - made the encoder compatible with vintage decoders
42  *   and added some yet unused code for possible future
43  *   incremental codebook updates
44  * - fixed a small memory leak
45  *
46  * version 2013-04-28 Rl
47  * - bugfixed codebook optimization logic
48  *
49  * version 2013-02-14 Rl
50  * "Valentine's Day" version:
51  * - made strip division more robust
52  * - minimized bruteforcing the number of strips,
53  *   (costs some R/D but speeds up compession a lot), the heuristic
54  *   assumption is that score as a function of the number of strips has
55  *   one wide minimum which moves slowly, of course not fully true
56  * - simplified codebook generation,
57  *   the old code was meant for other optimizations than we actually do
58  * - optimized the codebook generation / error estimation for MODE_MC
59  *
60  * version 2013-02-12 Rl
61  * - separated codebook training sets, avoided the transfer of wasted bytes,
62  *   which yields both better quality and smaller files
63  * - now using the correct colorspace (TODO: move conversion to libswscale)
64  *
65  * version 2013-02-08 Rl
66  * - fixes/optimization in multistrip encoding and codebook size choice,
67  *   quality/bitrate is now better than that of the binary proprietary encoder
68  */
69
70 #include "libavutil/intreadwrite.h"
71 #include "avcodec.h"
72 #include "libavutil/lfg.h"
73 #include "elbg.h"
74 #include "internal.h"
75
76 #include "libavutil/avassert.h"
77
78 #define CVID_HEADER_SIZE 10
79 #define STRIP_HEADER_SIZE 12
80 #define CHUNK_HEADER_SIZE 4
81
82 #define MB_SIZE 4           //4x4 MBs
83 #define MB_AREA (MB_SIZE*MB_SIZE)
84
85 #define VECTOR_MAX 6        //six or four entries per vector depending on format
86 #define CODEBOOK_MAX 256    //size of a codebook
87
88 //#define MAX_STRIPS  32      //Note: having fewer choices regarding the number of strips speeds up encoding (obviously)
89 #define MAX_STRIPS  3       // This seems to be max for vintage players! -- rl
90 // TODO: we might want to have a "vintage compatibilty" switch
91 #define MIN_STRIPS  1       //Note: having more strips speeds up encoding the frame (this is less obvious)
92 // MAX_STRIPS limits the maximum quality you can reach
93 //            when you want hight quality on high resolutions,
94 // MIN_STRIPS limits the minimum efficiently encodable bit rate
95 //            on low resolutions
96 // the numbers are only used for brute force optimization for the first frame,
97 // for the following frames they are adaptively readjusted
98 // NOTE the decoder in ffmpeg has its own arbitrary limitation on the number
99 // of strips, currently 32
100
101 typedef enum {
102     MODE_V1_ONLY = 0,
103     MODE_V1_V4,
104     MODE_MC,
105
106     MODE_COUNT,
107 } CinepakMode;
108
109 typedef enum {
110     ENC_V1,
111     ENC_V4,
112     ENC_SKIP,
113
114     ENC_UNCERTAIN
115 } mb_encoding;
116
117 typedef struct {
118     int v1_vector;                  //index into v1 codebook
119     int v1_error;                   //error when using V1 encoding
120     int v4_vector[4];               //indices into v4 codebooks
121     int v4_error;                   //error when using V4 encoding
122     int skip_error;                 //error when block is skipped (aka copied from last frame)
123     mb_encoding best_encoding;      //last result from calculate_mode_score()
124 } mb_info;
125
126 typedef struct {
127     int v1_codebook[CODEBOOK_MAX*VECTOR_MAX];
128     int v4_codebook[CODEBOOK_MAX*VECTOR_MAX];
129     int v1_size;
130     int v4_size;
131     CinepakMode mode;
132 } strip_info;
133
134 typedef struct {
135     AVCodecContext *avctx;
136     unsigned char *pict_bufs[4], *strip_buf, *frame_buf;
137     AVFrame *last_frame;
138     AVFrame *best_frame;
139     AVFrame *scratch_frame;
140     AVFrame *input_frame;
141     enum AVPixelFormat pix_fmt;
142     int w, h;
143     int frame_buf_size;
144     int curframe, keyint;
145     AVLFG randctx;
146     uint64_t lambda;
147     int *codebook_input;
148     int *codebook_closest;
149     mb_info *mb;                                //MB RD state
150     int min_strips;          //the current limit
151     int max_strips;          //the current limit
152 #ifdef CINEPAKENC_DEBUG
153     mb_info *best_mb;                           //TODO: remove. only used for printing stats
154     int num_v1_mode, num_v4_mode, num_mc_mode;
155     int num_v1_encs, num_v4_encs, num_skips;
156 #endif
157 } CinepakEncContext;
158
159 static av_cold int cinepak_encode_init(AVCodecContext *avctx)
160 {
161     CinepakEncContext *s = avctx->priv_data;
162     int x, mb_count, strip_buf_size, frame_buf_size;
163
164     if (avctx->width & 3 || avctx->height & 3) {
165         av_log(avctx, AV_LOG_ERROR, "width and height must be multiples of four (got %ix%i)\n",
166                 avctx->width, avctx->height);
167         return AVERROR(EINVAL);
168     }
169
170     if (!(s->last_frame = av_frame_alloc()))
171         return AVERROR(ENOMEM);
172     if (!(s->best_frame = av_frame_alloc()))
173         goto enomem;
174     if (!(s->scratch_frame = av_frame_alloc()))
175         goto enomem;
176     if (avctx->pix_fmt == AV_PIX_FMT_RGB24)
177         if (!(s->input_frame = av_frame_alloc()))
178             goto enomem;
179
180     if (!(s->codebook_input = av_malloc(sizeof(int) * (avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4) * (avctx->width * avctx->height) >> 2)))
181         goto enomem;
182
183     if (!(s->codebook_closest = av_malloc(sizeof(int) * (avctx->width * avctx->height) >> 2)))
184         goto enomem;
185
186     for(x = 0; x < (avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 4 : 3); x++)
187         if(!(s->pict_bufs[x] = av_malloc((avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4) * (avctx->width * avctx->height) >> 2)))
188             goto enomem;
189
190     mb_count = avctx->width * avctx->height / MB_AREA;
191
192     //the largest possible chunk is 0x31 with all MBs encoded in V4 mode
193     //and full codebooks being replaced in INTER mode,
194     // which is 34 bits per MB
195     //and 2*256 extra flag bits per strip
196     strip_buf_size = STRIP_HEADER_SIZE + 3 * CHUNK_HEADER_SIZE + 2 * VECTOR_MAX * CODEBOOK_MAX + 4 * (mb_count + (mb_count + 15) / 16) + (2 * CODEBOOK_MAX)/8;
197
198     frame_buf_size = CVID_HEADER_SIZE + MAX_STRIPS * strip_buf_size;
199
200     if (!(s->strip_buf = av_malloc(strip_buf_size)))
201         goto enomem;
202
203     if (!(s->frame_buf = av_malloc(frame_buf_size)))
204         goto enomem;
205
206     if (!(s->mb = av_malloc(mb_count*sizeof(mb_info))))
207         goto enomem;
208
209 #ifdef CINEPAKENC_DEBUG
210     if (!(s->best_mb = av_malloc(mb_count*sizeof(mb_info))))
211         goto enomem;
212 #endif
213
214     av_lfg_init(&s->randctx, 1);
215     s->avctx = avctx;
216     s->w = avctx->width;
217     s->h = avctx->height;
218     s->frame_buf_size = frame_buf_size;
219     s->curframe = 0;
220     s->keyint = avctx->keyint_min;
221     s->pix_fmt = avctx->pix_fmt;
222
223     //set up AVFrames
224     s->last_frame->data[0]        = s->pict_bufs[0];
225     s->last_frame->linesize[0]    = s->w;
226     s->best_frame->data[0]        = s->pict_bufs[1];
227     s->best_frame->linesize[0]    = s->w;
228     s->scratch_frame->data[0]     = s->pict_bufs[2];
229     s->scratch_frame->linesize[0] = s->w;
230
231     if (s->pix_fmt == AV_PIX_FMT_RGB24) {
232         s->last_frame->data[1]        = s->last_frame->data[0] + s->w * s->h;
233         s->last_frame->data[2]        = s->last_frame->data[1] + ((s->w * s->h) >> 2);
234         s->last_frame->linesize[1]    = s->last_frame->linesize[2] = s->w >> 1;
235
236         s->best_frame->data[1]        = s->best_frame->data[0] + s->w * s->h;
237         s->best_frame->data[2]        = s->best_frame->data[1] + ((s->w * s->h) >> 2);
238         s->best_frame->linesize[1]    = s->best_frame->linesize[2] = s->w >> 1;
239
240         s->scratch_frame->data[1]     = s->scratch_frame->data[0] + s->w * s->h;
241         s->scratch_frame->data[2]     = s->scratch_frame->data[1] + ((s->w * s->h) >> 2);
242         s->scratch_frame->linesize[1] = s->scratch_frame->linesize[2] = s->w >> 1;
243
244         s->input_frame->data[0]       = s->pict_bufs[3];
245         s->input_frame->linesize[0]   = s->w;
246         s->input_frame->data[1]       = s->input_frame->data[0] + s->w * s->h;
247         s->input_frame->data[2]       = s->input_frame->data[1] + ((s->w * s->h) >> 2);
248         s->input_frame->linesize[1]   = s->input_frame->linesize[2] = s->w >> 1;
249     }
250
251     s->min_strips = MIN_STRIPS;
252     s->max_strips = MAX_STRIPS;
253
254 #ifdef CINEPAKENC_DEBUG
255     s->num_v1_mode = s->num_v4_mode = s->num_mc_mode = s->num_v1_encs = s->num_v4_encs = s->num_skips = 0;
256 #endif
257
258     return 0;
259
260 enomem:
261     av_frame_free(&s->last_frame);
262     av_frame_free(&s->best_frame);
263     av_frame_free(&s->scratch_frame);
264     if (avctx->pix_fmt == AV_PIX_FMT_RGB24)
265         av_frame_free(&s->input_frame);
266     av_freep(&s->codebook_input);
267     av_freep(&s->codebook_closest);
268     av_freep(&s->strip_buf);
269     av_freep(&s->frame_buf);
270     av_freep(&s->mb);
271 #ifdef CINEPAKENC_DEBUG
272     av_freep(&s->best_mb);
273 #endif
274
275     for(x = 0; x < (avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 4 : 3); x++)
276         av_freep(&s->pict_bufs[x]);
277
278     return AVERROR(ENOMEM);
279 }
280
281 static int64_t calculate_mode_score(CinepakEncContext *s, int h, strip_info *info, int report, int *training_set_v1_shrunk, int *training_set_v4_shrunk
282 #ifdef CINEPAK_REPORT_SERR
283 , int64_t *serr
284 #endif
285 )
286 {
287     //score = FF_LAMBDA_SCALE * error + lambda * bits
288     int x;
289     int entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
290     int mb_count = s->w * h / MB_AREA;
291     mb_info *mb;
292     int64_t score1, score2, score3;
293     int64_t ret = s->lambda * ((info->v1_size ? CHUNK_HEADER_SIZE + info->v1_size * entry_size : 0) +
294                    (info->v4_size ? CHUNK_HEADER_SIZE + info->v4_size * entry_size : 0) +
295                    CHUNK_HEADER_SIZE) << 3;
296
297     //av_log(s->avctx, AV_LOG_INFO, "sizes %3i %3i -> %9lli score mb_count %i", info->v1_size, info->v4_size, (long long int)ret, mb_count);
298
299 #ifdef CINEPAK_REPORT_SERR
300     *serr = 0;
301 #endif
302
303     switch(info->mode) {
304     case MODE_V1_ONLY:
305         //one byte per MB
306         ret += s->lambda * 8 * mb_count;
307
308 // while calculating we assume all blocks are ENC_V1
309         for(x = 0; x < mb_count; x++) {
310             mb = &s->mb[x];
311             ret += FF_LAMBDA_SCALE * mb->v1_error;
312 #ifdef CINEPAK_REPORT_SERR
313             *serr += mb->v1_error;
314 #endif
315 // this function is never called for report in MODE_V1_ONLY
316 //            if(!report)
317             mb->best_encoding = ENC_V1;
318         }
319
320         break;
321     case MODE_V1_V4:
322         //9 or 33 bits per MB
323         if(report) {
324 // no moves between the corresponding training sets are allowed
325             *training_set_v1_shrunk = *training_set_v4_shrunk = 0;
326             for(x = 0; x < mb_count; x++) {
327                 int mberr;
328                 mb = &s->mb[x];
329                 if(mb->best_encoding == ENC_V1)
330                     score1 = s->lambda * 9  + FF_LAMBDA_SCALE * (mberr=mb->v1_error);
331                 else
332                     score1 = s->lambda * 33 + FF_LAMBDA_SCALE * (mberr=mb->v4_error);
333                 ret += score1;
334 #ifdef CINEPAK_REPORT_SERR
335                 *serr += mberr;
336 #endif
337             }
338         } else { // find best mode per block
339             for(x = 0; x < mb_count; x++) {
340                 mb = &s->mb[x];
341                 score1 = s->lambda * 9  + FF_LAMBDA_SCALE * mb->v1_error;
342                 score2 = s->lambda * 33 + FF_LAMBDA_SCALE * mb->v4_error;
343
344                 if(score1 <= score2) {
345                     ret += score1;
346 #ifdef CINEPAK_REPORT_SERR
347                     *serr += mb->v1_error;
348 #endif
349                     mb->best_encoding = ENC_V1;
350                 } else {
351                     ret += score2;
352 #ifdef CINEPAK_REPORT_SERR
353                     *serr += mb->v4_error;
354 #endif
355                     mb->best_encoding = ENC_V4;
356                 }
357             }
358         }
359
360         break;
361     case MODE_MC:
362         //1, 10 or 34 bits per MB
363         if(report) {
364             int v1_shrunk = 0, v4_shrunk = 0;
365             for(x = 0; x < mb_count; x++) {
366                 mb = &s->mb[x];
367 // it is OK to move blocks to ENC_SKIP here
368 // but not to any codebook encoding!
369                 score1 = s->lambda * 1  + FF_LAMBDA_SCALE * mb->skip_error;
370                 if(mb->best_encoding == ENC_SKIP) {
371                     ret += score1;
372 #ifdef CINEPAK_REPORT_SERR
373                     *serr += mb->skip_error;
374 #endif
375                 } else if(mb->best_encoding == ENC_V1) {
376                     if((score2=s->lambda * 10 + FF_LAMBDA_SCALE * mb->v1_error) >= score1) {
377                         mb->best_encoding = ENC_SKIP;
378                         ++v1_shrunk;
379                         ret += score1;
380 #ifdef CINEPAK_REPORT_SERR
381                         *serr += mb->skip_error;
382 #endif
383                     } else {
384                         ret += score2;
385 #ifdef CINEPAK_REPORT_SERR
386                         *serr += mb->v1_error;
387 #endif
388                     }
389                 } else {
390                     if((score3=s->lambda * 34 + FF_LAMBDA_SCALE * mb->v4_error) >= score1) {
391                         mb->best_encoding = ENC_SKIP;
392                         ++v4_shrunk;
393                         ret += score1;
394 #ifdef CINEPAK_REPORT_SERR
395                         *serr += mb->skip_error;
396 #endif
397                     } else {
398                         ret += score3;
399 #ifdef CINEPAK_REPORT_SERR
400                         *serr += mb->v4_error;
401 #endif
402                     }
403                 }
404             }
405             *training_set_v1_shrunk = v1_shrunk;
406             *training_set_v4_shrunk = v4_shrunk;
407         } else { // find best mode per block
408             for(x = 0; x < mb_count; x++) {
409                 mb = &s->mb[x];
410                 score1 = s->lambda * 1  + FF_LAMBDA_SCALE * mb->skip_error;
411                 score2 = s->lambda * 10 + FF_LAMBDA_SCALE * mb->v1_error;
412                 score3 = s->lambda * 34 + FF_LAMBDA_SCALE * mb->v4_error;
413
414                 if(score1 <= score2 && score1 <= score3) {
415                     ret += score1;
416 #ifdef CINEPAK_REPORT_SERR
417                     *serr += mb->skip_error;
418 #endif
419                     mb->best_encoding = ENC_SKIP;
420                 } else if(score2 <= score3) {
421                     ret += score2;
422 #ifdef CINEPAK_REPORT_SERR
423                     *serr += mb->v1_error;
424 #endif
425                     mb->best_encoding = ENC_V1;
426                 } else {
427                     ret += score3;
428 #ifdef CINEPAK_REPORT_SERR
429                     *serr += mb->v4_error;
430 #endif
431                     mb->best_encoding = ENC_V4;
432                 }
433             }
434         }
435
436         break;
437     }
438
439     return ret;
440 }
441
442 static int write_chunk_header(unsigned char *buf, int chunk_type, int chunk_size)
443 {
444     buf[0] = chunk_type;
445     AV_WB24(&buf[1], chunk_size + CHUNK_HEADER_SIZE);
446     return CHUNK_HEADER_SIZE;
447 }
448
449 static int encode_codebook(CinepakEncContext *s, int *codebook, int size, int chunk_type_yuv, int chunk_type_gray, unsigned char *buf)
450 {
451     int x, y, ret, entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
452     int incremental_codebook_replacement_mode = 0; // hardcoded here,
453                 // the compiler should notice that this is a constant -- rl
454
455     ret = write_chunk_header(buf,
456           s->pix_fmt == AV_PIX_FMT_RGB24 ?
457            chunk_type_yuv+(incremental_codebook_replacement_mode?1:0) :
458            chunk_type_gray+(incremental_codebook_replacement_mode?1:0),
459           entry_size * size
460            + (incremental_codebook_replacement_mode?(size+31)/32*4:0) );
461
462 // we do codebook encoding according to the "intra" mode
463 // but we keep the "dead" code for reference in case we will want
464 // to use incremental codebook updates (which actually would give us
465 // "kind of" motion compensation, especially in 1 strip/frame case) -- rl
466 // (of course, the code will be not useful as-is)
467     if(incremental_codebook_replacement_mode) {
468         int flags = 0;
469         int flagsind;
470         for(x = 0; x < size; x++) {
471             if(flags == 0) {
472                 flagsind = ret;
473                 ret += 4;
474                 flags = 0x80000000;
475             } else
476                 flags = ((flags>>1) | 0x80000000);
477             for(y = 0; y < entry_size; y++)
478                 buf[ret++] = codebook[y + x*entry_size] ^ (y >= 4 ? 0x80 : 0);
479             if((flags&0xffffffff) == 0xffffffff) {
480                 AV_WB32(&buf[flagsind], flags);
481                 flags = 0;
482             }
483         }
484         if(flags)
485             AV_WB32(&buf[flagsind], flags);
486     } else
487         for(x = 0; x < size; x++)
488             for(y = 0; y < entry_size; y++)
489                 buf[ret++] = codebook[y + x*entry_size] ^ (y >= 4 ? 0x80 : 0);
490
491     return ret;
492 }
493
494 //sets out to the sub picture starting at (x,y) in in
495 static void get_sub_picture(CinepakEncContext *s, int x, int y, AVPicture *in, AVPicture *out)
496 {
497     out->data[0] = in->data[0] + x + y * in->linesize[0];
498     out->linesize[0] = in->linesize[0];
499
500     if(s->pix_fmt == AV_PIX_FMT_RGB24) {
501         out->data[1] = in->data[1] + (x >> 1) + (y >> 1) * in->linesize[1];
502         out->linesize[1] = in->linesize[1];
503
504         out->data[2] = in->data[2] + (x >> 1) + (y >> 1) * in->linesize[2];
505         out->linesize[2] = in->linesize[2];
506     }
507 }
508
509 //decodes the V1 vector in mb into the 4x4 MB pointed to by sub_pict
510 static void decode_v1_vector(CinepakEncContext *s, AVPicture *sub_pict, int v1_vector, strip_info *info)
511 {
512     int entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
513
514     sub_pict->data[0][0] =
515             sub_pict->data[0][1] =
516             sub_pict->data[0][    sub_pict->linesize[0]] =
517             sub_pict->data[0][1+  sub_pict->linesize[0]] = info->v1_codebook[v1_vector*entry_size];
518
519     sub_pict->data[0][2] =
520             sub_pict->data[0][3] =
521             sub_pict->data[0][2+  sub_pict->linesize[0]] =
522             sub_pict->data[0][3+  sub_pict->linesize[0]] = info->v1_codebook[v1_vector*entry_size+1];
523
524     sub_pict->data[0][2*sub_pict->linesize[0]] =
525             sub_pict->data[0][1+2*sub_pict->linesize[0]] =
526             sub_pict->data[0][  3*sub_pict->linesize[0]] =
527             sub_pict->data[0][1+3*sub_pict->linesize[0]] = info->v1_codebook[v1_vector*entry_size+2];
528
529     sub_pict->data[0][2+2*sub_pict->linesize[0]] =
530             sub_pict->data[0][3+2*sub_pict->linesize[0]] =
531             sub_pict->data[0][2+3*sub_pict->linesize[0]] =
532             sub_pict->data[0][3+3*sub_pict->linesize[0]] = info->v1_codebook[v1_vector*entry_size+3];
533
534     if(s->pix_fmt == AV_PIX_FMT_RGB24) {
535         sub_pict->data[1][0] =
536             sub_pict->data[1][1] =
537             sub_pict->data[1][    sub_pict->linesize[1]] =
538             sub_pict->data[1][1+  sub_pict->linesize[1]] = info->v1_codebook[v1_vector*entry_size+4];
539
540         sub_pict->data[2][0] =
541             sub_pict->data[2][1] =
542             sub_pict->data[2][    sub_pict->linesize[2]] =
543             sub_pict->data[2][1+  sub_pict->linesize[2]] = info->v1_codebook[v1_vector*entry_size+5];
544     }
545 }
546
547 //decodes the V4 vectors in mb into the 4x4 MB pointed to by sub_pict
548 static void decode_v4_vector(CinepakEncContext *s, AVPicture *sub_pict, int *v4_vector, strip_info *info)
549 {
550     int i, x, y, entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
551
552     for(i = y = 0; y < 4; y += 2) {
553         for(x = 0; x < 4; x += 2, i++) {
554             sub_pict->data[0][x   +     y*sub_pict->linesize[0]] = info->v4_codebook[v4_vector[i]*entry_size];
555             sub_pict->data[0][x+1 +     y*sub_pict->linesize[0]] = info->v4_codebook[v4_vector[i]*entry_size+1];
556             sub_pict->data[0][x   + (y+1)*sub_pict->linesize[0]] = info->v4_codebook[v4_vector[i]*entry_size+2];
557             sub_pict->data[0][x+1 + (y+1)*sub_pict->linesize[0]] = info->v4_codebook[v4_vector[i]*entry_size+3];
558
559             if(s->pix_fmt == AV_PIX_FMT_RGB24) {
560                 sub_pict->data[1][(x>>1) + (y>>1)*sub_pict->linesize[1]] = info->v4_codebook[v4_vector[i]*entry_size+4];
561                 sub_pict->data[2][(x>>1) + (y>>1)*sub_pict->linesize[2]] = info->v4_codebook[v4_vector[i]*entry_size+5];
562             }
563         }
564     }
565 }
566
567 static void copy_mb(CinepakEncContext *s, AVPicture *a, AVPicture *b)
568 {
569     int y, p;
570
571     for(y = 0; y < MB_SIZE; y++) {
572         memcpy(a->data[0]+y*a->linesize[0], b->data[0]+y*b->linesize[0],
573                MB_SIZE);
574     }
575
576     if(s->pix_fmt == AV_PIX_FMT_RGB24) {
577         for(p = 1; p <= 2; p++) {
578             for(y = 0; y < MB_SIZE/2; y++) {
579                 memcpy(a->data[p] + y*a->linesize[p],
580                        b->data[p] + y*b->linesize[p],
581                        MB_SIZE/2);
582             }
583         }
584     }
585 }
586
587 static int encode_mode(CinepakEncContext *s, int h, AVPicture *scratch_pict, AVPicture *last_pict, strip_info *info, unsigned char *buf)
588 {
589     int x, y, z, flags, bits, temp_size, header_ofs, ret = 0, mb_count = s->w * h / MB_AREA;
590     int needs_extra_bit, should_write_temp;
591     unsigned char temp[64]; //32/2 = 16 V4 blocks at 4 B each -> 64 B
592     mb_info *mb;
593     AVPicture sub_scratch, sub_last;
594
595     //encode codebooks
596 ////// MacOS vintage decoder compatibility dictates the presence of
597 ////// the codebook chunk even when the codebook is empty - pretty dumb...
598 ////// and also the certain order of the codebook chunks -- rl
599 //    if(info->v4_size)
600         ret += encode_codebook(s, info->v4_codebook, info->v4_size, 0x20, 0x24, buf + ret);
601
602 //    if(info->v1_size)
603         ret += encode_codebook(s, info->v1_codebook, info->v1_size, 0x22, 0x26, buf + ret);
604
605     //update scratch picture
606     for(z = y = 0; y < h; y += MB_SIZE) {
607         for(x = 0; x < s->w; x += MB_SIZE, z++) {
608             mb = &s->mb[z];
609
610             get_sub_picture(s, x, y, scratch_pict, &sub_scratch);
611
612             if(info->mode == MODE_MC && mb->best_encoding == ENC_SKIP) {
613                 get_sub_picture(s, x, y, last_pict, &sub_last);
614                 copy_mb(s, &sub_scratch, &sub_last);
615             } else if(info->mode == MODE_V1_ONLY || mb->best_encoding == ENC_V1)
616                 decode_v1_vector(s, &sub_scratch, mb->v1_vector, info);
617             else
618                 decode_v4_vector(s, &sub_scratch, mb->v4_vector, info);
619         }
620     }
621
622     switch(info->mode) {
623     case MODE_V1_ONLY:
624         //av_log(s->avctx, AV_LOG_INFO, "mb_count = %i\n", mb_count);
625         ret += write_chunk_header(buf + ret, 0x32, mb_count);
626
627         for(x = 0; x < mb_count; x++)
628             buf[ret++] = s->mb[x].v1_vector;
629
630         break;
631     case MODE_V1_V4:
632         //remember header position
633         header_ofs = ret;
634         ret += CHUNK_HEADER_SIZE;
635
636         for(x = 0; x < mb_count; x += 32) {
637             flags = 0;
638             for(y = x; y < FFMIN(x+32, mb_count); y++)
639                 if(s->mb[y].best_encoding == ENC_V4)
640                     flags |= 1 << (31 - y + x);
641
642             AV_WB32(&buf[ret], flags);
643             ret += 4;
644
645             for(y = x; y < FFMIN(x+32, mb_count); y++) {
646                 mb = &s->mb[y];
647
648                 if(mb->best_encoding == ENC_V1)
649                     buf[ret++] = mb->v1_vector;
650                 else
651                     for(z = 0; z < 4; z++)
652                         buf[ret++] = mb->v4_vector[z];
653             }
654         }
655
656         write_chunk_header(buf + header_ofs, 0x30, ret - header_ofs - CHUNK_HEADER_SIZE);
657
658         break;
659     case MODE_MC:
660         //remember header position
661         header_ofs = ret;
662         ret += CHUNK_HEADER_SIZE;
663         flags = bits = temp_size = 0;
664
665         for(x = 0; x < mb_count; x++) {
666             mb = &s->mb[x];
667             flags |= (mb->best_encoding != ENC_SKIP) << (31 - bits++);
668             needs_extra_bit = 0;
669             should_write_temp = 0;
670
671             if(mb->best_encoding != ENC_SKIP) {
672                 if(bits < 32)
673                     flags |= (mb->best_encoding == ENC_V4) << (31 - bits++);
674                 else
675                     needs_extra_bit = 1;
676             }
677
678             if(bits == 32) {
679                 AV_WB32(&buf[ret], flags);
680                 ret += 4;
681                 flags = bits = 0;
682
683                 if(mb->best_encoding == ENC_SKIP || needs_extra_bit) {
684                     memcpy(&buf[ret], temp, temp_size);
685                     ret += temp_size;
686                     temp_size = 0;
687                 } else
688                     should_write_temp = 1;
689             }
690
691             if(needs_extra_bit) {
692                 flags = (mb->best_encoding == ENC_V4) << 31;
693                 bits = 1;
694             }
695
696             if(mb->best_encoding == ENC_V1)
697                 temp[temp_size++] = mb->v1_vector;
698             else if(mb->best_encoding == ENC_V4)
699                 for(z = 0; z < 4; z++)
700                     temp[temp_size++] = mb->v4_vector[z];
701
702             if(should_write_temp) {
703                 memcpy(&buf[ret], temp, temp_size);
704                 ret += temp_size;
705                 temp_size = 0;
706             }
707         }
708
709         if(bits > 0) {
710             AV_WB32(&buf[ret], flags);
711             ret += 4;
712             memcpy(&buf[ret], temp, temp_size);
713             ret += temp_size;
714         }
715
716         write_chunk_header(buf + header_ofs, 0x31, ret - header_ofs - CHUNK_HEADER_SIZE);
717
718         break;
719     }
720
721     return ret;
722 }
723
724 //computes distortion of 4x4 MB in b compared to a
725 static int compute_mb_distortion(CinepakEncContext *s, AVPicture *a, AVPicture *b)
726 {
727     int x, y, p, d, ret = 0;
728
729     for(y = 0; y < MB_SIZE; y++) {
730         for(x = 0; x < MB_SIZE; x++) {
731             d = a->data[0][x + y*a->linesize[0]] - b->data[0][x + y*b->linesize[0]];
732             ret += d*d;
733         }
734     }
735
736     if(s->pix_fmt == AV_PIX_FMT_RGB24) {
737         for(p = 1; p <= 2; p++) {
738             for(y = 0; y < MB_SIZE/2; y++) {
739                 for(x = 0; x < MB_SIZE/2; x++) {
740                     d = a->data[p][x + y*a->linesize[p]] - b->data[p][x + y*b->linesize[p]];
741                     ret += d*d;
742                 }
743             }
744         }
745     }
746
747     return ret;
748 }
749
750 // return the possibly adjusted size of the codebook
751 #define CERTAIN(x) ((x)!=ENC_UNCERTAIN)
752 static int quantize(CinepakEncContext *s, int h, AVPicture *pict,
753                     int v1mode, strip_info *info,
754                     mb_encoding encoding)
755 {
756     int x, y, i, j, k, x2, y2, x3, y3, plane, shift, mbn;
757     int entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
758     int *codebook = v1mode ? info->v1_codebook : info->v4_codebook;
759     int size = v1mode ? info->v1_size : info->v4_size;
760     int64_t total_error = 0;
761     uint8_t vq_pict_buf[(MB_AREA*3)/2];
762     AVPicture sub_pict, vq_pict;
763
764     for(mbn = i = y = 0; y < h; y += MB_SIZE) {
765         for(x = 0; x < s->w; x += MB_SIZE, ++mbn) {
766             int *base;
767
768             if(CERTAIN(encoding)) {
769 // use for the training only the blocks known to be to be encoded [sic:-]
770                if(s->mb[mbn].best_encoding != encoding) continue;
771             }
772
773             base = s->codebook_input + i*entry_size;
774             if(v1mode) {
775                 //subsample
776                 for(j = y2 = 0; y2 < entry_size; y2 += 2) {
777                     for(x2 = 0; x2 < 4; x2 += 2, j++) {
778                         plane = y2 < 4 ? 0 : 1 + (x2 >> 1);
779                         shift = y2 < 4 ? 0 : 1;
780                         x3 = shift ? 0 : x2;
781                         y3 = shift ? 0 : y2;
782                         base[j] = (pict->data[plane][((x+x3) >> shift) +      ((y+y3) >> shift)      * pict->linesize[plane]] +
783                                    pict->data[plane][((x+x3) >> shift) + 1 +  ((y+y3) >> shift)      * pict->linesize[plane]] +
784                                    pict->data[plane][((x+x3) >> shift) +     (((y+y3) >> shift) + 1) * pict->linesize[plane]] +
785                                    pict->data[plane][((x+x3) >> shift) + 1 + (((y+y3) >> shift) + 1) * pict->linesize[plane]]) >> 2;
786                     }
787                 }
788             } else {
789                 //copy
790                 for(j = y2 = 0; y2 < MB_SIZE; y2 += 2) {
791                     for(x2 = 0; x2 < MB_SIZE; x2 += 2) {
792                         for(k = 0; k < entry_size; k++, j++) {
793                             plane = k >= 4 ? k - 3 : 0;
794
795                             if(k >= 4) {
796                                 x3 = (x+x2) >> 1;
797                                 y3 = (y+y2) >> 1;
798                             } else {
799                                 x3 = x + x2 + (k & 1);
800                                 y3 = y + y2 + (k >> 1);
801                             }
802
803                             base[j] = pict->data[plane][x3 + y3*pict->linesize[plane]];
804                         }
805                     }
806                 }
807             }
808             i += v1mode ? 1 : 4;
809         }
810     }
811 //    if(i < mbn*(v1mode ? 1 : 4)) {
812 //        av_log(s->avctx, AV_LOG_INFO, "reducing training set for %s from %i to %i (encoding %i)\n", v1mode?"v1":"v4", mbn*(v1mode ? 1 : 4), i, encoding);
813 //    }
814
815     if(i == 0) // empty training set, nothing to do
816         return 0;
817     if(i < size) {
818         //av_log(s->avctx, (CERTAIN(encoding) ? AV_LOG_ERROR : AV_LOG_INFO), "WOULD WASTE: %s cbsize %i bigger than training set size %i (encoding %i)\n", v1mode?"v1":"v4", size, i, encoding);
819         size = i;
820     }
821
822     avpriv_init_elbg(s->codebook_input, entry_size, i, codebook, size, 1, s->codebook_closest, &s->randctx);
823     avpriv_do_elbg(s->codebook_input, entry_size, i, codebook, size, 1, s->codebook_closest, &s->randctx);
824
825     //setup vq_pict, which contains a single MB
826     vq_pict.data[0] = vq_pict_buf;
827     vq_pict.linesize[0] = MB_SIZE;
828     vq_pict.data[1] = &vq_pict_buf[MB_AREA];
829     vq_pict.data[2] = vq_pict.data[1] + (MB_AREA >> 2);
830     vq_pict.linesize[1] = vq_pict.linesize[2] = MB_SIZE >> 1;
831
832     //copy indices
833     for(i = j = y = 0; y < h; y += MB_SIZE) {
834         for(x = 0; x < s->w; x += MB_SIZE, j++) {
835             mb_info *mb = &s->mb[j];
836 // skip uninteresting blocks if we know their preferred encoding
837             if(CERTAIN(encoding) && mb->best_encoding != encoding)
838                 continue;
839
840             //point sub_pict to current MB
841             get_sub_picture(s, x, y, pict, &sub_pict);
842
843             if(v1mode) {
844                 mb->v1_vector = s->codebook_closest[i];
845
846                 //fill in vq_pict with V1 data
847                 decode_v1_vector(s, &vq_pict, mb->v1_vector, info);
848
849                 mb->v1_error = compute_mb_distortion(s, &sub_pict, &vq_pict);
850                 total_error += mb->v1_error;
851             } else {
852                 for(k = 0; k < 4; k++)
853                     mb->v4_vector[k] = s->codebook_closest[i+k];
854
855                 //fill in vq_pict with V4 data
856                 decode_v4_vector(s, &vq_pict, mb->v4_vector, info);
857
858                 mb->v4_error = compute_mb_distortion(s, &sub_pict, &vq_pict);
859                 total_error += mb->v4_error;
860             }
861             i += v1mode ? 1 : 4;
862         }
863     }
864 // check that we did it right in the beginning of the function
865     av_assert0(i >= size); // training set is no smaller than the codebook
866
867     //av_log(s->avctx, AV_LOG_INFO, "isv1 %i size= %i i= %i error %lli\n", v1mode, size, i, (long long int)total_error);
868
869     return size;
870 }
871
872 static void calculate_skip_errors(CinepakEncContext *s, int h, AVPicture *last_pict, AVPicture *pict, strip_info *info)
873 {
874     int x, y, i;
875     AVPicture sub_last, sub_pict;
876
877     for(i = y = 0; y < h; y += MB_SIZE) {
878         for(x = 0; x < s->w; x += MB_SIZE, i++) {
879             get_sub_picture(s, x, y, last_pict, &sub_last);
880             get_sub_picture(s, x, y, pict,      &sub_pict);
881
882             s->mb[i].skip_error = compute_mb_distortion(s, &sub_last, &sub_pict);
883         }
884     }
885 }
886
887 static void write_strip_header(CinepakEncContext *s, int y, int h, int keyframe, unsigned char *buf, int strip_size)
888 {
889 // actually we are exclusively using intra strip coding (how much can we win
890 // otherwise? how to choose which part of a codebook to update?),
891 // keyframes are different only because we disallow ENC_SKIP on them -- rl
892 // (besides, the logic here used to be inverted: )
893 //    buf[0] = keyframe ? 0x11: 0x10;
894     buf[0] = keyframe ? 0x10: 0x11;
895     AV_WB24(&buf[1], strip_size + STRIP_HEADER_SIZE);
896 //    AV_WB16(&buf[4], y); /* using absolute y values works -- rl */
897     AV_WB16(&buf[4], 0); /* using relative values works as well -- rl */
898     AV_WB16(&buf[6], 0);
899 //    AV_WB16(&buf[8], y+h); /* using absolute y values works -- rl */
900     AV_WB16(&buf[8], h); /* using relative values works as well -- rl */
901     AV_WB16(&buf[10], s->w);
902     //av_log(s->avctx, AV_LOG_INFO, "write_strip_header() %x keyframe=%d\n", buf[0], keyframe);
903 }
904
905 static int rd_strip(CinepakEncContext *s, int y, int h, int keyframe, AVPicture *last_pict, AVPicture *pict, AVPicture *scratch_pict, unsigned char *buf, int64_t *best_score
906 #ifdef CINEPAK_REPORT_SERR
907 , int64_t *best_serr
908 #endif
909 )
910 {
911     int64_t score = 0;
912 #ifdef CINEPAK_REPORT_SERR
913     int64_t serr;
914 #endif
915     int best_size = 0;
916     strip_info info;
917 // for codebook optimization:
918     int v1enough, v1_size, v4enough, v4_size;
919     int new_v1_size, new_v4_size;
920     int v1shrunk, v4shrunk;
921
922     if(!keyframe)
923         calculate_skip_errors(s, h, last_pict, pict, &info);
924
925     //try some powers of 4 for the size of the codebooks
926     //constraint the v4 codebook to be no bigger than v1 one,
927     //(and no less than v1_size/4)
928     //thus making v1 preferable and possibly losing small details? should be ok
929 #define SMALLEST_CODEBOOK 1
930     for(v1enough = 0, v1_size = SMALLEST_CODEBOOK; v1_size <= CODEBOOK_MAX && !v1enough; v1_size <<= 2) {
931         for(v4enough = 0, v4_size = 0; v4_size <= v1_size && !v4enough; v4_size = v4_size ? v4_size << 2 : v1_size >= SMALLEST_CODEBOOK << 2 ? v1_size >> 2 : SMALLEST_CODEBOOK) {
932             //try all modes
933             for(CinepakMode mode = 0; mode < MODE_COUNT; mode++) {
934                 //don't allow MODE_MC in intra frames
935                 if(keyframe && mode == MODE_MC)
936                     continue;
937
938                 if(mode == MODE_V1_ONLY) {
939                     info.v1_size = v1_size;
940 // the size may shrink even before optimizations if the input is short:
941                     info.v1_size = quantize(s, h, pict, 1, &info, ENC_UNCERTAIN);
942                     if(info.v1_size < v1_size)
943 // too few eligible blocks, no sense in trying bigger sizes
944                         v1enough = 1;
945
946                     info.v4_size = 0;
947                 } else { // mode != MODE_V1_ONLY
948                     // if v4 codebook is empty then only allow V1-only mode
949                     if(!v4_size)
950                         continue;
951
952                     if(mode == MODE_V1_V4) {
953                         info.v4_size = v4_size;
954                         info.v4_size = quantize(s, h, pict, 0, &info, ENC_UNCERTAIN);
955                         if(info.v4_size < v4_size)
956 // too few eligible blocks, no sense in trying bigger sizes
957                             v4enough = 1;
958                     }
959                 }
960
961                 info.mode = mode;
962 // choose the best encoding per block, based on current experience
963                 score = calculate_mode_score(s, h, &info, 0,
964                                              &v1shrunk, &v4shrunk
965 #ifdef CINEPAK_REPORT_SERR
966 , &serr
967 #endif
968 );
969
970                 if(mode != MODE_V1_ONLY){
971 // recompute the codebooks, omitting the extra blocks
972 // we assume we _may_ come here with more blocks to encode than before
973                     info.v1_size = v1_size;
974                     new_v1_size = quantize(s, h, pict, 1, &info, ENC_V1);
975                     if(new_v1_size < info.v1_size){
976                         //av_log(s->avctx, AV_LOG_INFO, "mode %i, %3i, %3i: cut v1 codebook to %i entries\n", mode, v1_size, v4_size, new_v1_size);
977                         info.v1_size = new_v1_size;
978                     }
979 // we assume we _may_ come here with more blocks to encode than before
980                     info.v4_size = v4_size;
981                     new_v4_size = quantize(s, h, pict, 0, &info, ENC_V4);
982                     if(new_v4_size < info.v4_size) {
983                         //av_log(s->avctx, AV_LOG_INFO, "mode %i, %3i, %3i: cut v4 codebook to %i entries at first iteration\n", mode, v1_size, v4_size, new_v4_size);
984                         info.v4_size = new_v4_size;
985                     }
986 // calculate the resulting score
987 // (do not move blocks to codebook encodings now, as some blocks may have
988 // got bigger errors despite a smaller training set - but we do not
989 // ever grow the training sets back)
990                     for(;;) {
991                         score = calculate_mode_score(s, h, &info, 1,
992                                                      &v1shrunk, &v4shrunk
993 #ifdef CINEPAK_REPORT_SERR
994 , &serr
995 #endif
996 );
997 // do we have a reason to reiterate?
998                         if(!v1shrunk && !v4shrunk) break;
999 // recompute the codebooks, omitting the extra blocks
1000                         if(v1shrunk) {
1001                             info.v1_size = v1_size;
1002                             new_v1_size = quantize(s, h, pict, 1, &info, ENC_V1);
1003                             if(new_v1_size < info.v1_size){
1004                                 //av_log(s->avctx, AV_LOG_INFO, "mode %i, %3i, %3i: cut v1 codebook to %i entries\n", mode, v1_size, v4_size, new_v1_size);
1005                                 info.v1_size = new_v1_size;
1006                             }
1007                         }
1008                         if(v4shrunk) {
1009                             info.v4_size = v4_size;
1010                             new_v4_size = quantize(s, h, pict, 0, &info, ENC_V4);
1011                             if(new_v4_size < info.v4_size) {
1012                                 //av_log(s->avctx, AV_LOG_INFO, "mode %i, %3i, %3i: cut v4 codebook to %i entries\n", mode, v1_size, v4_size, new_v4_size);
1013                                 info.v4_size = new_v4_size;
1014                             }
1015                         }
1016                     }
1017                 }
1018
1019                 //av_log(s->avctx, AV_LOG_INFO, "%3i %3i score = %lli\n", v1_size, v4_size, (long long int)score);
1020
1021                 if(best_size == 0 || score < *best_score) {
1022
1023                     *best_score = score;
1024 #ifdef CINEPAK_REPORT_SERR
1025                     *best_serr = serr;
1026 #endif
1027                     best_size = encode_mode(s, h, scratch_pict, last_pict, &info, s->strip_buf + STRIP_HEADER_SIZE);
1028
1029                     //av_log(s->avctx, AV_LOG_INFO, "mode %i, %3i, %3i: %18lli %i B", mode, info.v1_size, info.v4_size, (long long int)score, best_size);
1030                     //av_log(s->avctx, AV_LOG_INFO, "\n");
1031 #ifdef CINEPAK_REPORT_SERR
1032                     av_log(s->avctx, AV_LOG_INFO, "mode %i, %3i, %3i: %18lli %i B\n", mode, v1_size, v4_size, (long long int)serr, best_size);
1033 #endif
1034
1035 #ifdef CINEPAKENC_DEBUG
1036                     //save MB encoding choices
1037                     memcpy(s->best_mb, s->mb, mb_count*sizeof(mb_info));
1038 #endif
1039
1040                     //memcpy(strip_temp + STRIP_HEADER_SIZE, strip_temp, best_size);
1041                     write_strip_header(s, y, h, keyframe, s->strip_buf, best_size);
1042
1043                 }
1044             }
1045         }
1046     }
1047
1048 #ifdef CINEPAKENC_DEBUG
1049     //gather stats. this will only work properly of MAX_STRIPS == 1
1050     if(best_info.mode == MODE_V1_ONLY) {
1051         s->num_v1_mode++;
1052         s->num_v1_encs += s->w*h/MB_AREA;
1053     } else {
1054         if(best_info.mode == MODE_V1_V4)
1055             s->num_v4_mode++;
1056         else
1057             s->num_mc_mode++;
1058
1059         int x;
1060         for(x = 0; x < s->w*h/MB_AREA; x++)
1061             if(s->best_mb[x].best_encoding == ENC_V1)
1062                 s->num_v1_encs++;
1063             else if(s->best_mb[x].best_encoding == ENC_V4)
1064                 s->num_v4_encs++;
1065             else
1066                 s->num_skips++;
1067     }
1068 #endif
1069
1070     best_size += STRIP_HEADER_SIZE;
1071     memcpy(buf, s->strip_buf, best_size);
1072
1073     return best_size;
1074 }
1075
1076 static int write_cvid_header(CinepakEncContext *s, unsigned char *buf, int num_strips, int data_size, int isakeyframe)
1077 {
1078     buf[0] = isakeyframe ? 0 : 1;
1079     AV_WB24(&buf[1], data_size + CVID_HEADER_SIZE);
1080     AV_WB16(&buf[4], s->w);
1081     AV_WB16(&buf[6], s->h);
1082     AV_WB16(&buf[8], num_strips);
1083
1084     return CVID_HEADER_SIZE;
1085 }
1086
1087 static int rd_frame(CinepakEncContext *s, AVFrame *frame, int isakeyframe, unsigned char *buf, int buf_size)
1088 {
1089     int num_strips, strip, i, y, nexty, size, temp_size, best_size;
1090     AVPicture last_pict, pict, scratch_pict;
1091     int64_t best_score = 0, score, score_temp;
1092 #ifdef CINEPAK_REPORT_SERR
1093     int64_t best_serr = 0, serr, serr_temp;
1094 #endif
1095
1096     int best_nstrips;
1097
1098     if(s->pix_fmt == AV_PIX_FMT_RGB24) {
1099         int x;
1100 // build a copy of the given frame in the correct colorspace
1101         for(y = 0; y < s->h; y += 2) {
1102             for(x = 0; x < s->w; x += 2) {
1103                 uint8_t *ir[2]; int32_t r, g, b, rr, gg, bb;
1104                 ir[0] = ((AVPicture*)frame)->data[0] + x*3 + y*((AVPicture*)frame)->linesize[0];
1105                 ir[1] = ir[0] + ((AVPicture*)frame)->linesize[0];
1106                 get_sub_picture(s, x, y, (AVPicture*)s->input_frame, &scratch_pict);
1107                 r = g = b = 0;
1108                 for(i=0; i<4; ++i) {
1109                     int i1, i2;
1110                     i1 = (i&1); i2 = (i>=2);
1111                     rr = ir[i2][i1*3+0];
1112                     gg = ir[i2][i1*3+1];
1113                     bb = ir[i2][i1*3+2];
1114                     r += rr; g += gg; b += bb;
1115 // using fixed point arithmetic for portable repeatability, scaling by 2^23
1116 // "Y"
1117 //                    rr = 0.2857*rr + 0.5714*gg + 0.1429*bb;
1118                     rr = (2396625*rr + 4793251*gg + 1198732*bb) >> 23;
1119                     if(      rr <   0) rr =   0;
1120                     else if (rr > 255) rr = 255;
1121                     scratch_pict.data[0][i1 + i2*scratch_pict.linesize[0]] = rr;
1122                 }
1123 // let us scale down as late as possible
1124 //                r /= 4; g /= 4; b /= 4;
1125 // "U"
1126 //                rr = -0.1429*r - 0.2857*g + 0.4286*b;
1127                 rr = (-299683*r - 599156*g + 898839*b) >> 23;
1128                 if(      rr < -128) rr = -128;
1129                 else if (rr >  127) rr =  127;
1130                 scratch_pict.data[1][0] = rr + 128; // quantize needs unsigned
1131 // "V"
1132 //                rr = 0.3571*r - 0.2857*g - 0.0714*b;
1133                 rr = (748893*r - 599156*g - 149737*b) >> 23;
1134                 if(      rr < -128) rr = -128;
1135                 else if (rr >  127) rr =  127;
1136                 scratch_pict.data[2][0] = rr + 128; // quantize needs unsigned
1137             }
1138         }
1139     }
1140
1141     //would be nice but quite certainly incompatible with vintage players:
1142     // support encoding zero strips (meaning skip the whole frame)
1143     for(num_strips = s->min_strips; num_strips <= s->max_strips && num_strips <= s->h / MB_SIZE; num_strips++) {
1144         score = 0;
1145         size = 0;
1146 #ifdef CINEPAK_REPORT_SERR
1147         serr = 0;
1148 #endif
1149
1150         for(y = 0, strip = 1; y < s->h; strip++, y = nexty) {
1151             int strip_height;
1152
1153             nexty = strip * s->h / num_strips; // <= s->h
1154             //make nexty the next multiple of 4 if not already there
1155             if(nexty & 3)
1156                 nexty += 4 - (nexty & 3);
1157
1158             strip_height = nexty - y;
1159             if(strip_height <= 0) { // can this ever happen?
1160                 av_log(s->avctx, AV_LOG_INFO, "skipping zero height strip %i of %i\n", strip, num_strips);
1161                 continue;
1162             }
1163
1164             if(s->pix_fmt == AV_PIX_FMT_RGB24)
1165                 get_sub_picture(s, 0, y, (AVPicture*)s->input_frame,    &pict);
1166             else
1167                 get_sub_picture(s, 0, y, (AVPicture*)frame,              &pict);
1168             get_sub_picture(s, 0, y, (AVPicture*)s->last_frame,    &last_pict);
1169             get_sub_picture(s, 0, y, (AVPicture*)s->scratch_frame, &scratch_pict);
1170
1171             if((temp_size = rd_strip(s, y, strip_height, isakeyframe, &last_pict, &pict, &scratch_pict, s->frame_buf + size + CVID_HEADER_SIZE, &score_temp
1172 #ifdef CINEPAK_REPORT_SERR
1173 , &serr_temp
1174 #endif
1175 )) < 0)
1176                 return temp_size;
1177
1178             score += score_temp;
1179 #ifdef CINEPAK_REPORT_SERR
1180             serr += serr_temp;
1181 #endif
1182             size += temp_size;
1183             //av_log(s->avctx, AV_LOG_INFO, "strip %d, isakeyframe=%d", strip, isakeyframe);
1184             //av_log(s->avctx, AV_LOG_INFO, "\n");
1185         }
1186
1187         if(best_score == 0 || score < best_score) {
1188             best_score = score;
1189 #ifdef CINEPAK_REPORT_SERR
1190             best_serr = serr;
1191 #endif
1192             best_size = size + write_cvid_header(s, s->frame_buf, num_strips, size, isakeyframe);
1193             //av_log(s->avctx, AV_LOG_INFO, "best number of strips so far: %2i, %12lli, %i B\n", num_strips, (long long int)score, best_size);
1194 #ifdef CINEPAK_REPORT_SERR
1195             av_log(s->avctx, AV_LOG_INFO, "best number of strips so far: %2i, %12lli, %i B\n", num_strips, (long long int)serr, best_size);
1196 #endif
1197
1198             FFSWAP(AVFrame *, s->best_frame, s->scratch_frame);
1199             memcpy(buf, s->frame_buf, best_size);
1200             best_nstrips = num_strips;
1201         }
1202 // avoid trying too many strip numbers without a real reason
1203 // (this makes the processing of the very first frame faster)
1204         if(num_strips - best_nstrips > 4)
1205             break;
1206     }
1207
1208 // let the number of strips slowly adapt to the changes in the contents,
1209 // compared to full bruteforcing every time this will occasionally lead
1210 // to some r/d performance loss but makes encoding up to several times faster
1211 #ifdef CINEPAK_AGGRESSIVE_STRIP_NUMBER_ADAPTIVITY
1212     s->max_strips = best_nstrips + 4;
1213     if(s->max_strips >= MAX_STRIPS)
1214         s->max_strips = MAX_STRIPS;
1215     s->min_strips = best_nstrips - 4;
1216     if(s->min_strips < MIN_STRIPS)
1217         s->min_strips = MIN_STRIPS;
1218 #else
1219     if(best_nstrips == s->max_strips) { // let us try to step up
1220         s->max_strips = best_nstrips + 1;
1221         if(s->max_strips >= MAX_STRIPS)
1222             s->max_strips = MAX_STRIPS;
1223     } else { // try to step down
1224         s->max_strips = best_nstrips;
1225     }
1226     s->min_strips = s->max_strips - 1;
1227     if(s->min_strips < MIN_STRIPS)
1228         s->min_strips = MIN_STRIPS;
1229 #endif
1230
1231     return best_size;
1232 }
1233
1234 static int cinepak_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
1235                                 const AVFrame *frame, int *got_packet)
1236 {
1237     CinepakEncContext *s = avctx->priv_data;
1238     int ret;
1239
1240     s->lambda = frame->quality ? frame->quality - 1 : 2 * FF_LAMBDA_SCALE;
1241
1242     if ((ret = ff_alloc_packet2(avctx, pkt, s->frame_buf_size)) < 0)
1243         return ret;
1244     ret = rd_frame(s, frame, (s->curframe == 0), pkt->data, s->frame_buf_size);
1245     pkt->size = ret;
1246     if (s->curframe == 0)
1247         pkt->flags |= AV_PKT_FLAG_KEY;
1248     *got_packet = 1;
1249
1250     avctx->coded_frame = frame;
1251
1252     FFSWAP(AVFrame *, s->last_frame, s->best_frame);
1253
1254     if (++s->curframe >= s->keyint)
1255         s->curframe = 0;
1256
1257     return 0;
1258 }
1259
1260 static av_cold int cinepak_encode_end(AVCodecContext *avctx)
1261 {
1262     CinepakEncContext *s = avctx->priv_data;
1263     int x;
1264
1265     av_frame_free(&s->last_frame);
1266     av_frame_free(&s->best_frame);
1267     av_frame_free(&s->scratch_frame);
1268     if (avctx->pix_fmt == AV_PIX_FMT_RGB24)
1269         av_frame_free(&s->input_frame);
1270     av_freep(&s->codebook_input);
1271     av_freep(&s->codebook_closest);
1272     av_freep(&s->strip_buf);
1273     av_freep(&s->frame_buf);
1274     av_freep(&s->mb);
1275 #ifdef CINEPAKENC_DEBUG
1276     av_freep(&s->best_mb);
1277 #endif
1278
1279     for(x = 0; x < (avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 4 : 3); x++)
1280         av_freep(&s->pict_bufs[x]);
1281
1282 #ifdef CINEPAKENC_DEBUG
1283     av_log(avctx, AV_LOG_INFO, "strip coding stats: %i V1 mode, %i V4 mode, %i MC mode (%i V1 encs, %i V4 encs, %i skips)\n",
1284         s->num_v1_mode, s->num_v4_mode, s->num_mc_mode, s->num_v1_encs, s->num_v4_encs, s->num_skips);
1285 #endif
1286
1287     return 0;
1288 }
1289
1290 AVCodec ff_cinepak_encoder = {
1291     .name           = "cinepak",
1292     .type           = AVMEDIA_TYPE_VIDEO,
1293     .id             = AV_CODEC_ID_CINEPAK,
1294     .priv_data_size = sizeof(CinepakEncContext),
1295     .init           = cinepak_encode_init,
1296     .encode2        = cinepak_encode_frame,
1297     .close          = cinepak_encode_end,
1298     .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_RGB24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
1299     .long_name      = NULL_IF_CONFIG_SMALL("Cinepak / CVID"),
1300 };