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