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/intreadwrite.h"
41 #include "libavutil/lfg.h"
42 #include "libavutil/mem.h"
43 #include "libavutil/opt.h"
44 
45 #include "avcodec.h"
46 #include "codec_internal.h"
47 #include "elbg.h"
48 #include "encode.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;
115  int curframe;
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
129  struct ELBGContext *elbg;
131 
132 #define OFFSET(x) offsetof(CinepakEncContext, x)
133 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
134 static const AVOption options[] = {
135  { "max_extra_cb_iterations", "Max extra codebook recalculation passes, more is better and slower",
136  OFFSET(max_extra_cb_iterations), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, INT_MAX, VE },
137  { "skip_empty_cb", "Avoid wasting bytes, ignore vintage MacOS decoder",
138  OFFSET(skip_empty_cb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
139  { "max_strips", "Limit strips/frame, vintage compatible is 1..3, otherwise the more the better",
140  OFFSET(max_max_strips), AV_OPT_TYPE_INT, { .i64 = 3 }, MIN_STRIPS, MAX_STRIPS, VE },
141  { "min_strips", "Enforce min strips/frame, more is worse and faster, must be <= max_strips",
142  OFFSET(min_min_strips), AV_OPT_TYPE_INT, { .i64 = MIN_STRIPS }, MIN_STRIPS, MAX_STRIPS, VE },
143  { "strip_number_adaptivity", "How fast the strip number adapts, more is slightly better, much slower",
144  OFFSET(strip_number_delta_range), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MAX_STRIPS - MIN_STRIPS, VE },
145  { NULL },
146 };
147 
148 static const AVClass cinepak_class = {
149  .class_name = "cinepak",
150  .item_name = av_default_item_name,
151  .option = options,
152  .version = LIBAVUTIL_VERSION_INT,
153 };
154 
156 {
157  CinepakEncContext *s = avctx->priv_data;
158  int x, mb_count, strip_buf_size, frame_buf_size;
159 
160  if (avctx->width & 3 || avctx->height & 3) {
161  av_log(avctx, AV_LOG_ERROR, "width and height must be multiples of four (got %ix%i)\n",
162  avctx->width, avctx->height);
163  return AVERROR(EINVAL);
164  }
165 
166  if (s->min_min_strips > s->max_max_strips) {
167  av_log(avctx, AV_LOG_ERROR, "minimum number of strips must not exceed maximum (got %i and %i)\n",
168  s->min_min_strips, s->max_max_strips);
169  return AVERROR(EINVAL);
170  }
171 
172  if (!(s->last_frame = av_frame_alloc()))
173  return AVERROR(ENOMEM);
174  if (!(s->best_frame = av_frame_alloc()))
175  return AVERROR(ENOMEM);
176  if (!(s->scratch_frame = av_frame_alloc()))
177  return AVERROR(ENOMEM);
178  if (avctx->pix_fmt == AV_PIX_FMT_RGB24)
179  if (!(s->input_frame = av_frame_alloc()))
180  return AVERROR(ENOMEM);
181 
182  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))))
183  return AVERROR(ENOMEM);
184 
185  if (!(s->codebook_closest = av_malloc_array((avctx->width * avctx->height) >> 2, sizeof(*s->codebook_closest))))
186  return AVERROR(ENOMEM);
187 
188  for (x = 0; x < (avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 4 : 3); x++)
189  if (!(s->pict_bufs[x] = av_malloc((avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4) * (avctx->width * avctx->height) >> 2)))
190  return AVERROR(ENOMEM);
191 
192  mb_count = avctx->width * avctx->height / MB_AREA;
193 
194  // the largest possible chunk is 0x31 with all MBs encoded in V4 mode
195  // and full codebooks being replaced in INTER mode,
196  // which is 34 bits per MB
197  // and 2*256 extra flag bits per strip
198  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;
199 
200  frame_buf_size = CVID_HEADER_SIZE + s->max_max_strips * strip_buf_size;
201 
202  if (!(s->strip_buf = av_malloc(strip_buf_size)))
203  return AVERROR(ENOMEM);
204 
205  if (!(s->frame_buf = av_malloc(frame_buf_size)))
206  return AVERROR(ENOMEM);
207 
208  if (!(s->mb = av_malloc_array(mb_count, sizeof(mb_info))))
209  return AVERROR(ENOMEM);
210 
211  av_lfg_init(&s->randctx, 1);
212  s->avctx = avctx;
213  s->w = avctx->width;
214  s->h = avctx->height;
215  s->frame_buf_size = frame_buf_size;
216  s->curframe = 0;
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 
258  strip_info *info, int report,
259  int *training_set_v1_shrunk,
260  int *training_set_v4_shrunk)
261 {
262  // score = FF_LAMBDA_SCALE * error + lambda * bits
263  int x;
264  int entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
265  int mb_count = s->w * h / MB_AREA;
266  mb_info *mb;
267  int64_t score1, score2, score3;
268  int64_t ret = s->lambda * ((info->v1_size ? CHUNK_HEADER_SIZE + info->v1_size * entry_size : 0) +
269  (info->v4_size ? CHUNK_HEADER_SIZE + info->v4_size * entry_size : 0) +
270  CHUNK_HEADER_SIZE) << 3;
271 
272  switch (info->mode) {
273  case MODE_V1_ONLY:
274  // one byte per MB
275  ret += s->lambda * 8 * mb_count;
276 
277  // while calculating we assume all blocks are ENC_V1
278  for (x = 0; x < mb_count; x++) {
279  mb = &s->mb[x];
280  ret += FF_LAMBDA_SCALE * mb->v1_error;
281  // this function is never called for report in MODE_V1_ONLY
282  // if (!report)
283  mb->best_encoding = ENC_V1;
284  }
285 
286  break;
287  case MODE_V1_V4:
288  // 9 or 33 bits per MB
289  if (report) {
290  // no moves between the corresponding training sets are allowed
291  *training_set_v1_shrunk = *training_set_v4_shrunk = 0;
292  for (x = 0; x < mb_count; x++) {
293  int mberr;
294  mb = &s->mb[x];
295  if (mb->best_encoding == ENC_V1)
296  score1 = s->lambda * 9 + FF_LAMBDA_SCALE * (mberr = mb->v1_error);
297  else
298  score1 = s->lambda * 33 + FF_LAMBDA_SCALE * (mberr = mb->v4_error);
299  ret += score1;
300  }
301  } else { // find best mode per block
302  for (x = 0; x < mb_count; x++) {
303  mb = &s->mb[x];
304  score1 = s->lambda * 9 + FF_LAMBDA_SCALE * mb->v1_error;
305  score2 = s->lambda * 33 + FF_LAMBDA_SCALE * mb->v4_error;
306 
307  if (score1 <= score2) {
308  ret += score1;
309  mb->best_encoding = ENC_V1;
310  } else {
311  ret += score2;
312  mb->best_encoding = ENC_V4;
313  }
314  }
315  }
316 
317  break;
318  case MODE_MC:
319  // 1, 10 or 34 bits per MB
320  if (report) {
321  int v1_shrunk = 0, v4_shrunk = 0;
322  for (x = 0; x < mb_count; x++) {
323  mb = &s->mb[x];
324  // it is OK to move blocks to ENC_SKIP here
325  // but not to any codebook encoding!
326  score1 = s->lambda * 1 + FF_LAMBDA_SCALE * mb->skip_error;
327  if (mb->best_encoding == ENC_SKIP) {
328  ret += score1;
329  } else if (mb->best_encoding == ENC_V1) {
330  if ((score2 = s->lambda * 10 + FF_LAMBDA_SCALE * mb->v1_error) >= score1) {
331  mb->best_encoding = ENC_SKIP;
332  ++v1_shrunk;
333  ret += score1;
334  } else {
335  ret += score2;
336  }
337  } else {
338  if ((score3 = s->lambda * 34 + FF_LAMBDA_SCALE * mb->v4_error) >= score1) {
339  mb->best_encoding = ENC_SKIP;
340  ++v4_shrunk;
341  ret += score1;
342  } else {
343  ret += score3;
344  }
345  }
346  }
347  *training_set_v1_shrunk = v1_shrunk;
348  *training_set_v4_shrunk = v4_shrunk;
349  } else { // find best mode per block
350  for (x = 0; x < mb_count; x++) {
351  mb = &s->mb[x];
352  score1 = s->lambda * 1 + FF_LAMBDA_SCALE * mb->skip_error;
353  score2 = s->lambda * 10 + FF_LAMBDA_SCALE * mb->v1_error;
354  score3 = s->lambda * 34 + FF_LAMBDA_SCALE * mb->v4_error;
355 
356  if (score1 <= score2 && score1 <= score3) {
357  ret += score1;
358  mb->best_encoding = ENC_SKIP;
359  } else if (score2 <= score3) {
360  ret += score2;
361  mb->best_encoding = ENC_V1;
362  } else {
363  ret += score3;
364  mb->best_encoding = ENC_V4;
365  }
366  }
367  }
368 
369  break;
370  }
371 
372  return ret;
373 }
374 
375 static int write_chunk_header(unsigned char *buf, int chunk_type, int chunk_size)
376 {
377  buf[0] = chunk_type;
378  AV_WB24(&buf[1], chunk_size + CHUNK_HEADER_SIZE);
379  return CHUNK_HEADER_SIZE;
380 }
381 
383  int chunk_type_yuv, int chunk_type_gray,
384  unsigned char *buf)
385 {
386  int x, y, ret, entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
387  int incremental_codebook_replacement_mode = 0; // hardcoded here,
388  // the compiler should notice that this is a constant -- rl
389 
390  ret = write_chunk_header(buf,
391  s->pix_fmt == AV_PIX_FMT_RGB24 ?
392  chunk_type_yuv + (incremental_codebook_replacement_mode ? 1 : 0) :
393  chunk_type_gray + (incremental_codebook_replacement_mode ? 1 : 0),
394  entry_size * size +
395  (incremental_codebook_replacement_mode ? (size + 31) / 32 * 4 : 0));
396 
397  // we do codebook encoding according to the "intra" mode
398  // but we keep the "dead" code for reference in case we will want
399  // to use incremental codebook updates (which actually would give us
400  // "kind of" motion compensation, especially in 1 strip/frame case) -- rl
401  // (of course, the code will be not useful as-is)
402  if (incremental_codebook_replacement_mode) {
403  int flags = 0;
404  int flagsind;
405  for (x = 0; x < size; x++) {
406  if (flags == 0) {
407  flagsind = ret;
408  ret += 4;
409  flags = 0x80000000;
410  } else
411  flags = ((flags >> 1) | 0x80000000);
412  for (y = 0; y < entry_size; y++)
413  buf[ret++] = codebook[y + x * entry_size] ^ (y >= 4 ? 0x80 : 0);
414  if ((flags & 0xffffffff) == 0xffffffff) {
415  AV_WB32(&buf[flagsind], flags);
416  flags = 0;
417  }
418  }
419  if (flags)
420  AV_WB32(&buf[flagsind], flags);
421  } else
422  for (x = 0; x < size; x++)
423  for (y = 0; y < entry_size; y++)
424  buf[ret++] = codebook[y + x * entry_size] ^ (y >= 4 ? 0x80 : 0);
425 
426  return ret;
427 }
428 
429 // sets out to the sub picture starting at (x,y) in in
430 static void get_sub_picture(CinepakEncContext *s, int x, int y,
431  uint8_t *const in_data[4], const int in_linesize[4],
432  uint8_t *out_data[4], int out_linesize[4])
433 {
434  out_data[0] = in_data[0] + x + y * in_linesize[0];
435  out_linesize[0] = in_linesize[0];
436 
437  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
438  out_data[1] = in_data[1] + (x >> 1) + (y >> 1) * in_linesize[1];
439  out_linesize[1] = in_linesize[1];
440 
441  out_data[2] = in_data[2] + (x >> 1) + (y >> 1) * in_linesize[2];
442  out_linesize[2] = in_linesize[2];
443  }
444 }
445 
446 // decodes the V1 vector in mb into the 4x4 MB pointed to by data
447 static void decode_v1_vector(CinepakEncContext *s, uint8_t *data[4],
448  int linesize[4], int v1_vector, strip_info *info)
449 {
450  int entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
451 
452  data[0][0] =
453  data[0][1] =
454  data[0][ linesize[0]] =
455  data[0][1 + linesize[0]] = info->v1_codebook[v1_vector * entry_size];
456 
457  data[0][2] =
458  data[0][3] =
459  data[0][2 + linesize[0]] =
460  data[0][3 + linesize[0]] = info->v1_codebook[v1_vector * entry_size + 1];
461 
462  data[0][ 2 * linesize[0]] =
463  data[0][1 + 2 * linesize[0]] =
464  data[0][ 3 * linesize[0]] =
465  data[0][1 + 3 * linesize[0]] = info->v1_codebook[v1_vector * entry_size + 2];
466 
467  data[0][2 + 2 * linesize[0]] =
468  data[0][3 + 2 * linesize[0]] =
469  data[0][2 + 3 * linesize[0]] =
470  data[0][3 + 3 * linesize[0]] = info->v1_codebook[v1_vector * entry_size + 3];
471 
472  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
473  data[1][0] =
474  data[1][1] =
475  data[1][ linesize[1]] =
476  data[1][1 + linesize[1]] = info->v1_codebook[v1_vector * entry_size + 4];
477 
478  data[2][0] =
479  data[2][1] =
480  data[2][ linesize[2]] =
481  data[2][1 + linesize[2]] = info->v1_codebook[v1_vector * entry_size + 5];
482  }
483 }
484 
485 // decodes the V4 vectors in mb into the 4x4 MB pointed to by data
486 static void decode_v4_vector(CinepakEncContext *s, uint8_t *data[4],
487  int linesize[4], int *v4_vector, strip_info *info)
488 {
489  int i, x, y, entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
490 
491  for (i = y = 0; y < 4; y += 2) {
492  for (x = 0; x < 4; x += 2, i++) {
493  data[0][x + y * linesize[0]] = info->v4_codebook[v4_vector[i] * entry_size];
494  data[0][x + 1 + y * linesize[0]] = info->v4_codebook[v4_vector[i] * entry_size + 1];
495  data[0][x + (y + 1) * linesize[0]] = info->v4_codebook[v4_vector[i] * entry_size + 2];
496  data[0][x + 1 + (y + 1) * linesize[0]] = info->v4_codebook[v4_vector[i] * entry_size + 3];
497 
498  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
499  data[1][(x >> 1) + (y >> 1) * linesize[1]] = info->v4_codebook[v4_vector[i] * entry_size + 4];
500  data[2][(x >> 1) + (y >> 1) * linesize[2]] = info->v4_codebook[v4_vector[i] * entry_size + 5];
501  }
502  }
503  }
504 }
505 
507  uint8_t *a_data[4], int a_linesize[4],
508  uint8_t *b_data[4], int b_linesize[4])
509 {
510  int y, p;
511 
512  for (y = 0; y < MB_SIZE; y++)
513  memcpy(a_data[0] + y * a_linesize[0], b_data[0] + y * b_linesize[0],
514  MB_SIZE);
515 
516  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
517  for (p = 1; p <= 2; p++)
518  for (y = 0; y < MB_SIZE / 2; y++)
519  memcpy(a_data[p] + y * a_linesize[p],
520  b_data[p] + y * b_linesize[p],
521  MB_SIZE / 2);
522  }
523 }
524 
525 static int encode_mode(CinepakEncContext *s, int h,
526  uint8_t *scratch_data[4], int scratch_linesize[4],
527  uint8_t *last_data[4], int last_linesize[4],
528  strip_info *info, unsigned char *buf)
529 {
530  int x, y, z, bits, temp_size, header_ofs, ret = 0, mb_count = s->w * h / MB_AREA;
531  int needs_extra_bit, should_write_temp;
532  uint32_t flags;
533  unsigned char temp[64]; // 32/2 = 16 V4 blocks at 4 B each -> 64 B
534  mb_info *mb;
535  uint8_t *sub_scratch_data[4] = { 0 }, *sub_last_data[4] = { 0 };
536  int sub_scratch_linesize[4] = { 0 }, sub_last_linesize[4] = { 0 };
537 
538  // encode codebooks
539  ////// MacOS vintage decoder compatibility dictates the presence of
540  ////// the codebook chunk even when the codebook is empty - pretty dumb...
541  ////// and also the certain order of the codebook chunks -- rl
542  if (info->v4_size || !s->skip_empty_cb)
543  ret += encode_codebook(s, info->v4_codebook, info->v4_size, 0x20, 0x24, buf + ret);
544 
545  if (info->v1_size || !s->skip_empty_cb)
546  ret += encode_codebook(s, info->v1_codebook, info->v1_size, 0x22, 0x26, buf + ret);
547 
548  // update scratch picture
549  for (z = y = 0; y < h; y += MB_SIZE)
550  for (x = 0; x < s->w; x += MB_SIZE, z++) {
551  mb = &s->mb[z];
552 
553  get_sub_picture(s, x, y, scratch_data, scratch_linesize,
554  sub_scratch_data, sub_scratch_linesize);
555 
556  if (info->mode == MODE_MC && mb->best_encoding == ENC_SKIP) {
557  get_sub_picture(s, x, y, last_data, last_linesize,
558  sub_last_data, sub_last_linesize);
559  copy_mb(s, sub_scratch_data, sub_scratch_linesize,
560  sub_last_data, sub_last_linesize);
561  } else if (info->mode == MODE_V1_ONLY || mb->best_encoding == ENC_V1)
562  decode_v1_vector(s, sub_scratch_data, sub_scratch_linesize,
563  mb->v1_vector, info);
564  else
565  decode_v4_vector(s, sub_scratch_data, sub_scratch_linesize,
566  mb->v4_vector, info);
567  }
568 
569  switch (info->mode) {
570  case MODE_V1_ONLY:
571  ret += write_chunk_header(buf + ret, 0x32, mb_count);
572 
573  for (x = 0; x < mb_count; x++)
574  buf[ret++] = s->mb[x].v1_vector;
575 
576  break;
577  case MODE_V1_V4:
578  // remember header position
579  header_ofs = ret;
581 
582  for (x = 0; x < mb_count; x += 32) {
583  flags = 0;
584  for (y = x; y < FFMIN(x + 32, mb_count); y++)
585  if (s->mb[y].best_encoding == ENC_V4)
586  flags |= 1U << (31 - y + x);
587 
588  AV_WB32(&buf[ret], flags);
589  ret += 4;
590 
591  for (y = x; y < FFMIN(x + 32, mb_count); y++) {
592  mb = &s->mb[y];
593 
594  if (mb->best_encoding == ENC_V1)
595  buf[ret++] = mb->v1_vector;
596  else
597  for (z = 0; z < 4; z++)
598  buf[ret++] = mb->v4_vector[z];
599  }
600  }
601 
602  write_chunk_header(buf + header_ofs, 0x30, ret - header_ofs - CHUNK_HEADER_SIZE);
603 
604  break;
605  case MODE_MC:
606  // remember header position
607  header_ofs = ret;
609  flags = bits = temp_size = 0;
610 
611  for (x = 0; x < mb_count; x++) {
612  mb = &s->mb[x];
613  flags |= (uint32_t)(mb->best_encoding != ENC_SKIP) << (31 - bits++);
614  needs_extra_bit = 0;
615  should_write_temp = 0;
616 
617  if (mb->best_encoding != ENC_SKIP) {
618  if (bits < 32)
619  flags |= (uint32_t)(mb->best_encoding == ENC_V4) << (31 - bits++);
620  else
621  needs_extra_bit = 1;
622  }
623 
624  if (bits == 32) {
625  AV_WB32(&buf[ret], flags);
626  ret += 4;
627  flags = bits = 0;
628 
629  if (mb->best_encoding == ENC_SKIP || needs_extra_bit) {
630  memcpy(&buf[ret], temp, temp_size);
631  ret += temp_size;
632  temp_size = 0;
633  } else
634  should_write_temp = 1;
635  }
636 
637  if (needs_extra_bit) {
638  flags = (uint32_t)(mb->best_encoding == ENC_V4) << 31;
639  bits = 1;
640  }
641 
642  if (mb->best_encoding == ENC_V1)
643  temp[temp_size++] = mb->v1_vector;
644  else if (mb->best_encoding == ENC_V4)
645  for (z = 0; z < 4; z++)
646  temp[temp_size++] = mb->v4_vector[z];
647 
648  if (should_write_temp) {
649  memcpy(&buf[ret], temp, temp_size);
650  ret += temp_size;
651  temp_size = 0;
652  }
653  }
654 
655  if (bits > 0) {
656  AV_WB32(&buf[ret], flags);
657  ret += 4;
658  memcpy(&buf[ret], temp, temp_size);
659  ret += temp_size;
660  }
661 
662  write_chunk_header(buf + header_ofs, 0x31, ret - header_ofs - CHUNK_HEADER_SIZE);
663 
664  break;
665  }
666 
667  return ret;
668 }
669 
670 // computes distortion of 4x4 MB in b compared to a
672  uint8_t *a_data[4], int a_linesize[4],
673  uint8_t *b_data[4], int b_linesize[4])
674 {
675  int x, y, p, d, ret = 0;
676 
677  for (y = 0; y < MB_SIZE; y++)
678  for (x = 0; x < MB_SIZE; x++) {
679  d = a_data[0][x + y * a_linesize[0]] - b_data[0][x + y * b_linesize[0]];
680  ret += d * d;
681  }
682 
683  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
684  for (p = 1; p <= 2; p++) {
685  for (y = 0; y < MB_SIZE / 2; y++)
686  for (x = 0; x < MB_SIZE / 2; x++) {
687  d = a_data[p][x + y * a_linesize[p]] - b_data[p][x + y * b_linesize[p]];
688  ret += d * d;
689  }
690  }
691  }
692 
693  return ret;
694 }
695 
696 // return the possibly adjusted size of the codebook
697 #define CERTAIN(x) ((x) != ENC_UNCERTAIN)
698 static int quantize(CinepakEncContext *s, int h, uint8_t *data[4],
699  int linesize[4], int v1mode, strip_info *info,
700  mb_encoding encoding)
701 {
702  int x, y, i, j, k, x2, y2, x3, y3, plane, shift, mbn;
703  int entry_size = s->pix_fmt == AV_PIX_FMT_RGB24 ? 6 : 4;
704  int *codebook = v1mode ? info->v1_codebook : info->v4_codebook;
705  int size = v1mode ? info->v1_size : info->v4_size;
706  uint8_t vq_pict_buf[(MB_AREA * 3) / 2];
707  uint8_t *sub_data[4], *vq_data[4];
708  int sub_linesize[4], vq_linesize[4];
709  int ret;
710 
711  for (mbn = i = y = 0; y < h; y += MB_SIZE) {
712  for (x = 0; x < s->w; x += MB_SIZE, ++mbn) {
713  int *base;
714 
715  if (CERTAIN(encoding)) {
716  // use for the training only the blocks known to be to be encoded [sic:-]
717  if (s->mb[mbn].best_encoding != encoding)
718  continue;
719  }
720 
721  base = s->codebook_input + i * entry_size;
722  if (v1mode) {
723  // subsample
724  for (j = y2 = 0; y2 < entry_size; y2 += 2)
725  for (x2 = 0; x2 < 4; x2 += 2, j++) {
726  plane = y2 < 4 ? 0 : 1 + (x2 >> 1);
727  shift = y2 < 4 ? 0 : 1;
728  x3 = shift ? 0 : x2;
729  y3 = shift ? 0 : y2;
730  base[j] = (data[plane][((x + x3) >> shift) + ((y + y3) >> shift) * linesize[plane]] +
731  data[plane][((x + x3) >> shift) + 1 + ((y + y3) >> shift) * linesize[plane]] +
732  data[plane][((x + x3) >> shift) + (((y + y3) >> shift) + 1) * linesize[plane]] +
733  data[plane][((x + x3) >> shift) + 1 + (((y + y3) >> shift) + 1) * linesize[plane]]) >> 2;
734  }
735  } else {
736  // copy
737  for (j = y2 = 0; y2 < MB_SIZE; y2 += 2) {
738  for (x2 = 0; x2 < MB_SIZE; x2 += 2)
739  for (k = 0; k < entry_size; k++, j++) {
740  plane = k >= 4 ? k - 3 : 0;
741 
742  if (k >= 4) {
743  x3 = (x + x2) >> 1;
744  y3 = (y + y2) >> 1;
745  } else {
746  x3 = x + x2 + (k & 1);
747  y3 = y + y2 + (k >> 1);
748  }
749 
750  base[j] = data[plane][x3 + y3 * linesize[plane]];
751  }
752  }
753  }
754  i += v1mode ? 1 : 4;
755  }
756  }
757 
758  if (i == 0) // empty training set, nothing to do
759  return 0;
760  if (i < size)
761  size = i;
762 
763  ret = avpriv_elbg_do(&s->elbg, s->codebook_input, entry_size, i, codebook,
764  size, 1, s->codebook_closest, &s->randctx, 0);
765  if (ret < 0)
766  return ret;
767 
768  // set up vq_data, which contains a single MB
769  vq_data[0] = vq_pict_buf;
770  vq_linesize[0] = MB_SIZE;
771  vq_data[1] = &vq_pict_buf[MB_AREA];
772  vq_data[2] = vq_data[1] + (MB_AREA >> 2);
773  vq_linesize[1] =
774  vq_linesize[2] = MB_SIZE >> 1;
775 
776  // copy indices
777  for (i = j = y = 0; y < h; y += MB_SIZE)
778  for (x = 0; x < s->w; x += MB_SIZE, j++) {
779  mb_info *mb = &s->mb[j];
780  // skip uninteresting blocks if we know their preferred encoding
781  if (CERTAIN(encoding) && mb->best_encoding != encoding)
782  continue;
783 
784  // point sub_data to current MB
785  get_sub_picture(s, x, y, data, linesize, sub_data, sub_linesize);
786 
787  if (v1mode) {
788  mb->v1_vector = s->codebook_closest[i];
789 
790  // fill in vq_data with V1 data
791  decode_v1_vector(s, vq_data, vq_linesize, mb->v1_vector, info);
792 
793  mb->v1_error = compute_mb_distortion(s, sub_data, sub_linesize,
794  vq_data, vq_linesize);
795  } else {
796  for (k = 0; k < 4; k++)
797  mb->v4_vector[k] = s->codebook_closest[i + k];
798 
799  // fill in vq_data with V4 data
800  decode_v4_vector(s, vq_data, vq_linesize, mb->v4_vector, info);
801 
802  mb->v4_error = compute_mb_distortion(s, sub_data, sub_linesize,
803  vq_data, vq_linesize);
804  }
805  i += v1mode ? 1 : 4;
806  }
807  // check that we did it right in the beginning of the function
808  av_assert0(i >= size); // training set is no smaller than the codebook
809 
810  return size;
811 }
812 
814  uint8_t *last_data[4], int last_linesize[4],
815  uint8_t *data[4], int linesize[4],
816  strip_info *info)
817 {
818  int x, y, i;
819  uint8_t *sub_last_data [4], *sub_pict_data [4];
820  int sub_last_linesize[4], sub_pict_linesize[4];
821 
822  for (i = y = 0; y < h; y += MB_SIZE)
823  for (x = 0; x < s->w; x += MB_SIZE, i++) {
824  get_sub_picture(s, x, y, last_data, last_linesize,
825  sub_last_data, sub_last_linesize);
826  get_sub_picture(s, x, y, data, linesize,
827  sub_pict_data, sub_pict_linesize);
828 
829  s->mb[i].skip_error =
831  sub_last_data, sub_last_linesize,
832  sub_pict_data, sub_pict_linesize);
833  }
834 }
835 
836 static void write_strip_keyframe(unsigned char *buf, int keyframe)
837 {
838  // actually we are exclusively using intra strip coding (how much can we win
839  // otherwise? how to choose which part of a codebook to update?),
840  // keyframes are different only because we disallow ENC_SKIP on them -- rl
841  // (besides, the logic here used to be inverted: )
842  // buf[0] = keyframe ? 0x11: 0x10;
843  buf[0] = keyframe ? 0x10 : 0x11;
844 }
845 
846 static void write_strip_header(CinepakEncContext *s, int y, int h, int keyframe,
847  unsigned char *buf, int strip_size)
848 {
849  write_strip_keyframe(buf, keyframe);
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, int *no_skip)
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  // in theory we could have MODE_MC without ENC_SKIP,
980  // but MODE_V1_V4 will always be more efficient
981  *no_skip = info.mode != MODE_MC;
982 
983  write_strip_header(s, y, h, keyframe, s->strip_buf, best_size);
984  }
985  }
986  }
987  }
988 
989  best_size += STRIP_HEADER_SIZE;
990  memcpy(buf, s->strip_buf, best_size);
991 
992  return best_size;
993 }
994 
995 static int write_cvid_header(CinepakEncContext *s, unsigned char *buf,
996  int num_strips, int data_size, int isakeyframe)
997 {
998  buf[0] = isakeyframe ? 0 : 1;
999  AV_WB24(&buf[1], data_size + CVID_HEADER_SIZE);
1000  AV_WB16(&buf[4], s->w);
1001  AV_WB16(&buf[6], s->h);
1002  AV_WB16(&buf[8], num_strips);
1003 
1004  return CVID_HEADER_SIZE;
1005 }
1006 
1008  int isakeyframe, unsigned char *buf, int buf_size, int *got_keyframe)
1009 {
1010  int num_strips, strip, i, y, nexty, size, temp_size, best_size;
1011  uint8_t *last_data [4], *data [4], *scratch_data [4];
1012  int last_linesize[4], linesize[4], scratch_linesize[4];
1013  int64_t best_score = 0, score, score_temp;
1014  int best_nstrips, best_strip_offsets[MAX_STRIPS];
1015 
1016  if (s->pix_fmt == AV_PIX_FMT_RGB24) {
1017  int x;
1018  // build a copy of the given frame in the correct colorspace
1019  for (y = 0; y < s->h; y += 2)
1020  for (x = 0; x < s->w; x += 2) {
1021  const uint8_t *ir[2];
1022  int32_t r, g, b, rr, gg, bb;
1023  ir[0] = frame->data[0] + x * 3 + y * frame->linesize[0];
1024  ir[1] = ir[0] + frame->linesize[0];
1025  get_sub_picture(s, x, y,
1026  s->input_frame->data, s->input_frame->linesize,
1027  scratch_data, scratch_linesize);
1028  r = g = b = 0;
1029  for (i = 0; i < 4; ++i) {
1030  int i1, i2;
1031  i1 = (i & 1);
1032  i2 = (i >= 2);
1033  rr = ir[i2][i1 * 3 + 0];
1034  gg = ir[i2][i1 * 3 + 1];
1035  bb = ir[i2][i1 * 3 + 2];
1036  r += rr;
1037  g += gg;
1038  b += bb;
1039  // using fixed point arithmetic for portable repeatability, scaling by 2^23
1040  // "Y"
1041  // rr = 0.2857 * rr + 0.5714 * gg + 0.1429 * bb;
1042  rr = (2396625 * rr + 4793251 * gg + 1198732 * bb) >> 23;
1043  if (rr < 0)
1044  rr = 0;
1045  else if (rr > 255)
1046  rr = 255;
1047  scratch_data[0][i1 + i2 * scratch_linesize[0]] = rr;
1048  }
1049  // let us scale down as late as possible
1050  // r /= 4; g /= 4; b /= 4;
1051  // "U"
1052  // rr = -0.1429 * r - 0.2857 * g + 0.4286 * b;
1053  rr = (-299683 * r - 599156 * g + 898839 * b) >> 23;
1054  if (rr < -128)
1055  rr = -128;
1056  else if (rr > 127)
1057  rr = 127;
1058  scratch_data[1][0] = rr + 128; // quantize needs unsigned
1059  // "V"
1060  // rr = 0.3571 * r - 0.2857 * g - 0.0714 * b;
1061  rr = (748893 * r - 599156 * g - 149737 * b) >> 23;
1062  if (rr < -128)
1063  rr = -128;
1064  else if (rr > 127)
1065  rr = 127;
1066  scratch_data[2][0] = rr + 128; // quantize needs unsigned
1067  }
1068  }
1069 
1070  // would be nice but quite certainly incompatible with vintage players:
1071  // support encoding zero strips (meaning skip the whole frame)
1072  for (num_strips = s->min_strips; num_strips <= s->max_strips && num_strips <= s->h / MB_SIZE; num_strips++) {
1073  int strip_offsets[MAX_STRIPS];
1074  int all_no_skip = 1;
1075  score = 0;
1076  size = 0;
1077 
1078  for (y = 0, strip = 1; y < s->h; strip++, y = nexty) {
1079  int strip_height, no_skip;
1080 
1081  strip_offsets[strip-1] = size + CVID_HEADER_SIZE;
1082  nexty = strip * s->h / num_strips; // <= s->h
1083  // make nexty the next multiple of 4 if not already there
1084  if (nexty & 3)
1085  nexty += 4 - (nexty & 3);
1086 
1087  strip_height = nexty - y;
1088  if (strip_height <= 0) { // can this ever happen?
1089  av_log(s->avctx, AV_LOG_INFO, "skipping zero height strip %i of %i\n", strip, num_strips);
1090  continue;
1091  }
1092 
1093  if (s->pix_fmt == AV_PIX_FMT_RGB24)
1094  get_sub_picture(s, 0, y,
1095  s->input_frame->data, s->input_frame->linesize,
1096  data, linesize);
1097  else
1098  get_sub_picture(s, 0, y,
1099  frame->data, frame->linesize,
1100  data, linesize);
1101  get_sub_picture(s, 0, y,
1102  s->last_frame->data, s->last_frame->linesize,
1103  last_data, last_linesize);
1104  get_sub_picture(s, 0, y,
1105  s->scratch_frame->data, s->scratch_frame->linesize,
1106  scratch_data, scratch_linesize);
1107 
1108  if ((temp_size = rd_strip(s, y, strip_height, isakeyframe,
1109  last_data, last_linesize, data, linesize,
1110  scratch_data, scratch_linesize,
1111  s->frame_buf + strip_offsets[strip-1],
1112  &score_temp, &no_skip)) < 0)
1113  return temp_size;
1114 
1115  score += score_temp;
1116  size += temp_size;
1117  all_no_skip &= no_skip;
1118  }
1119 
1120  if (best_score == 0 || score < best_score) {
1121  best_score = score;
1122  best_size = size + write_cvid_header(s, s->frame_buf, num_strips, size, all_no_skip);
1123 
1124  FFSWAP(AVFrame *, s->best_frame, s->scratch_frame);
1125  memcpy(buf, s->frame_buf, best_size);
1126  best_nstrips = num_strips;
1127  *got_keyframe = all_no_skip; // no skip MBs in any strip -> keyframe
1128  memcpy(best_strip_offsets, strip_offsets, sizeof(strip_offsets));
1129  }
1130  // avoid trying too many strip numbers without a real reason
1131  // (this makes the processing of the very first frame faster)
1132  if (num_strips - best_nstrips > 4)
1133  break;
1134  }
1135 
1136  // update strip headers
1137  for (i = 0; i < best_nstrips; i++) {
1138  write_strip_keyframe(s->frame_buf + best_strip_offsets[i], *got_keyframe);
1139  }
1140 
1141  // let the number of strips slowly adapt to the changes in the contents,
1142  // compared to full bruteforcing every time this will occasionally lead
1143  // to some r/d performance loss but makes encoding up to several times faster
1144  if (!s->strip_number_delta_range) {
1145  if (best_nstrips == s->max_strips) { // let us try to step up
1146  s->max_strips = best_nstrips + 1;
1147  if (s->max_strips >= s->max_max_strips)
1148  s->max_strips = s->max_max_strips;
1149  } else { // try to step down
1150  s->max_strips = best_nstrips;
1151  }
1152  s->min_strips = s->max_strips - 1;
1153  if (s->min_strips < s->min_min_strips)
1154  s->min_strips = s->min_min_strips;
1155  } else {
1156  s->max_strips = best_nstrips + s->strip_number_delta_range;
1157  if (s->max_strips >= s->max_max_strips)
1158  s->max_strips = s->max_max_strips;
1159  s->min_strips = best_nstrips - s->strip_number_delta_range;
1160  if (s->min_strips < s->min_min_strips)
1161  s->min_strips = s->min_min_strips;
1162  }
1163 
1164  return best_size;
1165 }
1166 
1168  const AVFrame *frame, int *got_packet)
1169 {
1170  CinepakEncContext *s = avctx->priv_data;
1171  int ret, got_keyframe;
1172 
1173  s->lambda = frame->quality ? frame->quality - 1 : 2 * FF_LAMBDA_SCALE;
1174 
1175  if ((ret = ff_alloc_packet(avctx, pkt, s->frame_buf_size)) < 0)
1176  return ret;
1177  ret = rd_frame(s, frame, (s->curframe == 0), pkt->data, s->frame_buf_size, &got_keyframe);
1178  pkt->size = ret;
1179  if (got_keyframe) {
1181  s->curframe = 0;
1182  }
1183  *got_packet = 1;
1184 
1185  FFSWAP(AVFrame *, s->last_frame, s->best_frame);
1186 
1187  if (++s->curframe >= avctx->gop_size)
1188  s->curframe = 0;
1189 
1190  return 0;
1191 }
1192 
1194 {
1195  CinepakEncContext *s = avctx->priv_data;
1196  int x;
1197 
1198  avpriv_elbg_free(&s->elbg);
1199  av_frame_free(&s->last_frame);
1200  av_frame_free(&s->best_frame);
1201  av_frame_free(&s->scratch_frame);
1202  if (avctx->pix_fmt == AV_PIX_FMT_RGB24)
1203  av_frame_free(&s->input_frame);
1204  av_freep(&s->codebook_input);
1205  av_freep(&s->codebook_closest);
1206  av_freep(&s->strip_buf);
1207  av_freep(&s->frame_buf);
1208  av_freep(&s->mb);
1209 
1210  for (x = 0; x < (avctx->pix_fmt == AV_PIX_FMT_RGB24 ? 4 : 3); x++)
1211  av_freep(&s->pict_bufs[x]);
1212 
1213  return 0;
1214 }
1215 
1217  .p.name = "cinepak",
1218  CODEC_LONG_NAME("Cinepak"),
1219  .p.type = AVMEDIA_TYPE_VIDEO,
1220  .p.id = AV_CODEC_ID_CINEPAK,
1222  .priv_data_size = sizeof(CinepakEncContext),
1225  .close = cinepak_encode_end,
1226  .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE },
1227  .p.priv_class = &cinepak_class,
1228  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1229 };
SMALLEST_CODEBOOK
#define SMALLEST_CODEBOOK
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
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: codec_internal.h:42
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:127
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:134
ff_cinepak_encoder
const FFCodec ff_cinepak_encoder
Definition: cinepakenc.c:1216
OFFSET
#define OFFSET(x)
Definition: cinepakenc.c:132
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:697
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:160
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:375
cinepak_encode_init
static av_cold int cinepak_encode_init(AVCodecContext *avctx)
Definition: cinepakenc.c:155
AVPacket::data
uint8_t * data
Definition: packet.h:524
CinepakEncContext::input_frame
AVFrame * input_frame
Definition: cinepakenc.c:111
AVOption
AVOption.
Definition: opt.h:346
encode.h
b
#define b
Definition: input.c:41
data
const char data[16]
Definition: mxf.c:148
ENC_V1
@ ENC_V1
Definition: cinepakenc.c:80
FFCodec
Definition: codec_internal.h:127
base
uint8_t base
Definition: vp3data.h:128
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:447
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:579
CinepakEncContext::randctx
AVLFG randctx
Definition: cinepakenc.c:116
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
CinepakEncContext::avctx
AVCodecContext * avctx
Definition: cinepakenc.c:106
cinepak_encode_end
static av_cold int cinepak_encode_end(AVCodecContext *avctx)
Definition: cinepakenc.c:1193
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
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:486
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:698
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:846
FF_CODEC_ENCODE_CB
#define FF_CODEC_ENCODE_CB(func)
Definition: codec_internal.h:296
write_cvid_header
static int write_cvid_header(CinepakEncContext *s, unsigned char *buf, int num_strips, int data_size, int isakeyframe)
Definition: cinepakenc.c:995
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:148
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:463
ENC_SKIP
@ ENC_SKIP
Definition: cinepakenc.c:82
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:60
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:51
MODE_V1_ONLY
@ MODE_V1_ONLY
Definition: cinepakenc.c:72
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
VE
#define VE
Definition: cinepakenc.c:133
CinepakEncContext::skip_empty_cb
int skip_empty_cb
Definition: cinepakenc.c:125
g
const char * g
Definition: vf_curves.c:128
info
MIPS optimizations info
Definition: mips.txt:2
lfg.h
MAX_STRIPS
#define MAX_STRIPS
Definition: cinepakenc.c:60
CinepakEncContext
Definition: cinepakenc.c:104
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition: codec.h:159
CinepakEncContext::frame_buf_size
int frame_buf_size
Definition: cinepakenc.c:114
bits
uint8_t bits
Definition: vp3data.h:128
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
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:382
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:90
strip_info::v1_size
int v1_size
Definition: cinepakenc.c:99
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:403
AV_CODEC_ID_CINEPAK
@ AV_CODEC_ID_CINEPAK
Definition: codec_id.h:95
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
cinepak_class
static const AVClass cinepak_class
Definition: cinepakenc.c:148
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
MB_SIZE
#define MB_SIZE
Definition: cinepakenc.c:54
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:417
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:506
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:366
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
CinepakEncContext::min_strips
int min_strips
Definition: cinepakenc.c:121
AVPacket::size
int size
Definition: packet.h:525
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1031
codec_internal.h
shift
static int shift(int a, int b)
Definition: bonk.c:261
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
size
int size
Definition: twinvq_data.h:10344
encode_mode
static int encode_mode(CinepakEncContext *s, int h, uint8_t *scratch_data[4], int scratch_linesize[4], uint8_t *last_data[4], int last_linesize[4], strip_info *info, unsigned char *buf)
Definition: cinepakenc.c:525
avpriv_elbg_free
av_cold void avpriv_elbg_free(ELBGContext **elbgp)
Free an ELBGContext and reset the pointer to it.
Definition: elbg.c:516
write_strip_keyframe
static void write_strip_keyframe(unsigned char *buf, int keyframe)
Definition: cinepakenc.c:836
CinepakEncContext::elbg
struct ELBGContext * elbg
Definition: cinepakenc.c:129
strip_info::v4_size
int v4_size
Definition: cinepakenc.c:100
AV_WB24
#define AV_WB24(p, d)
Definition: intreadwrite.h:448
rd_frame
static int rd_frame(CinepakEncContext *s, const AVFrame *frame, int isakeyframe, unsigned char *buf, int buf_size, int *got_keyframe)
Definition: cinepakenc.c:1007
VECTOR_MAX
#define VECTOR_MAX
Definition: cinepakenc.c:57
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:530
mb
#define mb
Definition: vf_colormatrix.c:99
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
mb_encoding
mb_encoding
Definition: cinepakenc.c:79
report
#define report
Definition: checkasm.h:182
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:256
cinepak_encode_frame
static int cinepak_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: cinepakenc.c:1167
ELBGContext
ELBG internal data.
Definition: elbg.c:47
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:31
CinepakEncContext::curframe
int curframe
Definition: cinepakenc.c:115
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
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:618
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:657
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: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:813
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:257
U
#define U(x)
Definition: vpx_arith.h:37
AVCodecContext
main external API structure.
Definition: avcodec.h:445
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
mb_info::v1_error
int v1_error
Definition: cinepakenc.c:89
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
write_chunk_header
static int write_chunk_header(unsigned char *buf, int chunk_type, int chunk_size)
Definition: cinepakenc.c:375
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:263
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
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
CHUNK_HEADER_SIZE
#define CHUNK_HEADER_SIZE
Definition: cinepakenc.c:52
mem.h
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:501
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:251
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
strip_info::v1_codebook
int v1_codebook[CODEBOOK_MAX *VECTOR_MAX]
Definition: cinepakenc.c:97
d
d
Definition: ffmpeg_filter.c:424
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:618
int32_t
int32_t
Definition: audioconvert.c:56
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
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:671
CinepakEncContext::min_min_strips
int min_min_strips
Definition: cinepakenc.c:126
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, int *no_skip)
Definition: cinepakenc.c:859
CinepakEncContext::strip_buf
unsigned char * strip_buf
Definition: cinepakenc.c:107
ff_alloc_packet
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size)
Check AVPacket size and allocate data.
Definition: encode.c:62
MIN_STRIPS
#define MIN_STRIPS
Definition: cinepakenc.c:61
get_sub_picture
static void get_sub_picture(CinepakEncContext *s, int x, int y, uint8_t *const in_data[4], const int in_linesize[4], uint8_t *out_data[4], int out_linesize[4])
Definition: cinepakenc.c:430
CinepakEncContext::w
int w
Definition: cinepakenc.c:113
mb_info
Definition: cinepakenc.c:87
codebook
static const unsigned codebook[256][2]
Definition: cfhdenc.c:41