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