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  int64_t total_error = 0;
709  uint8_t vq_pict_buf[(MB_AREA * 3) / 2];
710  uint8_t *sub_data[4], *vq_data[4];
711  int sub_linesize[4], vq_linesize[4];
712  int ret;
713 
714  for (mbn = i = y = 0; y < h; y += MB_SIZE) {
715  for (x = 0; x < s->w; x += MB_SIZE, ++mbn) {
716  int *base;
717 
718  if (CERTAIN(encoding)) {
719  // use for the training only the blocks known to be to be encoded [sic:-]
720  if (s->mb[mbn].best_encoding != encoding)
721  continue;
722  }
723 
724  base = s->codebook_input + i * entry_size;
725  if (v1mode) {
726  // subsample
727  for (j = y2 = 0; y2 < entry_size; y2 += 2)
728  for (x2 = 0; x2 < 4; x2 += 2, j++) {
729  plane = y2 < 4 ? 0 : 1 + (x2 >> 1);
730  shift = y2 < 4 ? 0 : 1;
731  x3 = shift ? 0 : x2;
732  y3 = shift ? 0 : y2;
733  base[j] = (data[plane][((x + x3) >> shift) + ((y + y3) >> shift) * linesize[plane]] +
734  data[plane][((x + x3) >> shift) + 1 + ((y + y3) >> shift) * linesize[plane]] +
735  data[plane][((x + x3) >> shift) + (((y + y3) >> shift) + 1) * linesize[plane]] +
736  data[plane][((x + x3) >> shift) + 1 + (((y + y3) >> shift) + 1) * linesize[plane]]) >> 2;
737  }
738  } else {
739  // copy
740  for (j = y2 = 0; y2 < MB_SIZE; y2 += 2) {
741  for (x2 = 0; x2 < MB_SIZE; x2 += 2)
742  for (k = 0; k < entry_size; k++, j++) {
743  plane = k >= 4 ? k - 3 : 0;
744 
745  if (k >= 4) {
746  x3 = (x + x2) >> 1;
747  y3 = (y + y2) >> 1;
748  } else {
749  x3 = x + x2 + (k & 1);
750  y3 = y + y2 + (k >> 1);
751  }
752 
753  base[j] = data[plane][x3 + y3 * linesize[plane]];
754  }
755  }
756  }
757  i += v1mode ? 1 : 4;
758  }
759  }
760 
761  if (i == 0) // empty training set, nothing to do
762  return 0;
763  if (i < size)
764  size = i;
765 
766  ret = avpriv_elbg_do(&s->elbg, s->codebook_input, entry_size, i, codebook,
767  size, 1, s->codebook_closest, &s->randctx, 0);
768  if (ret < 0)
769  return ret;
770 
771  // set up vq_data, which contains a single MB
772  vq_data[0] = vq_pict_buf;
773  vq_linesize[0] = MB_SIZE;
774  vq_data[1] = &vq_pict_buf[MB_AREA];
775  vq_data[2] = vq_data[1] + (MB_AREA >> 2);
776  vq_linesize[1] =
777  vq_linesize[2] = MB_SIZE >> 1;
778 
779  // copy indices
780  for (i = j = y = 0; y < h; y += MB_SIZE)
781  for (x = 0; x < s->w; x += MB_SIZE, j++) {
782  mb_info *mb = &s->mb[j];
783  // skip uninteresting blocks if we know their preferred encoding
784  if (CERTAIN(encoding) && mb->best_encoding != encoding)
785  continue;
786 
787  // point sub_data to current MB
788  get_sub_picture(s, x, y, data, linesize, sub_data, sub_linesize);
789 
790  if (v1mode) {
791  mb->v1_vector = s->codebook_closest[i];
792 
793  // fill in vq_data with V1 data
794  decode_v1_vector(s, vq_data, vq_linesize, mb->v1_vector, info);
795 
796  mb->v1_error = compute_mb_distortion(s, sub_data, sub_linesize,
797  vq_data, vq_linesize);
798  total_error += mb->v1_error;
799  } else {
800  for (k = 0; k < 4; k++)
801  mb->v4_vector[k] = s->codebook_closest[i + k];
802 
803  // fill in vq_data with V4 data
804  decode_v4_vector(s, vq_data, vq_linesize, mb->v4_vector, info);
805 
806  mb->v4_error = compute_mb_distortion(s, sub_data, sub_linesize,
807  vq_data, vq_linesize);
808  total_error += mb->v4_error;
809  }
810  i += v1mode ? 1 : 4;
811  }
812  // check that we did it right in the beginning of the function
813  av_assert0(i >= size); // training set is no smaller than the codebook
814 
815  return size;
816 }
817 
819  uint8_t *last_data[4], int last_linesize[4],
820  uint8_t *data[4], int linesize[4],
821  strip_info *info)
822 {
823  int x, y, i;
824  uint8_t *sub_last_data [4], *sub_pict_data [4];
825  int sub_last_linesize[4], sub_pict_linesize[4];
826 
827  for (i = y = 0; y < h; y += MB_SIZE)
828  for (x = 0; x < s->w; x += MB_SIZE, i++) {
829  get_sub_picture(s, x, y, last_data, last_linesize,
830  sub_last_data, sub_last_linesize);
831  get_sub_picture(s, x, y, data, linesize,
832  sub_pict_data, sub_pict_linesize);
833 
834  s->mb[i].skip_error =
836  sub_last_data, sub_last_linesize,
837  sub_pict_data, sub_pict_linesize);
838  }
839 }
840 
841 static void write_strip_header(CinepakEncContext *s, int y, int h, int keyframe,
842  unsigned char *buf, int strip_size)
843 {
844  // actually we are exclusively using intra strip coding (how much can we win
845  // otherwise? how to choose which part of a codebook to update?),
846  // keyframes are different only because we disallow ENC_SKIP on them -- rl
847  // (besides, the logic here used to be inverted: )
848  // buf[0] = keyframe ? 0x11: 0x10;
849  buf[0] = keyframe ? 0x10 : 0x11;
850  AV_WB24(&buf[1], strip_size + STRIP_HEADER_SIZE);
851  // AV_WB16(&buf[4], y); /* using absolute y values works -- rl */
852  AV_WB16(&buf[4], 0); /* using relative values works as well -- rl */
853  AV_WB16(&buf[6], 0);
854  // AV_WB16(&buf[8], y + h); /* using absolute y values works -- rl */
855  AV_WB16(&buf[8], h); /* using relative values works as well -- rl */
856  AV_WB16(&buf[10], s->w);
857 }
858 
859 static int rd_strip(CinepakEncContext *s, int y, int h, int keyframe,
860  uint8_t *last_data[4], int last_linesize[4],
861  uint8_t *data[4], int linesize[4],
862  uint8_t *scratch_data[4], int scratch_linesize[4],
863  unsigned char *buf, int64_t *best_score)
864 {
865  int64_t score = 0;
866  int best_size = 0;
868  // for codebook optimization:
869  int v1enough, v1_size, v4enough, v4_size;
870  int new_v1_size, new_v4_size;
871  int v1shrunk, v4shrunk;
872 
873  if (!keyframe)
874  calculate_skip_errors(s, h, last_data, last_linesize, data, linesize,
875  &info);
876 
877  // try some powers of 4 for the size of the codebooks
878  // constraint the v4 codebook to be no bigger than v1 one,
879  // (and no less than v1_size/4)
880  // thus making v1 preferable and possibly losing small details? should be ok
881 #define SMALLEST_CODEBOOK 1
882  for (v1enough = 0, v1_size = SMALLEST_CODEBOOK; v1_size <= CODEBOOK_MAX && !v1enough; v1_size <<= 2) {
883  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) {
885  // try all modes
886  for (mode = 0; mode < MODE_COUNT; mode++) {
887  // don't allow MODE_MC in intra frames
888  if (keyframe && mode == MODE_MC)
889  continue;
890 
891  if (mode == MODE_V1_ONLY) {
892  info.v1_size = v1_size;
893  // the size may shrink even before optimizations if the input is short:
894  if ((new_v1_size = quantize(s, h, data, linesize, 1,
895  &info, ENC_UNCERTAIN)) < 0)
896  return new_v1_size;
897  info.v1_size = new_v1_size;
898  if (info.v1_size < v1_size)
899  // too few eligible blocks, no sense in trying bigger sizes
900  v1enough = 1;
901 
902  info.v4_size = 0;
903  } else { // mode != MODE_V1_ONLY
904  // if v4 codebook is empty then only allow V1-only mode
905  if (!v4_size)
906  continue;
907 
908  if (mode == MODE_V1_V4) {
909  info.v4_size = v4_size;
910  new_v4_size = quantize(s, h, data, linesize, 0,
911  &info, ENC_UNCERTAIN);
912  if (new_v4_size < 0)
913  return new_v4_size;
914  info.v4_size = new_v4_size;
915  if (info.v4_size < v4_size)
916  // too few eligible blocks, no sense in trying bigger sizes
917  v4enough = 1;
918  }
919  }
920 
921  info.mode = mode;
922  // choose the best encoding per block, based on current experience
923  score = calculate_mode_score(s, h, &info, 0,
924  &v1shrunk, &v4shrunk);
925 
926  if (mode != MODE_V1_ONLY) {
927  int extra_iterations_limit = s->max_extra_cb_iterations;
928  // recompute the codebooks, omitting the extra blocks
929  // we assume we _may_ come here with more blocks to encode than before
930  info.v1_size = v1_size;
931  new_v1_size = quantize(s, h, data, linesize, 1, &info, ENC_V1);
932  if (new_v1_size < 0)
933  return new_v1_size;
934  if (new_v1_size < info.v1_size)
935  info.v1_size = new_v1_size;
936  // we assume we _may_ come here with more blocks to encode than before
937  info.v4_size = v4_size;
938  new_v4_size = quantize(s, h, data, linesize, 0, &info, ENC_V4);
939  if (new_v4_size < 0)
940  return new_v4_size;
941  if (new_v4_size < info.v4_size)
942  info.v4_size = new_v4_size;
943  // calculate the resulting score
944  // (do not move blocks to codebook encodings now, as some blocks may have
945  // got bigger errors despite a smaller training set - but we do not
946  // ever grow the training sets back)
947  for (;;) {
948  score = calculate_mode_score(s, h, &info, 1,
949  &v1shrunk, &v4shrunk);
950  // do we have a reason to reiterate? if so, have we reached the limit?
951  if ((!v1shrunk && !v4shrunk) || !extra_iterations_limit--)
952  break;
953  // recompute the codebooks, omitting the extra blocks
954  if (v1shrunk) {
955  info.v1_size = v1_size;
956  new_v1_size = quantize(s, h, data, linesize, 1, &info, ENC_V1);
957  if (new_v1_size < 0)
958  return new_v1_size;
959  if (new_v1_size < info.v1_size)
960  info.v1_size = new_v1_size;
961  }
962  if (v4shrunk) {
963  info.v4_size = v4_size;
964  new_v4_size = quantize(s, h, data, linesize, 0, &info, ENC_V4);
965  if (new_v4_size < 0)
966  return new_v4_size;
967  if (new_v4_size < info.v4_size)
968  info.v4_size = new_v4_size;
969  }
970  }
971  }
972 
973  if (best_size == 0 || score < *best_score) {
974  *best_score = score;
975  best_size = encode_mode(s, h,
976  scratch_data, scratch_linesize,
977  last_data, last_linesize, &info,
978  s->strip_buf + STRIP_HEADER_SIZE);
979 
980  write_strip_header(s, y, h, keyframe, s->strip_buf, best_size);
981  }
982  }
983  }
984  }
985 
986  best_size += STRIP_HEADER_SIZE;
987  memcpy(buf, s->strip_buf, best_size);
988 
989  return best_size;
990 }
991 
992 static int write_cvid_header(CinepakEncContext *s, unsigned char *buf,
993  int num_strips, int data_size, int isakeyframe)
994 {
995  buf[0] = isakeyframe ? 0 : 1;
996  AV_WB24(&buf[1], data_size + CVID_HEADER_SIZE);
997  AV_WB16(&buf[4], s->w);
998  AV_WB16(&buf[6], s->h);
999  AV_WB16(&buf[8], num_strips);
1000 
1001  return CVID_HEADER_SIZE;
1002 }
1003 
1005  int isakeyframe, unsigned char *buf, int buf_size)
1006 {
1007  int num_strips, strip, i, y, nexty, size, temp_size, best_size;
1008  uint8_t *last_data [4], *data [4], *scratch_data [4];
1009  int last_linesize[4], linesize[4], scratch_linesize[4];
1010  int64_t best_score = 0, score, score_temp;
1011  int best_nstrips;
1012 
1013  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
1014  int x;
1015  // build a copy of the given frame in the correct colorspace
1016  for (y = 0; y < s->h; y += 2)
1017  for (x = 0; x < s->w; x += 2) {
1018  uint8_t *ir[2];
1019  int32_t r, g, b, rr, gg, bb;
1020  ir[0] = frame->data[0] + x * 3 + y * frame->linesize[0];
1021  ir[1] = ir[0] + frame->linesize[0];
1022  get_sub_picture(s, x, y,
1023  s->input_frame->data, s->input_frame->linesize,
1024  scratch_data, scratch_linesize);
1025  r = g = b = 0;
1026  for (i = 0; i < 4; ++i) {
1027  int i1, i2;
1028  i1 = (i & 1);
1029  i2 = (i >= 2);
1030  rr = ir[i2][i1 * 3 + 0];
1031  gg = ir[i2][i1 * 3 + 1];
1032  bb = ir[i2][i1 * 3 + 2];
1033  r += rr;
1034  g += gg;
1035  b += bb;
1036  // using fixed point arithmetic for portable repeatability, scaling by 2^23
1037  // "Y"
1038  // rr = 0.2857 * rr + 0.5714 * gg + 0.1429 * bb;
1039  rr = (2396625 * rr + 4793251 * gg + 1198732 * bb) >> 23;
1040  if (rr < 0)
1041  rr = 0;
1042  else if (rr > 255)
1043  rr = 255;
1044  scratch_data[0][i1 + i2 * scratch_linesize[0]] = rr;
1045  }
1046  // let us scale down as late as possible
1047  // r /= 4; g /= 4; b /= 4;
1048  // "U"
1049  // rr = -0.1429 * r - 0.2857 * g + 0.4286 * b;
1050  rr = (-299683 * r - 599156 * g + 898839 * b) >> 23;
1051  if (rr < -128)
1052  rr = -128;
1053  else if (rr > 127)
1054  rr = 127;
1055  scratch_data[1][0] = rr + 128; // quantize needs unsigned
1056  // "V"
1057  // rr = 0.3571 * r - 0.2857 * g - 0.0714 * b;
1058  rr = (748893 * r - 599156 * g - 149737 * b) >> 23;
1059  if (rr < -128)
1060  rr = -128;
1061  else if (rr > 127)
1062  rr = 127;
1063  scratch_data[2][0] = rr + 128; // quantize needs unsigned
1064  }
1065  }
1066 
1067  // would be nice but quite certainly incompatible with vintage players:
1068  // support encoding zero strips (meaning skip the whole frame)
1069  for (num_strips = s->min_strips; num_strips <= s->max_strips && num_strips <= s->h / MB_SIZE; num_strips++) {
1070  score = 0;
1071  size = 0;
1072 
1073  for (y = 0, strip = 1; y < s->h; strip++, y = nexty) {
1074  int strip_height;
1075 
1076  nexty = strip * s->h / num_strips; // <= s->h
1077  // make nexty the next multiple of 4 if not already there
1078  if (nexty & 3)
1079  nexty += 4 - (nexty & 3);
1080 
1081  strip_height = nexty - y;
1082  if (strip_height <= 0) { // can this ever happen?
1083  av_log(s->avctx, AV_LOG_INFO, "skipping zero height strip %i of %i\n", strip, num_strips);
1084  continue;
1085  }
1086 
1087  if (s->pix_fmt == AV_PIX_FMT_RGB24)
1088  get_sub_picture(s, 0, y,
1089  s->input_frame->data, s->input_frame->linesize,
1090  data, linesize);
1091  else
1092  get_sub_picture(s, 0, y,
1093  (uint8_t **)frame->data, (int *)frame->linesize,
1094  data, linesize);
1095  get_sub_picture(s, 0, y,
1096  s->last_frame->data, s->last_frame->linesize,
1097  last_data, last_linesize);
1098  get_sub_picture(s, 0, y,
1099  s->scratch_frame->data, s->scratch_frame->linesize,
1100  scratch_data, scratch_linesize);
1101 
1102  if ((temp_size = rd_strip(s, y, strip_height, isakeyframe,
1103  last_data, last_linesize, data, linesize,
1104  scratch_data, scratch_linesize,
1105  s->frame_buf + size + CVID_HEADER_SIZE,
1106  &score_temp)) < 0)
1107  return temp_size;
1108 
1109  score += score_temp;
1110  size += temp_size;
1111  }
1112 
1113  if (best_score == 0 || score < best_score) {
1114  best_score = score;
1115  best_size = size + write_cvid_header(s, s->frame_buf, num_strips, size, isakeyframe);
1116 
1117  FFSWAP(AVFrame *, s->best_frame, s->scratch_frame);
1118  memcpy(buf, s->frame_buf, best_size);
1119  best_nstrips = num_strips;
1120  }
1121  // avoid trying too many strip numbers without a real reason
1122  // (this makes the processing of the very first frame faster)
1123  if (num_strips - best_nstrips > 4)
1124  break;
1125  }
1126 
1127  // let the number of strips slowly adapt to the changes in the contents,
1128  // compared to full bruteforcing every time this will occasionally lead
1129  // to some r/d performance loss but makes encoding up to several times faster
1130  if (!s->strip_number_delta_range) {
1131  if (best_nstrips == s->max_strips) { // let us try to step up
1132  s->max_strips = best_nstrips + 1;
1133  if (s->max_strips >= s->max_max_strips)
1134  s->max_strips = s->max_max_strips;
1135  } else { // try to step down
1136  s->max_strips = best_nstrips;
1137  }
1138  s->min_strips = s->max_strips - 1;
1139  if (s->min_strips < s->min_min_strips)
1140  s->min_strips = s->min_min_strips;
1141  } else {
1142  s->max_strips = best_nstrips + s->strip_number_delta_range;
1143  if (s->max_strips >= s->max_max_strips)
1144  s->max_strips = s->max_max_strips;
1145  s->min_strips = best_nstrips - s->strip_number_delta_range;
1146  if (s->min_strips < s->min_min_strips)
1147  s->min_strips = s->min_min_strips;
1148  }
1149 
1150  return best_size;
1151 }
1152 
1154  const AVFrame *frame, int *got_packet)
1155 {
1156  CinepakEncContext *s = avctx->priv_data;
1157  int ret;
1158 
1159  s->lambda = frame->quality ? frame->quality - 1 : 2 * FF_LAMBDA_SCALE;
1160 
1161  if ((ret = ff_alloc_packet(avctx, pkt, s->frame_buf_size)) < 0)
1162  return ret;
1163  ret = rd_frame(s, frame, (s->curframe == 0), pkt->data, s->frame_buf_size);
1164  pkt->size = ret;
1165  if (s->curframe == 0)
1167  *got_packet = 1;
1168 
1169  FFSWAP(AVFrame *, s->last_frame, s->best_frame);
1170 
1171  if (++s->curframe >= s->keyint)
1172  s->curframe = 0;
1173 
1174  return 0;
1175 }
1176 
1178 {
1179  CinepakEncContext *s = avctx->priv_data;
1180  int x;
1181 
1182  avpriv_elbg_free(&s->elbg);
1183  av_frame_free(&s->last_frame);
1184  av_frame_free(&s->best_frame);
1185  av_frame_free(&s->scratch_frame);
1186  if (avctx->pix_fmt == AV_PIX_FMT_RGB24)
1187  av_frame_free(&s->input_frame);
1188  av_freep(&s->codebook_input);
1189  av_freep(&s->codebook_closest);
1190  av_freep(&s->strip_buf);
1191  av_freep(&s->frame_buf);
1192  av_freep(&s->mb);
1193 
1194  for (x = 0; x < (avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 4 : 3); x++)
1195  av_freep(&s->pict_bufs[x]);
1196 
1197  return 0;
1198 }
1199 
1201  .name = "cinepak",
1202  .long_name = NULL_IF_CONFIG_SMALL("Cinepak"),
1203  .type = AVMEDIA_TYPE_VIDEO,
1204  .id = AV_CODEC_ID_CINEPAK,
1205  .priv_data_size = sizeof(CinepakEncContext),
1207  .encode2 = cinepak_encode_frame,
1208  .close = cinepak_encode_end,
1210  .priv_class = &cinepak_class,
1212 };
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
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
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:112
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:859
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
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:1004
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:425
CinepakEncContext::randctx
AVLFG randctx
Definition: cinepakenc.c:117
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
CinepakEncContext::avctx
AVCodecContext * avctx
Definition: cinepakenc.c:107
cinepak_encode_end
static av_cold int cinepak_encode_end(AVCodecContext *avctx)
Definition: cinepakenc.c:1177
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:841
write_cvid_header
static int write_cvid_header(CinepakEncContext *s, unsigned char *buf, int num_strips, int data_size, int isakeyframe)
Definition: cinepakenc.c:992
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:99
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:290
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
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
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
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:130
CinepakEncContext::max_extra_cb_iterations
int max_extra_cb_iterations
Definition: cinepakenc.c:125
i
int i
Definition: input.c:406
mb_info::v1_vector
int v1_vector
Definition: cinepakenc.c:89
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:1153
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:818
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:256
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:83
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:156
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:556
ff_cinepak_encoder
const AVCodec ff_cinepak_encoder
Definition: cinepakenc.c:1200
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