@ -25,6 +25,7 @@
# include "libavutil/attributes.h"
# include "libavutil/mem.h"
# include "libavutil/mem_internal.h"
# include "libavutil/thread.h"
# include "asv.h"
@ -33,8 +34,10 @@
# include "codec_internal.h"
# include "config_components.h"
# include "decode.h"
# include "get_bits.h"
# include "idctdsp.h"
# include "mpeg12data.h"
# include "vlc.h"
# define CCP_VLC_BITS 5
# define DC_CCP_VLC_BITS 4
@ -48,6 +51,20 @@ static VLC dc_ccp_vlc;
static VLC ac_ccp_vlc ;
static VLC asv2_level_vlc ;
typedef struct ASVDecContext {
ASVCommonContext c ;
GetBitContext gb ;
BlockDSPContext bdsp ;
IDCTDSPContext idsp ;
ScanTable scantable ;
DECLARE_ALIGNED ( 32 , int16_t , block ) [ 6 ] [ 64 ] ;
uint16_t intra_matrix [ 64 ] ;
uint8_t * bitstream_buffer ;
unsigned int bitstream_buffer_size ;
} ASVDecContext ;
static av_cold void init_vlcs ( void )
{
INIT_VLC_STATIC ( & ccp_vlc , CCP_VLC_BITS , 17 ,
@ -106,7 +123,7 @@ static inline int asv2_get_level(GetBitContext *gb)
return code - 31 ;
}
static inline int asv1_decode_block ( ASV1 Context * a , int16_t block [ 64 ] )
static inline int asv1_decode_block ( ASVDec Context * a , int16_t block [ 64 ] )
{
int i ;
@ -119,7 +136,7 @@ static inline int asv1_decode_block(ASV1Context *a, int16_t block[64])
if ( ccp = = 16 )
break ;
if ( ccp < 0 | | i > = 10 ) {
av_log ( a - > avctx , AV_LOG_ERROR , " coded coeff pattern damaged \n " ) ;
av_log ( a - > c . avctx , AV_LOG_ERROR , " coded coeff pattern damaged \n " ) ;
return AVERROR_INVALIDDATA ;
}
@ -137,7 +154,7 @@ static inline int asv1_decode_block(ASV1Context *a, int16_t block[64])
return 0 ;
}
static inline int asv2_decode_block ( ASV1 Context * a , int16_t block [ 64 ] )
static inline int asv2_decode_block ( ASVDec Context * a , int16_t block [ 64 ] )
{
int i , count , ccp ;
@ -173,13 +190,13 @@ static inline int asv2_decode_block(ASV1Context *a, int16_t block[64])
return 0 ;
}
static inline int decode_mb ( ASV1 Context * a , int16_t block [ 6 ] [ 64 ] )
static inline int decode_mb ( ASVDec Context * a , int16_t block [ 6 ] [ 64 ] )
{
int i , ret ;
a - > bdsp . clear_blocks ( block [ 0 ] ) ;
if ( a - > avctx - > codec_id = = AV_CODEC_ID_ASV1 ) {
if ( a - > c . avctx - > codec_id = = AV_CODEC_ID_ASV1 ) {
for ( i = 0 ; i < 6 ; i + + ) {
if ( ( ret = asv1_decode_block ( a , block [ i ] ) ) < 0 )
return ret ;
@ -193,7 +210,7 @@ static inline int decode_mb(ASV1Context *a, int16_t block[6][64])
return 0 ;
}
static inline void idct_put ( ASV1 Context * a , AVFrame * frame , int mb_x , int mb_y )
static inline void idct_put ( ASVDec Context * a , AVFrame * frame , int mb_x , int mb_y )
{
int16_t ( * block ) [ 64 ] = a - > block ;
int linesize = frame - > linesize [ 0 ] ;
@ -207,7 +224,7 @@ static inline void idct_put(ASV1Context *a, AVFrame *frame, int mb_x, int mb_y)
a - > idsp . idct_put ( dest_y + 8 * linesize , linesize , block [ 2 ] ) ;
a - > idsp . idct_put ( dest_y + 8 * linesize + 8 , linesize , block [ 3 ] ) ;
if ( ! ( a - > avctx - > flags & AV_CODEC_FLAG_GRAY ) ) {
if ( ! ( a - > c . avctx - > flags & AV_CODEC_FLAG_GRAY ) ) {
a - > idsp . idct_put ( dest_cb , frame - > linesize [ 1 ] , block [ 4 ] ) ;
a - > idsp . idct_put ( dest_cr , frame - > linesize [ 2 ] , block [ 5 ] ) ;
}
@ -216,12 +233,13 @@ static inline void idct_put(ASV1Context *a, AVFrame *frame, int mb_x, int mb_y)
static int decode_frame ( AVCodecContext * avctx , AVFrame * p ,
int * got_frame , AVPacket * avpkt )
{
ASV1Context * const a = avctx - > priv_data ;
ASVDecContext * const a = avctx - > priv_data ;
const ASVCommonContext * const c = & a - > c ;
const uint8_t * buf = avpkt - > data ;
int buf_size = avpkt - > size ;
int mb_x , mb_y , ret ;
int ret ;
if ( buf_size * 8LL < a - > mb_height * a - > mb_width * 13LL )
if ( buf_size * 8LL < c - > mb_height * c - > mb_width * 13LL )
return AVERROR_INVALIDDATA ;
if ( ( ret = ff_get_buffer ( avctx , p , 0 ) ) < 0 )
@ -235,7 +253,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
if ( ! a - > bitstream_buffer )
return AVERROR ( ENOMEM ) ;
a - > bbdsp . bswap_buf ( ( uint32_t * ) a - > bitstream_buffer ,
c - > bbdsp . bswap_buf ( ( uint32_t * ) a - > bitstream_buffer ,
( const uint32_t * ) buf , buf_size / 4 ) ;
ret = init_get_bits8 ( & a - > gb , a - > bitstream_buffer , buf_size ) ;
} else {
@ -244,8 +262,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
if ( ret < 0 )
return ret ;
for ( mb_y = 0 ; mb_y < a - > mb_height2 ; mb_y + + ) {
for ( mb_x = 0 ; mb_x < a - > mb_width2 ; mb_x + + ) {
for ( int mb_y = 0 ; mb_y < c - > mb_height2 ; mb_y + + ) {
for ( int mb_x = 0 ; mb_x < c - > mb_width2 ; mb_x + + ) {
if ( ( ret = decode_mb ( a , a - > block ) ) < 0 )
return ret ;
@ -253,9 +271,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
}
}
if ( a - > mb_width2 ! = a - > mb_width ) {
mb_x = a - > mb_width2 ;
for ( mb_y = 0 ; mb_y < a - > mb_height2 ; mb_y + + ) {
if ( c - > mb_width2 ! = c - > mb_width ) {
int mb_x = c - > mb_width2 ;
for ( int mb_y = 0 ; mb_y < c - > mb_height2 ; mb_y + + ) {
if ( ( ret = decode_mb ( a , a - > block ) ) < 0 )
return ret ;
@ -263,9 +281,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
}
}
if ( a - > mb_height2 ! = a - > mb_height ) {
mb_y = a - > mb_height2 ;
for ( mb_x = 0 ; mb_x < a - > mb_width ; mb_x + + ) {
if ( c - > mb_height2 ! = c - > mb_height ) {
int mb_y = c - > mb_height2 ;
for ( int mb_x = 0 ; mb_x < c - > mb_width ; mb_x + + ) {
if ( ( ret = decode_mb ( a , a - > block ) ) < 0 )
return ret ;
@ -283,8 +301,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
static av_cold int decode_init ( AVCodecContext * avctx )
{
static AVOnce init_static_once = AV_ONCE_INIT ;
ASV1 Context * const a = avctx - > priv_data ;
ASVDec Context * const a = avctx - > priv_data ;
const int scale = avctx - > codec_id = = AV_CODEC_ID_ASV1 ? 1 : 2 ;
int inv_qscale ;
int i ;
if ( avctx - > extradata_size < 1 ) {
@ -297,19 +316,19 @@ static av_cold int decode_init(AVCodecContext *avctx)
ff_init_scantable ( a - > idsp . idct_permutation , & a - > scantable , ff_asv_scantab ) ;
avctx - > pix_fmt = AV_PIX_FMT_YUV420P ;
if ( avctx - > extradata_size < 1 | | ( a - > inv_qscale = avctx - > extradata [ 0 ] ) = = 0 ) {
if ( avctx - > extradata_size < 1 | | ( inv_qscale = avctx - > extradata [ 0 ] ) = = 0 ) {
av_log ( avctx , AV_LOG_ERROR , " illegal qscale 0 \n " ) ;
if ( avctx - > codec_id = = AV_CODEC_ID_ASV1 )
a - > inv_qscale = 6 ;
inv_qscale = 6 ;
else
a - > inv_qscale = 10 ;
inv_qscale = 10 ;
}
for ( i = 0 ; i < 64 ; i + + ) {
int index = ff_asv_scantab [ i ] ;
a - > intra_matrix [ i ] = 64 * scale * ff_mpeg1_default_intra_matrix [ index ] /
a - > inv_qscale ;
inv_qscale ;
}
ff_thread_once ( & init_static_once , init_vlcs ) ;
@ -319,7 +338,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
static av_cold int decode_end ( AVCodecContext * avctx )
{
ASV1 Context * const a = avctx - > priv_data ;
ASVDec Context * const a = avctx - > priv_data ;
av_freep ( & a - > bitstream_buffer ) ;
a - > bitstream_buffer_size = 0 ;
@ -333,7 +352,7 @@ const FFCodec ff_asv1_decoder = {
CODEC_LONG_NAME ( " ASUS V1 " ) ,
. p . type = AVMEDIA_TYPE_VIDEO ,
. p . id = AV_CODEC_ID_ASV1 ,
. priv_data_size = sizeof ( ASV1 Context ) ,
. priv_data_size = sizeof ( ASVDec Context ) ,
. init = decode_init ,
. close = decode_end ,
FF_CODEC_DECODE_CB ( decode_frame ) ,
@ -347,7 +366,7 @@ const FFCodec ff_asv2_decoder = {
CODEC_LONG_NAME ( " ASUS V2 " ) ,
. p . type = AVMEDIA_TYPE_VIDEO ,
. p . id = AV_CODEC_ID_ASV2 ,
. priv_data_size = sizeof ( ASV1 Context ) ,
. priv_data_size = sizeof ( ASVDec Context ) ,
. init = decode_init ,
FF_CODEC_DECODE_CB ( decode_frame ) ,
. p . capabilities = AV_CODEC_CAP_DR1 ,