# HG changeset patch # User michaelni # Date 1036780539 0 # Node ID e460775adb38bf6dcaa980354bc0ff75aecaeadc # Parent 4033915880d9db9505e81659262e2a94c90f70ff cleanup (breaks compatibility, requested by fabrice) remove CODEC_FLAG_NOT_TRUNCATED & add CODEC_FLAG_TRUNCATED add CODEC_CAP_TRUNCATED add alpha plane to AVPicture remove CODEC_ID_MSMPEG4 remove various unused stuff support "truncated" mpeg4 streams diff -r 4033915880d9 -r e460775adb38 avcodec.h --- a/avcodec.h Wed Nov 06 11:59:17 2002 +0000 +++ b/avcodec.h Fri Nov 08 18:35:39 2002 +0000 @@ -5,8 +5,8 @@ #define LIBAVCODEC_VERSION_INT 0x000406 #define LIBAVCODEC_VERSION "0.4.6" -#define LIBAVCODEC_BUILD 4634 -#define LIBAVCODEC_BUILD_STR "4634" +#define LIBAVCODEC_BUILD 4635 +#define LIBAVCODEC_BUILD_STR "4635" enum CodecID { CODEC_ID_NONE, @@ -50,7 +50,6 @@ CODEC_ID_ADPCM_IMA_WAV, CODEC_ID_ADPCM_MS, }; -#define CODEC_ID_MSMPEG4 CODEC_ID_MSMPEG4V3 enum CodecType { CODEC_TYPE_UNKNOWN = -1, @@ -80,6 +79,12 @@ /* in bytes */ #define AVCODEC_MAX_AUDIO_FRAME_SIZE 131072 +/** + * Required number of zero bytes at the end of the input bitstream for decoding. + * to avoid overreading (and possibly segfaulting) + */ +#define FF_INPUT_BUFFER_PADDING_SIZE 8 + /* motion estimation type, EPZS by default */ enum Motion_Est_ID { ME_ZERO = 1, @@ -128,8 +133,8 @@ #define CODEC_FLAG_GRAY 0x2000 /* only decode/encode grayscale */ #define CODEC_FLAG_EMU_EDGE 0x4000/* dont draw edges */ #define CODEC_FLAG_DR1 0x8000 /* direct renderig type 1 (store internal frames in external buffers) */ -#define CODEC_FLAG_NOT_TRUNCATED 0x00010000 /* input bitstream is not truncated, except before a startcode - allows the last part of a frame to be decoded earlier */ +#define CODEC_FLAG_TRUNCATED 0x00010000 /* input bitstream might be truncated at a random location instead + of only at frame boundaries */ #define CODEC_FLAG_NORMALIZE_AQP 0x00020000 /* normalize adaptive quantization */ #define CODEC_FLAG_INTERLACED_DCT 0x00040000 /* use interlaced dct */ #define CODEC_FLAG_LOW_DELAY 0x00080000 /* force low delay / will fail on b frames */ @@ -141,6 +146,7 @@ /* if 'parse_only' field is true, then avcodec_parse_frame() can be used */ #define CODEC_CAP_PARSE_ONLY 0x0004 +#define CODEC_CAP_TRUNCATED 0x0008 #define FRAME_RATE_BASE 10000 @@ -770,10 +776,13 @@ struct AVCodec *next; } AVCodec; -/* three components are given, that's all */ +/** + * four components are given, that's all. + * the last component is alpha + */ typedef struct AVPicture { - UINT8 *data[3]; - int linesize[3]; + UINT8 *data[4]; + int linesize[4]; } AVPicture; extern AVCodec ac3_encoder; @@ -925,13 +934,6 @@ void avcodec_flush_buffers(AVCodecContext *avctx); -// deprecated / obsolete stuff, WILL be removed -#ifndef MBC -#define MBC 128 -#define MBR 96 -#endif -#define QP_TYPE int - /** * Interface for 0.5.0 version * diff -r 4033915880d9 -r e460775adb38 h263dec.c --- a/h263dec.c Wed Nov 06 11:59:17 2002 +0000 +++ b/h263dec.c Fri Nov 08 18:35:39 2002 +0000 @@ -125,9 +125,14 @@ */ static int get_consumed_bytes(MpegEncContext *s, int buf_size){ int pos= (get_bits_count(&s->gb)+7)>>3; + if(s->divx_version>=500){ //we would have to scan through the whole buf to handle the weird reordering ... return buf_size; + }else if(s->flags&CODEC_FLAG_TRUNCATED){ + pos -= s->parse_context.last_index; + if(pos<0) pos=0; // padding is not really read so this might be -1 + return pos; }else{ if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...) if(pos+10>buf_size) pos=buf_size; // oops ;) @@ -299,6 +304,43 @@ return -1; } +/** + * finds the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +static int mpeg4_find_frame_end(MpegEncContext *s, UINT8 *buf, int buf_size){ + ParseContext *pc= &s->parse_context; + int vop_found, i; + uint32_t state; + + vop_found= pc->frame_start_found; + state= pc->state; + + i=0; + if(!vop_found){ + for(i=0; iframe_start_found=0; + pc->state=-1; + return i-3; + } + } + pc->frame_start_found= vop_found; + pc->state= state; + return -1; +} + static int h263_decode_frame(AVCodecContext *avctx, void *data, int *data_size, UINT8 *buf, int buf_size) @@ -325,6 +367,42 @@ if (buf_size == 0) { return 0; } + + if(s->flags&CODEC_FLAG_TRUNCATED){ + int next; + ParseContext *pc= &s->parse_context; + + pc->last_index= pc->index; + + if(s->codec_id==CODEC_ID_MPEG4){ + next= mpeg4_find_frame_end(s, buf, buf_size); + }else{ + fprintf(stderr, "this codec doesnt support truncated bitstreams\n"); + return -1; + } + if(next==-1){ + if(buf_size + FF_INPUT_BUFFER_PADDING_SIZE + pc->index > pc->buffer_size){ + pc->buffer_size= buf_size + pc->index + 10*1024; + pc->buffer= realloc(pc->buffer, pc->buffer_size); + } + + memcpy(&pc->buffer[pc->index], buf, buf_size); + pc->index += buf_size; + return buf_size; + } + + if(pc->index){ + if(next + FF_INPUT_BUFFER_PADDING_SIZE + pc->index > pc->buffer_size){ + pc->buffer_size= next + pc->index + 10*1024; + pc->buffer= realloc(pc->buffer, pc->buffer_size); + } + + memcpy(&pc->buffer[pc->index], buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); + pc->index = 0; + buf= pc->buffer; + buf_size= pc->last_index + next; + } + } retry: @@ -627,7 +705,7 @@ NULL, h263_decode_end, h263_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, + CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, }; AVCodec h263_decoder = { diff -r 4033915880d9 -r e460775adb38 mpeg12.c --- a/mpeg12.c Wed Nov 06 11:59:17 2002 +0000 +++ b/mpeg12.c Fri Nov 08 18:35:39 2002 +0000 @@ -1876,7 +1876,7 @@ } else { memcpy(s->buf_ptr, buf_start, len); s->buf_ptr += len; - if( (s2->flags&CODEC_FLAG_NOT_TRUNCATED) && (!start_code_found) + if( (!(s2->flags&CODEC_FLAG_TRUNCATED)) && (!start_code_found) && s->buf_ptr+4buffer+s->buffer_size){ start_code_found= 1; code= 0x1FF; @@ -1971,5 +1971,5 @@ NULL, mpeg_decode_end, mpeg_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, + CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, }; diff -r 4033915880d9 -r e460775adb38 mpegvideo.c --- a/mpegvideo.c Wed Nov 06 11:59:17 2002 +0000 +++ b/mpegvideo.c Fri Nov 08 18:35:39 2002 +0000 @@ -445,6 +445,8 @@ s->block= s->blocks[0]; + s->parse_context.state= -1; + s->context_initialized = 1; return 0; fail: diff -r 4033915880d9 -r e460775adb38 mpegvideo.h --- a/mpegvideo.h Wed Nov 06 11:59:17 2002 +0000 +++ b/mpegvideo.h Fri Nov 08 18:35:39 2002 +0000 @@ -109,6 +109,15 @@ #endif } ScanTable; +typedef struct ParseContext{ + UINT8 *buffer; + int index; + int last_index; + int buffer_size; + int state; + int frame_start_found; +} ParseContext; + typedef struct MpegEncContext { struct AVCodecContext *avctx; /* the following parameters must be initialized before encoding */ @@ -351,6 +360,8 @@ int mb_num_left; /* number of MBs left in this video packet (for partitioned Slices only)*/ int next_p_frame_damaged; /* set if the next p frame is damaged, to avoid showing trashed b frames */ int error_resilience; + + ParseContext parse_context; /* H.263 specific */ int gob_number;