annotate roqvideoenc.c @ 12530:63edd10ad4bc libavcodec tip

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