annotate roqvideoenc.c @ 9473:e38284cd69dc libavcodec

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