diff options
author | Mike Melanson <mike@multimedia.cx> | 2003-05-09 00:25:49 +0000 |
---|---|---|
committer | Mike Melanson <mike@multimedia.cx> | 2003-05-09 00:25:49 +0000 |
commit | 1cc910726e54d912f7aaa8e9b8bf2cbfb4c16fff (patch) | |
tree | e4a1118306b795a660107d1ffb625734a62ed37b | |
parent | 4b55f2a805638a3d817a6df37c5540243887274a (diff) | |
download | xine-lib-1cc910726e54d912f7aaa8e9b8bf2cbfb4c16fff.tar.gz xine-lib-1cc910726e54d912f7aaa8e9b8bf2cbfb4c16fff.tar.bz2 |
routine ffmpeg tree sync; also, remove motion_est.c and ratecontrol.c
from the Makefile
CVS patchset: 4803
CVS date: 2003/05/09 00:25:49
-rw-r--r-- | src/libffmpeg/libavcodec/Makefile.am | 2 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/avcodec.h | 67 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/dsputil.c | 32 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/dsputil.h | 26 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/dv.c | 25 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/h264.c | 5 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/huffyuv.c | 56 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/mpegvideo.c | 89 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/mpegvideo.h | 5 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/utils.c | 108 |
10 files changed, 292 insertions, 123 deletions
diff --git a/src/libffmpeg/libavcodec/Makefile.am b/src/libffmpeg/libavcodec/Makefile.am index d0742bd9c..e9b5aa0ae 100644 --- a/src/libffmpeg/libavcodec/Makefile.am +++ b/src/libffmpeg/libavcodec/Makefile.am @@ -39,13 +39,11 @@ libavcodec_la_SOURCES = \ mace.c \ mem.c \ mjpeg.c \ - motion_est.c \ mpeg12.c \ mpegaudiodec.c \ mpegvideo.c \ msmpeg4.c \ opts.c \ - ratecontrol.c \ rv10.c \ simple_idct.c \ svq1.c \ diff --git a/src/libffmpeg/libavcodec/avcodec.h b/src/libffmpeg/libavcodec/avcodec.h index d3c2bb13d..6e7532874 100644 --- a/src/libffmpeg/libavcodec/avcodec.h +++ b/src/libffmpeg/libavcodec/avcodec.h @@ -15,8 +15,8 @@ extern "C" { #define LIBAVCODEC_VERSION_INT 0x000406 #define LIBAVCODEC_VERSION "0.4.6" -#define LIBAVCODEC_BUILD 4663 -#define LIBAVCODEC_BUILD_STR "4663" +#define LIBAVCODEC_BUILD 4666 +#define LIBAVCODEC_BUILD_STR "4666" #define LIBAVCODEC_IDENT "FFmpeg" LIBAVCODEC_VERSION "b" LIBAVCODEC_BUILD_STR @@ -93,6 +93,9 @@ enum PixelFormat { PIX_FMT_MONOWHITE, ///< 0 is white PIX_FMT_MONOBLACK, ///< 0 is black PIX_FMT_PAL8, ///< 8 bit with RGBA palette + PIX_FMT_YUVJ420P, ///< YUV full scale (jpeg) + PIX_FMT_YUVJ422P, ///< YUV full scale (jpeg) + PIX_FMT_YUVJ444P, ///< YUV full scale (jpeg) PIX_FMT_NB, }; @@ -182,7 +185,11 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG, /* codec capabilities */ #define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< decoder can use draw_horiz_band callback -#define CODEC_CAP_DR1 0x0002 ///< direct rendering method 1 +/** + * Codec uses get_buffer() for allocating buffers. + * direct rendering method 1 + */ +#define CODEC_CAP_DR1 0x0002 /* if 'parse_only' field is true, then avcodec_parse_frame() can be used */ #define CODEC_CAP_PARSE_ONLY 0x0004 @@ -310,8 +317,15 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG, * - encoding: unused\ * - decoding: set by lavc\ */\ - int repeat_pict; + int repeat_pict;\ + \ + /**\ + * \ + */\ + int qscale_type;\ +#define FF_QSCALE_TYPE_MPEG1 0 +#define FF_QSCALE_TYPE_MPEG2 1 #define FF_BUFFER_TYPE_INTERNAL 1 #define FF_BUFFER_TYPE_USER 2 ///< Direct rendering buffers @@ -1066,7 +1080,26 @@ typedef struct AVCodecContext { * - decoding: unused */ int inter_quant_bias; + + /** + * color table ID. + * - encoding: unused. + * - decoding: which clrtable should be used for 8bit RGB images + * table have to be stored somewhere FIXME + */ + int color_table_id; + /** + * internal_buffer count. + * Dont touch, used by lavc default_get_buffer() + */ + int internal_buffer_count; + + /** + * internal_buffers. + * Dont touch, used by lavc default_get_buffer() + */ + void *internal_buffer; } AVCodecContext; @@ -1119,7 +1152,7 @@ int avoption_parse(void* strct, const AVOption* list, const char* opts); */ typedef struct AVCodec { const char *name; - int type; + enum CodecType type; int id; int priv_data_size; int (*init)(AVCodecContext *); @@ -1185,6 +1218,7 @@ extern AVCodec oggvorbis_decoder; extern AVCodec cyuv_decoder; extern AVCodec h264_decoder; extern AVCodec indeo3_decoder; +extern AVCodec vp3_decoder; /* pcm codecs */ #define PCM_CODEC(id, name) \ @@ -1209,7 +1243,8 @@ PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms); #undef PCM_CODEC /* dummy raw video codec */ -extern AVCodec rawvideo_codec; +extern AVCodec rawvideo_encoder; +extern AVCodec rawvideo_decoder; /* the following codecs use external GPL libs */ extern AVCodec ac3_decoder; @@ -1246,9 +1281,28 @@ void img_resample_close(ImgReSampleContext *s); int avpicture_fill(AVPicture *picture, uint8_t *ptr, int pix_fmt, int width, int height); +int avpicture_layout(AVPicture* src, int pix_fmt, int width, int height, + unsigned char *dest, int dest_size); int avpicture_get_size(int pix_fmt, int width, int height); void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift); const char *avcodec_get_pix_fmt_name(int pix_fmt); +enum PixelFormat avcodec_get_pix_fmt(const char* name); + +#define FF_LOSS_RESOLUTION 0x0001 /* loss due to resolution change */ +#define FF_LOSS_DEPTH 0x0002 /* loss due to color depth change */ +#define FF_LOSS_COLORSPACE 0x0004 /* loss due to color space conversion */ +#define FF_LOSS_ALPHA 0x0008 /* loss of alpha bits */ +#define FF_LOSS_COLORQUANT 0x0010 /* loss due to color quantization */ +#define FF_LOSS_CHROMA 0x0020 /* loss of chroma (e.g. rgb to gray conversion) */ + +int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, + int has_alpha); +int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt, + int has_alpha, int *loss_ptr); + +#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */ +#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */ +int img_get_alpha_info(AVPicture *src, int pix_fmt, int width, int height); /* convert among pixel formats */ int img_convert(AVPicture *dst, int dst_pix_fmt, @@ -1282,6 +1336,7 @@ AVFrame *avcodec_alloc_frame(void); int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic); void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic); +void avcodec_default_free_buffers(AVCodecContext *s); int avcodec_open(AVCodecContext *avctx, AVCodec *codec); int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, diff --git a/src/libffmpeg/libavcodec/dsputil.c b/src/libffmpeg/libavcodec/dsputil.c index 146a657dd..b9a5f1382 100644 --- a/src/libffmpeg/libavcodec/dsputil.c +++ b/src/libffmpeg/libavcodec/dsputil.c @@ -2489,26 +2489,28 @@ static void ff_jref_idct_add(uint8_t *dest, int line_size, DCTELEM *block) add_pixels_clamped_c(block, dest, line_size); } -void dsputil_init(DSPContext* c, AVCodecContext *avctx) +/* init static data */ +void dsputil_static_init(void) { - static int init_done = 0; int i; - if (!init_done) { - for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i; - for(i=0;i<MAX_NEG_CROP;i++) { - cropTbl[i] = 0; - cropTbl[i + MAX_NEG_CROP + 256] = 255; - } - - for(i=0;i<512;i++) { - squareTbl[i] = (i - 256) * (i - 256); - } + for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i; + for(i=0;i<MAX_NEG_CROP;i++) { + cropTbl[i] = 0; + cropTbl[i + MAX_NEG_CROP + 256] = 255; + } + + for(i=0;i<512;i++) { + squareTbl[i] = (i - 256) * (i - 256); + } + + for(i=0; i<64; i++) inv_zigzag_direct16[ff_zigzag_direct[i]]= i+1; +} - for(i=0; i<64; i++) inv_zigzag_direct16[ff_zigzag_direct[i]]= i+1; - init_done = 1; - } +void dsputil_init(DSPContext* c, AVCodecContext *avctx) +{ + int i; #ifdef CONFIG_ENCODERS if(avctx->dct_algo==FF_DCT_FASTINT) diff --git a/src/libffmpeg/libavcodec/dsputil.h b/src/libffmpeg/libavcodec/dsputil.h index 14ea882b3..e4a524d8d 100644 --- a/src/libffmpeg/libavcodec/dsputil.h +++ b/src/libffmpeg/libavcodec/dsputil.h @@ -20,6 +20,8 @@ /** * @file dsputil.h * DSP utils. + * note, many functions in here may use MMX which trashes the FPU state, it is + * absolutely necessary to call emms_c() between dsp & float/double code */ #ifndef DSPUTIL_H @@ -27,14 +29,17 @@ #include "common.h" #include "avcodec.h" + + #include "xineutils.h" #if defined(ARCH_X86) -#define HAVE_MMX 1 +#define HAVE_MMX 1 #endif #undef DEBUG +//#define DEBUG /* dct code */ typedef short DCTELEM; //typedef int DCTELEM; @@ -152,7 +157,9 @@ typedef struct DSPContext { /* maybe create an array for 16/8 functions */ /** * Halfpel motion compensation with rounding (a+b+1)>>1. - * *pixels_tab[ 0->16x16 1->8x8 ][ xhalfpel + 2*yhalfpel ] + * this is an array[2][4] of motion compensation funcions for 2 + * horizontal blocksizes (8,16) and the 4 halfpel positions<br> + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * @param block destination where the result is stored * @param pixels source * @param line_size number of bytes in a horizontal line of block @@ -162,7 +169,9 @@ typedef struct DSPContext { /** * Halfpel motion compensation with rounding (a+b+1)>>1. - * *pixels_tab[ 0->16x16 1->8x8 ][ xhalfpel + 2*yhalfpel ] + * this is an array[2][4] of motion compensation funcions for 2 + * horizontal blocksizes (8,16) and the 4 halfpel positions<br> + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * @param block destination into which the result is averaged (a+b+1)>>1 * @param pixels source * @param line_size number of bytes in a horizontal line of block @@ -172,7 +181,9 @@ typedef struct DSPContext { /** * Halfpel motion compensation with no rounding (a+b)>>1. - * *pixels_tab[ 0->16x16 1->8x8 ][ xhalfpel + 2*yhalfpel ] + * this is an array[2][4] of motion compensation funcions for 2 + * horizontal blocksizes (8,16) and the 4 halfpel positions<br> + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * @param block destination where the result is stored * @param pixels source * @param line_size number of bytes in a horizontal line of block @@ -182,7 +193,9 @@ typedef struct DSPContext { /** * Halfpel motion compensation with no rounding (a+b)>>1. - * *pixels_tab[ 0->16x16 1->8x8 ][ xhalfpel + 2*yhalfpel ] + * this is an array[2][4] of motion compensation funcions for 2 + * horizontal blocksizes (8,16) and the 4 halfpel positions<br> + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * @param block destination into which the result is averaged (a+b)>>1 * @param pixels source * @param line_size number of bytes in a horizontal line of block @@ -250,6 +263,7 @@ typedef struct DSPContext { } DSPContext; +void dsputil_static_init(void); void dsputil_init(DSPContext* p, AVCodecContext *avctx); /** @@ -286,7 +300,7 @@ extern int mm_flags; void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); -#if 0 +#if 0 static inline void emms(void) { __asm __volatile ("emms;":::"memory"); diff --git a/src/libffmpeg/libavcodec/dv.c b/src/libffmpeg/libavcodec/dv.c index eb8dbb7c0..32d4c3a27 100644 --- a/src/libffmpeg/libavcodec/dv.c +++ b/src/libffmpeg/libavcodec/dv.c @@ -278,7 +278,7 @@ static void dv_decode_ac(DVVideoDecodeContext *s, if (pos >= 64) { read_error: #if defined(VLC_DEBUG) || 1 - printf("error pos=%d\n", pos); + fprintf(stderr, "error pos=%d\n", pos); #endif /* for errors, we consider the eob is reached */ mb->eob_reached = 1; @@ -538,16 +538,17 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, width = 720; if (dsf) { avctx->frame_rate = 25; + avctx->frame_rate_base = 1; packet_size = PAL_FRAME_SIZE; height = 576; nb_dif_segs = 12; } else { - avctx->frame_rate = 30; + avctx->frame_rate = 30000; + avctx->frame_rate_base = 1001; packet_size = NTSC_FRAME_SIZE; height = 480; nb_dif_segs = 10; } - avctx->frame_rate_base= 1; /* NOTE: we only accept several full frames */ if (buf_size < packet_size) return -1; @@ -579,6 +580,9 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, else avctx->aspect_ratio = 4.0 / 3.0; + if(s->picture.data[0]) + avctx->release_buffer(avctx, &s->picture); + s->picture.reference= 0; if(avctx->get_buffer(avctx, &s->picture) < 0) { fprintf(stderr, "get_buffer() failed\n"); @@ -616,23 +620,14 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, *data_size = sizeof(AVFrame); *(AVFrame*)data= s->picture; - avctx->release_buffer(avctx, &s->picture); - return packet_size; } static int dvvideo_decode_end(AVCodecContext *avctx) { DVVideoDecodeContext *s = avctx->priv_data; - int i; - - if(avctx->get_buffer == avcodec_default_get_buffer){ - for(i=0; i<4; i++){ - av_freep(&s->picture.base[i]); - s->picture.data[i]= NULL; - } - av_freep(&s->picture.opaque); - } + + avcodec_default_free_buffers(avctx); return 0; } @@ -730,8 +725,8 @@ static int dvaudio_decode_frame(AVCodecContext *avctx, avctx->sample_rate = dv_audio_frequency[freq]; avctx->channels = 2; + avctx->bit_rate = avctx->channels * avctx->sample_rate * 16; // What about: - // avctx->bit_rate = // avctx->frame_size = *data_size = (dv_audio_min_samples[sys][freq] + smpls) * diff --git a/src/libffmpeg/libavcodec/h264.c b/src/libffmpeg/libavcodec/h264.c index 31cb74963..5acce0d83 100644 --- a/src/libffmpeg/libavcodec/h264.c +++ b/src/libffmpeg/libavcodec/h264.c @@ -3868,6 +3868,7 @@ fprintf(stderr, "FMO not supported\n"); |) | | | | slice_group_id[ i ] |1 |u(v) | #endif + break; } } pps->ref_count[0]= get_ue_golomb(&s->gb) + 1; @@ -3942,7 +3943,7 @@ static int find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){ } pc->state= state; - return -1; + return END_NOT_FOUND; } static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ @@ -4366,6 +4367,6 @@ AVCodec h264_decoder = { NULL, decode_end, decode_frame, - /*CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | */CODEC_CAP_TRUNCATED, + /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, }; diff --git a/src/libffmpeg/libavcodec/huffyuv.c b/src/libffmpeg/libavcodec/huffyuv.c index ea4d26943..1ab31a933 100644 --- a/src/libffmpeg/libavcodec/huffyuv.c +++ b/src/libffmpeg/libavcodec/huffyuv.c @@ -170,6 +170,8 @@ static inline void add_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *d *left= l; *left_top= lt; } + +#ifdef CONFIG_ENCODERS //FIXME optimize static inline void sub_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top){ int i; @@ -189,6 +191,7 @@ static inline void sub_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *s *left_top= lt; } +#endif //CONFIG_ENCODERS static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){ int i; @@ -212,6 +215,7 @@ static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, *blue= b; } +#ifdef CONFIG_ENCODERS static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){ int i; if(w<32){ @@ -231,7 +235,7 @@ static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src return src[w-1]; } } - +#endif //CONFIG_ENCODERS static void read_len_table(uint8_t *dst, GetBitContext *gb){ int i, val, repeat; @@ -266,6 +270,8 @@ static int generate_bits_table(uint32_t *dst, uint8_t *len_table){ return 0; } +#ifdef CONFIG_ENCODERS + static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){ uint64_t counts[2*size]; int up[2*size]; @@ -322,6 +328,8 @@ static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){ } } +#endif //CONFIG_ENCODERS + static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){ GetBitContext gb; int i; @@ -472,6 +480,8 @@ s->bgr32=1; return 0; } +#ifdef CONFIG_ENCODERS + static void store_table(HYuvContext *s, uint8_t *len){ int i; int index= s->avctx->extradata_size; @@ -585,17 +595,19 @@ static int encode_init(AVCodecContext *avctx) s->stats[i][j]= 0; s->interlaced= height > 288; - + // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced); - + s->picture_number=0; - + return 0; } +#endif //CONFIG_ENCODERS + static void decode_422_bitstream(HYuvContext *s, int count){ int i; - + count/=2; for(i=0; i<count; i++){ @@ -617,6 +629,8 @@ static void decode_gray_bitstream(HYuvContext *s, int count){ } } +#ifdef CONFIG_ENCODERS + static void encode_422_bitstream(HYuvContext *s, int count){ int i; @@ -655,9 +669,11 @@ static void encode_gray_bitstream(HYuvContext *s, int count){ } } +#endif //CONFIG_ENCODERS + static void decode_bgr_bitstream(HYuvContext *s, int count){ int i; - + if(s->decorrelate){ if(s->bitstream_bpp==24){ for(i=0; i<count; i++){ @@ -737,6 +753,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 init_get_bits(&s->gb, s->bitstream_buffer, buf_size*8); + if(p->data[0]) + avctx->release_buffer(avctx, p); + p->reference= 0; if(avctx->get_buffer(avctx, p) < 0){ fprintf(stderr, "get_buffer() failed\n"); @@ -943,9 +962,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 emms_c(); *picture= *p; - - avctx->release_buffer(avctx, p); - *data_size = sizeof(AVFrame); return (get_bits_count(&s->gb)+31)/32*4; @@ -959,18 +975,14 @@ static int decode_end(AVCodecContext *avctx) for(i=0; i<3; i++){ free_vlc(&s->vlc[i]); } - - if(avctx->get_buffer == avcodec_default_get_buffer){ - for(i=0; i<4; i++){ - av_freep(&s->picture.base[i]); - s->picture.data[i]= NULL; - } - av_freep(&s->picture.opaque); - } + + avcodec_default_free_buffers(avctx); return 0; } +#ifdef CONFIG_ENCODERS + static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ HYuvContext *s = avctx->priv_data; AVFrame *pict = data; @@ -1132,6 +1144,8 @@ static int encode_end(AVCodecContext *avctx) return 0; } +#endif //CONFIG_ENCODERS + static const AVOption huffyuv_options[] = { AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0), @@ -1151,6 +1165,8 @@ AVCodec huffyuv_decoder = { NULL }; +#ifdef CONFIG_ENCODERS + AVCodec huffyuv_encoder = { "huffyuv", CODEC_TYPE_VIDEO, @@ -1159,7 +1175,7 @@ AVCodec huffyuv_encoder = { encode_init, encode_frame, encode_end, - NULL, - 0, - huffyuv_options, + .options = huffyuv_options, }; + +#endif //CONFIG_ENCODERS
\ No newline at end of file diff --git a/src/libffmpeg/libavcodec/mpegvideo.c b/src/libffmpeg/libavcodec/mpegvideo.c index c576695f3..ea24c2a48 100644 --- a/src/libffmpeg/libavcodec/mpegvideo.c +++ b/src/libffmpeg/libavcodec/mpegvideo.c @@ -34,7 +34,8 @@ #include "fastmemcpy.h" #endif -#define CONFIG_RISKY +//#undef NDEBUG +//#include <assert.h> #ifdef CONFIG_ENCODERS static void encode_picture(MpegEncContext *s, int picture_number); @@ -304,15 +305,8 @@ static void free_picture(MpegEncContext *s, Picture *pic){ av_freep(&pic->motion_val[i]); av_freep(&pic->ref_index[i]); } - - if(pic->type == FF_BUFFER_TYPE_INTERNAL){ - for(i=0; i<4; i++){ - av_freep(&pic->base[i]); - pic->data[i]= NULL; - } - av_freep(&pic->opaque); - pic->type= 0; - }else if(pic->type == FF_BUFFER_TYPE_SHARED){ + + if(pic->type == FF_BUFFER_TYPE_SHARED){ for(i=0; i<4; i++){ pic->base[i]= pic->data[i]= NULL; @@ -523,6 +517,7 @@ void MPV_common_end(MpegEncContext *s) for(i=0; i<MAX_PICTURE_COUNT; i++){ free_picture(s, &s->picture[i]); } + avcodec_default_free_buffers(s->avctx); s->context_initialized = 0; } @@ -934,7 +929,7 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) s->mb_skiped = 0; assert(s->last_picture_ptr==NULL || s->out_format != FMT_H264); - + /* mark&release old frames */ if (s->pict_type != B_TYPE && s->last_picture_ptr) { avctx->release_buffer(avctx, (AVFrame*)s->last_picture_ptr); @@ -950,9 +945,15 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) } } } - alloc: if(!s->encoding){ + /* release non refernce frames */ + for(i=0; i<MAX_PICTURE_COUNT; i++){ + if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){ + s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]); + } + } + i= find_unused_picture(s, 0); pic= (AVFrame*)&s->picture[i]; @@ -977,6 +978,7 @@ alloc: s->last_picture_ptr= s->next_picture_ptr; s->next_picture_ptr= s->current_picture_ptr; } + if(s->last_picture_ptr) s->last_picture= *s->last_picture_ptr; if(s->next_picture_ptr) s->next_picture= *s->next_picture_ptr; if(s->new_picture_ptr ) s->new_picture = *s->new_picture_ptr; @@ -1045,12 +1047,14 @@ void MPV_frame_end(MpegEncContext *s) assert(i<MAX_PICTURE_COUNT); #endif - /* release non refernce frames */ - for(i=0; i<MAX_PICTURE_COUNT; i++){ - if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/) - s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]); + if(s->encoding){ + /* release non refernce frames */ + for(i=0; i<MAX_PICTURE_COUNT; i++){ + if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){ + s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]); + } + } } - // clear copies, to avoid confusion #if 0 memset(&s->last_picture, 0, sizeof(Picture)); @@ -1865,6 +1869,18 @@ inline int ff_h263_round_chroma(int x){ } } +/** + * motion compesation of a single macroblock + * @param s context + * @param dest_y luma destination pointer + * @param dest_cb chroma cb/u destination pointer + * @param dest_cr chroma cr/v destination pointer + * @param dir direction (0->forward, 1->backward) + * @param ref_picture array[3] of pointers to the 3 planes of the reference picture + * @param pic_op halfpel motion compensation function (average or put normally) + * @param pic_op qpel motion compensation function (average or put normally) + * the motion vectors are taken from s->mv and the MV type from s->mv_type + */ static inline void MPV_motion(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int dir, uint8_t **ref_picture, @@ -2774,17 +2790,33 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) */ int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size){ ParseContext *pc= &s->parse_context; - + +#if 0 + if(pc->overread){ + printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); + printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); + } +#endif + + /* copy overreaded byes from last frame into buffer */ + for(; pc->overread>0; pc->overread--){ + pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; + } + pc->last_index= pc->index; - if(next==-1){ + /* copy into buffer end return */ + if(next == END_NOT_FOUND){ pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(&pc->buffer[pc->index], *buf, *buf_size); pc->index += *buf_size; return -1; } - + + pc->overread_index= pc->index + next; + + /* append to buffer */ if(pc->index){ pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); @@ -2794,6 +2826,19 @@ int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size) *buf_size= pc->last_index + next; } + /* store overread bytes */ + for(;next < 0; next++){ + pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next]; + pc->overread++; + } + +#if 0 + if(pc->overread){ + printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); + printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); + } +#endif + return 0; } @@ -3863,8 +3908,8 @@ static int dct_quantize_c(MpegEncContext *s, level = block[j]; level = level * qmat[j]; -// if( bias+level >= (1<<(QMAT_SHIFT - 3)) -// || bias-level >= (1<<(QMAT_SHIFT - 3))){ +// if( bias+level >= (1<<QMAT_SHIFT) +// || bias-level >= (1<<QMAT_SHIFT)){ if(((unsigned)(level+threshold1))>threshold2){ if(level>0){ level= (bias + level)>>QMAT_SHIFT; diff --git a/src/libffmpeg/libavcodec/mpegvideo.h b/src/libffmpeg/libavcodec/mpegvideo.h index dc15a51f8..2cbc0ef19 100644 --- a/src/libffmpeg/libavcodec/mpegvideo.h +++ b/src/libffmpeg/libavcodec/mpegvideo.h @@ -205,8 +205,10 @@ typedef struct ParseContext{ int index; int last_index; int buffer_size; - int state; + uint32_t state; ///< contains the last few bytes in MSB order int frame_start_found; + int overread; ///< the number of bytes which where irreversibly read from the next frame + int overread_index; ///< the index into ParseContext.buffer of the overreaded bytes } ParseContext; struct MpegEncContext; @@ -709,6 +711,7 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h); void ff_emulated_edge_mc(MpegEncContext *s, uint8_t *src, int linesize, int block_w, int block_h, int src_x, int src_y, int w, int h); char ff_get_pict_type_char(int pict_type); +#define END_NOT_FOUND -100 int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size); void ff_print_debug_info(MpegEncContext *s, Picture *pict); diff --git a/src/libffmpeg/libavcodec/utils.c b/src/libffmpeg/libavcodec/utils.c index 8face129f..a422cf282 100644 --- a/src/libffmpeg/libavcodec/utils.c +++ b/src/libffmpeg/libavcodec/utils.c @@ -119,29 +119,39 @@ void register_avcodec(AVCodec *format) format->next = NULL; } -typedef struct DefaultPicOpaque{ +typedef struct InternalBuffer{ int last_pic_num; + uint8_t *base[4]; uint8_t *data[4]; -}DefaultPicOpaque; +}InternalBuffer; + +#define INTERNAL_BUFFER_SIZE 32 int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ int i; const int width = s->width; const int height= s->height; - DefaultPicOpaque *opaque; + InternalBuffer *buf; assert(pic->data[0]==NULL); - assert(pic->type==0 || pic->type==FF_BUFFER_TYPE_INTERNAL); - - if(pic->opaque){ - opaque= (DefaultPicOpaque *)pic->opaque; - for(i=0; i<3; i++) - pic->data[i]= opaque->data[i]; + assert(INTERNAL_BUFFER_SIZE > s->internal_buffer_count); -// printf("get_buffer %X coded_pic_num:%d last:%d\n", pic->opaque, pic->coded_picture_number, opaque->last_pic_num); - pic->age= pic->coded_picture_number - opaque->last_pic_num; - opaque->last_pic_num= pic->coded_picture_number; -//printf("age: %d %d %d\n", pic->age, c->picture_number, pic->coded_picture_number); + if(s->internal_buffer==NULL){ + s->internal_buffer= av_mallocz(INTERNAL_BUFFER_SIZE*sizeof(InternalBuffer)); + } +#if 0 + s->internal_buffer= av_fast_realloc( + s->internal_buffer, + &s->internal_buffer_size, + sizeof(InternalBuffer)*FFMAX(99, s->internal_buffer_count+1)/*FIXME*/ + ); +#endif + + buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count]; + + if(buf->base[0]){ + pic->age= pic->coded_picture_number - buf->last_pic_num; + buf->last_pic_num= pic->coded_picture_number; }else{ int align, h_chroma_shift, v_chroma_shift; int w, h, pixel_size; @@ -174,11 +184,7 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ h+= EDGE_WIDTH*2; } - opaque= av_mallocz(sizeof(DefaultPicOpaque)); - if(opaque==NULL) return -1; - - pic->opaque= opaque; - opaque->last_pic_num= -256*256*256*64; + buf->last_pic_num= -256*256*256*64; for(i=0; i<3; i++){ const int h_shift= i==0 ? 0 : h_chroma_shift; @@ -186,32 +192,51 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ pic->linesize[i]= pixel_size*w>>h_shift; - pic->base[i]= av_mallocz((pic->linesize[i]*h>>v_shift)+16); //FIXME 16 - if(pic->base[i]==NULL) return -1; - - memset(pic->base[i], 128, pic->linesize[i]*h>>v_shift); + buf->base[i]= av_mallocz((pic->linesize[i]*h>>v_shift)+16); //FIXME 16 + if(buf->base[i]==NULL) return -1; + memset(buf->base[i], 128, pic->linesize[i]*h>>v_shift); if(s->flags&CODEC_FLAG_EMU_EDGE) - pic->data[i] = pic->base[i]; + buf->data[i] = buf->base[i]; else - pic->data[i] = pic->base[i] + (pic->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift); - - opaque->data[i]= pic->data[i]; + buf->data[i] = buf->base[i] + (pic->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift); } pic->age= 256*256*256*64; pic->type= FF_BUFFER_TYPE_INTERNAL; } + for(i=0; i<4; i++){ + pic->base[i]= buf->base[i]; + pic->data[i]= buf->data[i]; + } + s->internal_buffer_count++; + return 0; } void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){ int i; - + InternalBuffer *buf, *last, temp; + assert(pic->type==FF_BUFFER_TYPE_INTERNAL); - - for(i=0; i<3; i++) + + for(i=0; i<s->internal_buffer_count; i++){ //just 3-5 checks so is not worth to optimize + buf= &((InternalBuffer*)s->internal_buffer)[i]; + if(buf->data[0] == pic->data[0]) + break; + } + assert(i < s->internal_buffer_count); + s->internal_buffer_count--; + last = &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count]; + + temp= *buf; + *buf= *last; + *last= temp; + + for(i=0; i<3; i++){ pic->data[i]=NULL; +// pic->base[i]=NULL; + } //printf("R%X\n", pic->opaque); } @@ -555,7 +580,7 @@ void avcodec_init(void) return; inited = 1; - //dsputil_init(); + dsputil_static_init(); } /* this can be called after seeking and before trying to decode the next keyframe */ @@ -565,13 +590,11 @@ void avcodec_flush_buffers(AVCodecContext *avctx) MpegEncContext *s = avctx->priv_data; switch(avctx->codec_id){ - case CODEC_ID_MJPEG: - case CODEC_ID_MJPEGB: - if(avctx->codec->priv_data_size != sizeof(MpegEncContext)) - break; case CODEC_ID_MPEG1VIDEO: case CODEC_ID_H263: case CODEC_ID_RV10: +// case CODEC_ID_MJPEG: +// case CODEC_ID_MJPEGB: case CODEC_ID_MPEG4: case CODEC_ID_MSMPEG4V1: case CODEC_ID_MSMPEG4V2: @@ -594,6 +617,23 @@ void avcodec_flush_buffers(AVCodecContext *avctx) } } +void avcodec_default_free_buffers(AVCodecContext *s){ + int i, j; + + if(s->internal_buffer==NULL) return; + + for(i=0; i<INTERNAL_BUFFER_SIZE; i++){ + InternalBuffer *buf= &((InternalBuffer*)s->internal_buffer)[i]; + for(j=0; j<4; j++){ + av_freep(&buf->base[j]); + buf->data[j]= NULL; + } + } + av_freep(&s->internal_buffer); + + s->internal_buffer_count=0; +} + int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){ int exact=1, sign=0; int64_t gcd, larger; |