Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Copyright (c) 2003 Michael Niedermayer | ||
3 | * | ||
4 | * This file is part of FFmpeg. | ||
5 | * | ||
6 | * FFmpeg is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU Lesser General Public | ||
8 | * License as published by the Free Software Foundation; either | ||
9 | * version 2.1 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * FFmpeg is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * Lesser General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU Lesser General Public | ||
17 | * License along with FFmpeg; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file | ||
23 | * ASUS V1/V2 encoder. | ||
24 | */ | ||
25 | |||
26 | #include "config_components.h" | ||
27 | |||
28 | #include "libavutil/attributes.h" | ||
29 | #include "libavutil/intreadwrite.h" | ||
30 | #include "libavutil/mem.h" | ||
31 | #include "libavutil/mem_internal.h" | ||
32 | |||
33 | #include "aandcttab.h" | ||
34 | #include "asv.h" | ||
35 | #include "avcodec.h" | ||
36 | #include "codec_internal.h" | ||
37 | #include "encode.h" | ||
38 | #include "fdctdsp.h" | ||
39 | #include "mpeg12data.h" | ||
40 | #include "pixblockdsp.h" | ||
41 | #include "put_bits.h" | ||
42 | |||
43 | typedef struct ASVEncContext { | ||
44 | ASVCommonContext c; | ||
45 | |||
46 | PutBitContext pb; | ||
47 | |||
48 | void (*get_pixels)(int16_t *restrict block, | ||
49 | const uint8_t *pixels, | ||
50 | ptrdiff_t stride); | ||
51 | |||
52 | PixblockDSPContext pdsp; | ||
53 | FDCTDSPContext fdsp; | ||
54 | DECLARE_ALIGNED(32, int16_t, block)[6][64]; | ||
55 | int q_intra_matrix[64]; | ||
56 | } ASVEncContext; | ||
57 | |||
58 | enum { | ||
59 | ASV1_MAX_BLOCK_SIZE = 8 + 10 * FFMAX(2 /* skip */, 5 /* ccp */ + 4 * 11 /* level */) + 5, | ||
60 | ASV1_MAX_MB_SIZE = 6 * ASV1_MAX_BLOCK_SIZE, | ||
61 | ASV2_MAX_BLOCK_SIZE = 4 + 8 + 16 * (6 /* ccp */ + 4 * 13 /* level */), | ||
62 | ASV2_MAX_MB_SIZE = 6 * ASV2_MAX_BLOCK_SIZE, | ||
63 | MAX_MB_SIZE = (FFMAX(ASV1_MAX_MB_SIZE, ASV2_MAX_MB_SIZE) + 7) / 8 | ||
64 | }; | ||
65 | |||
66 | 2970458 | static inline void asv1_put_level(PutBitContext *pb, int level) | |
67 | { | ||
68 | 2970458 | unsigned int index = level + 3; | |
69 | unsigned n, code; | ||
70 | |||
71 |
2/2✓ Branch 0 taken 2541647 times.
✓ Branch 1 taken 428811 times.
|
2970458 | if (index <= 6) { |
72 | 2541647 | n = ff_asv_level_tab[index][1]; | |
73 | 2541647 | code = ff_asv_level_tab[index][0]; | |
74 | } else { | ||
75 | 428811 | n = 3 + 8; | |
76 | 428811 | code = (0 /* Escape code */ << 8) | (level & 0xFF); | |
77 | } | ||
78 | 2970458 | put_bits(pb, n, code); | |
79 | 2970458 | } | |
80 | |||
81 | 3657862 | static inline void asv2_put_level(ASVEncContext *a, PutBitContext *pb, int level) | |
82 | { | ||
83 | 3657862 | unsigned int index = level + 31; | |
84 | unsigned n, code; | ||
85 | |||
86 |
2/2✓ Branch 0 taken 3657249 times.
✓ Branch 1 taken 613 times.
|
3657862 | if (index <= 62) { |
87 | 3657249 | n = ff_asv2_level_tab[index][1]; | |
88 | 3657249 | code = ff_asv2_level_tab[index][0]; | |
89 | } else { | ||
90 |
2/4✓ Branch 0 taken 613 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 613 times.
|
613 | if (level < -128 || level > 127) { |
91 | ✗ | av_log(a->c.avctx, AV_LOG_WARNING, "Clipping level %d, increase qscale\n", level); | |
92 | ✗ | level = av_clip_int8(level); | |
93 | } | ||
94 | 613 | n = 5 + 8; | |
95 | 613 | code = (level & 0xFF) << 5 | /* Escape code */ 0; | |
96 | } | ||
97 | 3657862 | put_bits_le(pb, n, code); | |
98 | 3657862 | } | |
99 | |||
100 | 359100 | static inline void asv1_encode_block(ASVEncContext *a, int16_t block[64]) | |
101 | { | ||
102 | 359100 | put_bits(&a->pb, 8, (block[0] + 32) >> 6); | |
103 | 359100 | block[0] = 0; | |
104 | |||
105 |
2/2✓ Branch 0 taken 3591000 times.
✓ Branch 1 taken 359100 times.
|
3950100 | for (unsigned i = 0, nc_bits = 0, nc_val = 0; i < 10; i++) { |
106 | 3591000 | const int index = ff_asv_scantab[4 * i]; | |
107 | 3591000 | int ccp = 0; | |
108 | |||
109 | 3591000 | if ((block[index + 0] = (block[index + 0] * | |
110 |
2/2✓ Branch 0 taken 758490 times.
✓ Branch 1 taken 2832510 times.
|
3591000 | a->q_intra_matrix[index + 0] + (1 << 15)) >> 16)) |
111 | 758490 | ccp |= 8; | |
112 | 3591000 | if ((block[index + 8] = (block[index + 8] * | |
113 |
2/2✓ Branch 0 taken 827835 times.
✓ Branch 1 taken 2763165 times.
|
3591000 | a->q_intra_matrix[index + 8] + (1 << 15)) >> 16)) |
114 | 827835 | ccp |= 4; | |
115 | 3591000 | if ((block[index + 1] = (block[index + 1] * | |
116 |
2/2✓ Branch 0 taken 780446 times.
✓ Branch 1 taken 2810554 times.
|
3591000 | a->q_intra_matrix[index + 1] + (1 << 15)) >> 16)) |
117 | 780446 | ccp |= 2; | |
118 | 3591000 | if ((block[index + 9] = (block[index + 9] * | |
119 |
2/2✓ Branch 0 taken 603687 times.
✓ Branch 1 taken 2987313 times.
|
3591000 | a->q_intra_matrix[index + 9] + (1 << 15)) >> 16)) |
120 | 603687 | ccp |= 1; | |
121 | |||
122 |
2/2✓ Branch 0 taken 1362801 times.
✓ Branch 1 taken 2228199 times.
|
3591000 | if (ccp) { |
123 | 1362801 | put_bits(&a->pb, nc_bits + ff_asv_ccp_tab[ccp][1], | |
124 | 1362801 | nc_val << ff_asv_ccp_tab[ccp][1] /* Skip */ | | |
125 | 1362801 | ff_asv_ccp_tab[ccp][0]); | |
126 | 1362801 | nc_bits = 0; | |
127 | 1362801 | nc_val = 0; | |
128 | |||
129 |
2/2✓ Branch 0 taken 758490 times.
✓ Branch 1 taken 604311 times.
|
1362801 | if (ccp & 8) |
130 | 758490 | asv1_put_level(&a->pb, block[index + 0]); | |
131 |
2/2✓ Branch 0 taken 827835 times.
✓ Branch 1 taken 534966 times.
|
1362801 | if (ccp & 4) |
132 | 827835 | asv1_put_level(&a->pb, block[index + 8]); | |
133 |
2/2✓ Branch 0 taken 780446 times.
✓ Branch 1 taken 582355 times.
|
1362801 | if (ccp & 2) |
134 | 780446 | asv1_put_level(&a->pb, block[index + 1]); | |
135 |
2/2✓ Branch 0 taken 603687 times.
✓ Branch 1 taken 759114 times.
|
1362801 | if (ccp & 1) |
136 | 603687 | asv1_put_level(&a->pb, block[index + 9]); | |
137 | } else { | ||
138 | 2228199 | nc_bits += 2; | |
139 | 2228199 | nc_val = (nc_val << 2) | 2; | |
140 | } | ||
141 | } | ||
142 | 359100 | put_bits(&a->pb, 5, 0xF); /* End of block */ | |
143 | 359100 | } | |
144 | |||
145 | 359100 | static inline void asv2_encode_block(ASVEncContext *a, int16_t block[64]) | |
146 | { | ||
147 | int i; | ||
148 | 359100 | int count = 0; | |
149 | |||
150 |
2/2✓ Branch 0 taken 14443629 times.
✓ Branch 1 taken 63439 times.
|
14507068 | for (count = 63; count > 3; count--) { |
151 | 14443629 | const int index = ff_asv_scantab[count]; | |
152 |
2/2✓ Branch 0 taken 295661 times.
✓ Branch 1 taken 14147968 times.
|
14443629 | if ((block[index] * a->q_intra_matrix[index] + (1 << 15)) >> 16) |
153 | 295661 | break; | |
154 | } | ||
155 | |||
156 | 359100 | count >>= 2; | |
157 | |||
158 | 359100 | put_bits_le(&a->pb, 4 + 8, count /* 4 bits */ | | |
159 | 359100 | (/* DC */(block[0] + 32) >> 6) << 4); | |
160 | 359100 | block[0] = 0; | |
161 | |||
162 |
2/2✓ Branch 0 taken 2347174 times.
✓ Branch 1 taken 359100 times.
|
2706274 | for (i = 0; i <= count; i++) { |
163 | 2347174 | const int index = ff_asv_scantab[4 * i]; | |
164 | 2347174 | int ccp = 0; | |
165 | |||
166 | 2347174 | if ((block[index + 0] = (block[index + 0] * | |
167 |
2/2✓ Branch 0 taken 967939 times.
✓ Branch 1 taken 1379235 times.
|
2347174 | a->q_intra_matrix[index + 0] + (1 << 15)) >> 16)) |
168 | 967939 | ccp |= 8; | |
169 | 2347174 | if ((block[index + 8] = (block[index + 8] * | |
170 |
2/2✓ Branch 0 taken 1013819 times.
✓ Branch 1 taken 1333355 times.
|
2347174 | a->q_intra_matrix[index + 8] + (1 << 15)) >> 16)) |
171 | 1013819 | ccp |= 4; | |
172 | 2347174 | if ((block[index + 1] = (block[index + 1] * | |
173 |
2/2✓ Branch 0 taken 950720 times.
✓ Branch 1 taken 1396454 times.
|
2347174 | a->q_intra_matrix[index + 1] + (1 << 15)) >> 16)) |
174 | 950720 | ccp |= 2; | |
175 | 2347174 | if ((block[index + 9] = (block[index + 9] * | |
176 |
2/2✓ Branch 0 taken 725384 times.
✓ Branch 1 taken 1621790 times.
|
2347174 | a->q_intra_matrix[index + 9] + (1 << 15)) >> 16)) |
177 | 725384 | ccp |= 1; | |
178 | |||
179 | av_assert2(i || ccp < 8); | ||
180 |
2/2✓ Branch 0 taken 1988074 times.
✓ Branch 1 taken 359100 times.
|
2347174 | if (i) |
181 | 1988074 | put_bits_le(&a->pb, ff_asv_ac_ccp_tab[ccp][1], ff_asv_ac_ccp_tab[ccp][0]); | |
182 | else | ||
183 | 359100 | put_bits_le(&a->pb, ff_asv_dc_ccp_tab[ccp][1], ff_asv_dc_ccp_tab[ccp][0]); | |
184 | |||
185 |
2/2✓ Branch 0 taken 1696154 times.
✓ Branch 1 taken 651020 times.
|
2347174 | if (ccp) { |
186 |
2/2✓ Branch 0 taken 967939 times.
✓ Branch 1 taken 728215 times.
|
1696154 | if (ccp & 8) |
187 | 967939 | asv2_put_level(a, &a->pb, block[index + 0]); | |
188 |
2/2✓ Branch 0 taken 1013819 times.
✓ Branch 1 taken 682335 times.
|
1696154 | if (ccp & 4) |
189 | 1013819 | asv2_put_level(a, &a->pb, block[index + 8]); | |
190 |
2/2✓ Branch 0 taken 950720 times.
✓ Branch 1 taken 745434 times.
|
1696154 | if (ccp & 2) |
191 | 950720 | asv2_put_level(a, &a->pb, block[index + 1]); | |
192 |
2/2✓ Branch 0 taken 725384 times.
✓ Branch 1 taken 970770 times.
|
1696154 | if (ccp & 1) |
193 | 725384 | asv2_put_level(a, &a->pb, block[index + 9]); | |
194 | } | ||
195 | } | ||
196 | 359100 | } | |
197 | |||
198 | 119700 | static inline int encode_mb(ASVEncContext *a, int16_t block[6][64]) | |
199 | { | ||
200 | int i; | ||
201 | |||
202 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 119700 times.
|
119700 | av_assert0(put_bytes_left(&a->pb, 0) >= MAX_MB_SIZE); |
203 | |||
204 |
2/2✓ Branch 0 taken 59850 times.
✓ Branch 1 taken 59850 times.
|
119700 | if (a->c.avctx->codec_id == AV_CODEC_ID_ASV1) { |
205 |
2/2✓ Branch 0 taken 359100 times.
✓ Branch 1 taken 59850 times.
|
418950 | for (i = 0; i < 6; i++) |
206 | 359100 | asv1_encode_block(a, block[i]); | |
207 | } else { | ||
208 |
2/2✓ Branch 0 taken 359100 times.
✓ Branch 1 taken 59850 times.
|
418950 | for (i = 0; i < 6; i++) { |
209 | 359100 | asv2_encode_block(a, block[i]); | |
210 | } | ||
211 | } | ||
212 | 119700 | return 0; | |
213 | } | ||
214 | |||
215 | 119200 | static inline void dct_get(ASVEncContext *a, const AVFrame *frame, | |
216 | int mb_x, int mb_y) | ||
217 | { | ||
218 | 119200 | int16_t (*block)[64] = a->block; | |
219 | 119200 | int linesize = frame->linesize[0]; | |
220 | int i; | ||
221 | |||
222 | 119200 | const uint8_t *ptr_y = frame->data[0] + (mb_y * 16 * linesize) + mb_x * 16; | |
223 | 119200 | const uint8_t *ptr_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8; | |
224 | 119200 | const uint8_t *ptr_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8; | |
225 | |||
226 | 119200 | a->get_pixels(block[0], ptr_y, linesize); | |
227 | 119200 | a->get_pixels(block[1], ptr_y + 8, linesize); | |
228 | 119200 | a->get_pixels(block[2], ptr_y + 8 * linesize, linesize); | |
229 | 119200 | a->get_pixels(block[3], ptr_y + 8 * linesize + 8, linesize); | |
230 |
2/2✓ Branch 0 taken 476800 times.
✓ Branch 1 taken 119200 times.
|
596000 | for (i = 0; i < 4; i++) |
231 | 476800 | a->fdsp.fdct(block[i]); | |
232 | |||
233 |
1/2✓ Branch 0 taken 119200 times.
✗ Branch 1 not taken.
|
119200 | if (!(a->c.avctx->flags & AV_CODEC_FLAG_GRAY)) { |
234 | 119200 | a->get_pixels(block[4], ptr_cb, frame->linesize[1]); | |
235 | 119200 | a->get_pixels(block[5], ptr_cr, frame->linesize[2]); | |
236 |
2/2✓ Branch 0 taken 238400 times.
✓ Branch 1 taken 119200 times.
|
357600 | for (i = 4; i < 6; i++) |
237 | 238400 | a->fdsp.fdct(block[i]); | |
238 | } | ||
239 | 119200 | } | |
240 | |||
241 | 500 | static void handle_partial_mb(ASVEncContext *a, const uint8_t *const data[3], | |
242 | const int linesizes[3], | ||
243 | int valid_width, int valid_height) | ||
244 | { | ||
245 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 500 times.
|
500 | const int nb_blocks = a->c.avctx->flags & AV_CODEC_FLAG_GRAY ? 4 : 6; |
246 | static const struct Descriptor { | ||
247 | uint8_t x_offset, y_offset; | ||
248 | uint8_t component, subsampling; | ||
249 | } block_descriptor[] = { | ||
250 | { 0, 0, 0, 0 }, { 8, 0, 0, 0 }, { 0, 8, 0, 0 }, { 8, 8, 0, 0 }, | ||
251 | { 0, 0, 1, 1 }, { 0, 0, 2, 1 }, | ||
252 | }; | ||
253 | |||
254 |
2/2✓ Branch 0 taken 3000 times.
✓ Branch 1 taken 500 times.
|
3500 | for (int i = 0; i < nb_blocks; ++i) { |
255 | 3000 | const struct Descriptor *const desc = block_descriptor + i; | |
256 | 3000 | int width_avail = AV_CEIL_RSHIFT(valid_width, desc->subsampling) - desc->x_offset; | |
257 | 3000 | int height_avail = AV_CEIL_RSHIFT(valid_height, desc->subsampling) - desc->y_offset; | |
258 | |||
259 |
4/4✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 600 times.
✓ Branch 2 taken 500 times.
✓ Branch 3 taken 1900 times.
|
3000 | if (width_avail <= 0 || height_avail <= 0) { |
260 | // This block is outside of the visible part; don't replicate pixels, | ||
261 | // just zero the block, so that only the dc value will be coded. | ||
262 | 1100 | memset(a->block[i], 0, sizeof(a->block[i])); | |
263 | 1100 | continue; | |
264 | } | ||
265 | 1900 | width_avail = FFMIN(width_avail, 8); | |
266 | 1900 | height_avail = FFMIN(height_avail, 8); | |
267 | |||
268 | 1900 | ptrdiff_t linesize = linesizes[desc->component]; | |
269 | 1900 | const uint8_t *src = data[desc->component] + desc->y_offset * linesize + desc->x_offset; | |
270 | 1900 | int16_t *block = a->block[i]; | |
271 | |||
272 | 8000 | for (int h = 0;; block += 8, src += linesize) { | |
273 | int16_t last; | ||
274 |
2/2✓ Branch 0 taken 19800 times.
✓ Branch 1 taken 8000 times.
|
27800 | for (int w = 0; w < width_avail; ++w) |
275 | 19800 | last = block[w] = src[w]; | |
276 |
2/2✓ Branch 0 taken 44200 times.
✓ Branch 1 taken 8000 times.
|
52200 | for (int w = width_avail; w < 8; ++w) |
277 | 44200 | block[w] = last; | |
278 |
2/2✓ Branch 0 taken 1900 times.
✓ Branch 1 taken 6100 times.
|
8000 | if (++h == height_avail) |
279 | 1900 | break; | |
280 | } | ||
281 | 1900 | const int16_t *const last_row = block; | |
282 |
2/2✓ Branch 0 taken 7200 times.
✓ Branch 1 taken 1900 times.
|
9100 | for (int h = height_avail; h < 8; ++h) { |
283 | 7200 | block += 8; | |
284 | 7200 | AV_COPY128(block, last_row); | |
285 | } | ||
286 | |||
287 | 1900 | a->fdsp.fdct(a->block[i]); | |
288 | } | ||
289 | |||
290 | 500 | encode_mb(a, a->block); | |
291 | 500 | } | |
292 | |||
293 | 400 | static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, | |
294 | const AVFrame *pict, int *got_packet) | ||
295 | { | ||
296 | 400 | ASVEncContext *const a = avctx->priv_data; | |
297 | 400 | const ASVCommonContext *const c = &a->c; | |
298 | int size, ret; | ||
299 | |||
300 | 400 | ret = ff_alloc_packet(avctx, pkt, c->mb_height * c->mb_width * MAX_MB_SIZE + 3); | |
301 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 400 times.
|
400 | if (ret < 0) |
302 | ✗ | return ret; | |
303 | |||
304 | if (!PIXBLOCKDSP_8BPP_GET_PIXELS_SUPPORTS_UNALIGNED && | ||
305 | ((uintptr_t)pict->data[0] & 7 || pict->linesize[0] & 7 || | ||
306 | (uintptr_t)pict->data[1] & 7 || pict->linesize[1] & 7 || | ||
307 | (uintptr_t)pict->data[2] & 7 || pict->linesize[2] & 7)) | ||
308 | a->get_pixels = a->pdsp.get_pixels_unaligned; | ||
309 | else | ||
310 | 400 | a->get_pixels = a->pdsp.get_pixels; | |
311 | |||
312 | 400 | init_put_bits(&a->pb, pkt->data, pkt->size); | |
313 | |||
314 |
2/2✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 400 times.
|
6000 | for (int mb_y = 0; mb_y < c->mb_height2; mb_y++) { |
315 |
2/2✓ Branch 0 taken 119200 times.
✓ Branch 1 taken 5600 times.
|
124800 | for (int mb_x = 0; mb_x < c->mb_width2; mb_x++) { |
316 | 119200 | dct_get(a, pict, mb_x, mb_y); | |
317 | 119200 | encode_mb(a, a->block); | |
318 | } | ||
319 | } | ||
320 | |||
321 |
2/2✓ Branch 0 taken 100 times.
✓ Branch 1 taken 300 times.
|
400 | if (avctx->width & 15) { |
322 | 100 | const uint8_t *src[3] = { | |
323 | 100 | pict->data[0] + c->mb_width2 * 16, | |
324 | 100 | pict->data[1] + c->mb_width2 * 8, | |
325 | 100 | pict->data[2] + c->mb_width2 * 8, | |
326 | }; | ||
327 | 100 | int available_width = avctx->width & 15; | |
328 | |||
329 |
2/2✓ Branch 0 taken 200 times.
✓ Branch 1 taken 100 times.
|
300 | for (int mb_y = 0; mb_y < c->mb_height2; mb_y++) { |
330 | 200 | handle_partial_mb(a, src, pict->linesize, available_width, 16); | |
331 | 200 | src[0] += 16 * pict->linesize[0]; | |
332 | 200 | src[1] += 8 * pict->linesize[1]; | |
333 | 200 | src[2] += 8 * pict->linesize[2]; | |
334 | } | ||
335 | } | ||
336 | |||
337 |
2/2✓ Branch 0 taken 100 times.
✓ Branch 1 taken 300 times.
|
400 | if (avctx->height & 15) { |
338 | 100 | const uint8_t *src[3] = { | |
339 | 100 | pict->data[0] + c->mb_height2 * 16 * pict->linesize[0], | |
340 | 100 | pict->data[1] + c->mb_height2 * 8 * pict->linesize[1], | |
341 | 100 | pict->data[2] + c->mb_height2 * 8 * pict->linesize[2], | |
342 | }; | ||
343 | 100 | int available_height = avctx->height & 15; | |
344 | |||
345 | 100 | for (int remaining = avctx->width;; remaining -= 16) { | |
346 | 300 | handle_partial_mb(a, src, pict->linesize, remaining, available_height); | |
347 |
2/2✓ Branch 0 taken 100 times.
✓ Branch 1 taken 200 times.
|
300 | if (remaining <= 16) |
348 | 100 | break; | |
349 | 200 | src[0] += 16; | |
350 | 200 | src[1] += 8; | |
351 | 200 | src[2] += 8; | |
352 | } | ||
353 | } | ||
354 | |||
355 |
2/2✓ Branch 0 taken 200 times.
✓ Branch 1 taken 200 times.
|
400 | if (avctx->codec_id == AV_CODEC_ID_ASV1) |
356 | 200 | flush_put_bits(&a->pb); | |
357 | else | ||
358 | 200 | flush_put_bits_le(&a->pb); | |
359 | 400 | AV_WN32(put_bits_ptr(&a->pb), 0); | |
360 | 400 | size = (put_bytes_output(&a->pb) + 3) / 4; | |
361 | |||
362 |
2/2✓ Branch 0 taken 200 times.
✓ Branch 1 taken 200 times.
|
400 | if (avctx->codec_id == AV_CODEC_ID_ASV1) { |
363 | 200 | c->bbdsp.bswap_buf((uint32_t *) pkt->data, | |
364 | 200 | (uint32_t *) pkt->data, size); | |
365 | } | ||
366 | |||
367 | 400 | pkt->size = size * 4; | |
368 | 400 | *got_packet = 1; | |
369 | |||
370 | 400 | return 0; | |
371 | } | ||
372 | |||
373 | 8 | static av_cold int encode_init(AVCodecContext *avctx) | |
374 | { | ||
375 | 8 | ASVEncContext *const a = avctx->priv_data; | |
376 | int i; | ||
377 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
|
8 | const int scale = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2; |
378 | int inv_qscale; | ||
379 | |||
380 | 8 | ff_asv_common_init(avctx); | |
381 | 8 | ff_fdctdsp_init(&a->fdsp, avctx); | |
382 | 8 | ff_pixblockdsp_init(&a->pdsp, 8); | |
383 | |||
384 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (avctx->global_quality <= 0) |
385 | ✗ | avctx->global_quality = 4 * FF_QUALITY_SCALE; | |
386 | |||
387 | 8 | inv_qscale = (32 * scale * FF_QUALITY_SCALE + | |
388 | 8 | avctx->global_quality / 2) / avctx->global_quality; | |
389 | |||
390 | 8 | avctx->extradata = av_mallocz(8); | |
391 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (!avctx->extradata) |
392 | ✗ | return AVERROR(ENOMEM); | |
393 | 8 | avctx->extradata_size = 8; | |
394 | 8 | AV_WL32A(avctx->extradata, inv_qscale); | |
395 | 8 | AV_WL32A(avctx->extradata + 4, MKTAG('A', 'S', 'U', 'S')); | |
396 | |||
397 |
2/2✓ Branch 0 taken 512 times.
✓ Branch 1 taken 8 times.
|
520 | for (i = 0; i < 64; i++) { |
398 |
1/2✓ Branch 0 taken 512 times.
✗ Branch 1 not taken.
|
512 | if (a->fdsp.fdct == ff_fdct_ifast) { |
399 | 512 | int q = 32LL * scale * ff_mpeg1_default_intra_matrix[i] * ff_aanscales[i]; | |
400 | 512 | a->q_intra_matrix[i] = (((int64_t)inv_qscale << 30) + q / 2) / q; | |
401 | } else { | ||
402 | ✗ | int q = 32 * scale * ff_mpeg1_default_intra_matrix[i]; | |
403 | ✗ | a->q_intra_matrix[i] = ((inv_qscale << 16) + q / 2) / q; | |
404 | } | ||
405 | } | ||
406 | |||
407 | 8 | return 0; | |
408 | } | ||
409 | |||
410 | #if CONFIG_ASV1_ENCODER | ||
411 | const FFCodec ff_asv1_encoder = { | ||
412 | .p.name = "asv1", | ||
413 | CODEC_LONG_NAME("ASUS V1"), | ||
414 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
415 | .p.id = AV_CODEC_ID_ASV1, | ||
416 | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, | ||
417 | .priv_data_size = sizeof(ASVEncContext), | ||
418 | .init = encode_init, | ||
419 | FF_CODEC_ENCODE_CB(encode_frame), | ||
420 | CODEC_PIXFMTS(AV_PIX_FMT_YUV420P), | ||
421 | .color_ranges = AVCOL_RANGE_MPEG, | ||
422 | }; | ||
423 | #endif | ||
424 | |||
425 | #if CONFIG_ASV2_ENCODER | ||
426 | const FFCodec ff_asv2_encoder = { | ||
427 | .p.name = "asv2", | ||
428 | CODEC_LONG_NAME("ASUS V2"), | ||
429 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
430 | .p.id = AV_CODEC_ID_ASV2, | ||
431 | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, | ||
432 | .priv_data_size = sizeof(ASVEncContext), | ||
433 | .init = encode_init, | ||
434 | FF_CODEC_ENCODE_CB(encode_frame), | ||
435 | CODEC_PIXFMTS(AV_PIX_FMT_YUV420P), | ||
436 | .color_ranges = AVCOL_RANGE_MPEG, | ||
437 | }; | ||
438 | #endif | ||
439 |