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