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