FFmpeg
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 
27 /*
28  * TODO:
29  * - optimize: color space conversion (move conversion to libswscale), ...
30  * MAYBE:
31  * - "optimally" split the frame into several non-regular areas
32  * using a separate codebook pair for each area and approximating
33  * the area by several rectangular strips (generally not full width ones)
34  * (use quadtree splitting? a simple fixed-granularity grid?)
35  */
36 
37 #include <string.h>
38 
39 #include "libavutil/avassert.h"
40 #include "libavutil/common.h"
41 #include "libavutil/internal.h"
42 #include "libavutil/intreadwrite.h"
43 #include "libavutil/lfg.h"
44 #include "libavutil/opt.h"
45 
46 #include "avcodec.h"
47 #include "elbg.h"
48 #include "encode.h"
49 #include "internal.h"
50 
51 #define CVID_HEADER_SIZE 10
52 #define STRIP_HEADER_SIZE 12
53 #define CHUNK_HEADER_SIZE 4
54 
55 #define MB_SIZE 4 //4x4 MBs
56 #define MB_AREA (MB_SIZE * MB_SIZE)
57 
58 #define VECTOR_MAX 6 // six or four entries per vector depending on format
59 #define CODEBOOK_MAX 256 // size of a codebook
60 
61 #define MAX_STRIPS 32 // Note: having fewer choices regarding the number of strips speeds up encoding (obviously)
62 #define MIN_STRIPS 1 // Note: having more strips speeds up encoding the frame (this is less obvious)
63 // MAX_STRIPS limits the maximum quality you can reach
64 // when you want high quality on high resolutions,
65 // MIN_STRIPS limits the minimum efficiently encodable bit rate
66 // on low resolutions
67 // the numbers are only used for brute force optimization for the first frame,
68 // for the following frames they are adaptively readjusted
69 // NOTE the decoder in ffmpeg has its own arbitrary limitation on the number
70 // of strips, currently 32
71 
72 typedef enum CinepakMode {
76 
78 } CinepakMode;
79 
80 typedef enum mb_encoding {
84 
86 } mb_encoding;
87 
88 typedef struct mb_info {
89  int v1_vector; // index into v1 codebook
90  int v1_error; // error when using V1 encoding
91  int v4_vector[4]; // indices into v4 codebook
92  int v4_error; // error when using V4 encoding
93  int skip_error; // error when block is skipped (aka copied from last frame)
94  mb_encoding best_encoding; // last result from calculate_mode_score()
95 } mb_info;
96 
97 typedef struct strip_info {
100  int v1_size;
101  int v4_size;
103 } strip_info;
104 
105 typedef struct CinepakEncContext {
106  const AVClass *class;
108  unsigned char *pict_bufs[4], *strip_buf, *frame_buf;
114  int w, h;
118  uint64_t lambda;
121  mb_info *mb; // MB RD state
122  int min_strips; // the current limit
123  int max_strips; // the current limit
124  // options
130  struct ELBGContext *elbg;
132 
133 #define OFFSET(x) offsetof(CinepakEncContext, x)
134 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
135 static const AVOption options[] = {
136  { "max_extra_cb_iterations", "Max extra codebook recalculation passes, more is better and slower",
137  OFFSET(max_extra_cb_iterations), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, INT_MAX, VE },
138  { "skip_empty_cb", "Avoid wasting bytes, ignore vintage MacOS decoder",
139  OFFSET(skip_empty_cb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
140  { "max_strips", "Limit strips/frame, vintage compatible is 1..3, otherwise the more the better",
141  OFFSET(max_max_strips), AV_OPT_TYPE_INT, { .i64 = 3 }, MIN_STRIPS, MAX_STRIPS, VE },
142  { "min_strips", "Enforce min strips/frame, more is worse and faster, must be <= max_strips",
143  OFFSET(min_min_strips), AV_OPT_TYPE_INT, { .i64 = MIN_STRIPS }, MIN_STRIPS, MAX_STRIPS, VE },
144  { "strip_number_adaptivity", "How fast the strip number adapts, more is slightly better, much slower",
145  OFFSET(strip_number_delta_range), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MAX_STRIPS - MIN_STRIPS, VE },
146  { NULL },
147 };
148 
149 static const AVClass cinepak_class = {
150  .class_name = "cinepak",
151  .item_name = av_default_item_name,
152  .option = options,
153  .version = LIBAVUTIL_VERSION_INT,
154 };
155 
157 {
158  CinepakEncContext *s = avctx->priv_data;
159  int x, mb_count, strip_buf_size, frame_buf_size;
160 
161  if (avctx->width & 3 || avctx->height & 3) {
162  av_log(avctx, AV_LOG_ERROR, "width and height must be multiples of four (got %ix%i)\n",
163  avctx->width, avctx->height);
164  return AVERROR(EINVAL);
165  }
166 
167  if (s->min_min_strips > s->max_max_strips) {
168  av_log(avctx, AV_LOG_ERROR, "minimum number of strips must not exceed maximum (got %i and %i)\n",
169  s->min_min_strips, s->max_max_strips);
170  return AVERROR(EINVAL);
171  }
172 
173  if (!(s->last_frame = av_frame_alloc()))
174  return AVERROR(ENOMEM);
175  if (!(s->best_frame = av_frame_alloc()))
176  return AVERROR(ENOMEM);
177  if (!(s->scratch_frame = av_frame_alloc()))
178  return AVERROR(ENOMEM);
179  if (avctx->pix_fmt == AV_PIX_FMT_RGB24)
180  if (!(s->input_frame = av_frame_alloc()))
181  return AVERROR(ENOMEM);
182 
183  if (!(s->codebook_input = av_malloc_array((avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4) * (avctx->width * avctx->height) >> 2, sizeof(*s->codebook_input))))
184  return AVERROR(ENOMEM);
185 
186  if (!(s->codebook_closest = av_malloc_array((avctx->width * avctx->height) >> 2, sizeof(*s->codebook_closest))))
187  return AVERROR(ENOMEM);
188 
189  for (x = 0; x < (avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 4 : 3); x++)
190  if (!(s->pict_bufs[x] = av_malloc((avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4) * (avctx->width * avctx->height) >> 2)))
191  return AVERROR(ENOMEM);
192 
193  mb_count = avctx->width * avctx->height / MB_AREA;
194 
195  // the largest possible chunk is 0x31 with all MBs encoded in V4 mode
196  // and full codebooks being replaced in INTER mode,
197  // which is 34 bits per MB
198  // and 2*256 extra flag bits per strip
199  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;
200 
201  frame_buf_size = CVID_HEADER_SIZE + s->max_max_strips * strip_buf_size;
202 
203  if (!(s->strip_buf = av_malloc(strip_buf_size)))
204  return AVERROR(ENOMEM);
205 
206  if (!(s->frame_buf = av_malloc(frame_buf_size)))
207  return AVERROR(ENOMEM);
208 
209  if (!(s->mb = av_malloc_array(mb_count, sizeof(mb_info))))
210  return AVERROR(ENOMEM);
211 
212  av_lfg_init(&s->randctx, 1);
213  s->avctx = avctx;
214  s->w = avctx->width;
215  s->h = avctx->height;
216  s->frame_buf_size = frame_buf_size;
217  s->curframe = 0;
218  s->keyint = avctx->keyint_min;
219  s->pix_fmt = avctx->pix_fmt;
220 
221  // set up AVFrames
222  s->last_frame->data[0] = s->pict_bufs[0];
223  s->last_frame->linesize[0] = s->w;
224  s->best_frame->data[0] = s->pict_bufs[1];
225  s->best_frame->linesize[0] = s->w;
226  s->scratch_frame->data[0] = s->pict_bufs[2];
227  s->scratch_frame->linesize[0] = s->w;
228 
229  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
230  s->last_frame->data[1] = s->last_frame->data[0] + s->w * s->h;
231  s->last_frame->data[2] = s->last_frame->data[1] + ((s->w * s->h) >> 2);
232  s->last_frame->linesize[1] =
233  s->last_frame->linesize[2] = s->w >> 1;
234 
235  s->best_frame->data[1] = s->best_frame->data[0] + s->w * s->h;
236  s->best_frame->data[2] = s->best_frame->data[1] + ((s->w * s->h) >> 2);
237  s->best_frame->linesize[1] =
238  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] =
243  s->scratch_frame->linesize[2] = s->w >> 1;
244 
245  s->input_frame->data[0] = s->pict_bufs[3];
246  s->input_frame->linesize[0] = s->w;
247  s->input_frame->data[1] = s->input_frame->data[0] + s->w * s->h;
248  s->input_frame->data[2] = s->input_frame->data[1] + ((s->w * s->h) >> 2);
249  s->input_frame->linesize[1] =
250  s->input_frame->linesize[2] = s->w >> 1;
251  }
252 
253  s->min_strips = s->min_min_strips;
254  s->max_strips = s->max_max_strips;
255 
256  return 0;
257 }
258 
260  strip_info *info, int report,
261  int *training_set_v1_shrunk,
262  int *training_set_v4_shrunk)
263 {
264  // score = FF_LAMBDA_SCALE * error + lambda * bits
265  int x;
266  int entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
267  int mb_count = s->w * h / MB_AREA;
268  mb_info *mb;
269  int64_t score1, score2, score3;
270  int64_t ret = s->lambda * ((info->v1_size ? CHUNK_HEADER_SIZE + info->v1_size * entry_size : 0) +
271  (info->v4_size ? CHUNK_HEADER_SIZE + info->v4_size * entry_size : 0) +
272  CHUNK_HEADER_SIZE) << 3;
273 
274  switch (info->mode) {
275  case MODE_V1_ONLY:
276  // one byte per MB
277  ret += s->lambda * 8 * mb_count;
278 
279  // while calculating we assume all blocks are ENC_V1
280  for (x = 0; x < mb_count; x++) {
281  mb = &s->mb[x];
282  ret += FF_LAMBDA_SCALE * mb->v1_error;
283  // this function is never called for report in MODE_V1_ONLY
284  // if (!report)
285  mb->best_encoding = ENC_V1;
286  }
287 
288  break;
289  case MODE_V1_V4:
290  // 9 or 33 bits per MB
291  if (report) {
292  // no moves between the corresponding training sets are allowed
293  *training_set_v1_shrunk = *training_set_v4_shrunk = 0;
294  for (x = 0; x < mb_count; x++) {
295  int mberr;
296  mb = &s->mb[x];
297  if (mb->best_encoding == ENC_V1)
298  score1 = s->lambda * 9 + FF_LAMBDA_SCALE * (mberr = mb->v1_error);
299  else
300  score1 = s->lambda * 33 + FF_LAMBDA_SCALE * (mberr = mb->v4_error);
301  ret += score1;
302  }
303  } else { // find best mode per block
304  for (x = 0; x < mb_count; x++) {
305  mb = &s->mb[x];
306  score1 = s->lambda * 9 + FF_LAMBDA_SCALE * mb->v1_error;
307  score2 = s->lambda * 33 + FF_LAMBDA_SCALE * mb->v4_error;
308 
309  if (score1 <= score2) {
310  ret += score1;
311  mb->best_encoding = ENC_V1;
312  } else {
313  ret += score2;
314  mb->best_encoding = ENC_V4;
315  }
316  }
317  }
318 
319  break;
320  case MODE_MC:
321  // 1, 10 or 34 bits per MB
322  if (report) {
323  int v1_shrunk = 0, v4_shrunk = 0;
324  for (x = 0; x < mb_count; x++) {
325  mb = &s->mb[x];
326  // it is OK to move blocks to ENC_SKIP here
327  // but not to any codebook encoding!
328  score1 = s->lambda * 1 + FF_LAMBDA_SCALE * mb->skip_error;
329  if (mb->best_encoding == ENC_SKIP) {
330  ret += score1;
331  } else if (mb->best_encoding == ENC_V1) {
332  if ((score2 = s->lambda * 10 + FF_LAMBDA_SCALE * mb->v1_error) >= score1) {
333  mb->best_encoding = ENC_SKIP;
334  ++v1_shrunk;
335  ret += score1;
336  } else {
337  ret += score2;
338  }
339  } else {
340  if ((score3 = s->lambda * 34 + FF_LAMBDA_SCALE * mb->v4_error) >= score1) {
341  mb->best_encoding = ENC_SKIP;
342  ++v4_shrunk;
343  ret += score1;
344  } else {
345  ret += score3;
346  }
347  }
348  }
349  *training_set_v1_shrunk = v1_shrunk;
350  *training_set_v4_shrunk = v4_shrunk;
351  } else { // find best mode per block
352  for (x = 0; x < mb_count; x++) {
353  mb = &s->mb[x];
354  score1 = s->lambda * 1 + FF_LAMBDA_SCALE * mb->skip_error;
355  score2 = s->lambda * 10 + FF_LAMBDA_SCALE * mb->v1_error;
356  score3 = s->lambda * 34 + FF_LAMBDA_SCALE * mb->v4_error;
357 
358  if (score1 <= score2 && score1 <= score3) {
359  ret += score1;
360  mb->best_encoding = ENC_SKIP;
361  } else if (score2 <= score3) {
362  ret += score2;
363  mb->best_encoding = ENC_V1;
364  } else {
365  ret += score3;
366  mb->best_encoding = ENC_V4;
367  }
368  }
369  }
370 
371  break;
372  }
373 
374  return ret;
375 }
376 
377 static int write_chunk_header(unsigned char *buf, int chunk_type, int chunk_size)
378 {
379  buf[0] = chunk_type;
380  AV_WB24(&buf[1], chunk_size + CHUNK_HEADER_SIZE);
381  return CHUNK_HEADER_SIZE;
382 }
383 
385  int chunk_type_yuv, int chunk_type_gray,
386  unsigned char *buf)
387 {
388  int x, y, ret, entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
389  int incremental_codebook_replacement_mode = 0; // hardcoded here,
390  // the compiler should notice that this is a constant -- rl
391 
392  ret = write_chunk_header(buf,
393  s->pix_fmt == AV_PIX_FMT_RGB24 ?
394  chunk_type_yuv + (incremental_codebook_replacement_mode ? 1 : 0) :
395  chunk_type_gray + (incremental_codebook_replacement_mode ? 1 : 0),
396  entry_size * size +
397  (incremental_codebook_replacement_mode ? (size + 31) / 32 * 4 : 0));
398 
399  // we do codebook encoding according to the "intra" mode
400  // but we keep the "dead" code for reference in case we will want
401  // to use incremental codebook updates (which actually would give us
402  // "kind of" motion compensation, especially in 1 strip/frame case) -- rl
403  // (of course, the code will be not useful as-is)
404  if (incremental_codebook_replacement_mode) {
405  int flags = 0;
406  int flagsind;
407  for (x = 0; x < size; x++) {
408  if (flags == 0) {
409  flagsind = ret;
410  ret += 4;
411  flags = 0x80000000;
412  } else
413  flags = ((flags >> 1) | 0x80000000);
414  for (y = 0; y < entry_size; y++)
415  buf[ret++] = codebook[y + x * entry_size] ^ (y >= 4 ? 0x80 : 0);
416  if ((flags & 0xffffffff) == 0xffffffff) {
417  AV_WB32(&buf[flagsind], flags);
418  flags = 0;
419  }
420  }
421  if (flags)
422  AV_WB32(&buf[flagsind], flags);
423  } else
424  for (x = 0; x < size; x++)
425  for (y = 0; y < entry_size; y++)
426  buf[ret++] = codebook[y + x * entry_size] ^ (y >= 4 ? 0x80 : 0);
427 
428  return ret;
429 }
430 
431 // sets out to the sub picture starting at (x,y) in in
432 static void get_sub_picture(CinepakEncContext *s, int x, int y,
433  uint8_t * in_data[4], int in_linesize[4],
434  uint8_t *out_data[4], int out_linesize[4])
435 {
436  out_data[0] = in_data[0] + x + y * in_linesize[0];
437  out_linesize[0] = in_linesize[0];
438 
439  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
440  out_data[1] = in_data[1] + (x >> 1) + (y >> 1) * in_linesize[1];
441  out_linesize[1] = in_linesize[1];
442 
443  out_data[2] = in_data[2] + (x >> 1) + (y >> 1) * in_linesize[2];
444  out_linesize[2] = in_linesize[2];
445  }
446 }
447 
448 // decodes the V1 vector in mb into the 4x4 MB pointed to by data
449 static void decode_v1_vector(CinepakEncContext *s, uint8_t *data[4],
450  int linesize[4], int v1_vector, strip_info *info)
451 {
452  int entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
453 
454  data[0][0] =
455  data[0][1] =
456  data[0][ linesize[0]] =
457  data[0][1 + linesize[0]] = info->v1_codebook[v1_vector * entry_size];
458 
459  data[0][2] =
460  data[0][3] =
461  data[0][2 + linesize[0]] =
462  data[0][3 + linesize[0]] = info->v1_codebook[v1_vector * entry_size + 1];
463 
464  data[0][ 2 * linesize[0]] =
465  data[0][1 + 2 * linesize[0]] =
466  data[0][ 3 * linesize[0]] =
467  data[0][1 + 3 * linesize[0]] = info->v1_codebook[v1_vector * entry_size + 2];
468 
469  data[0][2 + 2 * linesize[0]] =
470  data[0][3 + 2 * linesize[0]] =
471  data[0][2 + 3 * linesize[0]] =
472  data[0][3 + 3 * linesize[0]] = info->v1_codebook[v1_vector * entry_size + 3];
473 
474  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
475  data[1][0] =
476  data[1][1] =
477  data[1][ linesize[1]] =
478  data[1][1 + linesize[1]] = info->v1_codebook[v1_vector * entry_size + 4];
479 
480  data[2][0] =
481  data[2][1] =
482  data[2][ linesize[2]] =
483  data[2][1 + linesize[2]] = info->v1_codebook[v1_vector * entry_size + 5];
484  }
485 }
486 
487 // decodes the V4 vectors in mb into the 4x4 MB pointed to by data
488 static void decode_v4_vector(CinepakEncContext *s, uint8_t *data[4],
489  int linesize[4], int *v4_vector, strip_info *info)
490 {
491  int i, x, y, entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
492 
493  for (i = y = 0; y < 4; y += 2) {
494  for (x = 0; x < 4; x += 2, i++) {
495  data[0][x + y * linesize[0]] = info->v4_codebook[v4_vector[i] * entry_size];
496  data[0][x + 1 + y * linesize[0]] = info->v4_codebook[v4_vector[i] * entry_size + 1];
497  data[0][x + (y + 1) * linesize[0]] = info->v4_codebook[v4_vector[i] * entry_size + 2];
498  data[0][x + 1 + (y + 1) * linesize[0]] = info->v4_codebook[v4_vector[i] * entry_size + 3];
499 
500  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
501  data[1][(x >> 1) + (y >> 1) * linesize[1]] = info->v4_codebook[v4_vector[i] * entry_size + 4];
502  data[2][(x >> 1) + (y >> 1) * linesize[2]] = info->v4_codebook[v4_vector[i] * entry_size + 5];
503  }
504  }
505  }
506 }
507 
509  uint8_t *a_data[4], int a_linesize[4],
510  uint8_t *b_data[4], int b_linesize[4])
511 {
512  int y, p;
513 
514  for (y = 0; y < MB_SIZE; y++)
515  memcpy(a_data[0] + y * a_linesize[0], b_data[0] + y * b_linesize[0],
516  MB_SIZE);
517 
518  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
519  for (p = 1; p <= 2; p++)
520  for (y = 0; y < MB_SIZE / 2; y++)
521  memcpy(a_data[p] + y * a_linesize[p],
522  b_data[p] + y * b_linesize[p],
523  MB_SIZE / 2);
524  }
525 }
526 
527 static int encode_mode(CinepakEncContext *s, int h,
528  uint8_t *scratch_data[4], int scratch_linesize[4],
529  uint8_t *last_data[4], int last_linesize[4],
530  strip_info *info, unsigned char *buf)
531 {
532  int x, y, z, bits, temp_size, header_ofs, ret = 0, mb_count = s->w * h / MB_AREA;
533  int needs_extra_bit, should_write_temp;
534  uint32_t flags;
535  unsigned char temp[64]; // 32/2 = 16 V4 blocks at 4 B each -> 64 B
536  mb_info *mb;
537  uint8_t *sub_scratch_data[4] = { 0 }, *sub_last_data[4] = { 0 };
538  int sub_scratch_linesize[4] = { 0 }, sub_last_linesize[4] = { 0 };
539 
540  // encode codebooks
541  ////// MacOS vintage decoder compatibility dictates the presence of
542  ////// the codebook chunk even when the codebook is empty - pretty dumb...
543  ////// and also the certain order of the codebook chunks -- rl
544  if (info->v4_size || !s->skip_empty_cb)
545  ret += encode_codebook(s, info->v4_codebook, info->v4_size, 0x20, 0x24, buf + ret);
546 
547  if (info->v1_size || !s->skip_empty_cb)
548  ret += encode_codebook(s, info->v1_codebook, info->v1_size, 0x22, 0x26, buf + ret);
549 
550  // update scratch picture
551  for (z = y = 0; y < h; y += MB_SIZE)
552  for (x = 0; x < s->w; x += MB_SIZE, z++) {
553  mb = &s->mb[z];
554 
555  get_sub_picture(s, x, y, scratch_data, scratch_linesize,
556  sub_scratch_data, sub_scratch_linesize);
557 
558  if (info->mode == MODE_MC && mb->best_encoding == ENC_SKIP) {
559  get_sub_picture(s, x, y, last_data, last_linesize,
560  sub_last_data, sub_last_linesize);
561  copy_mb(s, sub_scratch_data, sub_scratch_linesize,
562  sub_last_data, sub_last_linesize);
563  } else if (info->mode == MODE_V1_ONLY || mb->best_encoding == ENC_V1)
564  decode_v1_vector(s, sub_scratch_data, sub_scratch_linesize,
565  mb->v1_vector, info);
566  else
567  decode_v4_vector(s, sub_scratch_data, sub_scratch_linesize,
568  mb->v4_vector, info);
569  }
570 
571  switch (info->mode) {
572  case MODE_V1_ONLY:
573  ret += write_chunk_header(buf + ret, 0x32, mb_count);
574 
575  for (x = 0; x < mb_count; x++)
576  buf[ret++] = s->mb[x].v1_vector;
577 
578  break;
579  case MODE_V1_V4:
580  // remember header position
581  header_ofs = ret;
583 
584  for (x = 0; x < mb_count; x += 32) {
585  flags = 0;
586  for (y = x; y < FFMIN(x + 32, mb_count); y++)
587  if (s->mb[y].best_encoding == ENC_V4)
588  flags |= 1U << (31 - y + x);
589 
590  AV_WB32(&buf[ret], flags);
591  ret += 4;
592 
593  for (y = x; y < FFMIN(x + 32, mb_count); y++) {
594  mb = &s->mb[y];
595 
596  if (mb->best_encoding == ENC_V1)
597  buf[ret++] = mb->v1_vector;
598  else
599  for (z = 0; z < 4; z++)
600  buf[ret++] = mb->v4_vector[z];
601  }
602  }
603 
604  write_chunk_header(buf + header_ofs, 0x30, ret - header_ofs - CHUNK_HEADER_SIZE);
605 
606  break;
607  case MODE_MC:
608  // remember header position
609  header_ofs = ret;
611  flags = bits = temp_size = 0;
612 
613  for (x = 0; x < mb_count; x++) {
614  mb = &s->mb[x];
615  flags |= (uint32_t)(mb->best_encoding != ENC_SKIP) << (31 - bits++);
616  needs_extra_bit = 0;
617  should_write_temp = 0;
618 
619  if (mb->best_encoding != ENC_SKIP) {
620  if (bits < 32)
621  flags |= (uint32_t)(mb->best_encoding == ENC_V4) << (31 - bits++);
622  else
623  needs_extra_bit = 1;
624  }
625 
626  if (bits == 32) {
627  AV_WB32(&buf[ret], flags);
628  ret += 4;
629  flags = bits = 0;
630 
631  if (mb->best_encoding == ENC_SKIP || needs_extra_bit) {
632  memcpy(&buf[ret], temp, temp_size);
633  ret += temp_size;
634  temp_size = 0;
635  } else
636  should_write_temp = 1;
637  }
638 
639  if (needs_extra_bit) {
640  flags = (uint32_t)(mb->best_encoding == ENC_V4) << 31;
641  bits = 1;
642  }
643 
644  if (mb->best_encoding == ENC_V1)
645  temp[temp_size++] = mb->v1_vector;
646  else if (mb->best_encoding == ENC_V4)
647  for (z = 0; z < 4; z++)
648  temp[temp_size++] = mb->v4_vector[z];
649 
650  if (should_write_temp) {
651  memcpy(&buf[ret], temp, temp_size);
652  ret += temp_size;
653  temp_size = 0;
654  }
655  }
656 
657  if (bits > 0) {
658  AV_WB32(&buf[ret], flags);
659  ret += 4;
660  memcpy(&buf[ret], temp, temp_size);
661  ret += temp_size;
662  }
663 
664  write_chunk_header(buf + header_ofs, 0x31, ret - header_ofs - CHUNK_HEADER_SIZE);
665 
666  break;
667  }
668 
669  return ret;
670 }
671 
672 // computes distortion of 4x4 MB in b compared to a
674  uint8_t *a_data[4], int a_linesize[4],
675  uint8_t *b_data[4], int b_linesize[4])
676 {
677  int x, y, p, d, ret = 0;
678 
679  for (y = 0; y < MB_SIZE; y++)
680  for (x = 0; x < MB_SIZE; x++) {
681  d = a_data[0][x + y * a_linesize[0]] - b_data[0][x + y * b_linesize[0]];
682  ret += d * d;
683  }
684 
685  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
686  for (p = 1; p <= 2; p++) {
687  for (y = 0; y < MB_SIZE / 2; y++)
688  for (x = 0; x < MB_SIZE / 2; x++) {
689  d = a_data[p][x + y * a_linesize[p]] - b_data[p][x + y * b_linesize[p]];
690  ret += d * d;
691  }
692  }
693  }
694 
695  return ret;
696 }
697 
698 // return the possibly adjusted size of the codebook
699 #define CERTAIN(x) ((x) != ENC_UNCERTAIN)
700 static int quantize(CinepakEncContext *s, int h, uint8_t *data[4],
701  int linesize[4], int v1mode, strip_info *info,
702  mb_encoding encoding)
703 {
704  int x, y, i, j, k, x2, y2, x3, y3, plane, shift, mbn;
705  int entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
706  int *codebook = v1mode ? info->v1_codebook : info->v4_codebook;
707  int size = v1mode ? info->v1_size : info->v4_size;
708  uint8_t vq_pict_buf[(MB_AREA * 3) / 2];
709  uint8_t *sub_data[4], *vq_data[4];
710  int sub_linesize[4], vq_linesize[4];
711  int ret;
712 
713  for (mbn = i = y = 0; y < h; y += MB_SIZE) {
714  for (x = 0; x < s->w; x += MB_SIZE, ++mbn) {
715  int *base;
716 
717  if (CERTAIN(encoding)) {
718  // use for the training only the blocks known to be to be encoded [sic:-]
719  if (s->mb[mbn].best_encoding != encoding)
720  continue;
721  }
722 
723  base = s->codebook_input + i * entry_size;
724  if (v1mode) {
725  // subsample
726  for (j = y2 = 0; y2 < entry_size; y2 += 2)
727  for (x2 = 0; x2 < 4; x2 += 2, j++) {
728  plane = y2 < 4 ? 0 : 1 + (x2 >> 1);
729  shift = y2 < 4 ? 0 : 1;
730  x3 = shift ? 0 : x2;
731  y3 = shift ? 0 : y2;
732  base[j] = (data[plane][((x + x3) >> shift) + ((y + y3) >> shift) * linesize[plane]] +
733  data[plane][((x + x3) >> shift) + 1 + ((y + y3) >> shift) * linesize[plane]] +
734  data[plane][((x + x3) >> shift) + (((y + y3) >> shift) + 1) * linesize[plane]] +
735  data[plane][((x + x3) >> shift) + 1 + (((y + y3) >> shift) + 1) * linesize[plane]]) >> 2;
736  }
737  } else {
738  // copy
739  for (j = y2 = 0; y2 < MB_SIZE; y2 += 2) {
740  for (x2 = 0; x2 < MB_SIZE; x2 += 2)
741  for (k = 0; k < entry_size; k++, j++) {
742  plane = k >= 4 ? k - 3 : 0;
743 
744  if (k >= 4) {
745  x3 = (x + x2) >> 1;
746  y3 = (y + y2) >> 1;
747  } else {
748  x3 = x + x2 + (k & 1);
749  y3 = y + y2 + (k >> 1);
750  }
751 
752  base[j] = data[plane][x3 + y3 * linesize[plane]];
753  }
754  }
755  }
756  i += v1mode ? 1 : 4;
757  }
758  }
759 
760  if (i == 0) // empty training set, nothing to do
761  return 0;
762  if (i < size)
763  size = i;
764 
765  ret = avpriv_elbg_do(&s->elbg, s->codebook_input, entry_size, i, codebook,
766  size, 1, s->codebook_closest, &s->randctx, 0);
767  if (ret < 0)
768  return ret;
769 
770  // set up vq_data, which contains a single MB
771  vq_data[0] = vq_pict_buf;
772  vq_linesize[0] = MB_SIZE;
773  vq_data[1] = &vq_pict_buf[MB_AREA];
774  vq_data[2] = vq_data[1] + (MB_AREA >> 2);
775  vq_linesize[1] =
776  vq_linesize[2] = MB_SIZE >> 1;
777 
778  // copy indices
779  for (i = j = y = 0; y < h; y += MB_SIZE)
780  for (x = 0; x < s->w; x += MB_SIZE, j++) {
781  mb_info *mb = &s->mb[j];
782  // skip uninteresting blocks if we know their preferred encoding
783  if (CERTAIN(encoding) && mb->best_encoding != encoding)
784  continue;
785 
786  // point sub_data to current MB
787  get_sub_picture(s, x, y, data, linesize, sub_data, sub_linesize);
788 
789  if (v1mode) {
790  mb->v1_vector = s->codebook_closest[i];
791 
792  // fill in vq_data with V1 data
793  decode_v1_vector(s, vq_data, vq_linesize, mb->v1_vector, info);
794 
795  mb->v1_error = compute_mb_distortion(s, sub_data, sub_linesize,
796  vq_data, vq_linesize);
797  } else {
798  for (k = 0; k < 4; k++)
799  mb->v4_vector[k] = s->codebook_closest[i + k];
800 
801  // fill in vq_data with V4 data
802  decode_v4_vector(s, vq_data, vq_linesize, mb->v4_vector, info);
803 
804  mb->v4_error = compute_mb_distortion(s, sub_data, sub_linesize,
805  vq_data, vq_linesize);
806  }
807  i += v1mode ? 1 : 4;
808  }
809  // check that we did it right in the beginning of the function
810  av_assert0(i >= size); // training set is no smaller than the codebook
811 
812  return size;
813 }
814 
816  uint8_t *last_data[4], int last_linesize[4],
817  uint8_t *data[4], int linesize[4],
818  strip_info *info)
819 {
820  int x, y, i;
821  uint8_t *sub_last_data [4], *sub_pict_data [4];
822  int sub_last_linesize[4], sub_pict_linesize[4];
823 
824  for (i = y = 0; y < h; y += MB_SIZE)
825  for (x = 0; x < s->w; x += MB_SIZE, i++) {
826  get_sub_picture(s, x, y, last_data, last_linesize,
827  sub_last_data, sub_last_linesize);
828  get_sub_picture(s, x, y, data, linesize,
829  sub_pict_data, sub_pict_linesize);
830 
831  s->mb[i].skip_error =
833  sub_last_data, sub_last_linesize,
834  sub_pict_data, sub_pict_linesize);
835  }
836 }
837 
838 static void write_strip_header(CinepakEncContext *s, int y, int h, int keyframe,
839  unsigned char *buf, int strip_size)
840 {
841  // actually we are exclusively using intra strip coding (how much can we win
842  // otherwise? how to choose which part of a codebook to update?),
843  // keyframes are different only because we disallow ENC_SKIP on them -- rl
844  // (besides, the logic here used to be inverted: )
845  // buf[0] = keyframe ? 0x11: 0x10;
846  buf[0] = keyframe ? 0x10 : 0x11;
847  AV_WB24(&buf[1], strip_size + STRIP_HEADER_SIZE);
848  // AV_WB16(&buf[4], y); /* using absolute y values works -- rl */
849  AV_WB16(&buf[4], 0); /* using relative values works as well -- rl */
850  AV_WB16(&buf[6], 0);
851  // AV_WB16(&buf[8], y + h); /* using absolute y values works -- rl */
852  AV_WB16(&buf[8], h); /* using relative values works as well -- rl */
853  AV_WB16(&buf[10], s->w);
854 }
855 
856 static int rd_strip(CinepakEncContext *s, int y, int h, int keyframe,
857  uint8_t *last_data[4], int last_linesize[4],
858  uint8_t *data[4], int linesize[4],
859  uint8_t *scratch_data[4], int scratch_linesize[4],
860  unsigned char *buf, int64_t *best_score)
861 {
862  int64_t score = 0;
863  int best_size = 0;
865  // for codebook optimization:
866  int v1enough, v1_size, v4enough, v4_size;
867  int new_v1_size, new_v4_size;
868  int v1shrunk, v4shrunk;
869 
870  if (!keyframe)
871  calculate_skip_errors(s, h, last_data, last_linesize, data, linesize,
872  &info);
873 
874  // try some powers of 4 for the size of the codebooks
875  // constraint the v4 codebook to be no bigger than v1 one,
876  // (and no less than v1_size/4)
877  // thus making v1 preferable and possibly losing small details? should be ok
878 #define SMALLEST_CODEBOOK 1
879  for (v1enough = 0, v1_size = SMALLEST_CODEBOOK; v1_size <= CODEBOOK_MAX && !v1enough; v1_size <<= 2) {
880  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) {
882  // try all modes
883  for (mode = 0; mode < MODE_COUNT; mode++) {
884  // don't allow MODE_MC in intra frames
885  if (keyframe && mode == MODE_MC)
886  continue;
887 
888  if (mode == MODE_V1_ONLY) {
889  info.v1_size = v1_size;
890  // the size may shrink even before optimizations if the input is short:
891  if ((new_v1_size = quantize(s, h, data, linesize, 1,
892  &info, ENC_UNCERTAIN)) < 0)
893  return new_v1_size;
894  info.v1_size = new_v1_size;
895  if (info.v1_size < v1_size)
896  // too few eligible blocks, no sense in trying bigger sizes
897  v1enough = 1;
898 
899  info.v4_size = 0;
900  } else { // mode != MODE_V1_ONLY
901  // if v4 codebook is empty then only allow V1-only mode
902  if (!v4_size)
903  continue;
904 
905  if (mode == MODE_V1_V4) {
906  info.v4_size = v4_size;
907  new_v4_size = quantize(s, h, data, linesize, 0,
908  &info, ENC_UNCERTAIN);
909  if (new_v4_size < 0)
910  return new_v4_size;
911  info.v4_size = new_v4_size;
912  if (info.v4_size < v4_size)
913  // too few eligible blocks, no sense in trying bigger sizes
914  v4enough = 1;
915  }
916  }
917 
918  info.mode = mode;
919  // choose the best encoding per block, based on current experience
920  score = calculate_mode_score(s, h, &info, 0,
921  &v1shrunk, &v4shrunk);
922 
923  if (mode != MODE_V1_ONLY) {
924  int extra_iterations_limit = s->max_extra_cb_iterations;
925  // recompute the codebooks, omitting the extra blocks
926  // we assume we _may_ come here with more blocks to encode than before
927  info.v1_size = v1_size;
928  new_v1_size = quantize(s, h, data, linesize, 1, &info, ENC_V1);
929  if (new_v1_size < 0)
930  return new_v1_size;
931  if (new_v1_size < info.v1_size)
932  info.v1_size = new_v1_size;
933  // we assume we _may_ come here with more blocks to encode than before
934  info.v4_size = v4_size;
935  new_v4_size = quantize(s, h, data, linesize, 0, &info, ENC_V4);
936  if (new_v4_size < 0)
937  return new_v4_size;
938  if (new_v4_size < info.v4_size)
939  info.v4_size = new_v4_size;
940  // calculate the resulting score
941  // (do not move blocks to codebook encodings now, as some blocks may have
942  // got bigger errors despite a smaller training set - but we do not
943  // ever grow the training sets back)
944  for (;;) {
945  score = calculate_mode_score(s, h, &info, 1,
946  &v1shrunk, &v4shrunk);
947  // do we have a reason to reiterate? if so, have we reached the limit?
948  if ((!v1shrunk && !v4shrunk) || !extra_iterations_limit--)
949  break;
950  // recompute the codebooks, omitting the extra blocks
951  if (v1shrunk) {
952  info.v1_size = v1_size;
953  new_v1_size = quantize(s, h, data, linesize, 1, &info, ENC_V1);
954  if (new_v1_size < 0)
955  return new_v1_size;
956  if (new_v1_size < info.v1_size)
957  info.v1_size = new_v1_size;
958  }
959  if (v4shrunk) {
960  info.v4_size = v4_size;
961  new_v4_size = quantize(s, h, data, linesize, 0, &info, ENC_V4);
962  if (new_v4_size < 0)
963  return new_v4_size;
964  if (new_v4_size < info.v4_size)
965  info.v4_size = new_v4_size;
966  }
967  }
968  }
969 
970  if (best_size == 0 || score < *best_score) {
971  *best_score = score;
972  best_size = encode_mode(s, h,
973  scratch_data, scratch_linesize,
974  last_data, last_linesize, &info,
975  s->strip_buf + STRIP_HEADER_SIZE);
976 
977  write_strip_header(s, y, h, keyframe, s->strip_buf, best_size);
978  }
979  }
980  }
981  }
982 
983  best_size += STRIP_HEADER_SIZE;
984  memcpy(buf, s->strip_buf, best_size);
985 
986  return best_size;
987 }
988 
989 static int write_cvid_header(CinepakEncContext *s, unsigned char *buf,
990  int num_strips, int data_size, int isakeyframe)
991 {
992  buf[0] = isakeyframe ? 0 : 1;
993  AV_WB24(&buf[1], data_size + CVID_HEADER_SIZE);
994  AV_WB16(&buf[4], s->w);
995  AV_WB16(&buf[6], s->h);
996  AV_WB16(&buf[8], num_strips);
997 
998  return CVID_HEADER_SIZE;
999 }
1000 
1002  int isakeyframe, unsigned char *buf, int buf_size)
1003 {
1004  int num_strips, strip, i, y, nexty, size, temp_size, best_size;
1005  uint8_t *last_data [4], *data [4], *scratch_data [4];
1006  int last_linesize[4], linesize[4], scratch_linesize[4];
1007  int64_t best_score = 0, score, score_temp;
1008  int best_nstrips;
1009 
1010  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
1011  int x;
1012  // build a copy of the given frame in the correct colorspace
1013  for (y = 0; y < s->h; y += 2)
1014  for (x = 0; x < s->w; x += 2) {
1015  uint8_t *ir[2];
1016  int32_t r, g, b, rr, gg, bb;
1017  ir[0] = frame->data[0] + x * 3 + y * frame->linesize[0];
1018  ir[1] = ir[0] + frame->linesize[0];
1019  get_sub_picture(s, x, y,
1020  s->input_frame->data, s->input_frame->linesize,
1021  scratch_data, scratch_linesize);
1022  r = g = b = 0;
1023  for (i = 0; i < 4; ++i) {
1024  int i1, i2;
1025  i1 = (i & 1);
1026  i2 = (i >= 2);
1027  rr = ir[i2][i1 * 3 + 0];
1028  gg = ir[i2][i1 * 3 + 1];
1029  bb = ir[i2][i1 * 3 + 2];
1030  r += rr;
1031  g += gg;
1032  b += bb;
1033  // using fixed point arithmetic for portable repeatability, scaling by 2^23
1034  // "Y"
1035  // rr = 0.2857 * rr + 0.5714 * gg + 0.1429 * bb;
1036  rr = (2396625 * rr + 4793251 * gg + 1198732 * bb) >> 23;
1037  if (rr < 0)
1038  rr = 0;
1039  else if (rr > 255)
1040  rr = 255;
1041  scratch_data[0][i1 + i2 * scratch_linesize[0]] = rr;
1042  }
1043  // let us scale down as late as possible
1044  // r /= 4; g /= 4; b /= 4;
1045  // "U"
1046  // rr = -0.1429 * r - 0.2857 * g + 0.4286 * b;
1047  rr = (-299683 * r - 599156 * g + 898839 * b) >> 23;
1048  if (rr < -128)
1049  rr = -128;
1050  else if (rr > 127)
1051  rr = 127;
1052  scratch_data[1][0] = rr + 128; // quantize needs unsigned
1053  // "V"
1054  // rr = 0.3571 * r - 0.2857 * g - 0.0714 * b;
1055  rr = (748893 * r - 599156 * g - 149737 * b) >> 23;
1056  if (rr < -128)
1057  rr = -128;
1058  else if (rr > 127)
1059  rr = 127;
1060  scratch_data[2][0] = rr + 128; // quantize needs unsigned
1061  }
1062  }
1063 
1064  // would be nice but quite certainly incompatible with vintage players:
1065  // support encoding zero strips (meaning skip the whole frame)
1066  for (num_strips = s->min_strips; num_strips <= s->max_strips && num_strips <= s->h / MB_SIZE; num_strips++) {
1067  score = 0;
1068  size = 0;
1069 
1070  for (y = 0, strip = 1; y < s->h; strip++, y = nexty) {
1071  int strip_height;
1072 
1073  nexty = strip * s->h / num_strips; // <= s->h
1074  // make nexty the next multiple of 4 if not already there
1075  if (nexty & 3)
1076  nexty += 4 - (nexty & 3);
1077 
1078  strip_height = nexty - y;
1079  if (strip_height <= 0) { // can this ever happen?
1080  av_log(s->avctx, AV_LOG_INFO, "skipping zero height strip %i of %i\n", strip, num_strips);
1081  continue;
1082  }
1083 
1084  if (s->pix_fmt == AV_PIX_FMT_RGB24)
1085  get_sub_picture(s, 0, y,
1086  s->input_frame->data, s->input_frame->linesize,
1087  data, linesize);
1088  else
1089  get_sub_picture(s, 0, y,
1090  (uint8_t **)frame->data, (int *)frame->linesize,
1091  data, linesize);
1092  get_sub_picture(s, 0, y,
1093  s->last_frame->data, s->last_frame->linesize,
1094  last_data, last_linesize);
1095  get_sub_picture(s, 0, y,
1096  s->scratch_frame->data, s->scratch_frame->linesize,
1097  scratch_data, scratch_linesize);
1098 
1099  if ((temp_size = rd_strip(s, y, strip_height, isakeyframe,
1100  last_data, last_linesize, data, linesize,
1101  scratch_data, scratch_linesize,
1102  s->frame_buf + size + CVID_HEADER_SIZE,
1103  &score_temp)) < 0)
1104  return temp_size;
1105 
1106  score += score_temp;
1107  size += temp_size;
1108  }
1109 
1110  if (best_score == 0 || score < best_score) {
1111  best_score = score;
1112  best_size = size + write_cvid_header(s, s->frame_buf, num_strips, size, isakeyframe);
1113 
1114  FFSWAP(AVFrame *, s->best_frame, s->scratch_frame);
1115  memcpy(buf, s->frame_buf, best_size);
1116  best_nstrips = num_strips;
1117  }
1118  // avoid trying too many strip numbers without a real reason
1119  // (this makes the processing of the very first frame faster)
1120  if (num_strips - best_nstrips > 4)
1121  break;
1122  }
1123 
1124  // let the number of strips slowly adapt to the changes in the contents,
1125  // compared to full bruteforcing every time this will occasionally lead
1126  // to some r/d performance loss but makes encoding up to several times faster
1127  if (!s->strip_number_delta_range) {
1128  if (best_nstrips == s->max_strips) { // let us try to step up
1129  s->max_strips = best_nstrips + 1;
1130  if (s->max_strips >= s->max_max_strips)
1131  s->max_strips = s->max_max_strips;
1132  } else { // try to step down
1133  s->max_strips = best_nstrips;
1134  }
1135  s->min_strips = s->max_strips - 1;
1136  if (s->min_strips < s->min_min_strips)
1137  s->min_strips = s->min_min_strips;
1138  } else {
1139  s->max_strips = best_nstrips + s->strip_number_delta_range;
1140  if (s->max_strips >= s->max_max_strips)
1141  s->max_strips = s->max_max_strips;
1142  s->min_strips = best_nstrips - s->strip_number_delta_range;
1143  if (s->min_strips < s->min_min_strips)
1144  s->min_strips = s->min_min_strips;
1145  }
1146 
1147  return best_size;
1148 }
1149 
1151  const AVFrame *frame, int *got_packet)
1152 {
1153  CinepakEncContext *s = avctx->priv_data;
1154  int ret;
1155 
1156  s->lambda = frame->quality ? frame->quality - 1 : 2 * FF_LAMBDA_SCALE;
1157 
1158  if ((ret = ff_alloc_packet(avctx, pkt, s->frame_buf_size)) < 0)
1159  return ret;
1160  ret = rd_frame(s, frame, (s->curframe == 0), pkt->data, s->frame_buf_size);
1161  pkt->size = ret;
1162  if (s->curframe == 0)
1164  *got_packet = 1;
1165 
1166  FFSWAP(AVFrame *, s->last_frame, s->best_frame);
1167 
1168  if (++s->curframe >= s->keyint)
1169  s->curframe = 0;
1170 
1171  return 0;
1172 }
1173 
1175 {
1176  CinepakEncContext *s = avctx->priv_data;
1177  int x;
1178 
1179  avpriv_elbg_free(&s->elbg);
1180  av_frame_free(&s->last_frame);
1181  av_frame_free(&s->best_frame);
1182  av_frame_free(&s->scratch_frame);
1183  if (avctx->pix_fmt == AV_PIX_FMT_RGB24)
1184  av_frame_free(&s->input_frame);
1185  av_freep(&s->codebook_input);
1186  av_freep(&s->codebook_closest);
1187  av_freep(&s->strip_buf);
1188  av_freep(&s->frame_buf);
1189  av_freep(&s->mb);
1190 
1191  for (x = 0; x < (avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 4 : 3); x++)
1192  av_freep(&s->pict_bufs[x]);
1193 
1194  return 0;
1195 }
1196 
1198  .name = "cinepak",
1199  .long_name = NULL_IF_CONFIG_SMALL("Cinepak"),
1200  .type = AVMEDIA_TYPE_VIDEO,
1201  .id = AV_CODEC_ID_CINEPAK,
1202  .priv_data_size = sizeof(CinepakEncContext),
1204  .encode2 = cinepak_encode_frame,
1205  .close = cinepak_encode_end,
1207  .priv_class = &cinepak_class,
1209 };
SMALLEST_CODEBOOK
#define SMALLEST_CODEBOOK
AVCodec
AVCodec.
Definition: codec.h:202
FF_CODEC_CAP_INIT_THREADSAFE
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:42
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
AVCodecContext::keyint_min
int keyint_min
minimum GOP size
Definition: avcodec.h:925
CinepakEncContext::scratch_frame
AVFrame * scratch_frame
Definition: cinepakenc.c:111
FF_LAMBDA_SCALE
#define FF_LAMBDA_SCALE
Definition: avutil.h:226
r
const char * r
Definition: vf_curves.c:116
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
options
static const AVOption options[]
Definition: cinepakenc.c:135
OFFSET
#define OFFSET(x)
Definition: cinepakenc.c:133
av_lfg_init
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:32
CERTAIN
#define CERTAIN(x)
Definition: cinepakenc.c:699
CinepakEncContext::codebook_input
int * codebook_input
Definition: cinepakenc.c:119
MB_AREA
#define MB_AREA
Definition: cinepakenc.c:56
CinepakEncContext::best_frame
AVFrame * best_frame
Definition: cinepakenc.c:110
CinepakEncContext::last_frame
AVFrame * last_frame
Definition: cinepakenc.c:109
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:109
rd_strip
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:856
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
CinepakEncContext::keyint
int keyint
Definition: cinepakenc.c:116
cinepak_encode_init
static av_cold int cinepak_encode_init(AVCodecContext *avctx)
Definition: cinepakenc.c:156
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:373
CinepakEncContext::input_frame
AVFrame * input_frame
Definition: cinepakenc.c:112
AVOption
AVOption.
Definition: opt.h:247
encode.h
b
#define b
Definition: input.c:40
data
const char data[16]
Definition: mxf.c:143
ENC_V1
@ ENC_V1
Definition: cinepakenc.c:81
base
uint8_t base
Definition: vp3data.h:141
rd_frame
static int rd_frame(CinepakEncContext *s, const AVFrame *frame, int isakeyframe, unsigned char *buf, int buf_size)
Definition: cinepakenc.c:1001
MODE_MC
@ MODE_MC
Definition: cinepakenc.c:75
decode_v1_vector
static void decode_v1_vector(CinepakEncContext *s, uint8_t *data[4], int linesize[4], int v1_vector, strip_info *info)
Definition: cinepakenc.c:449
CODEBOOK_MAX
#define CODEBOOK_MAX
Definition: cinepakenc.c:59
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:428
CinepakEncContext::randctx
AVLFG randctx
Definition: cinepakenc.c:117
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
init
static int init
Definition: av_tx.c:47
CinepakEncContext::avctx
AVCodecContext * avctx
Definition: cinepakenc.c:107
cinepak_encode_end
static av_cold int cinepak_encode_end(AVCodecContext *avctx)
Definition: cinepakenc.c:1174
U
#define U(x)
Definition: vp56_arith.h:37
decode_v4_vector
static void decode_v4_vector(CinepakEncContext *s, uint8_t *data[4], int linesize[4], int *v4_vector, strip_info *info)
Definition: cinepakenc.c:488
MODE_V1_V4
@ MODE_V1_V4
Definition: cinepakenc.c:74
quantize
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:700
strip_info
Definition: cinepakenc.c:97
write_strip_header
static void write_strip_header(CinepakEncContext *s, int y, int h, int keyframe, unsigned char *buf, int strip_size)
Definition: cinepakenc.c:838
write_cvid_header
static int write_cvid_header(CinepakEncContext *s, unsigned char *buf, int num_strips, int data_size, int isakeyframe)
Definition: cinepakenc.c:989
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:97
avpriv_elbg_do
int avpriv_elbg_do(ELBGContext **elbgp, int *points, int dim, int numpoints, int *codebook, int num_cb, int max_steps, int *closest_cb, AVLFG *rand_state, uintptr_t flags)
Implementation of the Enhanced LBG Algorithm Based on the paper "Neural Networks 14:1219-1237" that c...
Definition: elbg.c:446
ENC_SKIP
@ ENC_SKIP
Definition: cinepakenc.c:83
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
STRIP_HEADER_SIZE
#define STRIP_HEADER_SIZE
Definition: cinepakenc.c:52
MODE_V1_ONLY
@ MODE_V1_ONLY
Definition: cinepakenc.c:73
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
VE
#define VE
Definition: cinepakenc.c:134
CinepakEncContext::skip_empty_cb
int skip_empty_cb
Definition: cinepakenc.c:126
g
const char * g
Definition: vf_curves.c:117
info
MIPS optimizations info
Definition: mips.txt:2
lfg.h
MAX_STRIPS
#define MAX_STRIPS
Definition: cinepakenc.c:61
CinepakEncContext
Definition: cinepakenc.c:105
CinepakEncContext::frame_buf_size
int frame_buf_size
Definition: cinepakenc.c:115
bits
uint8_t bits
Definition: vp3data.h:141
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:296
if
if(ret)
Definition: filter_design.txt:179
elbg.h
encode_codebook
static int encode_codebook(CinepakEncContext *s, int *codebook, int size, int chunk_type_yuv, int chunk_type_gray, unsigned char *buf)
Definition: cinepakenc.c:384
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
mb_info::v4_vector
int v4_vector[4]
Definition: cinepakenc.c:91
strip_info::v1_size
int v1_size
Definition: cinepakenc.c:100
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:405
AV_CODEC_ID_CINEPAK
@ AV_CODEC_ID_CINEPAK
Definition: codec_id.h:93
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
cinepak_class
static const AVClass cinepak_class
Definition: cinepakenc.c:149
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
MB_SIZE
#define MB_SIZE
Definition: cinepakenc.c:55
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
ENC_UNCERTAIN
@ ENC_UNCERTAIN
Definition: cinepakenc.c:85
AVLFG
Context structure for the Lagged Fibonacci PRNG.
Definition: lfg.h:33
copy_mb
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:508
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
CinepakEncContext::min_strips
int min_strips
Definition: cinepakenc.c:122
AVPacket::size
int size
Definition: packet.h:374
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
get_sub_picture
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:432
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
size
int size
Definition: twinvq_data.h:10344
encode_mode
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:527
avpriv_elbg_free
av_cold void avpriv_elbg_free(ELBGContext **elbgp)
Free an ELBGContext and reset the pointer to it.
Definition: elbg.c:499
CinepakEncContext::elbg
struct ELBGContext * elbg
Definition: cinepakenc.c:130
strip_info::v4_size
int v4_size
Definition: cinepakenc.c:101
AV_WB24
#define AV_WB24(p, d)
Definition: intreadwrite.h:450
VECTOR_MAX
#define VECTOR_MAX
Definition: cinepakenc.c:58
strip_info::v4_codebook
int v4_codebook[CODEBOOK_MAX *VECTOR_MAX]
Definition: cinepakenc.c:99
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:379
mb
#define mb
Definition: vf_colormatrix.c:101
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
mb_encoding
mb_encoding
Definition: cinepakenc.c:80
report
#define report
Definition: checkasm.h:131
CinepakEncContext::max_extra_cb_iterations
int max_extra_cb_iterations
Definition: cinepakenc.c:125
mb_info::v1_vector
int v1_vector
Definition: cinepakenc.c:89
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:50
internal.h
cinepak_encode_frame
static int cinepak_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: cinepakenc.c:1150
ELBGContext
ELBG internal data.
Definition: elbg.c:46
ENC_V4
@ ENC_V4
Definition: cinepakenc.c:82
CinepakEncContext::h
int h
Definition: cinepakenc.c:114
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
common.h
CinepakEncContext::curframe
int curframe
Definition: cinepakenc.c:116
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
CinepakEncContext::pict_bufs
unsigned char * pict_bufs[4]
Definition: cinepakenc.c:108
CinepakEncContext::codebook_closest
int * codebook_closest
Definition: cinepakenc.c:120
AVCodecContext::height
int height
Definition: avcodec.h:556
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:593
avcodec.h
ret
ret
Definition: filter_design.txt:187
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
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:71
mb_info::best_encoding
mb_encoding best_encoding
Definition: cinepakenc.c:94
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
calculate_skip_errors
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:815
mb_info::v4_error
int v4_error
Definition: cinepakenc.c:92
CVID_HEADER_SIZE
#define CVID_HEADER_SIZE
Definition: cinepakenc.c:51
CinepakMode
CinepakMode
Definition: cinepakenc.c:72
calculate_mode_score
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:259
AVCodecContext
main external API structure.
Definition: avcodec.h:383
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
mb_info::v1_error
int v1_error
Definition: cinepakenc.c:90
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
write_chunk_header
static int write_chunk_header(unsigned char *buf, int chunk_type, int chunk_size)
Definition: cinepakenc.c:377
CinepakEncContext::mb
mb_info * mb
Definition: cinepakenc.c:121
CinepakEncContext::pix_fmt
enum AVPixelFormat pix_fmt
Definition: cinepakenc.c:113
temp
else temp
Definition: vf_mcdeint.c:248
CinepakEncContext::lambda
uint64_t lambda
Definition: cinepakenc.c:118
CinepakEncContext::frame_buf
unsigned char * frame_buf
Definition: cinepakenc.c:108
CinepakEncContext::max_strips
int max_strips
Definition: cinepakenc.c:123
shift
static int shift(int a, int b)
Definition: sonic.c:84
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
CHUNK_HEADER_SIZE
#define CHUNK_HEADER_SIZE
Definition: cinepakenc.c:53
strip_info::mode
CinepakMode mode
Definition: cinepakenc.c:102
mb_info::skip_error
int skip_error
Definition: cinepakenc.c:93
CinepakEncContext::strip_number_delta_range
int strip_number_delta_range
Definition: cinepakenc.c:129
AVPacket
This structure stores compressed data.
Definition: packet.h:350
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:410
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:241
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
strip_info::v1_codebook
int v1_codebook[CODEBOOK_MAX *VECTOR_MAX]
Definition: cinepakenc.c:98
d
d
Definition: ffmpeg_filter.c:153
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:556
ff_cinepak_encoder
const AVCodec ff_cinepak_encoder
Definition: cinepakenc.c:1197
int32_t
int32_t
Definition: audioconvert.c:56
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
MODE_COUNT
@ MODE_COUNT
Definition: cinepakenc.c:77
h
h
Definition: vp9dsp_template.c:2038
CinepakEncContext::max_max_strips
int max_max_strips
Definition: cinepakenc.c:128
compute_mb_distortion
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:673
CinepakEncContext::min_min_strips
int min_min_strips
Definition: cinepakenc.c:127
CinepakEncContext::strip_buf
unsigned char * strip_buf
Definition: cinepakenc.c:108
ff_alloc_packet
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size)
Check AVPacket size and allocate data.
Definition: encode.c:34
MIN_STRIPS
#define MIN_STRIPS
Definition: cinepakenc.c:62
CinepakEncContext::w
int w
Definition: cinepakenc.c:114
mb_info
Definition: cinepakenc.c:88
codebook
static const unsigned codebook[256][2]
Definition: cfhdenc.c:42