roqvideoenc.c
Go to the documentation of this file.
1 /*
2  * RoQ Video Encoder.
3  *
4  * Copyright (C) 2007 Vitor Sessak <vitor1001@gmail.com>
5  * Copyright (C) 2004-2007 Eric Lasota
6  * Based on RoQ specs (C) 2001 Tim Ferguson
7  *
8  * This file is part of FFmpeg.
9  *
10  * FFmpeg is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * FFmpeg is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with FFmpeg; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 /**
26  * @file
27  * id RoQ encoder by Vitor. Based on the Switchblade3 library and the
28  * Switchblade3 FFmpeg glue by Eric Lasota.
29  */
30 
31 /*
32  * COSTS:
33  * Level 1:
34  * SKIP - 2 bits
35  * MOTION - 2 + 8 bits
36  * CODEBOOK - 2 + 8 bits
37  * SUBDIVIDE - 2 + combined subcel cost
38  *
39  * Level 2:
40  * SKIP - 2 bits
41  * MOTION - 2 + 8 bits
42  * CODEBOOK - 2 + 8 bits
43  * SUBDIVIDE - 2 + 4*8 bits
44  *
45  * Maximum cost: 138 bits per cel
46  *
47  * Proper evaluation requires LCD fraction comparison, which requires
48  * Squared Error (SE) loss * savings increase
49  *
50  * Maximum savings increase: 136 bits
51  * Maximum SE loss without overflow: 31580641
52  * Components in 8x8 supercel: 192
53  * Maximum SE precision per component: 164482
54  * >65025, so no truncation is needed (phew)
55  */
56 
57 #include <string.h>
58 
59 #include "roqvideo.h"
60 #include "bytestream.h"
61 #include "elbg.h"
62 #include "internal.h"
63 #include "mathops.h"
64 
65 #define CHROMA_BIAS 1
66 
67 /**
68  * Maximum number of generated 4x4 codebooks. Can't be 256 to workaround a
69  * Quake 3 bug.
70  */
71 #define MAX_CBS_4x4 255
72 
73 #define MAX_CBS_2x2 256 ///< Maximum number of 2x2 codebooks.
74 
75 /* The cast is useful when multiplying it by INT_MAX */
76 #define ROQ_LAMBDA_SCALE ((uint64_t) FF_LAMBDA_SCALE)
77 
78 /* Macroblock support functions */
79 static void unpack_roq_cell(roq_cell *cell, uint8_t u[4*3])
80 {
81  memcpy(u , cell->y, 4);
82  memset(u+4, cell->u, 4);
83  memset(u+8, cell->v, 4);
84 }
85 
86 static void unpack_roq_qcell(uint8_t cb2[], roq_qcell *qcell, uint8_t u[4*4*3])
87 {
88  int i,cp;
89  static const int offsets[4] = {0, 2, 8, 10};
90 
91  for (cp=0; cp<3; cp++)
92  for (i=0; i<4; i++) {
93  u[4*4*cp + offsets[i] ] = cb2[qcell->idx[i]*2*2*3 + 4*cp ];
94  u[4*4*cp + offsets[i]+1] = cb2[qcell->idx[i]*2*2*3 + 4*cp+1];
95  u[4*4*cp + offsets[i]+4] = cb2[qcell->idx[i]*2*2*3 + 4*cp+2];
96  u[4*4*cp + offsets[i]+5] = cb2[qcell->idx[i]*2*2*3 + 4*cp+3];
97  }
98 }
99 
100 
101 static void enlarge_roq_mb4(uint8_t base[3*16], uint8_t u[3*64])
102 {
103  int x,y,cp;
104 
105  for(cp=0; cp<3; cp++)
106  for(y=0; y<8; y++)
107  for(x=0; x<8; x++)
108  *u++ = base[(y/2)*4 + (x/2) + 16*cp];
109 }
110 
111 static inline int square(int x)
112 {
113  return x*x;
114 }
115 
116 static inline int eval_sse(const uint8_t *a, const uint8_t *b, int count)
117 {
118  int diff=0;
119 
120  while(count--)
121  diff += square(*b++ - *a++);
122 
123  return diff;
124 }
125 
126 // FIXME Could use DSPContext.sse, but it is not so speed critical (used
127 // just for motion estimation).
128 static int block_sse(uint8_t * const *buf1, uint8_t * const *buf2, int x1, int y1,
129  int x2, int y2, const int *stride1, const int *stride2, int size)
130 {
131  int i, k;
132  int sse=0;
133 
134  for (k=0; k<3; k++) {
135  int bias = (k ? CHROMA_BIAS : 4);
136  for (i=0; i<size; i++)
137  sse += bias*eval_sse(buf1[k] + (y1+i)*stride1[k] + x1,
138  buf2[k] + (y2+i)*stride2[k] + x2, size);
139  }
140 
141  return sse;
142 }
143 
144 static int eval_motion_dist(RoqContext *enc, int x, int y, motion_vect vect,
145  int size)
146 {
147  int mx=vect.d[0];
148  int my=vect.d[1];
149 
150  if (mx < -7 || mx > 7)
151  return INT_MAX;
152 
153  if (my < -7 || my > 7)
154  return INT_MAX;
155 
156  mx += x;
157  my += y;
158 
159  if ((unsigned) mx > enc->width-size || (unsigned) my > enc->height-size)
160  return INT_MAX;
161 
162  return block_sse(enc->frame_to_enc->data, enc->last_frame->data, x, y,
163  mx, my,
165  size);
166 }
167 
168 /**
169  * @return distortion between two macroblocks
170  */
171 static inline int squared_diff_macroblock(uint8_t a[], uint8_t b[], int size)
172 {
173  int cp, sdiff=0;
174 
175  for(cp=0;cp<3;cp++) {
176  int bias = (cp ? CHROMA_BIAS : 4);
177  sdiff += bias*eval_sse(a, b, size*size);
178  a += size*size;
179  b += size*size;
180  }
181 
182  return sdiff;
183 }
184 
185 typedef struct
186 {
187  int eval_dist[4];
190 
191  int subCels[4];
193  int cbEntry;
195 
196 typedef struct
197 {
198  int eval_dist[4];
200 
201  SubcelEvaluation subCels[4];
202 
204  int cbEntry;
205 
206  int sourceX, sourceY;
207 } CelEvaluation;
208 
209 typedef struct
210 {
211  int numCB4;
212  int numCB2;
213  int usedCB2[MAX_CBS_2x2];
214  int usedCB4[MAX_CBS_4x4];
215  uint8_t unpacked_cb2[MAX_CBS_2x2*2*2*3];
216  uint8_t unpacked_cb4[MAX_CBS_4x4*4*4*3];
217  uint8_t unpacked_cb4_enlarged[MAX_CBS_4x4*8*8*3];
218 } RoqCodebooks;
219 
220 /**
221  * Temporary vars
222  */
223 typedef struct RoqTempData
224 {
226 
231 
233 
234  int numCB4;
235  int numCB2;
236 
238 
240  int used_option[4];
241 } RoqTempdata;
242 
243 /**
244  * Initialize cel evaluators and set their source coordinates
245  */
246 static void create_cel_evals(RoqContext *enc, RoqTempdata *tempData)
247 {
248  int n=0, x, y, i;
249 
250  tempData->cel_evals = av_malloc(enc->width*enc->height/64 * sizeof(CelEvaluation));
251 
252  /* Map to the ROQ quadtree order */
253  for (y=0; y<enc->height; y+=16)
254  for (x=0; x<enc->width; x+=16)
255  for(i=0; i<4; i++) {
256  tempData->cel_evals[n ].sourceX = x + (i&1)*8;
257  tempData->cel_evals[n++].sourceY = y + (i&2)*4;
258  }
259 }
260 
261 /**
262  * Get macroblocks from parts of the image
263  */
264 static void get_frame_mb(const AVFrame *frame, int x, int y, uint8_t mb[], int dim)
265 {
266  int i, j, cp;
267 
268  for (cp=0; cp<3; cp++) {
269  int stride = frame->linesize[cp];
270  for (i=0; i<dim; i++)
271  for (j=0; j<dim; j++)
272  *mb++ = frame->data[cp][(y+i)*stride + x + j];
273  }
274 }
275 
276 /**
277  * Find the codebook with the lowest distortion from an image
278  */
279 static int index_mb(uint8_t cluster[], uint8_t cb[], int numCB,
280  int *outIndex, int dim)
281 {
282  int i, lDiff = INT_MAX, pick=0;
283 
284  /* Diff against the others */
285  for (i=0; i<numCB; i++) {
286  int diff = squared_diff_macroblock(cluster, cb + i*dim*dim*3, dim);
287  if (diff < lDiff) {
288  lDiff = diff;
289  pick = i;
290  }
291  }
292 
293  *outIndex = pick;
294  return lDiff;
295 }
296 
297 #define EVAL_MOTION(MOTION) \
298  do { \
299  diff = eval_motion_dist(enc, j, i, MOTION, blocksize); \
300  \
301  if (diff < lowestdiff) { \
302  lowestdiff = diff; \
303  bestpick = MOTION; \
304  } \
305  } while(0)
306 
307 static void motion_search(RoqContext *enc, int blocksize)
308 {
309  static const motion_vect offsets[8] = {
310  {{ 0,-1}},
311  {{ 0, 1}},
312  {{-1, 0}},
313  {{ 1, 0}},
314  {{-1, 1}},
315  {{ 1,-1}},
316  {{-1,-1}},
317  {{ 1, 1}},
318  };
319 
320  int diff, lowestdiff, oldbest;
321  int off[3];
322  motion_vect bestpick = {{0,0}};
323  int i, j, k, offset;
324 
325  motion_vect *last_motion;
326  motion_vect *this_motion;
327  motion_vect vect, vect2;
328 
329  int max=(enc->width/blocksize)*enc->height/blocksize;
330 
331  if (blocksize == 4) {
332  last_motion = enc->last_motion4;
333  this_motion = enc->this_motion4;
334  } else {
335  last_motion = enc->last_motion8;
336  this_motion = enc->this_motion8;
337  }
338 
339  for (i=0; i<enc->height; i+=blocksize)
340  for (j=0; j<enc->width; j+=blocksize) {
341  lowestdiff = eval_motion_dist(enc, j, i, (motion_vect) {{0,0}},
342  blocksize);
343  bestpick.d[0] = 0;
344  bestpick.d[1] = 0;
345 
346  if (blocksize == 4)
347  EVAL_MOTION(enc->this_motion8[(i/8)*(enc->width/8) + j/8]);
348 
349  offset = (i/blocksize)*enc->width/blocksize + j/blocksize;
350  if (offset < max && offset >= 0)
351  EVAL_MOTION(last_motion[offset]);
352 
353  offset++;
354  if (offset < max && offset >= 0)
355  EVAL_MOTION(last_motion[offset]);
356 
357  offset = (i/blocksize + 1)*enc->width/blocksize + j/blocksize;
358  if (offset < max && offset >= 0)
359  EVAL_MOTION(last_motion[offset]);
360 
361  off[0]= (i/blocksize)*enc->width/blocksize + j/blocksize - 1;
362  off[1]= off[0] - enc->width/blocksize + 1;
363  off[2]= off[1] + 1;
364 
365  if (i) {
366 
367  for(k=0; k<2; k++)
368  vect.d[k]= mid_pred(this_motion[off[0]].d[k],
369  this_motion[off[1]].d[k],
370  this_motion[off[2]].d[k]);
371 
372  EVAL_MOTION(vect);
373  for(k=0; k<3; k++)
374  EVAL_MOTION(this_motion[off[k]]);
375  } else if(j)
376  EVAL_MOTION(this_motion[off[0]]);
377 
378  vect = bestpick;
379 
380  oldbest = -1;
381  while (oldbest != lowestdiff) {
382  oldbest = lowestdiff;
383  for (k=0; k<8; k++) {
384  vect2 = vect;
385  vect2.d[0] += offsets[k].d[0];
386  vect2.d[1] += offsets[k].d[1];
387  EVAL_MOTION(vect2);
388  }
389  vect = bestpick;
390  }
391  offset = (i/blocksize)*enc->width/blocksize + j/blocksize;
392  this_motion[offset] = bestpick;
393  }
394 }
395 
396 /**
397  * Get distortion for all options available to a subcel
398  */
399 static void gather_data_for_subcel(SubcelEvaluation *subcel, int x,
400  int y, RoqContext *enc, RoqTempdata *tempData)
401 {
402  uint8_t mb4[4*4*3];
403  uint8_t mb2[2*2*3];
404  int cluster_index;
405  int i, best_dist;
406 
407  static const int bitsUsed[4] = {2, 10, 10, 34};
408 
409  if (enc->framesSinceKeyframe >= 1) {
410  subcel->motion = enc->this_motion4[y*enc->width/16 + x/4];
411 
412  subcel->eval_dist[RoQ_ID_FCC] =
413  eval_motion_dist(enc, x, y,
414  enc->this_motion4[y*enc->width/16 + x/4], 4);
415  } else
416  subcel->eval_dist[RoQ_ID_FCC] = INT_MAX;
417 
418  if (enc->framesSinceKeyframe >= 2)
420  enc->current_frame->data, x,
421  y, x, y,
422  enc->frame_to_enc->linesize,
423  enc->current_frame->linesize,
424  4);
425  else
426  subcel->eval_dist[RoQ_ID_MOT] = INT_MAX;
427 
428  cluster_index = y*enc->width/16 + x/4;
429 
430  get_frame_mb(enc->frame_to_enc, x, y, mb4, 4);
431 
432  subcel->eval_dist[RoQ_ID_SLD] = index_mb(mb4,
433  tempData->codebooks.unpacked_cb4,
434  tempData->codebooks.numCB4,
435  &subcel->cbEntry, 4);
436 
437  subcel->eval_dist[RoQ_ID_CCC] = 0;
438 
439  for(i=0;i<4;i++) {
440  subcel->subCels[i] = tempData->closest_cb2[cluster_index*4+i];
441 
442  get_frame_mb(enc->frame_to_enc, x+2*(i&1),
443  y+(i&2), mb2, 2);
444 
445  subcel->eval_dist[RoQ_ID_CCC] +=
446  squared_diff_macroblock(tempData->codebooks.unpacked_cb2 + subcel->subCels[i]*2*2*3, mb2, 2);
447  }
448 
449  best_dist = INT_MAX;
450  for (i=0; i<4; i++)
451  if (ROQ_LAMBDA_SCALE*subcel->eval_dist[i] + enc->lambda*bitsUsed[i] <
452  best_dist) {
453  subcel->best_coding = i;
454  subcel->best_bit_use = bitsUsed[i];
455  best_dist = ROQ_LAMBDA_SCALE*subcel->eval_dist[i] +
456  enc->lambda*bitsUsed[i];
457  }
458 }
459 
460 /**
461  * Get distortion for all options available to a cel
462  */
464  RoqTempdata *tempData)
465 {
466  uint8_t mb8[8*8*3];
467  int index = cel->sourceY*enc->width/64 + cel->sourceX/8;
468  int i, j, best_dist, divide_bit_use;
469 
470  int bitsUsed[4] = {2, 10, 10, 0};
471 
472  if (enc->framesSinceKeyframe >= 1) {
473  cel->motion = enc->this_motion8[index];
474 
475  cel->eval_dist[RoQ_ID_FCC] =
476  eval_motion_dist(enc, cel->sourceX, cel->sourceY,
477  enc->this_motion8[index], 8);
478  } else
479  cel->eval_dist[RoQ_ID_FCC] = INT_MAX;
480 
481  if (enc->framesSinceKeyframe >= 2)
483  enc->current_frame->data,
484  cel->sourceX, cel->sourceY,
485  cel->sourceX, cel->sourceY,
486  enc->frame_to_enc->linesize,
487  enc->current_frame->linesize,8);
488  else
489  cel->eval_dist[RoQ_ID_MOT] = INT_MAX;
490 
491  get_frame_mb(enc->frame_to_enc, cel->sourceX, cel->sourceY, mb8, 8);
492 
493  cel->eval_dist[RoQ_ID_SLD] =
495  tempData->codebooks.numCB4, &cel->cbEntry, 8);
496 
497  gather_data_for_subcel(cel->subCels + 0, cel->sourceX+0, cel->sourceY+0, enc, tempData);
498  gather_data_for_subcel(cel->subCels + 1, cel->sourceX+4, cel->sourceY+0, enc, tempData);
499  gather_data_for_subcel(cel->subCels + 2, cel->sourceX+0, cel->sourceY+4, enc, tempData);
500  gather_data_for_subcel(cel->subCels + 3, cel->sourceX+4, cel->sourceY+4, enc, tempData);
501 
502  cel->eval_dist[RoQ_ID_CCC] = 0;
503  divide_bit_use = 0;
504  for (i=0; i<4; i++) {
505  cel->eval_dist[RoQ_ID_CCC] +=
506  cel->subCels[i].eval_dist[cel->subCels[i].best_coding];
507  divide_bit_use += cel->subCels[i].best_bit_use;
508  }
509 
510  best_dist = INT_MAX;
511  bitsUsed[3] = 2 + divide_bit_use;
512 
513  for (i=0; i<4; i++)
514  if (ROQ_LAMBDA_SCALE*cel->eval_dist[i] + enc->lambda*bitsUsed[i] <
515  best_dist) {
516  cel->best_coding = i;
517  best_dist = ROQ_LAMBDA_SCALE*cel->eval_dist[i] +
518  enc->lambda*bitsUsed[i];
519  }
520 
521  tempData->used_option[cel->best_coding]++;
522  tempData->mainChunkSize += bitsUsed[cel->best_coding];
523 
524  if (cel->best_coding == RoQ_ID_SLD)
525  tempData->codebooks.usedCB4[cel->cbEntry]++;
526 
527  if (cel->best_coding == RoQ_ID_CCC)
528  for (i=0; i<4; i++) {
529  if (cel->subCels[i].best_coding == RoQ_ID_SLD)
530  tempData->codebooks.usedCB4[cel->subCels[i].cbEntry]++;
531  else if (cel->subCels[i].best_coding == RoQ_ID_CCC)
532  for (j=0; j<4; j++)
533  tempData->codebooks.usedCB2[cel->subCels[i].subCels[j]]++;
534  }
535 }
536 
537 static void remap_codebooks(RoqContext *enc, RoqTempdata *tempData)
538 {
539  int i, j, idx=0;
540 
541  /* Make remaps for the final codebook usage */
542  for (i=0; i<MAX_CBS_4x4; i++) {
543  if (tempData->codebooks.usedCB4[i]) {
544  tempData->i2f4[i] = idx;
545  tempData->f2i4[idx] = i;
546  for (j=0; j<4; j++)
547  tempData->codebooks.usedCB2[enc->cb4x4[i].idx[j]]++;
548  idx++;
549  }
550  }
551 
552  tempData->numCB4 = idx;
553 
554  idx = 0;
555  for (i=0; i<MAX_CBS_2x2; i++) {
556  if (tempData->codebooks.usedCB2[i]) {
557  tempData->i2f2[i] = idx;
558  tempData->f2i2[idx] = i;
559  idx++;
560  }
561  }
562  tempData->numCB2 = idx;
563 
564 }
565 
566 /**
567  * Write codebook chunk
568  */
569 static void write_codebooks(RoqContext *enc, RoqTempdata *tempData)
570 {
571  int i, j;
572  uint8_t **outp= &enc->out_buf;
573 
574  if (tempData->numCB2) {
575  bytestream_put_le16(outp, RoQ_QUAD_CODEBOOK);
576  bytestream_put_le32(outp, tempData->numCB2*6 + tempData->numCB4*4);
577  bytestream_put_byte(outp, tempData->numCB4);
578  bytestream_put_byte(outp, tempData->numCB2);
579 
580  for (i=0; i<tempData->numCB2; i++) {
581  bytestream_put_buffer(outp, enc->cb2x2[tempData->f2i2[i]].y, 4);
582  bytestream_put_byte(outp, enc->cb2x2[tempData->f2i2[i]].u);
583  bytestream_put_byte(outp, enc->cb2x2[tempData->f2i2[i]].v);
584  }
585 
586  for (i=0; i<tempData->numCB4; i++)
587  for (j=0; j<4; j++)
588  bytestream_put_byte(outp, tempData->i2f2[enc->cb4x4[tempData->f2i4[i]].idx[j]]);
589 
590  }
591 }
592 
593 static inline uint8_t motion_arg(motion_vect mot)
594 {
595  uint8_t ax = 8 - ((uint8_t) mot.d[0]);
596  uint8_t ay = 8 - ((uint8_t) mot.d[1]);
597  return ((ax&15)<<4) | (ay&15);
598 }
599 
600 typedef struct
601 {
604  uint8_t argumentSpool[64];
607 } CodingSpool;
608 
609 /* NOTE: Typecodes must be spooled AFTER arguments!! */
611 {
612  s->typeSpool |= (type & 3) << (14 - s->typeSpoolLength);
613  s->typeSpoolLength += 2;
614  if (s->typeSpoolLength == 16) {
615  bytestream_put_le16(s->pout, s->typeSpool);
617  s->args - s->argumentSpool);
618  s->typeSpoolLength = 0;
619  s->typeSpool = 0;
620  s->args = s->argumentSpool;
621  }
622 }
623 
624 static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, int w, int h, int numBlocks)
625 {
626  int i, j, k;
627  int x, y;
628  int subX, subY;
629  int dist=0;
630 
631  roq_qcell *qcell;
633 
634  CodingSpool spool;
635 
636  spool.typeSpool=0;
637  spool.typeSpoolLength=0;
638  spool.args = spool.argumentSpool;
639  spool.pout = &enc->out_buf;
640 
641  if (tempData->used_option[RoQ_ID_CCC]%2)
642  tempData->mainChunkSize+=8; //FIXME
643 
644  /* Write the video chunk header */
645  bytestream_put_le16(&enc->out_buf, RoQ_QUAD_VQ);
646  bytestream_put_le32(&enc->out_buf, tempData->mainChunkSize/8);
647  bytestream_put_byte(&enc->out_buf, 0x0);
648  bytestream_put_byte(&enc->out_buf, 0x0);
649 
650  for (i=0; i<numBlocks; i++) {
651  eval = tempData->cel_evals + i;
652 
653  x = eval->sourceX;
654  y = eval->sourceY;
655  dist += eval->eval_dist[eval->best_coding];
656 
657  switch (eval->best_coding) {
658  case RoQ_ID_MOT:
659  write_typecode(&spool, RoQ_ID_MOT);
660  break;
661 
662  case RoQ_ID_FCC:
663  bytestream_put_byte(&spool.args, motion_arg(eval->motion));
664 
665  write_typecode(&spool, RoQ_ID_FCC);
666  ff_apply_motion_8x8(enc, x, y,
667  eval->motion.d[0], eval->motion.d[1]);
668  break;
669 
670  case RoQ_ID_SLD:
671  bytestream_put_byte(&spool.args, tempData->i2f4[eval->cbEntry]);
672  write_typecode(&spool, RoQ_ID_SLD);
673 
674  qcell = enc->cb4x4 + eval->cbEntry;
675  ff_apply_vector_4x4(enc, x , y , enc->cb2x2 + qcell->idx[0]);
676  ff_apply_vector_4x4(enc, x+4, y , enc->cb2x2 + qcell->idx[1]);
677  ff_apply_vector_4x4(enc, x , y+4, enc->cb2x2 + qcell->idx[2]);
678  ff_apply_vector_4x4(enc, x+4, y+4, enc->cb2x2 + qcell->idx[3]);
679  break;
680 
681  case RoQ_ID_CCC:
682  write_typecode(&spool, RoQ_ID_CCC);
683 
684  for (j=0; j<4; j++) {
685  subX = x + 4*(j&1);
686  subY = y + 2*(j&2);
687 
688  switch(eval->subCels[j].best_coding) {
689  case RoQ_ID_MOT:
690  break;
691 
692  case RoQ_ID_FCC:
693  bytestream_put_byte(&spool.args,
694  motion_arg(eval->subCels[j].motion));
695 
696  ff_apply_motion_4x4(enc, subX, subY,
697  eval->subCels[j].motion.d[0],
698  eval->subCels[j].motion.d[1]);
699  break;
700 
701  case RoQ_ID_SLD:
702  bytestream_put_byte(&spool.args,
703  tempData->i2f4[eval->subCels[j].cbEntry]);
704 
705  qcell = enc->cb4x4 + eval->subCels[j].cbEntry;
706 
707  ff_apply_vector_2x2(enc, subX , subY ,
708  enc->cb2x2 + qcell->idx[0]);
709  ff_apply_vector_2x2(enc, subX+2, subY ,
710  enc->cb2x2 + qcell->idx[1]);
711  ff_apply_vector_2x2(enc, subX , subY+2,
712  enc->cb2x2 + qcell->idx[2]);
713  ff_apply_vector_2x2(enc, subX+2, subY+2,
714  enc->cb2x2 + qcell->idx[3]);
715  break;
716 
717  case RoQ_ID_CCC:
718  for (k=0; k<4; k++) {
719  int cb_idx = eval->subCels[j].subCels[k];
720  bytestream_put_byte(&spool.args,
721  tempData->i2f2[cb_idx]);
722 
723  ff_apply_vector_2x2(enc, subX + 2*(k&1), subY + (k&2),
724  enc->cb2x2 + cb_idx);
725  }
726  break;
727  }
728  write_typecode(&spool, eval->subCels[j].best_coding);
729  }
730  break;
731  }
732  }
733 
734  /* Flush the remainder of the argument/type spool */
735  while (spool.typeSpoolLength)
736  write_typecode(&spool, 0x0);
737 
738 #if 0
739  uint8_t *fdata[3] = {enc->frame_to_enc->data[0],
740  enc->frame_to_enc->data[1],
741  enc->frame_to_enc->data[2]};
742  uint8_t *cdata[3] = {enc->current_frame->data[0],
743  enc->current_frame->data[1],
744  enc->current_frame->data[2]};
745  av_log(enc->avctx, AV_LOG_ERROR, "Expected distortion: %i Actual: %i\n",
746  dist,
747  block_sse(fdata, cdata, 0, 0, 0, 0,
748  enc->frame_to_enc->linesize,
749  enc->current_frame->linesize,
750  enc->width)); //WARNING: Square dimensions implied...
751 #endif
752 }
753 
754 
755 /**
756  * Create a single YUV cell from a 2x2 section of the image
757  */
758 static inline void frame_block_to_cell(uint8_t *block, uint8_t * const *data,
759  int top, int left, const int *stride)
760 {
761  int i, j, u=0, v=0;
762 
763  for (i=0; i<2; i++)
764  for (j=0; j<2; j++) {
765  int x = (top+i)*stride[0] + left + j;
766  *block++ = data[0][x];
767  x = (top+i)*stride[1] + left + j;
768  u += data[1][x];
769  v += data[2][x];
770  }
771 
772  *block++ = (u+2)/4;
773  *block++ = (v+2)/4;
774 }
775 
776 /**
777  * Create YUV clusters for the entire image
778  */
779 static void create_clusters(const AVFrame *frame, int w, int h, uint8_t *yuvClusters)
780 {
781  int i, j, k, l;
782 
783  for (i=0; i<h; i+=4)
784  for (j=0; j<w; j+=4) {
785  for (k=0; k < 2; k++)
786  for (l=0; l < 2; l++)
787  frame_block_to_cell(yuvClusters + (l + 2*k)*6, frame->data,
788  i+2*k, j+2*l, frame->linesize);
789  yuvClusters += 24;
790  }
791 }
792 
793 static void generate_codebook(RoqContext *enc, RoqTempdata *tempdata,
794  int *points, int inputCount, roq_cell *results,
795  int size, int cbsize)
796 {
797  int i, j, k;
798  int c_size = size*size/4;
799  int *buf;
800  int *codebook = av_malloc(6*c_size*cbsize*sizeof(int));
801  int *closest_cb;
802 
803  if (size == 4)
804  closest_cb = av_malloc(6*c_size*inputCount*sizeof(int));
805  else
806  closest_cb = tempdata->closest_cb2;
807 
808  ff_init_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx);
809  ff_do_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx);
810 
811  if (size == 4)
812  av_free(closest_cb);
813 
814  buf = codebook;
815  for (i=0; i<cbsize; i++)
816  for (k=0; k<c_size; k++) {
817  for(j=0; j<4; j++)
818  results->y[j] = *buf++;
819 
820  results->u = (*buf++ + CHROMA_BIAS/2)/CHROMA_BIAS;
821  results->v = (*buf++ + CHROMA_BIAS/2)/CHROMA_BIAS;
822  results++;
823  }
824 
825  av_free(codebook);
826 }
827 
828 static void generate_new_codebooks(RoqContext *enc, RoqTempdata *tempData)
829 {
830  int i,j;
831  RoqCodebooks *codebooks = &tempData->codebooks;
832  int max = enc->width*enc->height/16;
833  uint8_t mb2[3*4];
834  roq_cell *results4 = av_malloc(sizeof(roq_cell)*MAX_CBS_4x4*4);
835  uint8_t *yuvClusters=av_malloc(sizeof(int)*max*6*4);
836  int *points = av_malloc(max*6*4*sizeof(int));
837  int bias;
838 
839  /* Subsample YUV data */
840  create_clusters(enc->frame_to_enc, enc->width, enc->height, yuvClusters);
841 
842  /* Cast to integer and apply chroma bias */
843  for (i=0; i<max*24; i++) {
844  bias = ((i%6)<4) ? 1 : CHROMA_BIAS;
845  points[i] = bias*yuvClusters[i];
846  }
847 
848  /* Create 4x4 codebooks */
849  generate_codebook(enc, tempData, points, max, results4, 4, MAX_CBS_4x4);
850 
851  codebooks->numCB4 = MAX_CBS_4x4;
852 
853  tempData->closest_cb2 = av_malloc(max*4*sizeof(int));
854 
855  /* Create 2x2 codebooks */
856  generate_codebook(enc, tempData, points, max*4, enc->cb2x2, 2, MAX_CBS_2x2);
857 
858  codebooks->numCB2 = MAX_CBS_2x2;
859 
860  /* Unpack 2x2 codebook clusters */
861  for (i=0; i<codebooks->numCB2; i++)
862  unpack_roq_cell(enc->cb2x2 + i, codebooks->unpacked_cb2 + i*2*2*3);
863 
864  /* Index all 4x4 entries to the 2x2 entries, unpack, and enlarge */
865  for (i=0; i<codebooks->numCB4; i++) {
866  for (j=0; j<4; j++) {
867  unpack_roq_cell(&results4[4*i + j], mb2);
868  index_mb(mb2, codebooks->unpacked_cb2, codebooks->numCB2,
869  &enc->cb4x4[i].idx[j], 2);
870  }
871  unpack_roq_qcell(codebooks->unpacked_cb2, enc->cb4x4 + i,
872  codebooks->unpacked_cb4 + i*4*4*3);
873  enlarge_roq_mb4(codebooks->unpacked_cb4 + i*4*4*3,
874  codebooks->unpacked_cb4_enlarged + i*8*8*3);
875  }
876 
877  av_free(yuvClusters);
878  av_free(points);
879  av_free(results4);
880 }
881 
882 static void roq_encode_video(RoqContext *enc)
883 {
884  RoqTempdata *tempData = enc->tmpData;
885  int i;
886 
887  memset(tempData, 0, sizeof(*tempData));
888 
889  create_cel_evals(enc, tempData);
890 
891  generate_new_codebooks(enc, tempData);
892 
893  if (enc->framesSinceKeyframe >= 1) {
894  motion_search(enc, 8);
895  motion_search(enc, 4);
896  }
897 
898  retry_encode:
899  for (i=0; i<enc->width*enc->height/64; i++)
900  gather_data_for_cel(tempData->cel_evals + i, enc, tempData);
901 
902  /* Quake 3 can't handle chunks bigger than 65535 bytes */
903  if (tempData->mainChunkSize/8 > 65535) {
904  av_log(enc->avctx, AV_LOG_ERROR,
905  "Warning, generated a frame too big (%d > 65535), "
906  "try using a smaller qscale value.\n",
907  tempData->mainChunkSize/8);
908  enc->lambda *= 1.5;
909  tempData->mainChunkSize = 0;
910  memset(tempData->used_option, 0, sizeof(tempData->used_option));
911  memset(tempData->codebooks.usedCB4, 0,
912  sizeof(tempData->codebooks.usedCB4));
913  memset(tempData->codebooks.usedCB2, 0,
914  sizeof(tempData->codebooks.usedCB2));
915 
916  goto retry_encode;
917  }
918 
919  remap_codebooks(enc, tempData);
920 
921  write_codebooks(enc, tempData);
922 
923  reconstruct_and_encode_image(enc, tempData, enc->width, enc->height,
924  enc->width*enc->height/64);
925 
926  enc->avctx->coded_frame = enc->current_frame;
927 
928  /* Rotate frame history */
929  FFSWAP(AVFrame *, enc->current_frame, enc->last_frame);
932 
933  av_free(tempData->cel_evals);
934  av_free(tempData->closest_cb2);
935 
936  enc->framesSinceKeyframe++;
937 }
938 
939 static int roq_encode_end(AVCodecContext *avctx)
940 {
941  RoqContext *enc = avctx->priv_data;
942 
944  av_frame_free(&enc->last_frame);
945 
946  av_free(enc->tmpData);
947  av_free(enc->this_motion4);
948  av_free(enc->last_motion4);
949  av_free(enc->this_motion8);
950  av_free(enc->last_motion8);
951 
952  return 0;
953 }
954 
955 static int roq_encode_init(AVCodecContext *avctx)
956 {
957  RoqContext *enc = avctx->priv_data;
958 
959  av_lfg_init(&enc->randctx, 1);
960 
961  enc->framesSinceKeyframe = 0;
962  if ((avctx->width & 0xf) || (avctx->height & 0xf)) {
963  av_log(avctx, AV_LOG_ERROR, "Dimensions must be divisible by 16\n");
964  return -1;
965  }
966 
967  if (((avctx->width)&(avctx->width-1))||((avctx->height)&(avctx->height-1)))
968  av_log(avctx, AV_LOG_ERROR, "Warning: dimensions not power of two\n");
969 
970  enc->width = avctx->width;
971  enc->height = avctx->height;
972 
973  enc->framesSinceKeyframe = 0;
974  enc->first_frame = 1;
975 
976  enc->last_frame = av_frame_alloc();
977  enc->current_frame = av_frame_alloc();
978  if (!enc->last_frame || !enc->current_frame) {
979  roq_encode_end(avctx);
980  return AVERROR(ENOMEM);
981  }
982 
983  enc->tmpData = av_malloc(sizeof(RoqTempdata));
984 
985  enc->this_motion4 =
986  av_mallocz((enc->width*enc->height/16)*sizeof(motion_vect));
987 
988  enc->last_motion4 =
989  av_malloc ((enc->width*enc->height/16)*sizeof(motion_vect));
990 
991  enc->this_motion8 =
992  av_mallocz((enc->width*enc->height/64)*sizeof(motion_vect));
993 
994  enc->last_motion8 =
995  av_malloc ((enc->width*enc->height/64)*sizeof(motion_vect));
996 
997  return 0;
998 }
999 
1001 {
1002  /* ROQ info chunk */
1003  bytestream_put_le16(&enc->out_buf, RoQ_INFO);
1004 
1005  /* Size: 8 bytes */
1006  bytestream_put_le32(&enc->out_buf, 8);
1007 
1008  /* Unused argument */
1009  bytestream_put_byte(&enc->out_buf, 0x00);
1010  bytestream_put_byte(&enc->out_buf, 0x00);
1011 
1012  /* Width */
1013  bytestream_put_le16(&enc->out_buf, enc->width);
1014 
1015  /* Height */
1016  bytestream_put_le16(&enc->out_buf, enc->height);
1017 
1018  /* Unused in Quake 3, mimics the output of the real encoder */
1019  bytestream_put_byte(&enc->out_buf, 0x08);
1020  bytestream_put_byte(&enc->out_buf, 0x00);
1021  bytestream_put_byte(&enc->out_buf, 0x04);
1022  bytestream_put_byte(&enc->out_buf, 0x00);
1023 }
1024 
1026  const AVFrame *frame, int *got_packet)
1027 {
1028  RoqContext *enc = avctx->priv_data;
1029  int size, ret;
1030 
1031  enc->avctx = avctx;
1032 
1033  enc->frame_to_enc = frame;
1034 
1035  if (frame->quality)
1036  enc->lambda = frame->quality - 1;
1037  else
1038  enc->lambda = 2*ROQ_LAMBDA_SCALE;
1039 
1040  /* 138 bits max per 8x8 block +
1041  * 256 codebooks*(6 bytes 2x2 + 4 bytes 4x4) + 8 bytes frame header */
1042  size = ((enc->width * enc->height / 64) * 138 + 7) / 8 + 256 * (6 + 4) + 8;
1043  if ((ret = ff_alloc_packet2(avctx, pkt, size)) < 0)
1044  return ret;
1045  enc->out_buf = pkt->data;
1046 
1047  /* Check for I frame */
1048  if (enc->framesSinceKeyframe == avctx->gop_size)
1049  enc->framesSinceKeyframe = 0;
1050 
1051  if (enc->first_frame) {
1052  /* Alloc memory for the reconstruction data (we must know the stride
1053  for that) */
1054  if ((ret = ff_get_buffer(avctx, enc->current_frame, 0)) < 0 ||
1055  (ret = ff_get_buffer(avctx, enc->last_frame, 0)) < 0)
1056  return ret;
1057 
1058  /* Before the first video frame, write a "video info" chunk */
1060 
1061  enc->first_frame = 0;
1062  }
1063 
1064  /* Encode the actual frame */
1065  roq_encode_video(enc);
1066 
1067  pkt->size = enc->out_buf - pkt->data;
1068  if (enc->framesSinceKeyframe == 1)
1069  pkt->flags |= AV_PKT_FLAG_KEY;
1070  *got_packet = 1;
1071 
1072  return 0;
1073 }
1074 
1076  .name = "roqvideo",
1077  .type = AVMEDIA_TYPE_VIDEO,
1078  .id = AV_CODEC_ID_ROQ,
1079  .priv_data_size = sizeof(RoqContext),
1080  .init = roq_encode_init,
1081  .encode2 = roq_encode_frame,
1082  .close = roq_encode_end,
1083  .supported_framerates = (const AVRational[]){ {30,1}, {0,0} },
1084  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P,
1085  AV_PIX_FMT_NONE },
1086  .long_name = NULL_IF_CONFIG_SMALL("id RoQ video"),
1087 };
SubcelEvaluation subCels[4]
Definition: roqvideoenc.c:201
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
float v
const char * s
Definition: avisynth_c.h:668
int d[2]
Definition: roqvideo.h:39
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
motion_vect * this_motion4
Definition: roqvideo.h:62
const AVFrame * frame_to_enc
Definition: roqvideo.h:70
#define EVAL_MOTION(MOTION)
Definition: roqvideoenc.c:297
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:73
AVFrame * coded_frame
the picture in the bitstream
if max(w)>1 w=0.9 *w/max(w)
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static int eval_motion_dist(RoqContext *enc, int x, int y, motion_vect vect, int size)
Definition: roqvideoenc.c:144
motion_vect motion
Definition: roqvideoenc.c:203
void ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell)
Definition: roqvideo.c:41
y1
Definition: lab5.m:33
static void remap_codebooks(RoqContext *enc, RoqTempdata *tempData)
Definition: roqvideoenc.c:537
#define RoQ_ID_FCC
Definition: roqvideo.h:82
static int sse(MpegEncContext *s, uint8_t *src1, uint8_t *src2, int w, int h, int stride)
x1
Definition: genspecsines3.m:7
#define RoQ_INFO
Definition: roqvideo.h:75
int * closest_cb2
Definition: roqvideoenc.c:239
int i2f2[MAX_CBS_2x2]
Definition: roqvideoenc.c:230
AVCodec ff_roq_encoder
Definition: roqvideoenc.c:1075
motion_vect * this_motion8
Definition: roqvideo.h:65
AVFrame * current_frame
Definition: roqvideo.h:49
int stride
Definition: mace.c:144
struct RoqTempData RoqTempdata
Temporary vars.
output residual component w
motion_vect * last_motion4
Definition: roqvideo.h:63
#define MAX_CBS_4x4
Maximum number of generated 4x4 codebooks.
Definition: roqvideoenc.c:71
int width
Definition: roqvideo.h:56
set threshold d
#define RoQ_ID_MOT
Definition: roqvideo.h:81
initialize output if(nPeaks >3)%at least 3 peaks in spectrum for trying to find f0 nf0peaks
AVLFG randctx
Definition: roqvideo.h:59
static int roq_encode_init(AVCodecContext *avctx)
Definition: roqvideoenc.c:955
static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, int y, RoqContext *enc, RoqTempdata *tempData)
Get distortion for all options available to a subcel.
Definition: roqvideoenc.c:399
static void roq_write_video_info_chunk(RoqContext *enc)
Definition: roqvideoenc.c:1000
uint8_t
#define mb
#define RoQ_QUAD_CODEBOOK
Definition: roqvideo.h:76
static AVPacket pkt
Definition: demuxing.c:56
#define b
Definition: input.c:42
uint8_t * args
Definition: roqvideoenc.c:605
unsigned int framesSinceKeyframe
Definition: roqvideo.h:68
int usedCB4[MAX_CBS_4x4]
Definition: roqvideoenc.c:214
uint8_t * data
uint8_t ** pout
Definition: roqvideoenc.c:606
#define ROQ_LAMBDA_SCALE
Definition: roqvideoenc.c:76
uint8_t unpacked_cb2[MAX_CBS_2x2 *2 *2 *3]
Definition: roqvideoenc.c:215
void ff_apply_motion_4x4(RoqContext *ri, int x, int y, int deltax, int deltay)
Definition: roqvideo.c:133
void ff_apply_motion_8x8(RoqContext *ri, int x, int y, int deltax, int deltay)
Definition: roqvideo.c:139
#define MAX_CBS_2x2
Maximum number of 2x2 codebooks.
Definition: roqvideoenc.c:73
CelEvaluation * cel_evals
Definition: roqvideoenc.c:225
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
frame
Definition: stft.m:14
static void generate_new_codebooks(RoqContext *enc, RoqTempdata *tempData)
Definition: roqvideoenc.c:828
Discrete Time axis x
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
#define CHROMA_BIAS
Definition: roqvideoenc.c:65
static void unpack_roq_cell(roq_cell *cell, uint8_t u[4 *3])
Definition: roqvideoenc.c:79
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Spectrum Plot time data
roq_qcell cb4x4[256]
Definition: roqvideo.h:53
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
static int square(int x)
Definition: roqvideoenc.c:111
struct RoqContext RoqContext
static const uint8_t offset[127][2]
Definition: vf_spp.c:70
static int index_mb(uint8_t cluster[], uint8_t cb[], int numCB, int *outIndex, int dim)
Find the codebook with the lowest distortion from an image.
Definition: roqvideoenc.c:279
#define RoQ_ID_CCC
Definition: roqvideo.h:84
unsigned char u
Definition: roqvideo.h:31
int size
int flags
A combination of AV_PKT_FLAG values.
static int block_sse(uint8_t *const *buf1, uint8_t *const *buf2, int x1, int y1, int x2, int y2, const int *stride1, const int *stride2, int size)
Definition: roqvideoenc.c:128
void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, int numCB, int max_steps, int *closest_cb, AVLFG *rand_state)
Implementation of the Enhanced LBG Algorithm Based on the paper "Neural Networks 14:1219-1237" that c...
Definition: elbg.c:354
static void frame_block_to_cell(uint8_t *block, uint8_t *const *data, int top, int left, const int *stride)
Create a single YUV cell from a 2x2 section of the image.
Definition: roqvideoenc.c:758
static void write_codebooks(RoqContext *enc, RoqTempdata *tempData)
Write codebook chunk.
Definition: roqvideoenc.c:569
int mainChunkSize
Definition: roqvideoenc.c:232
static void write_typecode(CodingSpool *s, uint8_t type)
Definition: roqvideoenc.c:610
static int squared_diff_macroblock(uint8_t a[], uint8_t b[], int size)
Definition: roqvideoenc.c:171
ret
Definition: avfilter.c:821
int width
picture width / height.
struct RoqTempData * tmpData
Definition: roqvideo.h:72
eval(cmd)
int typeSpoolLength
Definition: roqvideoenc.c:603
int quality
quality (between 1 (good) and FF_LAMBDA_MAX (bad))
Definition: frame.h:185
static void create_cel_evals(RoqContext *enc, RoqTempdata *tempData)
Initialize cel evaluators and set their source coordinates.
Definition: roqvideoenc.c:246
float u
#define diff(a, as, b, bs)
Definition: vf_phase.c:80
static void motion_search(RoqContext *enc, int blocksize)
Definition: roqvideoenc.c:307
y2
Definition: lab5.m:34
static uint8_t motion_arg(motion_vect mot)
Definition: roqvideoenc.c:593
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int size)
Check AVPacket size and/or allocate data.
static int roq_encode_end(AVCodecContext *avctx)
Definition: roqvideoenc.c:939
int idx[4]
Definition: roqvideo.h:35
for k
RoqCodebooks codebooks
Definition: roqvideoenc.c:237
int first_frame
Definition: roqvideo.h:50
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
FIXME Range Coding of cb
Definition: snow.txt:367
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
#define RoQ_ID_SLD
Definition: roqvideo.h:83
unsigned char y[4]
Definition: roqvideo.h:30
void * buf
Definition: avisynth_c.h:594
static int eval_sse(const uint8_t *a, const uint8_t *b, int count)
Definition: roqvideoenc.c:116
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
static void generate_codebook(RoqContext *enc, RoqTempdata *tempdata, int *points, int inputCount, roq_cell *results, int size, int cbsize)
Definition: roqvideoenc.c:793
static void roq_encode_video(RoqContext *enc)
Definition: roqvideoenc.c:882
uint64_t lambda
Definition: roqvideo.h:60
x2
Definition: genspecsines3.m:8
int index
Definition: gxfenc.c:89
synthesis window for stochastic i
rational number numerator/denominator
Definition: rational.h:43
#define mid_pred
Definition: mathops.h:94
int dim
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:30
int i2f4[MAX_CBS_4x4]
Definition: roqvideoenc.c:228
static void gather_data_for_cel(CelEvaluation *cel, RoqContext *enc, RoqTempdata *tempData)
Get distortion for all options available to a cel.
Definition: roqvideoenc.c:463
void ff_init_elbg(int *points, int dim, int numpoints, int *codebook, int numCB, int max_steps, int *closest_cb, AVLFG *rand_state)
Initialize the **codebook vector for the elbg algorithm.
Definition: elbg.c:327
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
#define type
uint8_t argumentSpool[64]
Definition: roqvideoenc.c:604
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:95
static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: roqvideoenc.c:1025
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
AVCodecContext * avctx
Definition: roqvideo.h:46
uint8_t * out_buf
Definition: roqvideo.h:71
common internal api header.
int used_option[4]
Definition: roqvideoenc.c:240
static void get_frame_mb(const AVFrame *frame, int x, int y, uint8_t mb[], int dim)
Get macroblocks from parts of the image.
Definition: roqvideoenc.c:264
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:108
Temporary vars.
Definition: roqvideoenc.c:223
function y
Definition: D.m:1
motion_vect * last_motion8
Definition: roqvideo.h:66
motion_vect motion
Definition: roqvideoenc.c:192
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:337
#define RoQ_QUAD_VQ
Definition: roqvideo.h:77
int f2i2[MAX_CBS_2x2]
Definition: roqvideoenc.c:229
static void enlarge_roq_mb4(uint8_t base[3 *16], uint8_t u[3 *64])
Definition: roqvideoenc.c:101
void ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell)
Definition: roqvideo.c:71
roq_cell cb2x2[256]
Definition: roqvideo.h:52
AVFrame * last_frame
Definition: roqvideo.h:48
static void create_clusters(const AVFrame *frame, int w, int h, uint8_t *yuvClusters)
Create YUV clusters for the entire image.
Definition: roqvideoenc.c:779
int usedCB2[MAX_CBS_2x2]
Definition: roqvideoenc.c:213
uint8_t unpacked_cb4[MAX_CBS_4x4 *4 *4 *3]
Definition: roqvideoenc.c:216
void INT64 INT64 count
Definition: avisynth_c.h:594
In the ELBG jargon, a cell is the set of points that are closest to a codebook entry.
Definition: elbg.c:39
static void unpack_roq_qcell(uint8_t cb2[], roq_qcell *qcell, uint8_t u[4 *4 *3])
Definition: roqvideoenc.c:86
#define FFSWAP(type, a, b)
Definition: common.h:61
int f2i4[MAX_CBS_4x4]
Definition: roqvideoenc.c:227
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
This structure stores compressed data.
uint8_t unpacked_cb4_enlarged[MAX_CBS_4x4 *8 *8 *3]
Definition: roqvideoenc.c:217
unsigned char v
Definition: roqvideo.h:31
int eval_dist[4]
Definition: roqvideoenc.c:198
int height
Definition: roqvideo.h:56
static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, int w, int h, int numBlocks)
Definition: roqvideoenc.c:624