]> git.sesse.net Git - ffmpeg/blob - libavcodec/asvenc.c
avcodec: add enum values on chroma sample location
[ffmpeg] / libavcodec / asvenc.c
1 /*
2  * Copyright (c) 2003 Michael Niedermayer
3  *
4  * This file is part of Libav.
5  *
6  * Libav 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  * Libav 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 Libav; 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 "libavutil/attributes.h"
27 #include "libavutil/mem.h"
28
29 #include "asv.h"
30 #include "avcodec.h"
31 #include "fdctdsp.h"
32 #include "mathops.h"
33 #include "mpeg12data.h"
34
35 static inline void asv2_put_bits(PutBitContext *pb, int n, int v)
36 {
37     put_bits(pb, n, ff_reverse[v << (8 - n)]);
38 }
39
40 static inline void asv1_put_level(PutBitContext *pb, int level)
41 {
42     unsigned int index = level + 3;
43
44     if (index <= 6) {
45         put_bits(pb, ff_asv_level_tab[index][1], ff_asv_level_tab[index][0]);
46     } else {
47         put_bits(pb, ff_asv_level_tab[3][1], ff_asv_level_tab[3][0]);
48         put_sbits(pb, 8, level);
49     }
50 }
51
52 static inline void asv2_put_level(PutBitContext *pb, int level)
53 {
54     unsigned int index = level + 31;
55
56     if (index <= 62) {
57         put_bits(pb, ff_asv2_level_tab[index][1], ff_asv2_level_tab[index][0]);
58     } else {
59         put_bits(pb, ff_asv2_level_tab[31][1], ff_asv2_level_tab[31][0]);
60         asv2_put_bits(pb, 8, level & 0xFF);
61     }
62 }
63
64 static inline void asv1_encode_block(ASV1Context *a, int16_t block[64])
65 {
66     int i;
67     int nc_count = 0;
68
69     put_bits(&a->pb, 8, (block[0] + 32) >> 6);
70     block[0] = 0;
71
72     for (i = 0; i < 10; i++) {
73         const int index = ff_asv_scantab[4 * i];
74         int ccp         = 0;
75
76         if ((block[index + 0] = (block[index + 0] *
77                                  a->q_intra_matrix[index + 0] + (1 << 15)) >> 16))
78             ccp |= 8;
79         if ((block[index + 8] = (block[index + 8] *
80                                  a->q_intra_matrix[index + 8] + (1 << 15)) >> 16))
81             ccp |= 4;
82         if ((block[index + 1] = (block[index + 1] *
83                                  a->q_intra_matrix[index + 1] + (1 << 15)) >> 16))
84             ccp |= 2;
85         if ((block[index + 9] = (block[index + 9] *
86                                  a->q_intra_matrix[index + 9] + (1 << 15)) >> 16))
87             ccp |= 1;
88
89         if (ccp) {
90             for (; nc_count; nc_count--)
91                 put_bits(&a->pb, ff_asv_ccp_tab[0][1], ff_asv_ccp_tab[0][0]);
92
93             put_bits(&a->pb, ff_asv_ccp_tab[ccp][1], ff_asv_ccp_tab[ccp][0]);
94
95             if (ccp & 8)
96                 asv1_put_level(&a->pb, block[index + 0]);
97             if (ccp & 4)
98                 asv1_put_level(&a->pb, block[index + 8]);
99             if (ccp & 2)
100                 asv1_put_level(&a->pb, block[index + 1]);
101             if (ccp & 1)
102                 asv1_put_level(&a->pb, block[index + 9]);
103         } else {
104             nc_count++;
105         }
106     }
107     put_bits(&a->pb, ff_asv_ccp_tab[16][1], ff_asv_ccp_tab[16][0]);
108 }
109
110 static inline void asv2_encode_block(ASV1Context *a, int16_t block[64])
111 {
112     int i;
113     int count = 0;
114
115     for (count = 63; count > 3; count--) {
116         const int index = ff_asv_scantab[count];
117         if ((block[index] * a->q_intra_matrix[index] + (1 << 15)) >> 16)
118             break;
119     }
120
121     count >>= 2;
122
123     asv2_put_bits(&a->pb, 4, count);
124     asv2_put_bits(&a->pb, 8, (block[0] + 32) >> 6);
125     block[0] = 0;
126
127     for (i = 0; i <= count; i++) {
128         const int index = ff_asv_scantab[4 * i];
129         int ccp         = 0;
130
131         if ((block[index + 0] = (block[index + 0] *
132                                  a->q_intra_matrix[index + 0] + (1 << 15)) >> 16))
133             ccp |= 8;
134         if ((block[index + 8] = (block[index + 8] *
135                                  a->q_intra_matrix[index + 8] + (1 << 15)) >> 16))
136             ccp |= 4;
137         if ((block[index + 1] = (block[index + 1] *
138                                  a->q_intra_matrix[index + 1] + (1 << 15)) >> 16))
139             ccp |= 2;
140         if ((block[index + 9] = (block[index + 9] *
141                                  a->q_intra_matrix[index + 9] + (1 << 15)) >> 16))
142             ccp |= 1;
143
144         assert(i || ccp < 8);
145         if (i)
146             put_bits(&a->pb, ff_asv_ac_ccp_tab[ccp][1], ff_asv_ac_ccp_tab[ccp][0]);
147         else
148             put_bits(&a->pb, ff_asv_dc_ccp_tab[ccp][1], ff_asv_dc_ccp_tab[ccp][0]);
149
150         if (ccp) {
151             if (ccp & 8)
152                 asv2_put_level(&a->pb, block[index + 0]);
153             if (ccp & 4)
154                 asv2_put_level(&a->pb, block[index + 8]);
155             if (ccp & 2)
156                 asv2_put_level(&a->pb, block[index + 1]);
157             if (ccp & 1)
158                 asv2_put_level(&a->pb, block[index + 9]);
159         }
160     }
161 }
162
163 #define MAX_MB_SIZE (30 * 16 * 16 * 3 / 2 / 8)
164
165 static inline int encode_mb(ASV1Context *a, int16_t block[6][64])
166 {
167     int i;
168
169     if (a->pb.buf_end - a->pb.buf - (put_bits_count(&a->pb) >> 3) < MAX_MB_SIZE) {
170         av_log(a->avctx, AV_LOG_ERROR, "encoded frame too large\n");
171         return -1;
172     }
173
174     if (a->avctx->codec_id == AV_CODEC_ID_ASV1) {
175         for (i = 0; i < 6; i++)
176             asv1_encode_block(a, block[i]);
177     } else {
178         for (i = 0; i < 6; i++)
179             asv2_encode_block(a, block[i]);
180     }
181     return 0;
182 }
183
184 static inline void dct_get(ASV1Context *a, const AVFrame *frame,
185                            int mb_x, int mb_y)
186 {
187     int16_t (*block)[64] = a->block;
188     int linesize = frame->linesize[0];
189     int i;
190
191     uint8_t *ptr_y  = frame->data[0] + (mb_y * 16 * linesize)           + mb_x * 16;
192     uint8_t *ptr_cb = frame->data[1] + (mb_y *  8 * frame->linesize[1]) + mb_x *  8;
193     uint8_t *ptr_cr = frame->data[2] + (mb_y *  8 * frame->linesize[2]) + mb_x *  8;
194
195     a->pdsp.get_pixels(block[0], ptr_y,                    linesize);
196     a->pdsp.get_pixels(block[1], ptr_y + 8,                linesize);
197     a->pdsp.get_pixels(block[2], ptr_y + 8 * linesize,     linesize);
198     a->pdsp.get_pixels(block[3], ptr_y + 8 * linesize + 8, linesize);
199     for (i = 0; i < 4; i++)
200         a->fdsp.fdct(block[i]);
201
202     if (!(a->avctx->flags & CODEC_FLAG_GRAY)) {
203         a->pdsp.get_pixels(block[4], ptr_cb, frame->linesize[1]);
204         a->pdsp.get_pixels(block[5], ptr_cr, frame->linesize[2]);
205         for (i = 4; i < 6; i++)
206             a->fdsp.fdct(block[i]);
207     }
208 }
209
210 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
211                         const AVFrame *pict, int *got_packet)
212 {
213     ASV1Context *const a = avctx->priv_data;
214     int size, ret;
215     int mb_x, mb_y;
216
217     if (!pkt->data &&
218         (ret = av_new_packet(pkt, a->mb_height * a->mb_width * MAX_MB_SIZE +
219                              FF_MIN_BUFFER_SIZE)) < 0) {
220         av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
221         return ret;
222     }
223
224     init_put_bits(&a->pb, pkt->data, pkt->size);
225
226     for (mb_y = 0; mb_y < a->mb_height2; mb_y++) {
227         for (mb_x = 0; mb_x < a->mb_width2; mb_x++) {
228             dct_get(a, pict, mb_x, mb_y);
229             encode_mb(a, a->block);
230         }
231     }
232
233     if (a->mb_width2 != a->mb_width) {
234         mb_x = a->mb_width2;
235         for (mb_y = 0; mb_y < a->mb_height2; mb_y++) {
236             dct_get(a, pict, mb_x, mb_y);
237             encode_mb(a, a->block);
238         }
239     }
240
241     if (a->mb_height2 != a->mb_height) {
242         mb_y = a->mb_height2;
243         for (mb_x = 0; mb_x < a->mb_width; mb_x++) {
244             dct_get(a, pict, mb_x, mb_y);
245             encode_mb(a, a->block);
246         }
247     }
248     emms_c();
249
250     avpriv_align_put_bits(&a->pb);
251     while (put_bits_count(&a->pb) & 31)
252         put_bits(&a->pb, 8, 0);
253
254     size = put_bits_count(&a->pb) / 32;
255
256     if (avctx->codec_id == AV_CODEC_ID_ASV1) {
257         a->bbdsp.bswap_buf((uint32_t *) pkt->data,
258                            (uint32_t *) pkt->data, size);
259     } else {
260         int i;
261         for (i = 0; i < 4 * size; i++)
262             pkt->data[i] = ff_reverse[pkt->data[i]];
263     }
264
265     pkt->size   = size * 4;
266     pkt->flags |= AV_PKT_FLAG_KEY;
267     *got_packet = 1;
268
269     return 0;
270 }
271
272 static av_cold int encode_init(AVCodecContext *avctx)
273 {
274     ASV1Context *const a = avctx->priv_data;
275     int i;
276     const int scale = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2;
277
278     avctx->coded_frame = av_frame_alloc();
279     if (!avctx->coded_frame)
280         return AVERROR(ENOMEM);
281     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
282     avctx->coded_frame->key_frame = 1;
283
284     ff_asv_common_init(avctx);
285     ff_fdctdsp_init(&a->fdsp, avctx);
286     ff_pixblockdsp_init(&a->pdsp, avctx);
287
288     if (avctx->global_quality == 0)
289         avctx->global_quality = 4 * FF_QUALITY_SCALE;
290
291     a->inv_qscale = (32 * scale * FF_QUALITY_SCALE +
292                      avctx->global_quality / 2) / avctx->global_quality;
293
294     avctx->extradata                   = av_mallocz(8);
295     avctx->extradata_size              = 8;
296     ((uint32_t *) avctx->extradata)[0] = av_le2ne32(a->inv_qscale);
297     ((uint32_t *) avctx->extradata)[1] = av_le2ne32(AV_RL32("ASUS"));
298
299     for (i = 0; i < 64; i++) {
300         int q = 32 * scale * ff_mpeg1_default_intra_matrix[i];
301         a->q_intra_matrix[i] = ((a->inv_qscale << 16) + q / 2) / q;
302     }
303
304     return 0;
305 }
306
307 static av_cold int asv_encode_close(AVCodecContext *avctx)
308 {
309     av_frame_free(&avctx->coded_frame);
310
311     return 0;
312 }
313
314 #if CONFIG_ASV1_ENCODER
315 AVCodec ff_asv1_encoder = {
316     .name           = "asv1",
317     .long_name      = NULL_IF_CONFIG_SMALL("ASUS V1"),
318     .type           = AVMEDIA_TYPE_VIDEO,
319     .id             = AV_CODEC_ID_ASV1,
320     .priv_data_size = sizeof(ASV1Context),
321     .init           = encode_init,
322     .encode2        = encode_frame,
323     .close          = asv_encode_close,
324     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
325                                                      AV_PIX_FMT_NONE },
326 };
327 #endif
328
329 #if CONFIG_ASV2_ENCODER
330 AVCodec ff_asv2_encoder = {
331     .name           = "asv2",
332     .long_name      = NULL_IF_CONFIG_SMALL("ASUS V2"),
333     .type           = AVMEDIA_TYPE_VIDEO,
334     .id             = AV_CODEC_ID_ASV2,
335     .priv_data_size = sizeof(ASV1Context),
336     .init           = encode_init,
337     .encode2        = encode_frame,
338     .close          = asv_encode_close,
339     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
340                                                      AV_PIX_FMT_NONE },
341 };
342 #endif