@ -25,34 +25,42 @@
* Determines the duration for each packet .
*/
# include "libavutil/log.h"
# include "get_bits.h"
# include "parser.h"
# include "xiph.h"
# include "vorbis_parser.h"
static int parse_id_header ( AVCodecContext * avctx , VorbisParseContext * s ,
static const AVClass vorbis_parser_class = {
. class_name = " Vorbis parser " ,
. item_name = av_default_item_name ,
. version = LIBAVUTIL_VERSION_INT ,
} ;
static int parse_id_header ( VorbisParseContext * s ,
const uint8_t * buf , int buf_size )
{
/* Id header should be 30 bytes */
if ( buf_size < 30 ) {
av_log ( avctx , AV_LOG_ERROR , " Id header is too short \n " ) ;
av_log ( s , AV_LOG_ERROR , " Id header is too short \n " ) ;
return AVERROR_INVALIDDATA ;
}
/* make sure this is the Id header */
if ( buf [ 0 ] ! = 1 ) {
av_log ( avctx , AV_LOG_ERROR , " Wrong packet type in Id header \n " ) ;
av_log ( s , AV_LOG_ERROR , " Wrong packet type in Id header \n " ) ;
return AVERROR_INVALIDDATA ;
}
/* check for header signature */
if ( memcmp ( & buf [ 1 ] , " vorbis " , 6 ) ) {
av_log ( avctx , AV_LOG_ERROR , " Invalid packet signature in Id header \n " ) ;
av_log ( s , AV_LOG_ERROR , " Invalid packet signature in Id header \n " ) ;
return AVERROR_INVALIDDATA ;
}
if ( ! ( buf [ 29 ] & 0x1 ) ) {
av_log ( avctx , AV_LOG_ERROR , " Invalid framing bit in Id header \n " ) ;
av_log ( s , AV_LOG_ERROR , " Invalid framing bit in Id header \n " ) ;
return AVERROR_INVALIDDATA ;
}
@ -62,7 +70,7 @@ static int parse_id_header(AVCodecContext *avctx, VorbisParseContext *s,
return 0 ;
}
static int parse_setup_header ( AVCodecContext * avctx , VorbisParseContext * s ,
static int parse_setup_header ( VorbisParseContext * s ,
const uint8_t * buf , int buf_size )
{
GetBitContext gb , gb0 ;
@ -72,25 +80,25 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s,
/* avoid overread */
if ( buf_size < 7 ) {
av_log ( avctx , AV_LOG_ERROR , " Setup header is too short \n " ) ;
av_log ( s , AV_LOG_ERROR , " Setup header is too short \n " ) ;
return AVERROR_INVALIDDATA ;
}
/* make sure this is the Setup header */
if ( buf [ 0 ] ! = 5 ) {
av_log ( avctx , AV_LOG_ERROR , " Wrong packet type in Setup header \n " ) ;
av_log ( s , AV_LOG_ERROR , " Wrong packet type in Setup header \n " ) ;
return AVERROR_INVALIDDATA ;
}
/* check for header signature */
if ( memcmp ( & buf [ 1 ] , " vorbis " , 6 ) ) {
av_log ( avctx , AV_LOG_ERROR , " Invalid packet signature in Setup header \n " ) ;
av_log ( s , AV_LOG_ERROR , " Invalid packet signature in Setup header \n " ) ;
return AVERROR_INVALIDDATA ;
}
/* reverse bytes so we can easily read backwards with get_bits() */
if ( ! ( rev_buf = av_malloc ( buf_size ) ) ) {
av_log ( avctx , AV_LOG_ERROR , " Out of memory \n " ) ;
av_log ( s , AV_LOG_ERROR , " Out of memory \n " ) ;
return AVERROR ( ENOMEM ) ;
}
for ( i = 0 ; i < buf_size ; i + + )
@ -105,7 +113,7 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s,
}
}
if ( ! got_framing_bit ) {
av_log ( avctx , AV_LOG_ERROR , " Invalid Setup header \n " ) ;
av_log ( s , AV_LOG_ERROR , " Invalid Setup header \n " ) ;
ret = AVERROR_INVALIDDATA ;
goto bad_header ;
}
@ -132,7 +140,7 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s,
}
}
if ( ! got_mode_header ) {
av_log ( avctx , AV_LOG_ERROR , " Invalid Setup header \n " ) ;
av_log ( s , AV_LOG_ERROR , " Invalid Setup header \n " ) ;
ret = AVERROR_INVALIDDATA ;
goto bad_header ;
}
@ -141,7 +149,7 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s,
* we may need to approach this the long way and parse the whole Setup
* header , but I hope very much that it never comes to that . */
if ( last_mode_count > 2 ) {
avpriv_request_sample ( avctx ,
avpriv_request_sample ( s ,
" %d modes (either a false positive or a "
" sample from an unknown encoder) " ,
last_mode_count ) ;
@ -149,7 +157,7 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s,
/* We're limiting the mode count to 63 so that we know that the previous
* block flag will be in the first packet byte . */
if ( last_mode_count > 63 ) {
av_log ( avctx , AV_LOG_ERROR , " Unsupported mode count: %d \n " ,
av_log ( s , AV_LOG_ERROR , " Unsupported mode count: %d \n " ,
last_mode_count ) ;
ret = AVERROR_INVALIDDATA ;
goto bad_header ;
@ -179,20 +187,20 @@ int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s)
int header_len [ 3 ] ;
int ret ;
s - > avctx = avctx ;
s - > class = & vorbis_parser_class ;
s - > extradata_parsed = 1 ;
if ( ( ret = avpriv_split_xiph_headers ( avctx - > extradata ,
avctx - > extradata_size , 30 ,
header_start , header_len ) ) < 0 ) {
av_log ( avctx , AV_LOG_ERROR , " Extradata corrupt. \n " ) ;
av_log ( s , AV_LOG_ERROR , " Extradata corrupt. \n " ) ;
return ret ;
}
if ( ( ret = parse_id_header ( avctx , s , header_start [ 0 ] , header_len [ 0 ] ) ) < 0 )
if ( ( ret = parse_id_header ( s , header_start [ 0 ] , header_len [ 0 ] ) ) < 0 )
return ret ;
if ( ( ret = parse_setup_header ( avctx , s , header_start [ 2 ] , header_len [ 2 ] ) ) < 0 )
if ( ( ret = parse_setup_header ( s , header_start [ 2 ] , header_len [ 2 ] ) ) < 0 )
return ret ;
s - > valid_extradata = 1 ;
@ -211,7 +219,7 @@ int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf,
int previous_blocksize = s - > previous_blocksize ;
if ( buf [ 0 ] & 1 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " Invalid packet \n " ) ;
av_log ( s , AV_LOG_ERROR , " Invalid packet \n " ) ;
return AVERROR_INVALIDDATA ;
}
if ( s - > mode_count = = 1 )
@ -219,7 +227,7 @@ int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf,
else
mode = ( buf [ 0 ] & s - > mode_mask ) > > 1 ;
if ( mode > = s - > mode_count ) {
av_log ( s - > avctx , AV_LOG_ERROR , " Invalid mode in packet \n " ) ;
av_log ( s , AV_LOG_ERROR , " Invalid mode in packet \n " ) ;
return AVERROR_INVALIDDATA ;
}
if ( mode ) {