]> git.sesse.net Git - ffmpeg/blob - libavcodec/asv1.c
works with old gcc versions too
[ffmpeg] / libavcodec / asv1.c
1 /*
2  * ASUS V1 codec
3  * Copyright (c) 2003 Michael Niedermayer
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19  
20 /**
21  * @file asv1.c
22  * ASUS V1 codec.
23  */
24  
25 #include "avcodec.h"
26 #include "dsputil.h"
27 #include "mpegvideo.h"
28
29 //#undef NDEBUG
30 //#include <assert.h>
31
32 #define VLC_BITS 5
33
34 typedef struct ASV1Context{
35     AVCodecContext *avctx;
36     DSPContext dsp;
37     AVFrame picture;
38     PutBitContext pb;
39     GetBitContext gb;
40     ScanTable scantable;
41     int inv_qscale;
42     int mb_width;
43     int mb_height;
44     int mb_width2;
45     int mb_height2;
46     DCTELEM __align8 block[6][64];
47     uint16_t __align8 intra_matrix[64];
48     int __align8 q_intra_matrix[64];
49     uint8_t *bitstream_buffer;
50     int bitstream_buffer_size;
51 } ASV1Context;
52
53 static const uint8_t scantab[64]={
54     0x00,0x08,0x01,0x09,0x10,0x18,0x11,0x19,
55     0x02,0x0A,0x03,0x0B,0x12,0x1A,0x13,0x1B,
56     0x04,0x0C,0x05,0x0D,0x20,0x28,0x21,0x29,
57     0x06,0x0E,0x07,0x0F,0x14,0x1C,0x15,0x1D,
58     0x22,0x2A,0x23,0x2B,0x30,0x38,0x31,0x39,
59 };
60
61 static const uint8_t ccp_tab[17][2]={
62     {0x2,2}, {0xE,5}, {0xD,5}, {0xC,5},
63     {0xB,5}, {0xA,5}, {0x9,5}, {0x8,5},
64     {0x7,5}, {0x6,5}, {0x5,5}, {0x4,5},
65     {0x3,5}, {0x2,5}, {0x1,5}, {0x3,2},
66     {0xF,5}, //EOB
67 };
68
69 static const uint8_t level_tab[7][2]={
70     {3,4}, {3,3}, {3,2}, {0,3}, {2,2}, {2,3}, {2,4}
71 };
72
73 static VLC ccp_vlc;
74 static VLC level_vlc;
75
76 static void init_vlcs(ASV1Context *a){
77     static int done = 0;
78
79     if (!done) {
80         done = 1;
81
82         init_vlc(&ccp_vlc, VLC_BITS, 17, 
83                  &ccp_tab[0][1], 2, 1,
84                  &ccp_tab[0][0], 2, 1);
85         init_vlc(&level_vlc,  VLC_BITS, 7, 
86                  &level_tab[0][1], 2, 1,
87                  &level_tab[0][0], 2, 1);
88     }
89 }
90
91 static inline int get_level(GetBitContext *gb){
92     int code= get_vlc2(gb, level_vlc.table, VLC_BITS, 1);
93
94     if(code==3) return get_sbits(gb, 8);
95     else        return code - 3;
96 }
97
98 #ifdef CONFIG_ENCODERS
99
100 static inline void put_level(PutBitContext *pb, int level){
101     unsigned int index= level + 3;
102
103     if(index <= 6) put_bits(pb, level_tab[index][1], level_tab[index][0]);
104     else{
105         put_bits(pb, level_tab[3][1], level_tab[3][0]);
106         put_bits(pb, 8, level&0xFF);
107     }
108 }
109
110 #endif //CONFIG_ENCODERS
111
112 static inline int decode_block(ASV1Context *a, DCTELEM block[64]){
113     int i;
114
115     block[0]= 8*get_bits(&a->gb, 8);
116     
117     for(i=0; i<11; i++){
118         const int ccp= get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1);
119
120         if(ccp){
121             if(ccp == 16) break;
122             if(ccp < 0 || i>=10){
123                 printf("coded coeff pattern damaged\n");
124                 return -1;
125             }
126
127             if(ccp&1) block[a->scantable.permutated[4*i+0]]= (get_level(&a->gb) * a->intra_matrix[4*i+0])>>4;
128             if(ccp&2) block[a->scantable.permutated[4*i+1]]= (get_level(&a->gb) * a->intra_matrix[4*i+1])>>4;;
129             if(ccp&4) block[a->scantable.permutated[4*i+2]]= (get_level(&a->gb) * a->intra_matrix[4*i+2])>>4;;
130             if(ccp&8) block[a->scantable.permutated[4*i+3]]= (get_level(&a->gb) * a->intra_matrix[4*i+3])>>4;;
131         }
132     }
133
134     return 0;
135 }
136
137 #ifdef CONFIG_ENCODERS
138
139 static inline void encode_block(ASV1Context *a, DCTELEM block[64]){
140     int i;
141     int nc_count=0;
142     
143     put_bits(&a->pb, 8, (block[0] + 32)>>6);
144     block[0]= 0;
145     
146     for(i=0; i<10; i++){
147         const int index= scantab[4*i];
148         int ccp=0;
149
150         if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 1;
151         if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 2;
152         if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 4;
153         if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 8;
154
155         if(ccp){
156             for(;nc_count; nc_count--) 
157                 put_bits(&a->pb, ccp_tab[0][1], ccp_tab[0][0]);
158
159             put_bits(&a->pb, ccp_tab[ccp][1], ccp_tab[ccp][0]);
160             
161             if(ccp&1) put_level(&a->pb, block[index + 0]);
162             if(ccp&2) put_level(&a->pb, block[index + 8]);
163             if(ccp&4) put_level(&a->pb, block[index + 1]);
164             if(ccp&8) put_level(&a->pb, block[index + 9]);
165         }else{
166             nc_count++;
167         }
168     }
169     put_bits(&a->pb, ccp_tab[16][1], ccp_tab[16][0]);
170 }
171
172 #endif //CONFIG_ENCODERS
173
174 static inline int decode_mb(ASV1Context *a, DCTELEM block[6][64]){
175     int i;
176
177     a->dsp.clear_blocks(block[0]);
178     
179     for(i=0; i<6; i++){
180         if( decode_block(a, block[i]) < 0) 
181             return -1;
182     }
183     return 0;
184 }
185
186 #ifdef CONFIG_ENCODERS
187
188 static inline void encode_mb(ASV1Context *a, DCTELEM block[6][64]){
189     int i;
190
191     for(i=0; i<6; i++){
192         encode_block(a, block[i]);
193     }
194 }
195         
196 #endif //CONFIG_ENCODERS
197
198 static inline void idct_put(ASV1Context *a, int mb_x, int mb_y){
199     DCTELEM (*block)[64]= a->block;
200     int linesize= a->picture.linesize[0];
201     
202     uint8_t *dest_y  = a->picture.data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
203     uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
204     uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8;
205
206     a->dsp.idct_put(dest_y                 , linesize, block[0]);
207     a->dsp.idct_put(dest_y              + 8, linesize, block[1]);
208     a->dsp.idct_put(dest_y + 8*linesize    , linesize, block[2]);
209     a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]);
210
211     if(!(a->avctx->flags&CODEC_FLAG_GRAY)){
212         a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]);
213         a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]);
214     }
215 }
216
217 #ifdef CONFIG_ENCODERS
218
219 static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){
220     DCTELEM (*block)[64]= a->block;
221     int linesize= a->picture.linesize[0];
222     int i;
223     
224     uint8_t *ptr_y  = a->picture.data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
225     uint8_t *ptr_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
226     uint8_t *ptr_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8;
227
228     a->dsp.get_pixels(block[0], ptr_y                 , linesize);
229     a->dsp.get_pixels(block[1], ptr_y              + 8, linesize);
230     a->dsp.get_pixels(block[2], ptr_y + 8*linesize    , linesize);
231     a->dsp.get_pixels(block[3], ptr_y + 8*linesize + 8, linesize);
232     for(i=0; i<4; i++)
233         a->dsp.fdct(block[i]);
234     
235     if(!(a->avctx->flags&CODEC_FLAG_GRAY)){
236         a->dsp.get_pixels(block[4], ptr_cb, a->picture.linesize[1]);
237         a->dsp.get_pixels(block[5], ptr_cr, a->picture.linesize[2]);
238         for(i=4; i<6; i++)
239             a->dsp.fdct(block[i]);
240     }
241 }
242
243 #endif //CONFIG_ENCODERS
244
245 static int decode_frame(AVCodecContext *avctx, 
246                         void *data, int *data_size,
247                         uint8_t *buf, int buf_size)
248 {
249     ASV1Context * const a = avctx->priv_data;
250     AVFrame *picture = data;
251     AVFrame * const p= (AVFrame*)&a->picture;
252     int mb_x, mb_y;
253
254     *data_size = 0;
255
256     /* special case for last picture */
257     if (buf_size == 0) {
258         return 0;
259     }
260
261     if(p->data[0])
262         avctx->release_buffer(avctx, p);
263
264     p->reference= 0;
265     if(avctx->get_buffer(avctx, p) < 0){
266         fprintf(stderr, "get_buffer() failed\n");
267         return -1;
268     }
269     p->pict_type= I_TYPE;
270     p->key_frame= 1;
271
272     a->bitstream_buffer= av_fast_realloc(a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
273     a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (uint32_t*)buf, buf_size/4);
274     init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8);
275
276     for(mb_y=0; mb_y<a->mb_height2; mb_y++){
277         for(mb_x=0; mb_x<a->mb_width2; mb_x++){
278             if( decode_mb(a, a->block) <0)
279                 return -1;
280              
281             idct_put(a, mb_x, mb_y);
282         }
283     }
284
285     if(a->mb_width2 != a->mb_width){
286         mb_x= a->mb_width2;
287         for(mb_y=0; mb_y<a->mb_height2; mb_y++){
288             if( decode_mb(a, a->block) <0)
289                 return -1;
290              
291             idct_put(a, mb_x, mb_y);
292         }
293     }
294
295     if(a->mb_height2 != a->mb_height){
296         mb_y= a->mb_height2;
297         for(mb_x=0; mb_x<a->mb_width; mb_x++){
298             if( decode_mb(a, a->block) <0)
299                 return -1;
300              
301             idct_put(a, mb_x, mb_y);
302         }
303     }
304 #if 0    
305 int i;
306 printf("%d %d\n", 8*buf_size, get_bits_count(&a->gb));
307 for(i=get_bits_count(&a->gb); i<8*buf_size; i++){
308     printf("%d", get_bits1(&a->gb));
309 }
310
311 for(i=0; i<s->avctx->extradata_size; i++){
312     printf("%c\n", ((uint8_t*)s->avctx->extradata)[i]);
313 }
314 #endif
315
316     p->quality= (32 + a->inv_qscale/2)/a->inv_qscale;
317     memset(p->qscale_table, p->quality, p->qstride*a->mb_height);
318     
319     *picture= *(AVFrame*)&a->picture;
320     *data_size = sizeof(AVPicture);
321
322     emms_c();
323     
324     return (get_bits_count(&a->gb)+31)/32*4;
325 }
326
327 #ifdef CONFIG_ENCODERS
328
329 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
330     ASV1Context * const a = avctx->priv_data;
331     AVFrame *pict = data;
332     AVFrame * const p= (AVFrame*)&a->picture;
333     int size;
334     int mb_x, mb_y;
335
336     init_put_bits(&a->pb, buf, buf_size, NULL, NULL);
337     
338     *p = *pict;
339     p->pict_type= I_TYPE;
340     p->key_frame= 1;
341
342     for(mb_y=0; mb_y<a->mb_height2; mb_y++){
343         for(mb_x=0; mb_x<a->mb_width2; mb_x++){
344             dct_get(a, mb_x, mb_y);
345             encode_mb(a, a->block);
346         }
347     }
348
349     if(a->mb_width2 != a->mb_width){
350         mb_x= a->mb_width2;
351         for(mb_y=0; mb_y<a->mb_height2; mb_y++){
352             dct_get(a, mb_x, mb_y);
353             encode_mb(a, a->block);
354         }
355     }
356
357     if(a->mb_height2 != a->mb_height){
358         mb_y= a->mb_height2;
359         for(mb_x=0; mb_x<a->mb_width; mb_x++){
360             dct_get(a, mb_x, mb_y);
361             encode_mb(a, a->block);
362         }
363     }
364     emms_c();
365     
366     align_put_bits(&a->pb);
367     while(get_bit_count(&a->pb)&31)
368         put_bits(&a->pb, 8, 0);
369     
370     size= get_bit_count(&a->pb)/32;
371     
372     a->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
373     
374     return size*4;
375 }
376
377 #endif //CONFIG_ENCODERS
378
379 static void common_init(AVCodecContext *avctx){
380     ASV1Context * const a = avctx->priv_data;
381
382     dsputil_init(&a->dsp, avctx);
383
384     a->mb_width   = (avctx->width  + 15) / 16;
385     a->mb_height  = (avctx->height + 15) / 16;
386     a->mb_width2  = (avctx->width  + 0) / 16;
387     a->mb_height2 = (avctx->height + 0) / 16;
388
389     avctx->coded_frame= (AVFrame*)&a->picture;
390     a->avctx= avctx;
391 }
392
393 static int decode_init(AVCodecContext *avctx){
394     ASV1Context * const a = avctx->priv_data;
395     AVFrame *p= (AVFrame*)&a->picture;
396     int i;
397  
398     common_init(avctx);
399     init_vlcs(a);
400     ff_init_scantable(a->dsp.idct_permutation, &a->scantable, scantab);
401
402     a->inv_qscale= le2me_32(((uint32_t*)avctx->extradata)[0]);
403     if(a->inv_qscale == 0){
404         printf("illegal qscale 0\n");
405         a->inv_qscale= 6;
406     }
407
408     for(i=0; i<64; i++){
409         int index= scantab[i];
410         a->intra_matrix[i]= 64*ff_mpeg1_default_intra_matrix[index] / a->inv_qscale;
411     }
412
413     p->qstride= a->mb_width;
414     p->qscale_table= av_mallocz( p->qstride * a->mb_height);
415
416     return 0;
417 }
418
419 #ifdef CONFIG_ENCODERS
420
421 static int encode_init(AVCodecContext *avctx){
422     ASV1Context * const a = avctx->priv_data;
423     int i;
424  
425     common_init(avctx);
426     
427     if(avctx->global_quality == 0) avctx->global_quality= 4*FF_QUALITY_SCALE;
428
429     a->inv_qscale= (32*FF_QUALITY_SCALE +  avctx->global_quality/2) / avctx->global_quality;
430     
431     avctx->extradata= av_mallocz(8);
432     avctx->extradata_size=8;
433     ((uint32_t*)avctx->extradata)[0]= le2me_32(a->inv_qscale);
434     ((uint32_t*)avctx->extradata)[1]= le2me_32(ff_get_fourcc("ASUS"));
435     
436     for(i=0; i<64; i++){
437         int q= 32*ff_mpeg1_default_intra_matrix[i];
438         a->q_intra_matrix[i]= ((a->inv_qscale<<16) + q/2) / q;
439     }
440
441     return 0;
442 }
443
444 #endif //CONFIG_ENCODERS
445
446 static int decode_end(AVCodecContext *avctx){
447     ASV1Context * const a = avctx->priv_data;
448
449     av_freep(&a->bitstream_buffer);
450     av_freep(&a->picture.qscale_table);
451     a->bitstream_buffer_size=0;
452     
453     avcodec_default_free_buffers(avctx);
454
455     return 0;
456 }
457
458 AVCodec asv1_decoder = {
459     "asv1",
460     CODEC_TYPE_VIDEO,
461     CODEC_ID_ASV1,
462     sizeof(ASV1Context),
463     decode_init,
464     NULL,
465     decode_end,
466     decode_frame,
467     CODEC_CAP_DR1,
468 };
469
470 #ifdef CONFIG_ENCODERS
471
472 AVCodec asv1_encoder = {
473     "asv1",
474     CODEC_TYPE_VIDEO,
475     CODEC_ID_ASV1,
476     sizeof(ASV1Context),
477     encode_init,
478     encode_frame,
479     //encode_end,
480 };
481
482 #endif //CONFIG_ENCODERS