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
45
49
50 // Workaround for GCC bug 102513
51 #if AV_GCC_VERSION_AT_LEAST(10, 0) && AV_GCC_VERSION_AT_MOST(12, 0) \
52 && !defined(__clang__) && !defined(__INTEL_COMPILER)
53 #pragma GCC optimize ("no-ipa-cp-clone")
54 #endif
55
57 /* FIXME: Needed for motion estimation, should not be used for anything
58 * else, the idea is to make the motion estimation eventually independent
59 * of MpegEncContext, so this will be removed then. */
66
67 /* Some compression statistics */
70
71 /* why ooh why this sick breadth first order,
72 * everything is slower and more complex */
74
77
78 /* Y plane block dimensions */
81
82 /* U & V plane (C planes) block dimensions */
85
87
92
94
96
98
101
103 {
105
106 /* frame code */
108
109 /* temporal reference (sure hope this is a "don't care") */
111
112 /* frame type */
114
116 /* no checksum since frame code is 0x20 */
117 /* no embedded string either */
118 /* output 5 unknown bits (2 + 2 + 1) */
119 put_bits(pb, 5, 2);
/* 2 needed by quicktime decoder */
120
123 s->frame_width,
s->frame_height);
125
129 }
130 }
131
132 /* no checksum or extra data (next 2 bits get 0) */
134 }
135
136 #define QUALITY_THRESHOLD 100
137 #define THRESHOLD_MULTIPLIER 0.6
138
141 {
143
145 score += (pix1[
i] - pix2[
i]) * (pix1[
i] - pix2[
i]);
146 return score;
147 }
148
151 int threshold, int lambda, int intra)
152 {
153 int count, y, x,
i, j,
split, best_mean, best_score, best_count;
154 int best_vector[6];
156 int w = 2 << (
level + 2 >> 1);
157 int h = 2 << (
level + 1 >> 1);
159 int16_t (*
block)[256] =
s->encoded_block_levels[
level];
160 const int8_t *codebook_sum, *
codebook;
161 const uint16_t(*mean_vlc)[2];
162 const uint8_t(*multistage_vlc)[2];
163
164 best_score = 0;
165 // FIXME: Optimize, this does not need to be done multiple times.
166 if (intra) {
167 // level is 5 when encode_block is called from svq1_encode_plane
168 // and always < 4 when called recursively from this function.
173 for (y = 0; y <
h; y++) {
174 for (x = 0; x <
w; x++) {
177 best_score += v * v;
179 }
180 }
181 } else {
182 // level is 5 or < 4, see above for details.
187 for (y = 0; y <
h; y++) {
188 for (x = 0; x <
w; x++) {
191 best_score += v * v;
193 }
194 }
195 }
196
197 best_count = 0;
200
202 for (count = 1; count < 7; count++) {
203 int best_vector_score = INT_MAX;
204 int best_vector_sum = -999, best_vector_mean = -999;
205 const int stage = count - 1;
206 const int8_t *vector;
207
208 for (
i = 0;
i < 16;
i++) {
209 int sum = codebook_sum[stage * 16 +
i];
211
213 sqr =
s->svq1encdsp.ssd_int8_vs_int16(vector,
block[stage],
size);
215 score =
sqr - (
diff * (int64_t)
diff >> (
level + 3));
// FIXME: 64 bits slooow
216 if (score < best_vector_score) {
220 best_vector_score = score;
221 best_vector[stage] =
i;
222 best_vector_sum = sum;
223 best_vector_mean =
mean;
224 }
225 }
228 for (j = 0; j <
size; j++)
229 block[stage + 1][j] =
block[stage][j] - vector[j];
231 best_vector_score += lambda *
232 (+1 + 4 * count +
233 multistage_vlc[1 + count][1]
234 + mean_vlc[best_vector_mean][1]);
235
236 if (best_vector_score < best_score) {
237 best_score = best_vector_score;
238 best_count = count;
239 best_mean = best_vector_mean;
240 }
241 }
242 }
243
244 if (best_mean == -128)
245 best_mean = -127;
246 else if (best_mean == 128)
247 best_mean = 127;
248
250 if (best_score > threshold &&
level) {
251 int score = 0;
254
256 backup[
i] =
s->reorder_pb[
i];
258 threshold >> 1, lambda, intra);
261 score += lambda;
262
263 if (score < best_score) {
264 best_score = score;
266 } else {
268 s->reorder_pb[
i] = backup[
i];
269 }
270 }
273
275 av_assert1(best_mean >= 0 && best_mean < 256 || !intra);
276 av_assert1(best_mean >= -256 && best_mean < 256);
277 av_assert1(best_count >= 0 && best_count < 7);
279
280 /* output the encoding */
282 multistage_vlc[1 + best_count][1],
283 multistage_vlc[1 + best_count][0]);
285 mean_vlc[best_mean][0]);
286
287 for (
i = 0;
i < best_count;
i++) {
290 }
291
292 for (y = 0; y <
h; y++)
293 for (x = 0; x <
w; x++)
295 block[best_count][x +
w * y] +
296 best_mean;
297 }
298
299 return best_score;
300 }
301
303 s->block_index[0]=
s->b8_stride*(
s->mb_y*2 ) +
s->mb_x*2;
304 s->block_index[1]=
s->b8_stride*(
s->mb_y*2 ) + 1 +
s->mb_x*2;
305 s->block_index[2]=
s->b8_stride*(
s->mb_y*2 + 1) +
s->mb_x*2;
306 s->block_index[3]=
s->b8_stride*(
s->mb_y*2 + 1) + 1 +
s->mb_x*2;
307 s->block_index[4]=
s->mb_stride*(
s->mb_y + 1) +
s->b8_stride*
s->mb_height*2 +
s->mb_x;
308 s->block_index[5]=
s->mb_stride*(
s->mb_y +
s->mb_height + 2) +
s->b8_stride*
s->mb_height*2 +
s->mb_x;
309 }
310
313 const unsigned char *src_plane,
314 unsigned char *ref_plane,
315 unsigned char *decoded_plane,
317 {
318 int x, y;
320 int block_width, block_height;
322 int threshold[6];
324 const int lambda = (
s->quality *
s->quality) >>
326
327 /* figure out the acceptable level thresholds in advance */
331
332 block_width = (
width + 15) / 16;
333 block_height = (
height + 15) / 16;
334
336 s->m.avctx =
s->avctx;
337 s->m.current_picture_ptr = &
s->m.current_picture;
338 s->m.last_picture_ptr = &
s->m.last_picture;
339 s->m.last_picture.f->data[0] = ref_plane;
341 s->m.last_picture.f->linesize[0] =
342 s->m.new_picture->linesize[0] =
343 s->m.current_picture.f->linesize[0] =
stride;
346 s->m.mb_width = block_width;
347 s->m.mb_height = block_height;
348 s->m.mb_stride =
s->m.mb_width + 1;
349 s->m.b8_stride = 2 *
s->m.mb_width + 1;
351 s->m.pict_type =
s->pict_type;
352 s->m.motion_est =
s->motion_est;
353 s->m.me.scene_change_score = 0;
354 // s->m.out_format = FMT_H263;
355 // s->m.unrestricted_mv = 1;
356 s->m.lambda =
s->quality;
357 s->m.qscale =
s->m.lambda * 139 +
360 s->m.lambda2 =
s->m.lambda *
s->m.lambda +
363
364 if (!
s->motion_val8[plane]) {
366 block_height * 2 + 2) *
367 2 * sizeof(int16_t));
369 (block_height + 2) + 1) *
370 2 * sizeof(int16_t));
371 if (!
s->motion_val8[plane] || !
s->motion_val16[plane])
373 }
374
375 s->m.mb_type =
s->mb_type;
376
377 // dummies, to avoid segfaults
378 s->m.mb_mean = (uint8_t *)
s->dummy;
379 s->m.mb_var = (uint16_t *)
s->dummy;
380 s->m.mc_mb_var = (uint16_t *)
s->dummy;
381 s->m.current_picture.mb_type =
s->dummy;
382
383 s->m.current_picture.motion_val[0] =
s->motion_val8[plane] + 2;
384 s->m.p_mv_table =
s->motion_val16[plane] +
386 s->m.mecc =
s->mecc;
// move
388
389 s->m.me.dia_size =
s->avctx->dia_size;
390 s->m.first_slice_line = 1;
391 for (y = 0; y < block_height; y++) {
392 s->m.new_picture->data[0] =
src - y * 16 *
stride;
// ugly
394
395 for (
i = 0;
i < 16 &&
i + 16 * y <
height;
i++) {
396 memcpy(&
src[
i *
stride], &src_plane[(
i + 16 * y) * src_stride],
398 for (x =
width; x < 16 * block_width; x++)
400 }
401 for (;
i < 16 &&
i + 16 * y < 16 * block_height;
i++)
403 16 * block_width);
404
405 for (x = 0; x < block_width; x++) {
408
410 }
411 s->m.first_slice_line = 0;
412 }
413
417 }
418
419 s->m.first_slice_line = 1;
420 for (y = 0; y < block_height; y++) {
421 for (
i = 0;
i < 16 &&
i + 16 * y <
height;
i++) {
422 memcpy(&
src[
i *
stride], &src_plane[(
i + 16 * y) * src_stride],
424 for (x =
width; x < 16 * block_width; x++)
426 }
427 for (;
i < 16 &&
i + 16 * y < 16 * block_height;
i++)
429
431 for (x = 0; x < block_width; x++) {
432 uint8_t reorder_buffer[2][6][7 * 32];
433 int count[2][6];
435 uint8_t *decoded = decoded_plane +
offset;
437 int score[4] = { 0, 0, 0, 0 }, best;
438 uint8_t *
temp =
s->scratchbuf;
439
442 return -1;
443 }
444
447
449 (
s->m.mb_type[x + y *
s->m.mb_stride] &
451 for (
i = 0;
i < 6;
i++)
453 7 * 32);
457 }
459 5, 64, lambda, 1);
460 for (
i = 0;
i < 6;
i++) {
463 }
464 } else
465 score[0] = INT_MAX;
466
467 best = 0;
468
470 int mx, my, pred_x, pred_y, dxy;
471 int16_t *motion_ptr;
472
474 if (
s->m.mb_type[x + y *
s->m.mb_stride] &
476 for (
i = 0;
i < 6;
i++)
478 7 * 32);
479
481
482 s->m.pb =
s->reorder_pb[5];
483 mx = motion_ptr[0];
484 my = motion_ptr[1];
491 s->reorder_pb[5] =
s->m.pb;
493
494 dxy = (mx & 1) + 2 * (my & 1);
495
500
502 decoded,
stride, 5, 64, lambda, 0);
503 best = score[1] <= score[0];
504
508 if (score[2] < score[best] && mx == 0 && my == 0) {
509 best = 2;
510 s->hdsp.put_pixels_tab[0][0](decoded,
ref,
stride, 16);
512 }
513 }
514
515 if (best == 1) {
516 for (
i = 0;
i < 6;
i++) {
519 }
520 } else {
521 motion_ptr[0] =
522 motion_ptr[1] =
523 motion_ptr[2] =
524 motion_ptr[3] =
525 motion_ptr[0 + 2 *
s->m.b8_stride] =
526 motion_ptr[1 + 2 *
s->m.b8_stride] =
527 motion_ptr[2 + 2 *
s->m.b8_stride] =
528 motion_ptr[3 + 2 *
s->m.b8_stride] = 0;
529 }
530 }
531
532 s->rd_total += score[best];
533
534 if (best != 2)
535 for (
i = 5;
i >= 0;
i--)
538 if (best == 0)
539 s->hdsp.put_pixels_tab[0][0](decoded,
temp,
stride, 16);
540 }
541 s->m.first_slice_line = 0;
542 }
543 return 0;
544 }
545
547 {
550
555
558
564
565 for (
i = 0;
i < 3;
i++) {
568 }
569
572
573 return 0;
574 }
575
577 {
578 int size = strlen(ident);
586 return 0;
587 }
588
590 {
593
594 if (avctx->
width >= 4096 || avctx->
height >= 4096) {
597 }
598
602
605 if (!
s->current_picture || !
s->last_picture) {
607 }
608
609 s->frame_width = avctx->
width;
610 s->frame_height = avctx->
height;
611
612 s->y_block_width = (
s->frame_width + 15) / 16;
613 s->y_block_height = (
s->frame_height + 15) / 16;
614
615 s->c_block_width = (
s->frame_width / 4 + 15) / 16;
616 s->c_block_height = (
s->frame_height / 4 + 15) / 16;
617
620
623 }
624
628 2 * 16 * 2 * sizeof(uint8_t));
630 s->y_block_height *
sizeof(int16_t));
632 s->y_block_height *
sizeof(
int32_t));
635
636 if (!
s->m.me.temp || !
s->m.me.scratchpad || !
s->m.me.map ||
637 !
s->mb_type || !
s->dummy)
640
641 #if ARCH_PPC
643 #elif ARCH_X86
645 #endif
646
648
650 }
651
653 const AVFrame *pict,
int *got_packet)
654 {
658
663
666 return -1;
667 }
668
669 if (!
s->current_picture->data[0]) {
672 }
673 }
674 if (!
s->last_picture->data[0]) {
678 }
679 if (!
s->scratchbuf) {
683 }
684
686
689 else
692
694
697 for (
i = 0;
i < 3;
i++) {
700 s->last_picture->data[
i],
701 s->current_picture->data[
i],
702 s->frame_width / (
i ? 4 : 1),
703 s->frame_height / (
i ? 4 : 1),
705 s->current_picture->linesize[
i]);
706 emms_c();
708 int j;
709 for (j = 0; j <
i; j++) {
712 }
714 return -1;
715 }
716 }
717
718 // align_put_bits(&pb);
721
723
727 *got_packet = 1;
728
729 return 0;
730 }
731
732 #define OFFSET(x) offsetof(struct SVQ1EncContext, x)
733 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
739
741 };
742
748 };
749
752 CODEC_LONG_NAME(
"Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"),
764 };