asv1.c
Go to the documentation of this file.
1 /*
2  * ASUS V1/V2 codec
3  * Copyright (c) 2003 Michael Niedermayer
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
27 #include "avcodec.h"
28 #include "libavutil/common.h"
29 #include "put_bits.h"
30 #include "dsputil.h"
31 #include "mpeg12data.h"
32 
33 //#undef NDEBUG
34 //#include <assert.h>
35 
36 #define VLC_BITS 6
37 #define ASV2_LEVEL_VLC_BITS 10
38 
39 typedef struct ASV1Context{
47  int mb_width;
48  int mb_height;
49  int mb_width2;
52  uint16_t intra_matrix[64];
53  int q_intra_matrix[64];
54  uint8_t *bitstream_buffer;
55  unsigned int bitstream_buffer_size;
56 } ASV1Context;
57 
58 static const uint8_t scantab[64]={
59  0x00,0x08,0x01,0x09,0x10,0x18,0x11,0x19,
60  0x02,0x0A,0x03,0x0B,0x12,0x1A,0x13,0x1B,
61  0x04,0x0C,0x05,0x0D,0x20,0x28,0x21,0x29,
62  0x06,0x0E,0x07,0x0F,0x14,0x1C,0x15,0x1D,
63  0x22,0x2A,0x23,0x2B,0x30,0x38,0x31,0x39,
64  0x16,0x1E,0x17,0x1F,0x24,0x2C,0x25,0x2D,
65  0x32,0x3A,0x33,0x3B,0x26,0x2E,0x27,0x2F,
66  0x34,0x3C,0x35,0x3D,0x36,0x3E,0x37,0x3F,
67 };
68 
69 
70 static const uint8_t ccp_tab[17][2]={
71  {0x2,2}, {0x7,5}, {0xB,5}, {0x3,5},
72  {0xD,5}, {0x5,5}, {0x9,5}, {0x1,5},
73  {0xE,5}, {0x6,5}, {0xA,5}, {0x2,5},
74  {0xC,5}, {0x4,5}, {0x8,5}, {0x3,2},
75  {0xF,5}, //EOB
76 };
77 
78 static const uint8_t level_tab[7][2]={
79  {3,4}, {3,3}, {3,2}, {0,3}, {2,2}, {2,3}, {2,4}
80 };
81 
82 static const uint8_t dc_ccp_tab[8][2]={
83  {0x1,2}, {0xD,4}, {0xF,4}, {0xC,4},
84  {0x5,3}, {0xE,4}, {0x4,3}, {0x0,2},
85 };
86 
87 static const uint8_t ac_ccp_tab[16][2]={
88  {0x00,2}, {0x3B,6}, {0x0A,4}, {0x3A,6},
89  {0x02,3}, {0x39,6}, {0x3C,6}, {0x38,6},
90  {0x03,3}, {0x3D,6}, {0x08,4}, {0x1F,5},
91  {0x09,4}, {0x0B,4}, {0x0D,4}, {0x0C,4},
92 };
93 
94 static const uint8_t asv2_level_tab[63][2]={
95  {0x3F,10},{0x2F,10},{0x37,10},{0x27,10},{0x3B,10},{0x2B,10},{0x33,10},{0x23,10},
96  {0x3D,10},{0x2D,10},{0x35,10},{0x25,10},{0x39,10},{0x29,10},{0x31,10},{0x21,10},
97  {0x1F, 8},{0x17, 8},{0x1B, 8},{0x13, 8},{0x1D, 8},{0x15, 8},{0x19, 8},{0x11, 8},
98  {0x0F, 6},{0x0B, 6},{0x0D, 6},{0x09, 6},
99  {0x07, 4},{0x05, 4},
100  {0x03, 2},
101  {0x00, 5},
102  {0x02, 2},
103  {0x04, 4},{0x06, 4},
104  {0x08, 6},{0x0C, 6},{0x0A, 6},{0x0E, 6},
105  {0x10, 8},{0x18, 8},{0x14, 8},{0x1C, 8},{0x12, 8},{0x1A, 8},{0x16, 8},{0x1E, 8},
106  {0x20,10},{0x30,10},{0x28,10},{0x38,10},{0x24,10},{0x34,10},{0x2C,10},{0x3C,10},
107  {0x22,10},{0x32,10},{0x2A,10},{0x3A,10},{0x26,10},{0x36,10},{0x2E,10},{0x3E,10},
108 };
109 
110 
111 static VLC ccp_vlc;
112 static VLC level_vlc;
116 
117 static av_cold void init_vlcs(ASV1Context *a){
118  static int done = 0;
119 
120  if (!done) {
121  done = 1;
122 
123  INIT_VLC_STATIC(&ccp_vlc, VLC_BITS, 17,
124  &ccp_tab[0][1], 2, 1,
125  &ccp_tab[0][0], 2, 1, 64);
126  INIT_VLC_STATIC(&dc_ccp_vlc, VLC_BITS, 8,
127  &dc_ccp_tab[0][1], 2, 1,
128  &dc_ccp_tab[0][0], 2, 1, 64);
129  INIT_VLC_STATIC(&ac_ccp_vlc, VLC_BITS, 16,
130  &ac_ccp_tab[0][1], 2, 1,
131  &ac_ccp_tab[0][0], 2, 1, 64);
132  INIT_VLC_STATIC(&level_vlc, VLC_BITS, 7,
133  &level_tab[0][1], 2, 1,
134  &level_tab[0][0], 2, 1, 64);
135  INIT_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63,
136  &asv2_level_tab[0][1], 2, 1,
137  &asv2_level_tab[0][0], 2, 1, 1024);
138  }
139 }
140 
141 //FIXME write a reversed bitstream reader to avoid the double reverse
142 static inline int asv2_get_bits(GetBitContext *gb, int n){
143  return av_reverse[ get_bits(gb, n) << (8-n) ];
144 }
145 
146 static inline void asv2_put_bits(PutBitContext *pb, int n, int v){
147  put_bits(pb, n, av_reverse[ v << (8-n) ]);
148 }
149 
150 static inline int asv1_get_level(GetBitContext *gb){
151  int code= get_vlc2(gb, level_vlc.table, VLC_BITS, 1);
152 
153  if(code==3) return get_sbits(gb, 8);
154  else return code - 3;
155 }
156 
157 static inline int asv2_get_level(GetBitContext *gb){
158  int code= get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1);
159 
160  if(code==31) return (int8_t)asv2_get_bits(gb, 8);
161  else return code - 31;
162 }
163 
164 static inline void asv1_put_level(PutBitContext *pb, int level){
165  unsigned int index= level + 3;
166 
167  if(index <= 6) put_bits(pb, level_tab[index][1], level_tab[index][0]);
168  else{
169  put_bits(pb, level_tab[3][1], level_tab[3][0]);
170  put_sbits(pb, 8, level);
171  }
172 }
173 
174 static inline void asv2_put_level(PutBitContext *pb, int level){
175  unsigned int index= level + 31;
176 
177  if(index <= 62) put_bits(pb, asv2_level_tab[index][1], asv2_level_tab[index][0]);
178  else{
179  put_bits(pb, asv2_level_tab[31][1], asv2_level_tab[31][0]);
180  asv2_put_bits(pb, 8, level&0xFF);
181  }
182 }
183 
184 static inline int asv1_decode_block(ASV1Context *a, DCTELEM block[64]){
185  int i;
186 
187  block[0]= 8*get_bits(&a->gb, 8);
188 
189  for(i=0; i<11; i++){
190  const int ccp= get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1);
191 
192  if(ccp){
193  if(ccp == 16) break;
194  if(ccp < 0 || i>=10){
195  av_log(a->avctx, AV_LOG_ERROR, "coded coeff pattern damaged\n");
196  return -1;
197  }
198 
199  if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4;
200  if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4;
201  if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4;
202  if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4;
203  }
204  }
205 
206  return 0;
207 }
208 
209 static inline int asv2_decode_block(ASV1Context *a, DCTELEM block[64]){
210  int i, count, ccp;
211 
212  count= asv2_get_bits(&a->gb, 4);
213 
214  block[0]= 8*asv2_get_bits(&a->gb, 8);
215 
216  ccp= get_vlc2(&a->gb, dc_ccp_vlc.table, VLC_BITS, 1);
217  if(ccp){
218  if(ccp&4) block[a->scantable.permutated[1]]= (asv2_get_level(&a->gb) * a->intra_matrix[1])>>4;
219  if(ccp&2) block[a->scantable.permutated[2]]= (asv2_get_level(&a->gb) * a->intra_matrix[2])>>4;
220  if(ccp&1) block[a->scantable.permutated[3]]= (asv2_get_level(&a->gb) * a->intra_matrix[3])>>4;
221  }
222 
223  for(i=1; i<count+1; i++){
224  const int ccp= get_vlc2(&a->gb, ac_ccp_vlc.table, VLC_BITS, 1);
225 
226  if(ccp){
227  if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4;
228  if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4;
229  if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4;
230  if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4;
231  }
232  }
233 
234  return 0;
235 }
236 
237 static inline void asv1_encode_block(ASV1Context *a, DCTELEM block[64]){
238  int i;
239  int nc_count=0;
240 
241  put_bits(&a->pb, 8, (block[0] + 32)>>6);
242  block[0]= 0;
243 
244  for(i=0; i<10; i++){
245  const int index= scantab[4*i];
246  int ccp=0;
247 
248  if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8;
249  if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4;
250  if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2;
251  if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1;
252 
253  if(ccp){
254  for(;nc_count; nc_count--)
255  put_bits(&a->pb, ccp_tab[0][1], ccp_tab[0][0]);
256 
257  put_bits(&a->pb, ccp_tab[ccp][1], ccp_tab[ccp][0]);
258 
259  if(ccp&8) asv1_put_level(&a->pb, block[index + 0]);
260  if(ccp&4) asv1_put_level(&a->pb, block[index + 8]);
261  if(ccp&2) asv1_put_level(&a->pb, block[index + 1]);
262  if(ccp&1) asv1_put_level(&a->pb, block[index + 9]);
263  }else{
264  nc_count++;
265  }
266  }
267  put_bits(&a->pb, ccp_tab[16][1], ccp_tab[16][0]);
268 }
269 
270 static inline void asv2_encode_block(ASV1Context *a, DCTELEM block[64]){
271  int i;
272  int count=0;
273 
274  for(count=63; count>3; count--){
275  const int index= scantab[count];
276 
277  if( (block[index]*a->q_intra_matrix[index] + (1<<15))>>16 )
278  break;
279  }
280 
281  count >>= 2;
282 
283  asv2_put_bits(&a->pb, 4, count);
284  asv2_put_bits(&a->pb, 8, (block[0] + 32)>>6);
285  block[0]= 0;
286 
287  for(i=0; i<=count; i++){
288  const int index= scantab[4*i];
289  int ccp=0;
290 
291  if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8;
292  if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4;
293  if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2;
294  if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1;
295 
296  assert(i || ccp<8);
297  if(i) put_bits(&a->pb, ac_ccp_tab[ccp][1], ac_ccp_tab[ccp][0]);
298  else put_bits(&a->pb, dc_ccp_tab[ccp][1], dc_ccp_tab[ccp][0]);
299 
300  if(ccp){
301  if(ccp&8) asv2_put_level(&a->pb, block[index + 0]);
302  if(ccp&4) asv2_put_level(&a->pb, block[index + 8]);
303  if(ccp&2) asv2_put_level(&a->pb, block[index + 1]);
304  if(ccp&1) asv2_put_level(&a->pb, block[index + 9]);
305  }
306  }
307 }
308 
309 static inline int decode_mb(ASV1Context *a, DCTELEM block[6][64]){
310  int i;
311 
312  a->dsp.clear_blocks(block[0]);
313 
314  if(a->avctx->codec_id == CODEC_ID_ASV1){
315  for(i=0; i<6; i++){
316  if( asv1_decode_block(a, block[i]) < 0)
317  return -1;
318  }
319  }else{
320  for(i=0; i<6; i++){
321  if( asv2_decode_block(a, block[i]) < 0)
322  return -1;
323  }
324  }
325  return 0;
326 }
327 
328 static inline int encode_mb(ASV1Context *a, DCTELEM block[6][64]){
329  int i;
330 
331  if(a->pb.buf_end - a->pb.buf - (put_bits_count(&a->pb)>>3) < 30*16*16*3/2/8){
332  av_log(a->avctx, AV_LOG_ERROR, "encoded frame too large\n");
333  return -1;
334  }
335 
336  if(a->avctx->codec_id == CODEC_ID_ASV1){
337  for(i=0; i<6; i++)
338  asv1_encode_block(a, block[i]);
339  }else{
340  for(i=0; i<6; i++)
341  asv2_encode_block(a, block[i]);
342  }
343  return 0;
344 }
345 
346 static inline void idct_put(ASV1Context *a, int mb_x, int mb_y){
347  DCTELEM (*block)[64]= a->block;
348  int linesize= a->picture.linesize[0];
349 
350  uint8_t *dest_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16;
351  uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
352  uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8;
353 
354  a->dsp.idct_put(dest_y , linesize, block[0]);
355  a->dsp.idct_put(dest_y + 8, linesize, block[1]);
356  a->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]);
357  a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]);
358 
359  if(!(a->avctx->flags&CODEC_FLAG_GRAY)){
360  a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]);
361  a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]);
362  }
363 }
364 
365 static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){
366  DCTELEM (*block)[64]= a->block;
367  int linesize= a->picture.linesize[0];
368  int i;
369 
370  uint8_t *ptr_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16;
371  uint8_t *ptr_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
372  uint8_t *ptr_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8;
373 
374  a->dsp.get_pixels(block[0], ptr_y , linesize);
375  a->dsp.get_pixels(block[1], ptr_y + 8, linesize);
376  a->dsp.get_pixels(block[2], ptr_y + 8*linesize , linesize);
377  a->dsp.get_pixels(block[3], ptr_y + 8*linesize + 8, linesize);
378  for(i=0; i<4; i++)
379  a->dsp.fdct(block[i]);
380 
381  if(!(a->avctx->flags&CODEC_FLAG_GRAY)){
382  a->dsp.get_pixels(block[4], ptr_cb, a->picture.linesize[1]);
383  a->dsp.get_pixels(block[5], ptr_cr, a->picture.linesize[2]);
384  for(i=4; i<6; i++)
385  a->dsp.fdct(block[i]);
386  }
387 }
388 
389 static int decode_frame(AVCodecContext *avctx,
390  void *data, int *data_size,
391  AVPacket *avpkt)
392 {
393  const uint8_t *buf = avpkt->data;
394  int buf_size = avpkt->size;
395  ASV1Context * const a = avctx->priv_data;
396  AVFrame *picture = data;
397  AVFrame * const p= &a->picture;
398  int mb_x, mb_y;
399 
400  if(p->data[0])
401  avctx->release_buffer(avctx, p);
402 
403  p->reference= 0;
404  if(avctx->get_buffer(avctx, p) < 0){
405  av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
406  return -1;
407  }
409  p->key_frame= 1;
410 
412  if (!a->bitstream_buffer)
413  return AVERROR(ENOMEM);
414 
415  if(avctx->codec_id == CODEC_ID_ASV1)
416  a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (const uint32_t*)buf, buf_size/4);
417  else{
418  int i;
419  for(i=0; i<buf_size; i++)
420  a->bitstream_buffer[i]= av_reverse[ buf[i] ];
421  }
422 
423  init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8);
424 
425  for(mb_y=0; mb_y<a->mb_height2; mb_y++){
426  for(mb_x=0; mb_x<a->mb_width2; mb_x++){
427  if( decode_mb(a, a->block) <0)
428  return -1;
429 
430  idct_put(a, mb_x, mb_y);
431  }
432  }
433 
434  if(a->mb_width2 != a->mb_width){
435  mb_x= a->mb_width2;
436  for(mb_y=0; mb_y<a->mb_height2; mb_y++){
437  if( decode_mb(a, a->block) <0)
438  return -1;
439 
440  idct_put(a, mb_x, mb_y);
441  }
442  }
443 
444  if(a->mb_height2 != a->mb_height){
445  mb_y= a->mb_height2;
446  for(mb_x=0; mb_x<a->mb_width; mb_x++){
447  if( decode_mb(a, a->block) <0)
448  return -1;
449 
450  idct_put(a, mb_x, mb_y);
451  }
452  }
453 
454  *picture= *(AVFrame*)&a->picture;
455  *data_size = sizeof(AVPicture);
456 
457  emms_c();
458 
459  return (get_bits_count(&a->gb)+31)/32*4;
460 }
461 
462 #if CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER
463 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
464  ASV1Context * const a = avctx->priv_data;
465  AVFrame *pict = data;
466  AVFrame * const p= &a->picture;
467  int size;
468  int mb_x, mb_y;
469 
470  init_put_bits(&a->pb, buf, buf_size);
471 
472  *p = *pict;
474  p->key_frame= 1;
475 
476  for(mb_y=0; mb_y<a->mb_height2; mb_y++){
477  for(mb_x=0; mb_x<a->mb_width2; mb_x++){
478  dct_get(a, mb_x, mb_y);
479  encode_mb(a, a->block);
480  }
481  }
482 
483  if(a->mb_width2 != a->mb_width){
484  mb_x= a->mb_width2;
485  for(mb_y=0; mb_y<a->mb_height2; mb_y++){
486  dct_get(a, mb_x, mb_y);
487  encode_mb(a, a->block);
488  }
489  }
490 
491  if(a->mb_height2 != a->mb_height){
492  mb_y= a->mb_height2;
493  for(mb_x=0; mb_x<a->mb_width; mb_x++){
494  dct_get(a, mb_x, mb_y);
495  encode_mb(a, a->block);
496  }
497  }
498  emms_c();
499 
501  while(put_bits_count(&a->pb)&31)
502  put_bits(&a->pb, 8, 0);
503 
504  size= put_bits_count(&a->pb)/32;
505 
506  if(avctx->codec_id == CODEC_ID_ASV1)
507  a->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
508  else{
509  int i;
510  for(i=0; i<4*size; i++)
511  buf[i]= av_reverse[ buf[i] ];
512  }
513 
514  return size*4;
515 }
516 #endif /* CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER */
517 
518 static av_cold void common_init(AVCodecContext *avctx){
519  ASV1Context * const a = avctx->priv_data;
520 
521  dsputil_init(&a->dsp, avctx);
522 
523  a->mb_width = (avctx->width + 15) / 16;
524  a->mb_height = (avctx->height + 15) / 16;
525  a->mb_width2 = (avctx->width + 0) / 16;
526  a->mb_height2 = (avctx->height + 0) / 16;
527 
528  avctx->coded_frame= &a->picture;
529  a->avctx= avctx;
530 }
531 
532 static av_cold int decode_init(AVCodecContext *avctx){
533  ASV1Context * const a = avctx->priv_data;
534  AVFrame *p= &a->picture;
535  int i;
536  const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2;
537 
538  if (avctx->extradata_size < 1) {
539  av_log(avctx, AV_LOG_ERROR, "No extradata provided\n");
540  return AVERROR_INVALIDDATA;
541  }
542 
543  common_init(avctx);
544  init_vlcs(a);
546  avctx->pix_fmt= PIX_FMT_YUV420P;
547 
548  a->inv_qscale= avctx->extradata[0];
549  if(a->inv_qscale == 0){
550  av_log(avctx, AV_LOG_ERROR, "illegal qscale 0\n");
551  if(avctx->codec_id == CODEC_ID_ASV1)
552  a->inv_qscale= 6;
553  else
554  a->inv_qscale= 10;
555  }
556 
557  for(i=0; i<64; i++){
558  int index= scantab[i];
559 
561  }
562 
563  p->qstride= a->mb_width;
564  p->qscale_table= av_malloc( p->qstride * a->mb_height);
565  p->quality= (32*scale + a->inv_qscale/2)/a->inv_qscale;
566  memset(p->qscale_table, p->quality, p->qstride*a->mb_height);
567 
568  return 0;
569 }
570 
571 #if CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER
572 static av_cold int encode_init(AVCodecContext *avctx){
573  ASV1Context * const a = avctx->priv_data;
574  int i;
575  const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2;
576 
577  common_init(avctx);
578 
579  if(avctx->global_quality == 0) avctx->global_quality= 4*FF_QUALITY_SCALE;
580 
581  a->inv_qscale= (32*scale*FF_QUALITY_SCALE + avctx->global_quality/2) / avctx->global_quality;
582 
583  avctx->extradata= av_mallocz(8);
584  avctx->extradata_size=8;
585  ((uint32_t*)avctx->extradata)[0]= av_le2ne32(a->inv_qscale);
586  ((uint32_t*)avctx->extradata)[1]= av_le2ne32(AV_RL32("ASUS"));
587 
588  for(i=0; i<64; i++){
589  int q= 32*scale*ff_mpeg1_default_intra_matrix[i];
590  a->q_intra_matrix[i]= ((a->inv_qscale<<16) + q/2) / q;
591  }
592 
593  return 0;
594 }
595 #endif /* CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER */
596 
597 static av_cold int decode_end(AVCodecContext *avctx){
598  ASV1Context * const a = avctx->priv_data;
599 
603 
604  if(a->picture.data[0])
605  avctx->release_buffer(avctx, &a->picture);
606 
607  return 0;
608 }
609 
611  .name = "asv1",
612  .type = AVMEDIA_TYPE_VIDEO,
613  .id = CODEC_ID_ASV1,
614  .priv_data_size = sizeof(ASV1Context),
615  .init = decode_init,
616  .close = decode_end,
617  .decode = decode_frame,
618  .capabilities = CODEC_CAP_DR1,
619  .long_name= NULL_IF_CONFIG_SMALL("ASUS V1"),
620 };
621 
623  .name = "asv2",
624  .type = AVMEDIA_TYPE_VIDEO,
625  .id = CODEC_ID_ASV2,
626  .priv_data_size = sizeof(ASV1Context),
627  .init = decode_init,
628  .close = decode_end,
629  .decode = decode_frame,
630  .capabilities = CODEC_CAP_DR1,
631  .long_name= NULL_IF_CONFIG_SMALL("ASUS V2"),
632 };
633 
634 #if CONFIG_ASV1_ENCODER
635 AVCodec ff_asv1_encoder = {
636  .name = "asv1",
637  .type = AVMEDIA_TYPE_VIDEO,
638  .id = CODEC_ID_ASV1,
639  .priv_data_size = sizeof(ASV1Context),
640  .init = encode_init,
641  .encode = encode_frame,
642  //encode_end,
643  .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
644  .long_name= NULL_IF_CONFIG_SMALL("ASUS V1"),
645 };
646 #endif
647 
648 #if CONFIG_ASV2_ENCODER
649 AVCodec ff_asv2_encoder = {
650  .name = "asv2",
651  .type = AVMEDIA_TYPE_VIDEO,
652  .id = CODEC_ID_ASV2,
653  .priv_data_size = sizeof(ASV1Context),
654  .init = encode_init,
655  .encode = encode_frame,
656  //encode_end,
657  .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
658  .long_name= NULL_IF_CONFIG_SMALL("ASUS V2"),
659 };
660 #endif