1 |
|
|
/* |
2 |
|
|
* SVQ1 Encoder |
3 |
|
|
* Copyright (C) 2004 Mike Melanson <melanson@pcisys.net> |
4 |
|
|
* |
5 |
|
|
* This file is part of FFmpeg. |
6 |
|
|
* |
7 |
|
|
* FFmpeg is free software; you can redistribute it and/or |
8 |
|
|
* modify it under the terms of the GNU Lesser General Public |
9 |
|
|
* License as published by the Free Software Foundation; either |
10 |
|
|
* version 2.1 of the License, or (at your option) any later version. |
11 |
|
|
* |
12 |
|
|
* FFmpeg is distributed in the hope that it will be useful, |
13 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 |
|
|
* Lesser General Public License for more details. |
16 |
|
|
* |
17 |
|
|
* You should have received a copy of the GNU Lesser General Public |
18 |
|
|
* License along with FFmpeg; if not, write to the Free Software |
19 |
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 |
|
|
*/ |
21 |
|
|
|
22 |
|
|
/** |
23 |
|
|
* @file |
24 |
|
|
* Sorenson Vector Quantizer #1 (SVQ1) video codec. |
25 |
|
|
* For more information of the SVQ1 algorithm, visit: |
26 |
|
|
* http://www.pcisys.net/~melanson/codecs/ |
27 |
|
|
*/ |
28 |
|
|
|
29 |
|
|
#include "avcodec.h" |
30 |
|
|
#include "hpeldsp.h" |
31 |
|
|
#include "me_cmp.h" |
32 |
|
|
#include "mpegvideo.h" |
33 |
|
|
#include "h263.h" |
34 |
|
|
#include "internal.h" |
35 |
|
|
#include "mpegutils.h" |
36 |
|
|
#include "packet_internal.h" |
37 |
|
|
#include "svq1.h" |
38 |
|
|
#include "svq1enc.h" |
39 |
|
|
#include "svq1enc_cb.h" |
40 |
|
|
#include "libavutil/avassert.h" |
41 |
|
|
|
42 |
|
|
|
43 |
|
200 |
static void svq1_write_header(SVQ1EncContext *s, int frame_type) |
44 |
|
|
{ |
45 |
|
|
int i; |
46 |
|
|
|
47 |
|
|
/* frame code */ |
48 |
|
200 |
put_bits(&s->pb, 22, 0x20); |
49 |
|
|
|
50 |
|
|
/* temporal reference (sure hope this is a "don't care") */ |
51 |
|
200 |
put_bits(&s->pb, 8, 0x00); |
52 |
|
|
|
53 |
|
|
/* frame type */ |
54 |
|
200 |
put_bits(&s->pb, 2, frame_type - 1); |
55 |
|
|
|
56 |
✓✓ |
200 |
if (frame_type == AV_PICTURE_TYPE_I) { |
57 |
|
|
/* no checksum since frame code is 0x20 */ |
58 |
|
|
/* no embedded string either */ |
59 |
|
|
/* output 5 unknown bits (2 + 2 + 1) */ |
60 |
|
20 |
put_bits(&s->pb, 5, 2); /* 2 needed by quicktime decoder */ |
61 |
|
|
|
62 |
|
20 |
i = ff_match_2uint16((void*)ff_svq1_frame_size_table, |
63 |
|
|
FF_ARRAY_ELEMS(ff_svq1_frame_size_table), |
64 |
|
|
s->frame_width, s->frame_height); |
65 |
|
20 |
put_bits(&s->pb, 3, i); |
66 |
|
|
|
67 |
✓✓ |
20 |
if (i == 7) { |
68 |
|
5 |
put_bits(&s->pb, 12, s->frame_width); |
69 |
|
5 |
put_bits(&s->pb, 12, s->frame_height); |
70 |
|
|
} |
71 |
|
|
} |
72 |
|
|
|
73 |
|
|
/* no checksum or extra data (next 2 bits get 0) */ |
74 |
|
200 |
put_bits(&s->pb, 2, 0); |
75 |
|
200 |
} |
76 |
|
|
|
77 |
|
|
#define QUALITY_THRESHOLD 100 |
78 |
|
|
#define THRESHOLD_MULTIPLIER 0.6 |
79 |
|
|
|
80 |
|
393187392 |
static int ssd_int8_vs_int16_c(const int8_t *pix1, const int16_t *pix2, |
81 |
|
|
intptr_t size) |
82 |
|
|
{ |
83 |
|
393187392 |
int score = 0, i; |
84 |
|
|
|
85 |
✓✓ |
7128095808 |
for (i = 0; i < size; i++) |
86 |
|
6734908416 |
score += (pix1[i] - pix2[i]) * (pix1[i] - pix2[i]); |
87 |
|
393187392 |
return score; |
88 |
|
|
} |
89 |
|
|
|
90 |
|
4302520 |
static int encode_block(SVQ1EncContext *s, uint8_t *src, uint8_t *ref, |
91 |
|
|
uint8_t *decoded, int stride, int level, |
92 |
|
|
int threshold, int lambda, int intra) |
93 |
|
|
{ |
94 |
|
|
int count, y, x, i, j, split, best_mean, best_score, best_count; |
95 |
|
|
int best_vector[6]; |
96 |
|
4302520 |
int block_sum[7] = { 0, 0, 0, 0, 0, 0 }; |
97 |
|
4302520 |
int w = 2 << (level + 2 >> 1); |
98 |
|
4302520 |
int h = 2 << (level + 1 >> 1); |
99 |
|
4302520 |
int size = w * h; |
100 |
|
4302520 |
int16_t (*block)[256] = s->encoded_block_levels[level]; |
101 |
|
|
const int8_t *codebook_sum, *codebook; |
102 |
|
|
const uint16_t(*mean_vlc)[2]; |
103 |
|
|
const uint8_t(*multistage_vlc)[2]; |
104 |
|
|
|
105 |
|
4302520 |
best_score = 0; |
106 |
|
|
// FIXME: Optimize, this does not need to be done multiple times. |
107 |
✓✓ |
4302520 |
if (intra) { |
108 |
|
|
// level is 5 when encode_block is called from svq1_encode_plane |
109 |
|
|
// and always < 4 when called recursively from this function. |
110 |
✓✓ |
643967 |
codebook_sum = level < 4 ? svq1_intra_codebook_sum[level] : NULL; |
111 |
|
643967 |
codebook = ff_svq1_intra_codebooks[level]; |
112 |
|
643967 |
mean_vlc = ff_svq1_intra_mean_vlc; |
113 |
|
643967 |
multistage_vlc = ff_svq1_intra_multistage_vlc[level]; |
114 |
✓✓ |
2941539 |
for (y = 0; y < h; y++) { |
115 |
✓✓ |
18101876 |
for (x = 0; x < w; x++) { |
116 |
|
15804304 |
int v = src[x + y * stride]; |
117 |
|
15804304 |
block[0][x + w * y] = v; |
118 |
|
15804304 |
best_score += v * v; |
119 |
|
15804304 |
block_sum[0] += v; |
120 |
|
|
} |
121 |
|
|
} |
122 |
|
|
} else { |
123 |
|
|
// level is 5 or < 4, see above for details. |
124 |
✓✓ |
3658553 |
codebook_sum = level < 4 ? svq1_inter_codebook_sum[level] : NULL; |
125 |
|
3658553 |
codebook = ff_svq1_inter_codebooks[level]; |
126 |
|
3658553 |
mean_vlc = ff_svq1_inter_mean_vlc + 256; |
127 |
|
3658553 |
multistage_vlc = ff_svq1_inter_multistage_vlc[level]; |
128 |
✓✓ |
16702413 |
for (y = 0; y < h; y++) { |
129 |
✓✓ |
102693156 |
for (x = 0; x < w; x++) { |
130 |
|
89649296 |
int v = src[x + y * stride] - ref[x + y * stride]; |
131 |
|
89649296 |
block[0][x + w * y] = v; |
132 |
|
89649296 |
best_score += v * v; |
133 |
|
89649296 |
block_sum[0] += v; |
134 |
|
|
} |
135 |
|
|
} |
136 |
|
|
} |
137 |
|
|
|
138 |
|
4302520 |
best_count = 0; |
139 |
|
4302520 |
best_score -= (int)((unsigned)block_sum[0] * block_sum[0] >> (level + 3)); |
140 |
|
4302520 |
best_mean = block_sum[0] + (size >> 1) >> (level + 3); |
141 |
|
|
|
142 |
✓✓ |
4302520 |
if (level < 4) { |
143 |
✓✓ |
28669914 |
for (count = 1; count < 7; count++) { |
144 |
|
24574212 |
int best_vector_score = INT_MAX; |
145 |
|
24574212 |
int best_vector_sum = -999, best_vector_mean = -999; |
146 |
|
24574212 |
const int stage = count - 1; |
147 |
|
|
const int8_t *vector; |
148 |
|
|
|
149 |
✓✓ |
417761604 |
for (i = 0; i < 16; i++) { |
150 |
|
393187392 |
int sum = codebook_sum[stage * 16 + i]; |
151 |
|
|
int sqr, diff, score; |
152 |
|
|
|
153 |
|
393187392 |
vector = codebook + stage * size * 16 + i * size; |
154 |
|
393187392 |
sqr = s->ssd_int8_vs_int16(vector, block[stage], size); |
155 |
|
393187392 |
diff = block_sum[stage] - sum; |
156 |
|
393187392 |
score = sqr - (diff * (int64_t)diff >> (level + 3)); // FIXME: 64 bits slooow |
157 |
✓✓ |
393187392 |
if (score < best_vector_score) { |
158 |
|
65429340 |
int mean = diff + (size >> 1) >> (level + 3); |
159 |
|
|
av_assert2(mean > -300 && mean < 300); |
160 |
✓✓ |
65429340 |
mean = av_clip(mean, intra ? 0 : -256, 255); |
161 |
|
65429340 |
best_vector_score = score; |
162 |
|
65429340 |
best_vector[stage] = i; |
163 |
|
65429340 |
best_vector_sum = sum; |
164 |
|
65429340 |
best_vector_mean = mean; |
165 |
|
|
} |
166 |
|
|
} |
167 |
✗✓ |
24574212 |
av_assert0(best_vector_mean != -999); |
168 |
|
24574212 |
vector = codebook + stage * size * 16 + best_vector[stage] * size; |
169 |
✓✓ |
445505988 |
for (j = 0; j < size; j++) |
170 |
|
420931776 |
block[stage + 1][j] = block[stage][j] - vector[j]; |
171 |
|
24574212 |
block_sum[stage + 1] = block_sum[stage] - best_vector_sum; |
172 |
|
24574212 |
best_vector_score += lambda * |
173 |
|
24574212 |
(+1 + 4 * count + |
174 |
|
24574212 |
multistage_vlc[1 + count][1] |
175 |
|
24574212 |
+ mean_vlc[best_vector_mean][1]); |
176 |
|
|
|
177 |
✓✓ |
24574212 |
if (best_vector_score < best_score) { |
178 |
|
5418702 |
best_score = best_vector_score; |
179 |
|
5418702 |
best_count = count; |
180 |
|
5418702 |
best_mean = best_vector_mean; |
181 |
|
|
} |
182 |
|
|
} |
183 |
|
|
} |
184 |
|
|
|
185 |
|
4302520 |
split = 0; |
186 |
✓✓✓✓
|
4302520 |
if (best_score > threshold && level) { |
187 |
|
2116785 |
int score = 0; |
188 |
✓✓ |
2116785 |
int offset = level & 1 ? stride * h / 2 : w / 2; |
189 |
|
|
PutBitContext backup[6]; |
190 |
|
|
|
191 |
✓✓ |
6020163 |
for (i = level - 1; i >= 0; i--) |
192 |
|
3903378 |
backup[i] = s->reorder_pb[i]; |
193 |
|
2116785 |
score += encode_block(s, src, ref, decoded, stride, level - 1, |
194 |
|
|
threshold >> 1, lambda, intra); |
195 |
|
2116785 |
score += encode_block(s, src + offset, ref + offset, decoded + offset, |
196 |
|
|
stride, level - 1, threshold >> 1, lambda, intra); |
197 |
|
2116785 |
score += lambda; |
198 |
|
|
|
199 |
✓✓ |
2116785 |
if (score < best_score) { |
200 |
|
1359022 |
best_score = score; |
201 |
|
1359022 |
split = 1; |
202 |
|
|
} else { |
203 |
✓✓ |
1804497 |
for (i = level - 1; i >= 0; i--) |
204 |
|
1046734 |
s->reorder_pb[i] = backup[i]; |
205 |
|
|
} |
206 |
|
|
} |
207 |
✓✓ |
4302520 |
if (level > 0) |
208 |
|
2127648 |
put_bits(&s->reorder_pb[level], 1, split); |
209 |
|
|
|
210 |
✓✓ |
4302520 |
if (!split) { |
211 |
|
|
av_assert1(best_mean >= 0 && best_mean < 256 || !intra); |
212 |
|
|
av_assert1(best_mean >= -256 && best_mean < 256); |
213 |
|
|
av_assert1(best_count >= 0 && best_count < 7); |
214 |
|
|
av_assert1(level < 4 || best_count == 0); |
215 |
|
|
|
216 |
|
|
/* output the encoding */ |
217 |
|
2943498 |
put_bits(&s->reorder_pb[level], |
218 |
|
2943498 |
multistage_vlc[1 + best_count][1], |
219 |
|
2943498 |
multistage_vlc[1 + best_count][0]); |
220 |
|
2943498 |
put_bits(&s->reorder_pb[level], mean_vlc[best_mean][1], |
221 |
|
2943498 |
mean_vlc[best_mean][0]); |
222 |
|
|
|
223 |
✓✓ |
6593260 |
for (i = 0; i < best_count; i++) { |
224 |
|
|
av_assert2(best_vector[i] >= 0 && best_vector[i] < 16); |
225 |
|
3649762 |
put_bits(&s->reorder_pb[level], 4, best_vector[i]); |
226 |
|
|
} |
227 |
|
|
|
228 |
✓✓ |
10625782 |
for (y = 0; y < h; y++) |
229 |
✓✓ |
43895628 |
for (x = 0; x < w; x++) |
230 |
|
36213344 |
decoded[x + y * stride] = src[x + y * stride] - |
231 |
|
36213344 |
block[best_count][x + w * y] + |
232 |
|
|
best_mean; |
233 |
|
|
} |
234 |
|
|
|
235 |
|
4302520 |
return best_score; |
236 |
|
|
} |
237 |
|
|
|
238 |
|
131005 |
static void init_block_index(MpegEncContext *s){ |
239 |
|
131005 |
s->block_index[0]= s->b8_stride*(s->mb_y*2 ) + s->mb_x*2; |
240 |
|
131005 |
s->block_index[1]= s->b8_stride*(s->mb_y*2 ) + 1 + s->mb_x*2; |
241 |
|
131005 |
s->block_index[2]= s->b8_stride*(s->mb_y*2 + 1) + s->mb_x*2; |
242 |
|
131005 |
s->block_index[3]= s->b8_stride*(s->mb_y*2 + 1) + 1 + s->mb_x*2; |
243 |
|
131005 |
s->block_index[4]= s->mb_stride*(s->mb_y + 1) + s->b8_stride*s->mb_height*2 + s->mb_x; |
244 |
|
131005 |
s->block_index[5]= s->mb_stride*(s->mb_y + s->mb_height + 2) + s->b8_stride*s->mb_height*2 + s->mb_x; |
245 |
|
131005 |
} |
246 |
|
|
|
247 |
|
600 |
static int svq1_encode_plane(SVQ1EncContext *s, int plane, |
248 |
|
|
unsigned char *src_plane, |
249 |
|
|
unsigned char *ref_plane, |
250 |
|
|
unsigned char *decoded_plane, |
251 |
|
|
int width, int height, int src_stride, int stride) |
252 |
|
|
{ |
253 |
|
|
int x, y; |
254 |
|
|
int i; |
255 |
|
|
int block_width, block_height; |
256 |
|
|
int level; |
257 |
|
|
int threshold[6]; |
258 |
|
600 |
uint8_t *src = s->scratchbuf + stride * 32; |
259 |
|
600 |
const int lambda = (s->quality * s->quality) >> |
260 |
|
|
(2 * FF_LAMBDA_SHIFT); |
261 |
|
|
|
262 |
|
|
/* figure out the acceptable level thresholds in advance */ |
263 |
|
600 |
threshold[5] = QUALITY_THRESHOLD; |
264 |
✓✓ |
3600 |
for (level = 4; level >= 0; level--) |
265 |
|
3000 |
threshold[level] = threshold[level + 1] * THRESHOLD_MULTIPLIER; |
266 |
|
|
|
267 |
|
600 |
block_width = (width + 15) / 16; |
268 |
|
600 |
block_height = (height + 15) / 16; |
269 |
|
|
|
270 |
✓✓ |
600 |
if (s->pict_type == AV_PICTURE_TYPE_P) { |
271 |
|
540 |
s->m.avctx = s->avctx; |
272 |
|
540 |
s->m.current_picture_ptr = &s->m.current_picture; |
273 |
|
540 |
s->m.last_picture_ptr = &s->m.last_picture; |
274 |
|
540 |
s->m.last_picture.f->data[0] = ref_plane; |
275 |
|
540 |
s->m.linesize = |
276 |
|
540 |
s->m.last_picture.f->linesize[0] = |
277 |
|
540 |
s->m.new_picture.f->linesize[0] = |
278 |
|
540 |
s->m.current_picture.f->linesize[0] = stride; |
279 |
|
540 |
s->m.width = width; |
280 |
|
540 |
s->m.height = height; |
281 |
|
540 |
s->m.mb_width = block_width; |
282 |
|
540 |
s->m.mb_height = block_height; |
283 |
|
540 |
s->m.mb_stride = s->m.mb_width + 1; |
284 |
|
540 |
s->m.b8_stride = 2 * s->m.mb_width + 1; |
285 |
|
540 |
s->m.f_code = 1; |
286 |
|
540 |
s->m.pict_type = s->pict_type; |
287 |
|
540 |
s->m.motion_est = s->motion_est; |
288 |
|
540 |
s->m.me.scene_change_score = 0; |
289 |
|
|
// s->m.out_format = FMT_H263; |
290 |
|
|
// s->m.unrestricted_mv = 1; |
291 |
|
540 |
s->m.lambda = s->quality; |
292 |
|
540 |
s->m.qscale = s->m.lambda * 139 + |
293 |
|
540 |
FF_LAMBDA_SCALE * 64 >> |
294 |
|
|
FF_LAMBDA_SHIFT + 7; |
295 |
|
540 |
s->m.lambda2 = s->m.lambda * s->m.lambda + |
296 |
|
540 |
FF_LAMBDA_SCALE / 2 >> |
297 |
|
|
FF_LAMBDA_SHIFT; |
298 |
|
|
|
299 |
✓✓ |
540 |
if (!s->motion_val8[plane]) { |
300 |
|
24 |
s->motion_val8[plane] = av_mallocz((s->m.b8_stride * |
301 |
|
12 |
block_height * 2 + 2) * |
302 |
|
|
2 * sizeof(int16_t)); |
303 |
|
24 |
s->motion_val16[plane] = av_mallocz((s->m.mb_stride * |
304 |
|
12 |
(block_height + 2) + 1) * |
305 |
|
|
2 * sizeof(int16_t)); |
306 |
✓✗✗✓
|
12 |
if (!s->motion_val8[plane] || !s->motion_val16[plane]) |
307 |
|
|
return AVERROR(ENOMEM); |
308 |
|
|
} |
309 |
|
|
|
310 |
|
540 |
s->m.mb_type = s->mb_type; |
311 |
|
|
|
312 |
|
|
// dummies, to avoid segfaults |
313 |
|
540 |
s->m.current_picture.mb_mean = (uint8_t *)s->dummy; |
314 |
|
540 |
s->m.current_picture.mb_var = (uint16_t *)s->dummy; |
315 |
|
540 |
s->m.current_picture.mc_mb_var = (uint16_t *)s->dummy; |
316 |
|
540 |
s->m.current_picture.mb_type = s->dummy; |
317 |
|
|
|
318 |
|
540 |
s->m.current_picture.motion_val[0] = s->motion_val8[plane] + 2; |
319 |
|
540 |
s->m.p_mv_table = s->motion_val16[plane] + |
320 |
|
540 |
s->m.mb_stride + 1; |
321 |
|
540 |
s->m.mecc = s->mecc; // move |
322 |
|
540 |
ff_init_me(&s->m); |
323 |
|
|
|
324 |
|
540 |
s->m.me.dia_size = s->avctx->dia_size; |
325 |
|
540 |
s->m.first_slice_line = 1; |
326 |
✓✓ |
4545 |
for (y = 0; y < block_height; y++) { |
327 |
|
4005 |
s->m.new_picture.f->data[0] = src - y * 16 * stride; // ugly |
328 |
|
4005 |
s->m.mb_y = y; |
329 |
|
|
|
330 |
✓✓✓✓
|
64575 |
for (i = 0; i < 16 && i + 16 * y < height; i++) { |
331 |
|
60570 |
memcpy(&src[i * stride], &src_plane[(i + 16 * y) * src_stride], |
332 |
|
|
width); |
333 |
✓✓ |
243270 |
for (x = width; x < 16 * block_width; x++) |
334 |
|
182700 |
src[i * stride + x] = src[i * stride + x - 1]; |
335 |
|
|
} |
336 |
✓✓✓✗
|
7515 |
for (; i < 16 && i + 16 * y < 16 * block_height; i++) |
337 |
|
3510 |
memcpy(&src[i * stride], &src[(i - 1) * stride], |
338 |
|
3510 |
16 * block_width); |
339 |
|
|
|
340 |
✓✓ |
66060 |
for (x = 0; x < block_width; x++) { |
341 |
|
62055 |
s->m.mb_x = x; |
342 |
|
62055 |
init_block_index(&s->m); |
343 |
|
|
|
344 |
|
62055 |
ff_estimate_p_frame_motion(&s->m, x, y); |
345 |
|
|
} |
346 |
|
4005 |
s->m.first_slice_line = 0; |
347 |
|
|
} |
348 |
|
|
|
349 |
|
540 |
ff_fix_long_p_mvs(&s->m, CANDIDATE_MB_TYPE_INTRA); |
350 |
|
540 |
ff_fix_long_mvs(&s->m, NULL, 0, s->m.p_mv_table, s->m.f_code, |
351 |
|
|
CANDIDATE_MB_TYPE_INTER, 0); |
352 |
|
|
} |
353 |
|
|
|
354 |
|
600 |
s->m.first_slice_line = 1; |
355 |
✓✓ |
5050 |
for (y = 0; y < block_height; y++) { |
356 |
✓✓✓✓
|
71750 |
for (i = 0; i < 16 && i + 16 * y < height; i++) { |
357 |
|
67300 |
memcpy(&src[i * stride], &src_plane[(i + 16 * y) * src_stride], |
358 |
|
|
width); |
359 |
✓✓ |
270300 |
for (x = width; x < 16 * block_width; x++) |
360 |
|
203000 |
src[i * stride + x] = src[i * stride + x - 1]; |
361 |
|
|
} |
362 |
✓✓✓✗
|
8350 |
for (; i < 16 && i + 16 * y < 16 * block_height; i++) |
363 |
|
3900 |
memcpy(&src[i * stride], &src[(i - 1) * stride], 16 * block_width); |
364 |
|
|
|
365 |
|
4450 |
s->m.mb_y = y; |
366 |
✓✓ |
73400 |
for (x = 0; x < block_width; x++) { |
367 |
|
|
uint8_t reorder_buffer[2][6][7 * 32]; |
368 |
|
|
int count[2][6]; |
369 |
|
68950 |
int offset = y * 16 * stride + x * 16; |
370 |
|
68950 |
uint8_t *decoded = decoded_plane + offset; |
371 |
|
68950 |
uint8_t *ref = ref_plane + offset; |
372 |
|
68950 |
int score[4] = { 0, 0, 0, 0 }, best; |
373 |
|
68950 |
uint8_t *temp = s->scratchbuf; |
374 |
|
|
|
375 |
|
137900 |
if (s->pb.buf_end - s->pb.buf - |
376 |
✗✓ |
68950 |
(put_bits_count(&s->pb) >> 3) < 3000) { // FIXME: check size |
377 |
|
|
av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); |
378 |
|
|
return -1; |
379 |
|
|
} |
380 |
|
|
|
381 |
|
68950 |
s->m.mb_x = x; |
382 |
|
68950 |
init_block_index(&s->m); |
383 |
|
|
|
384 |
✓✓ |
68950 |
if (s->pict_type == AV_PICTURE_TYPE_I || |
385 |
✓✓ |
62055 |
(s->m.mb_type[x + y * s->m.mb_stride] & |
386 |
|
|
CANDIDATE_MB_TYPE_INTRA)) { |
387 |
✓✓ |
72443 |
for (i = 0; i < 6; i++) |
388 |
|
62094 |
init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], |
389 |
|
|
7 * 32); |
390 |
✓✓ |
10349 |
if (s->pict_type == AV_PICTURE_TYPE_P) { |
391 |
|
3454 |
const uint8_t *vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_INTRA]; |
392 |
|
3454 |
put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); |
393 |
|
3454 |
score[0] = vlc[1] * lambda; |
394 |
|
|
} |
395 |
|
10349 |
score[0] += encode_block(s, src + 16 * x, NULL, temp, stride, |
396 |
|
|
5, 64, lambda, 1); |
397 |
✓✓ |
72443 |
for (i = 0; i < 6; i++) { |
398 |
|
62094 |
count[0][i] = put_bits_count(&s->reorder_pb[i]); |
399 |
|
62094 |
flush_put_bits(&s->reorder_pb[i]); |
400 |
|
|
} |
401 |
|
|
} else |
402 |
|
58601 |
score[0] = INT_MAX; |
403 |
|
|
|
404 |
|
68950 |
best = 0; |
405 |
|
|
|
406 |
✓✓ |
68950 |
if (s->pict_type == AV_PICTURE_TYPE_P) { |
407 |
|
62055 |
const uint8_t *vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_INTER]; |
408 |
|
|
int mx, my, pred_x, pred_y, dxy; |
409 |
|
|
int16_t *motion_ptr; |
410 |
|
|
|
411 |
|
62055 |
motion_ptr = ff_h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y); |
412 |
✓✓ |
62055 |
if (s->m.mb_type[x + y * s->m.mb_stride] & |
413 |
|
|
CANDIDATE_MB_TYPE_INTER) { |
414 |
✓✓ |
410207 |
for (i = 0; i < 6; i++) |
415 |
|
351606 |
init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], |
416 |
|
|
7 * 32); |
417 |
|
|
|
418 |
|
58601 |
put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); |
419 |
|
|
|
420 |
|
58601 |
s->m.pb = s->reorder_pb[5]; |
421 |
|
58601 |
mx = motion_ptr[0]; |
422 |
|
58601 |
my = motion_ptr[1]; |
423 |
|
|
av_assert1(mx >= -32 && mx <= 31); |
424 |
|
|
av_assert1(my >= -32 && my <= 31); |
425 |
|
|
av_assert1(pred_x >= -32 && pred_x <= 31); |
426 |
|
|
av_assert1(pred_y >= -32 && pred_y <= 31); |
427 |
|
58601 |
ff_h263_encode_motion(&s->m.pb, mx - pred_x, 1); |
428 |
|
58601 |
ff_h263_encode_motion(&s->m.pb, my - pred_y, 1); |
429 |
|
58601 |
s->reorder_pb[5] = s->m.pb; |
430 |
|
58601 |
score[1] += lambda * put_bits_count(&s->reorder_pb[5]); |
431 |
|
|
|
432 |
|
58601 |
dxy = (mx & 1) + 2 * (my & 1); |
433 |
|
|
|
434 |
|
58601 |
s->hdsp.put_pixels_tab[0][dxy](temp + 16*stride, |
435 |
|
58601 |
ref + (mx >> 1) + |
436 |
|
58601 |
stride * (my >> 1), |
437 |
|
|
stride, 16); |
438 |
|
|
|
439 |
|
58601 |
score[1] += encode_block(s, src + 16 * x, temp + 16*stride, |
440 |
|
|
decoded, stride, 5, 64, lambda, 0); |
441 |
|
58601 |
best = score[1] <= score[0]; |
442 |
|
|
|
443 |
|
58601 |
vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_SKIP]; |
444 |
|
58601 |
score[2] = s->mecc.sse[0](NULL, src + 16 * x, ref, |
445 |
|
|
stride, 16); |
446 |
|
58601 |
score[2] += vlc[1] * lambda; |
447 |
✓✓✓✓ ✓✓ |
58601 |
if (score[2] < score[best] && mx == 0 && my == 0) { |
448 |
|
84 |
best = 2; |
449 |
|
84 |
s->hdsp.put_pixels_tab[0][0](decoded, ref, stride, 16); |
450 |
|
84 |
put_bits(&s->pb, vlc[1], vlc[0]); |
451 |
|
|
} |
452 |
|
|
} |
453 |
|
|
|
454 |
✓✓ |
62055 |
if (best == 1) { |
455 |
✓✓ |
409619 |
for (i = 0; i < 6; i++) { |
456 |
|
351102 |
count[1][i] = put_bits_count(&s->reorder_pb[i]); |
457 |
|
351102 |
flush_put_bits(&s->reorder_pb[i]); |
458 |
|
|
} |
459 |
|
|
} else { |
460 |
|
3538 |
motion_ptr[0] = |
461 |
|
3538 |
motion_ptr[1] = |
462 |
|
3538 |
motion_ptr[2] = |
463 |
|
3538 |
motion_ptr[3] = |
464 |
|
3538 |
motion_ptr[0 + 2 * s->m.b8_stride] = |
465 |
|
3538 |
motion_ptr[1 + 2 * s->m.b8_stride] = |
466 |
|
3538 |
motion_ptr[2 + 2 * s->m.b8_stride] = |
467 |
|
3538 |
motion_ptr[3 + 2 * s->m.b8_stride] = 0; |
468 |
|
|
} |
469 |
|
|
} |
470 |
|
|
|
471 |
|
68950 |
s->rd_total += score[best]; |
472 |
|
|
|
473 |
✓✓ |
68950 |
if (best != 2) |
474 |
✓✓ |
482062 |
for (i = 5; i >= 0; i--) |
475 |
|
413196 |
ff_copy_bits(&s->pb, reorder_buffer[best][i], |
476 |
|
|
count[best][i]); |
477 |
✓✓ |
68950 |
if (best == 0) |
478 |
|
10349 |
s->hdsp.put_pixels_tab[0][0](decoded, temp, stride, 16); |
479 |
|
|
} |
480 |
|
4450 |
s->m.first_slice_line = 0; |
481 |
|
|
} |
482 |
|
600 |
return 0; |
483 |
|
|
} |
484 |
|
|
|
485 |
|
4 |
static av_cold int svq1_encode_end(AVCodecContext *avctx) |
486 |
|
|
{ |
487 |
|
4 |
SVQ1EncContext *const s = avctx->priv_data; |
488 |
|
|
int i; |
489 |
|
|
|
490 |
|
4 |
av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", |
491 |
|
4 |
s->rd_total / (double)(avctx->width * avctx->height * |
492 |
|
4 |
avctx->frame_number)); |
493 |
|
|
|
494 |
|
4 |
s->m.mb_type = NULL; |
495 |
|
4 |
ff_mpv_common_end(&s->m); |
496 |
|
|
|
497 |
|
4 |
av_freep(&s->m.me.scratchpad); |
498 |
|
4 |
av_freep(&s->m.me.map); |
499 |
|
4 |
av_freep(&s->m.me.score_map); |
500 |
|
4 |
av_freep(&s->mb_type); |
501 |
|
4 |
av_freep(&s->dummy); |
502 |
|
4 |
av_freep(&s->scratchbuf); |
503 |
|
|
|
504 |
✓✓ |
16 |
for (i = 0; i < 3; i++) { |
505 |
|
12 |
av_freep(&s->motion_val8[i]); |
506 |
|
12 |
av_freep(&s->motion_val16[i]); |
507 |
|
|
} |
508 |
|
|
|
509 |
|
4 |
av_frame_free(&s->current_picture); |
510 |
|
4 |
av_frame_free(&s->last_picture); |
511 |
|
|
|
512 |
|
4 |
return 0; |
513 |
|
|
} |
514 |
|
|
|
515 |
|
4 |
static av_cold int svq1_encode_init(AVCodecContext *avctx) |
516 |
|
|
{ |
517 |
|
4 |
SVQ1EncContext *const s = avctx->priv_data; |
518 |
|
|
int ret; |
519 |
|
|
|
520 |
✓✗✗✓
|
4 |
if (avctx->width >= 4096 || avctx->height >= 4096) { |
521 |
|
|
av_log(avctx, AV_LOG_ERROR, "Dimensions too large, maximum is 4095x4095\n"); |
522 |
|
|
return AVERROR(EINVAL); |
523 |
|
|
} |
524 |
|
|
|
525 |
|
4 |
ff_hpeldsp_init(&s->hdsp, avctx->flags); |
526 |
|
4 |
ff_me_cmp_init(&s->mecc, avctx); |
527 |
|
4 |
ff_mpegvideoencdsp_init(&s->m.mpvencdsp, avctx); |
528 |
|
|
|
529 |
|
4 |
s->current_picture = av_frame_alloc(); |
530 |
|
4 |
s->last_picture = av_frame_alloc(); |
531 |
✓✗✗✓
|
4 |
if (!s->current_picture || !s->last_picture) { |
532 |
|
|
return AVERROR(ENOMEM); |
533 |
|
|
} |
534 |
|
|
|
535 |
|
4 |
s->frame_width = avctx->width; |
536 |
|
4 |
s->frame_height = avctx->height; |
537 |
|
|
|
538 |
|
4 |
s->y_block_width = (s->frame_width + 15) / 16; |
539 |
|
4 |
s->y_block_height = (s->frame_height + 15) / 16; |
540 |
|
|
|
541 |
|
4 |
s->c_block_width = (s->frame_width / 4 + 15) / 16; |
542 |
|
4 |
s->c_block_height = (s->frame_height / 4 + 15) / 16; |
543 |
|
|
|
544 |
|
4 |
s->avctx = avctx; |
545 |
|
4 |
s->m.avctx = avctx; |
546 |
|
|
|
547 |
✗✓ |
4 |
if ((ret = ff_mpv_common_init(&s->m)) < 0) { |
548 |
|
|
return ret; |
549 |
|
|
} |
550 |
|
|
|
551 |
|
4 |
s->m.picture_structure = PICT_FRAME; |
552 |
|
4 |
s->m.me.temp = |
553 |
|
8 |
s->m.me.scratchpad = av_mallocz((avctx->width + 64) * |
554 |
|
4 |
2 * 16 * 2 * sizeof(uint8_t)); |
555 |
|
4 |
s->m.me.map = av_mallocz(ME_MAP_SIZE * sizeof(uint32_t)); |
556 |
|
4 |
s->m.me.score_map = av_mallocz(ME_MAP_SIZE * sizeof(uint32_t)); |
557 |
|
8 |
s->mb_type = av_mallocz((s->y_block_width + 1) * |
558 |
|
4 |
s->y_block_height * sizeof(int16_t)); |
559 |
|
8 |
s->dummy = av_mallocz((s->y_block_width + 1) * |
560 |
|
4 |
s->y_block_height * sizeof(int32_t)); |
561 |
|
4 |
s->ssd_int8_vs_int16 = ssd_int8_vs_int16_c; |
562 |
|
|
|
563 |
✓✗✓✗ ✓✗ |
4 |
if (!s->m.me.temp || !s->m.me.scratchpad || !s->m.me.map || |
564 |
✓✗✓✗ ✗✓ |
4 |
!s->m.me.score_map || !s->mb_type || !s->dummy) { |
565 |
|
|
return AVERROR(ENOMEM); |
566 |
|
|
} |
567 |
|
|
|
568 |
|
|
if (ARCH_PPC) |
569 |
|
|
ff_svq1enc_init_ppc(s); |
570 |
|
|
if (ARCH_X86) |
571 |
|
4 |
ff_svq1enc_init_x86(s); |
572 |
|
|
|
573 |
|
4 |
ff_h263_encode_init(&s->m); // mv_penalty |
574 |
|
|
|
575 |
|
4 |
return 0; |
576 |
|
|
} |
577 |
|
|
|
578 |
|
200 |
static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, |
579 |
|
|
const AVFrame *pict, int *got_packet) |
580 |
|
|
{ |
581 |
|
200 |
SVQ1EncContext *const s = avctx->priv_data; |
582 |
|
|
int i, ret; |
583 |
|
|
|
584 |
✗✓ |
200 |
if ((ret = ff_alloc_packet2(avctx, pkt, s->y_block_width * s->y_block_height * |
585 |
|
200 |
MAX_MB_BYTES*3 + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0) |
586 |
|
|
return ret; |
587 |
|
|
|
588 |
✗✓ |
200 |
if (avctx->pix_fmt != AV_PIX_FMT_YUV410P) { |
589 |
|
|
av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n"); |
590 |
|
|
return -1; |
591 |
|
|
} |
592 |
|
|
|
593 |
✓✓ |
200 |
if (!s->current_picture->data[0]) { |
594 |
✗✓ |
4 |
if ((ret = ff_get_buffer(avctx, s->current_picture, 0)) < 0) { |
595 |
|
|
return ret; |
596 |
|
|
} |
597 |
|
|
} |
598 |
✓✓ |
200 |
if (!s->last_picture->data[0]) { |
599 |
|
4 |
ret = ff_get_buffer(avctx, s->last_picture, 0); |
600 |
✗✓ |
4 |
if (ret < 0) |
601 |
|
|
return ret; |
602 |
|
|
} |
603 |
✓✓ |
200 |
if (!s->scratchbuf) { |
604 |
|
4 |
s->scratchbuf = av_malloc_array(s->current_picture->linesize[0], 16 * 3); |
605 |
✗✓ |
4 |
if (!s->scratchbuf) |
606 |
|
|
return AVERROR(ENOMEM); |
607 |
|
|
} |
608 |
|
|
|
609 |
|
200 |
FFSWAP(AVFrame*, s->current_picture, s->last_picture); |
610 |
|
|
|
611 |
|
200 |
init_put_bits(&s->pb, pkt->data, pkt->size); |
612 |
|
|
|
613 |
✓✗✓✓
|
200 |
if (avctx->gop_size && (avctx->frame_number % avctx->gop_size)) |
614 |
|
180 |
s->pict_type = AV_PICTURE_TYPE_P; |
615 |
|
|
else |
616 |
|
20 |
s->pict_type = AV_PICTURE_TYPE_I; |
617 |
|
200 |
s->quality = pict->quality; |
618 |
|
|
|
619 |
|
|
#if FF_API_CODED_FRAME |
620 |
|
|
FF_DISABLE_DEPRECATION_WARNINGS |
621 |
|
200 |
avctx->coded_frame->pict_type = s->pict_type; |
622 |
|
200 |
avctx->coded_frame->key_frame = s->pict_type == AV_PICTURE_TYPE_I; |
623 |
|
|
FF_ENABLE_DEPRECATION_WARNINGS |
624 |
|
|
#endif |
625 |
|
|
|
626 |
|
200 |
ff_side_data_set_encoder_stats(pkt, pict->quality, NULL, 0, s->pict_type); |
627 |
|
|
|
628 |
|
200 |
svq1_write_header(s, s->pict_type); |
629 |
✓✓ |
800 |
for (i = 0; i < 3; i++) { |
630 |
|
1800 |
int ret = svq1_encode_plane(s, i, |
631 |
|
600 |
pict->data[i], |
632 |
|
600 |
s->last_picture->data[i], |
633 |
|
600 |
s->current_picture->data[i], |
634 |
✓✓ |
600 |
s->frame_width / (i ? 4 : 1), |
635 |
|
600 |
s->frame_height / (i ? 4 : 1), |
636 |
|
|
pict->linesize[i], |
637 |
✓✓ |
600 |
s->current_picture->linesize[i]); |
638 |
|
600 |
emms_c(); |
639 |
✗✓ |
600 |
if (ret < 0) { |
640 |
|
|
int j; |
641 |
|
|
for (j = 0; j < i; j++) { |
642 |
|
|
av_freep(&s->motion_val8[j]); |
643 |
|
|
av_freep(&s->motion_val16[j]); |
644 |
|
|
} |
645 |
|
|
av_freep(&s->scratchbuf); |
646 |
|
|
return -1; |
647 |
|
|
} |
648 |
|
|
} |
649 |
|
|
|
650 |
|
|
// align_put_bits(&s->pb); |
651 |
✓✓ |
3365 |
while (put_bits_count(&s->pb) & 31) |
652 |
|
3165 |
put_bits(&s->pb, 1, 0); |
653 |
|
|
|
654 |
|
200 |
flush_put_bits(&s->pb); |
655 |
|
|
|
656 |
|
200 |
pkt->size = put_bits_count(&s->pb) / 8; |
657 |
✓✓ |
200 |
if (s->pict_type == AV_PICTURE_TYPE_I) |
658 |
|
20 |
pkt->flags |= AV_PKT_FLAG_KEY; |
659 |
|
200 |
*got_packet = 1; |
660 |
|
|
|
661 |
|
200 |
return 0; |
662 |
|
|
} |
663 |
|
|
|
664 |
|
|
#define OFFSET(x) offsetof(struct SVQ1EncContext, x) |
665 |
|
|
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM |
666 |
|
|
static const AVOption options[] = { |
667 |
|
|
{ "motion-est", "Motion estimation algorithm", OFFSET(motion_est), AV_OPT_TYPE_INT, { .i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, VE, "motion-est"}, |
668 |
|
|
{ "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, "motion-est" }, |
669 |
|
|
{ "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, "motion-est" }, |
670 |
|
|
{ "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, FF_MPV_OPT_FLAGS, "motion-est" }, |
671 |
|
|
|
672 |
|
|
{ NULL }, |
673 |
|
|
}; |
674 |
|
|
|
675 |
|
|
static const AVClass svq1enc_class = { |
676 |
|
|
.class_name = "svq1enc", |
677 |
|
|
.item_name = av_default_item_name, |
678 |
|
|
.option = options, |
679 |
|
|
.version = LIBAVUTIL_VERSION_INT, |
680 |
|
|
}; |
681 |
|
|
|
682 |
|
|
AVCodec ff_svq1_encoder = { |
683 |
|
|
.name = "svq1", |
684 |
|
|
.long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), |
685 |
|
|
.type = AVMEDIA_TYPE_VIDEO, |
686 |
|
|
.id = AV_CODEC_ID_SVQ1, |
687 |
|
|
.priv_data_size = sizeof(SVQ1EncContext), |
688 |
|
|
.priv_class = &svq1enc_class, |
689 |
|
|
.init = svq1_encode_init, |
690 |
|
|
.encode2 = svq1_encode_frame, |
691 |
|
|
.close = svq1_encode_end, |
692 |
|
|
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP, |
693 |
|
|
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P, |
694 |
|
|
AV_PIX_FMT_NONE }, |
695 |
|
|
}; |