diff options
Diffstat (limited to 'contrib/ffmpeg/libavcodec/mpeg12.c')
-rw-r--r-- | contrib/ffmpeg/libavcodec/mpeg12.c | 166 |
1 files changed, 115 insertions, 51 deletions
diff --git a/contrib/ffmpeg/libavcodec/mpeg12.c b/contrib/ffmpeg/libavcodec/mpeg12.c index c392e17af..c0fa7e4bc 100644 --- a/contrib/ffmpeg/libavcodec/mpeg12.c +++ b/contrib/ffmpeg/libavcodec/mpeg12.c @@ -31,6 +31,7 @@ #include "mpegvideo.h" #include "mpeg12data.h" +#include "bytestream.h" //#undef NDEBUG //#include <assert.h> @@ -93,7 +94,7 @@ static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = { PIX_FMT_XVMC_MPEG2_MC, -1}; #ifdef CONFIG_ENCODERS -static uint8_t (*mv_penalty)[MAX_MV*2+1]= NULL; +static uint8_t mv_penalty[MAX_FCODE+1][MAX_MV*2+1]; static uint8_t fcode_tab[MAX_MV*2+1]; static uint8_t uni_mpeg1_ac_vlc_len [64*64*2]; @@ -107,6 +108,8 @@ static uint8_t mpeg1_index_run[2][64]; static int8_t mpeg1_max_level[2][64]; #endif //CONFIG_ENCODERS +static uint8_t static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; + static void init_2d_vlc_rl(RLTable *rl, int use_static) { int i; @@ -234,11 +237,28 @@ static int encode_init(AVCodecContext *avctx) } } - if(avctx->profile == FF_PROFILE_UNKNOWN) - avctx->profile = s->chroma_format == CHROMA_420 ? 4 : 0; + if(avctx->profile == FF_PROFILE_UNKNOWN){ + if(avctx->level != FF_LEVEL_UNKNOWN){ + av_log(avctx, AV_LOG_ERROR, "Set profile and level\n"); + return -1; + } + avctx->profile = s->chroma_format == CHROMA_420 ? 4 : 0; /* Main or 4:2:2 */ + } - if(avctx->level == FF_LEVEL_UNKNOWN) - avctx->level = s->chroma_format == CHROMA_420 ? 8 : 5; + if(avctx->level == FF_LEVEL_UNKNOWN){ + if(avctx->profile == 0){ /* 4:2:2 */ + if(avctx->width <= 720 && avctx->height <= 608) avctx->level = 5; /* Main */ + else avctx->level = 2; /* High */ + }else{ + if(avctx->profile != 1 && s->chroma_format != CHROMA_420){ + av_log(avctx, AV_LOG_ERROR, "Only High(1) and 4:2:2(0) profiles support 4:2:2 color sampling\n"); + return -1; + } + if(avctx->width <= 720 && avctx->height <= 576) avctx->level = 8; /* Main */ + else if(avctx->width <= 1440) avctx->level = 6; /* High 1440 */ + else avctx->level = 4; /* High */ + } + } if((avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) && s->frame_rate_index != 4){ av_log(avctx, AV_LOG_ERROR, "Drop frame time code only allowed with 1001/30000 fps\n"); @@ -333,7 +353,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) put_header(s, EXT_START_CODE); put_bits(&s->pb, 4, 1); //seq ext - put_bits(&s->pb, 1, s->chroma_format == CHROMA_422); //escx + put_bits(&s->pb, 1, s->avctx->profile == 0); //escx 1 for 4:2:2 profile */ put_bits(&s->pb, 3, s->avctx->profile); //profile put_bits(&s->pb, 4, s->avctx->level); //level @@ -351,7 +371,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) } put_header(s, GOP_START_CODE); - put_bits(&s->pb, 1, !!(s->avctx->flags & CODEC_FLAG2_DROP_FRAME_TIMECODE)); /* drop frame flag */ + put_bits(&s->pb, 1, !!(s->avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE)); /* drop frame flag */ /* time code : we must convert from the real frame rate to a fake mpeg frame rate in case of low frame rate */ fps = (framerate.num + framerate.den/2)/ framerate.den; @@ -402,9 +422,19 @@ void ff_mpeg1_clean_buffers(MpegEncContext *s){ #ifdef CONFIG_ENCODERS +static av_always_inline void put_qscale(MpegEncContext *s) +{ + if(s->q_scale_type){ + assert(s->qscale>=1 && s->qscale <=12); + put_bits(&s->pb, 5, inv_non_linear_qscale[s->qscale]); + }else{ + put_bits(&s->pb, 5, s->qscale); + } +} + void ff_mpeg1_encode_slice_header(MpegEncContext *s){ put_header(s, SLICE_MIN_START_CODE + s->mb_y); - put_bits(&s->pb, 5, s->qscale); /* quantizer scale */ + put_qscale(s); put_bits(&s->pb, 1, 0); /* slice extra information */ } @@ -508,7 +538,7 @@ static inline void put_mb_modes(MpegEncContext *s, int n, int bits, } } -static always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, +static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y, int mb_block_count) @@ -550,7 +580,7 @@ static always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, if (s->pict_type == I_TYPE) { if(s->dquant && cbp){ put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */ - put_bits(&s->pb, 5, s->qscale); + put_qscale(s); }else{ put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */ s->qscale -= s->dquant; @@ -560,7 +590,7 @@ static always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, } else if (s->mb_intra) { if(s->dquant && cbp){ put_mb_modes(s, 6, 0x01, 0, 0); - put_bits(&s->pb, 5, s->qscale); + put_qscale(s); }else{ put_mb_modes(s, 5, 0x03, 0, 0); s->qscale -= s->dquant; @@ -574,7 +604,7 @@ static always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, if ((motion_x|motion_y) == 0) { if(s->dquant){ put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */ - put_bits(&s->pb, 5, s->qscale); + put_qscale(s); }else{ put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */ } @@ -582,7 +612,7 @@ static always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, } else { if(s->dquant){ put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */ - put_bits(&s->pb, 5, s->qscale); + put_qscale(s); }else{ put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */ } @@ -609,7 +639,7 @@ static always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, if (cbp) { if(s->dquant){ put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */ - put_bits(&s->pb, 5, s->qscale); + put_qscale(s); }else{ put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */ } @@ -647,7 +677,7 @@ static always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, put_mb_modes(s, 6, 3, 1, 0); else put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 0); - put_bits(&s->pb, 5, s->qscale); + put_qscale(s); } else { put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 0); } @@ -681,7 +711,7 @@ static always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, put_mb_modes(s, 6, 3, 1, 1); else put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 1); - put_bits(&s->pb, 5, s->qscale); + put_qscale(s); } else { put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 1); } @@ -797,9 +827,8 @@ void ff_mpeg1_encode_init(MpegEncContext *s) int i; done=1; - init_rl(&rl_mpeg1, 1); - if(s->intra_vlc_format) - init_rl(&rl_mpeg2, 1); + init_rl(&rl_mpeg1, static_rl_table_store[0]); + init_rl(&rl_mpeg2, static_rl_table_store[1]); for(i=0; i<64; i++) { @@ -831,8 +860,6 @@ void ff_mpeg1_encode_init(MpegEncContext *s) mpeg1_chr_dc_uni[i+255]= bits + (code<<8); } - mv_penalty= av_mallocz( sizeof(uint8_t)*(MAX_FCODE+1)*(2*MAX_MV+1) ); - for(f_code=1; f_code<=MAX_FCODE; f_code++){ for(mv=-MAX_MV; mv<=MAX_MV; mv++){ int len; @@ -968,7 +995,7 @@ static void mpeg1_encode_block(MpegEncContext *s, next_coef: #if 0 if (level != 0) - dprintf("level[%d]=%d\n", i, level); + dprintf(s->avctx, "level[%d]=%d\n", i, level); #endif /* encode using VLC */ if (level != 0) { @@ -1049,8 +1076,8 @@ static void init_vlcs(void) init_vlc(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11, &table_mb_btype[0][1], 2, 1, &table_mb_btype[0][0], 2, 1, 1); - init_rl(&rl_mpeg1, 1); - init_rl(&rl_mpeg2, 1); + init_rl(&rl_mpeg1, static_rl_table_store[0]); + init_rl(&rl_mpeg2, static_rl_table_store[1]); init_2d_vlc_rl(&rl_mpeg1, 1); init_2d_vlc_rl(&rl_mpeg2, 1); @@ -1087,7 +1114,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int i, j, k, cbp, val, mb_type, motion_type; const int mb_block_count = 4 + (1<< s->chroma_format); - dprintf("decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y); + dprintf(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y); assert(s->mb_skipped==0); @@ -1171,7 +1198,7 @@ static int mpeg_decode_mb(MpegEncContext *s, mb_type = btype2mb_type[ mb_type ]; break; } - dprintf("mb_type=%x\n", mb_type); + dprintf(s->avctx, "mb_type=%x\n", mb_type); // motion_type = 0; /* avoid warning */ if (IS_INTRA(mb_type)) { s->dsp.clear_blocks(s->block[0]); @@ -1281,7 +1308,7 @@ static int mpeg_decode_mb(MpegEncContext *s, for(i=0;i<2;i++) { if (USES_LIST(mb_type, i)) { s->mv_dir |= (MV_DIR_FORWARD >> i); - dprintf("motion_type=%d\n", motion_type); + dprintf(s->avctx, "motion_type=%d\n", motion_type); switch(motion_type) { case MT_FRAME: /* or MT_16X8 */ if (s->picture_structure == PICT_FRAME) { @@ -1322,12 +1349,12 @@ static int mpeg_decode_mb(MpegEncContext *s, s->last_mv[i][j][0]); s->last_mv[i][j][0] = val; s->mv[i][j][0] = val; - dprintf("fmx=%d\n", val); + dprintf(s->avctx, "fmx=%d\n", val); val = mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][j][1] >> 1); s->last_mv[i][j][1] = val << 1; s->mv[i][j][1] = val; - dprintf("fmy=%d\n", val); + dprintf(s->avctx, "fmy=%d\n", val); } } else { mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; @@ -1552,7 +1579,7 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, dc += diff; s->last_dc[component] = dc; block[0] = dc<<3; - dprintf("dc=%d diff=%d\n", dc, diff); + dprintf(s->avctx, "dc=%d diff=%d\n", dc, diff); i = 0; { OPEN_READER(re, &s->gb); @@ -1926,7 +1953,7 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, dc += diff; s->last_dc[component] = dc; block[0] = dc << (3 - s->intra_dc_precision); - dprintf("dc=%d\n", block[0]); + dprintf(s->avctx, "dc=%d\n", block[0]); mismatch = block[0] ^ 1; i = 0; if (s->intra_vlc_format) @@ -2277,7 +2304,7 @@ static void mpeg_decode_sequence_extension(Mpeg1Context *s1) s1->frame_rate_ext.num = get_bits(&s->gb, 2)+1; s1->frame_rate_ext.den = get_bits(&s->gb, 5)+1; - dprintf("sequence extension\n"); + dprintf(s->avctx, "sequence extension\n"); s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG2VIDEO; s->avctx->sub_id = 2; /* indicates mpeg2 found */ @@ -2349,7 +2376,7 @@ static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) { int i, v, j; - dprintf("matrix extension\n"); + dprintf(s->avctx, "matrix extension\n"); if (get_bits1(&s->gb)) { for(i=0;i<64;i++) { @@ -2420,15 +2447,15 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s) } /* composite display not parsed */ - dprintf("intra_dc_precision=%d\n", s->intra_dc_precision); - dprintf("picture_structure=%d\n", s->picture_structure); - dprintf("top field first=%d\n", s->top_field_first); - dprintf("repeat first field=%d\n", s->repeat_first_field); - dprintf("conceal=%d\n", s->concealment_motion_vectors); - dprintf("intra_vlc_format=%d\n", s->intra_vlc_format); - dprintf("alternate_scan=%d\n", s->alternate_scan); - dprintf("frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct); - dprintf("progressive_frame=%d\n", s->progressive_frame); + dprintf(s->avctx, "intra_dc_precision=%d\n", s->intra_dc_precision); + dprintf(s->avctx, "picture_structure=%d\n", s->picture_structure); + dprintf(s->avctx, "top field first=%d\n", s->top_field_first); + dprintf(s->avctx, "repeat first field=%d\n", s->repeat_first_field); + dprintf(s->avctx, "conceal=%d\n", s->concealment_motion_vectors); + dprintf(s->avctx, "intra_vlc_format=%d\n", s->intra_vlc_format); + dprintf(s->avctx, "alternate_scan=%d\n", s->alternate_scan); + dprintf(s->avctx, "frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct); + dprintf(s->avctx, "progressive_frame=%d\n", s->progressive_frame); } static void mpeg_decode_extension(AVCodecContext *avctx, @@ -2576,6 +2603,10 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, break; } } + if(s->mb_x >= (unsigned)s->mb_width){ + av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n"); + return -1; + } s->resync_mb_x= s->mb_x; s->resync_mb_y= s->mb_y= mb_y; @@ -2603,7 +2634,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, ret = mpeg_decode_mb(s, s->block); s->chroma_qscale= s->qscale; - dprintf("ret=%d\n", ret); + dprintf(s->avctx, "ret=%d\n", ret); if (ret < 0) return -1; @@ -2826,10 +2857,10 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, s->chroma_intra_matrix[j] = v; } #ifdef DEBUG - dprintf("intra matrix present\n"); + dprintf(s->avctx, "intra matrix present\n"); for(i=0;i<64;i++) - dprintf(" %d", s->intra_matrix[s->dsp.idct_permutation[i]]); - dprintf("\n"); + dprintf(s->avctx, " %d", s->intra_matrix[s->dsp.idct_permutation[i]]); + dprintf(s->avctx, "\n"); #endif } else { for(i=0;i<64;i++) { @@ -2851,10 +2882,10 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, s->chroma_inter_matrix[j] = v; } #ifdef DEBUG - dprintf("non intra matrix present\n"); + dprintf(s->avctx, "non intra matrix present\n"); for(i=0;i<64;i++) - dprintf(" %d", s->inter_matrix[s->dsp.idct_permutation[i]]); - dprintf("\n"); + dprintf(s->avctx, " %d", s->inter_matrix[s->dsp.idct_permutation[i]]); + dprintf(s->avctx, "\n"); #endif } else { for(i=0;i<64;i++) { @@ -3054,7 +3085,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, int ret, input_size; AVFrame *picture = data; MpegEncContext *s2 = &s->mpeg_enc_ctx; - dprintf("fill_buffer\n"); + dprintf(avctx, "fill_buffer\n"); if (buf_size == 0) { /* special case for last picture */ @@ -3178,6 +3209,10 @@ static int mpeg_decode_frame(AVCodecContext *avctx, if(mpeg_field_start(s2) < 0) return -1; } + if(!s2->current_picture_ptr){ + av_log(avctx, AV_LOG_ERROR, "current_picture not initalized\n"); + return -1; + } if(avctx->thread_count > 1){ int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count; @@ -3298,7 +3333,7 @@ static int mpeg_mc_decode_init(AVCodecContext *avctx){ if( !(avctx->slice_flags & SLICE_FLAG_CODED_ORDER) ) return -1; if( !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD) ){ - dprintf("mpeg12.c: XvMC decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n"); + dprintf(avctx, "mpeg12.c: XvMC decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n"); } mpeg_decode_init(avctx); s = avctx->priv_data; @@ -3487,6 +3522,35 @@ AVCodecParser mpegvideo_parser = { }; #endif /* !CONFIG_MPEGVIDEO_PARSER */ +static int imx_dump_header(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe) +{ + /* MXF essence element key */ + static const uint8_t imx_header[16] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }; + uint8_t *poutbufp; + + if (avctx->codec_id != CODEC_ID_MPEG2VIDEO) { + av_log(avctx, AV_LOG_ERROR, "imx bitstream filter only applies to mpeg2video codec\n"); + return 0; + } + + *poutbuf = av_malloc(buf_size + 20 + FF_INPUT_BUFFER_PADDING_SIZE); + poutbufp = *poutbuf; + bytestream_put_buffer(&poutbufp, imx_header, 16); + bytestream_put_byte(&poutbufp, 0x83); /* KLV BER long form */ + bytestream_put_be24(&poutbufp, buf_size); + bytestream_put_buffer(&poutbufp, buf, buf_size); + *poutbuf_size = poutbufp - *poutbuf; + return 1; +} + +AVBitStreamFilter imx_dump_header_bsf = { + "imxdump", + 0, + imx_dump_header, +}; + /* this is ugly i know, but the alternative is too make hundreds of vars global and prefix them with ff_mpeg1_ which is far uglier. */ |