diff options
author | Baptiste Coudurier <baptiste.coudurier@gmail.com> | 2006-05-16 15:19:54 +0000 |
---|---|---|
committer | Baptiste Coudurier <baptiste.coudurier@gmail.com> | 2006-05-16 15:19:54 +0000 |
commit | 2d974017b03503c09082eff5558c3b2606dbcdaf (patch) | |
tree | 675a111c8620a323985d87f5e8d537a34132e0f8 /libavcodec/mpeg12.c | |
parent | c2f69579bb9cb929fb2cfcba426f524f0f107169 (diff) | |
download | ffmpeg-2d974017b03503c09082eff5558c3b2606dbcdaf.tar.gz |
MPEG-2 4:2:2 encoding support
Originally committed as revision 5387 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/mpeg12.c')
-rw-r--r-- | libavcodec/mpeg12.c | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 86377850d2..d805ae5903 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -232,6 +232,12 @@ static int encode_init(AVCodecContext *avctx) } } + if(avctx->profile == FF_PROFILE_UNKNOWN) + avctx->profile = s->chroma_format == CHROMA_420 ? 4 : 0; + + if(avctx->level == FF_LEVEL_UNKNOWN) + avctx->level = s->chroma_format == CHROMA_420 ? 8 : 5; + return 0; } @@ -319,22 +325,14 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) if(s->codec_id == CODEC_ID_MPEG2VIDEO){ put_header(s, EXT_START_CODE); put_bits(&s->pb, 4, 1); //seq ext - put_bits(&s->pb, 1, 0); //esc - if(s->avctx->profile == FF_PROFILE_UNKNOWN){ - put_bits(&s->pb, 3, 4); //profile - }else{ - put_bits(&s->pb, 3, s->avctx->profile); //profile - } + put_bits(&s->pb, 1, s->chroma_format == CHROMA_422); //escx - if(s->avctx->level == FF_LEVEL_UNKNOWN){ - put_bits(&s->pb, 4, 8); //level - }else{ - put_bits(&s->pb, 4, s->avctx->level); //level - } + put_bits(&s->pb, 3, s->avctx->profile); //profile + put_bits(&s->pb, 4, s->avctx->level); //level put_bits(&s->pb, 1, s->progressive_sequence); - put_bits(&s->pb, 2, 1); //chroma format 4:2:0 + put_bits(&s->pb, 2, s->chroma_format); put_bits(&s->pb, 2, 0); //horizontal size ext put_bits(&s->pb, 2, 0); //vertical size ext put_bits(&s->pb, 12, v>>18); //bitrate ext @@ -468,7 +466,7 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) put_bits(&s->pb, 1, s->alternate_scan); put_bits(&s->pb, 1, s->repeat_first_field); s->progressive_frame = s->progressive_sequence; - put_bits(&s->pb, 1, s->chroma_420_type=s->progressive_frame); + put_bits(&s->pb, 1, s->chroma_format == CHROMA_420 ? s->progressive_frame : 0); /* chroma_420_type */ put_bits(&s->pb, 1, s->progressive_frame); put_bits(&s->pb, 1, 0); //composite_display_flag } @@ -496,9 +494,10 @@ static inline void put_mb_modes(MpegEncContext *s, int n, int bits, } } -void mpeg1_encode_mb(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y) +static always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, + DCTELEM block[6][64], + int motion_x, int motion_y, + int mb_block_count) { int i, cbp; const int mb_x = s->mb_x; @@ -507,9 +506,9 @@ void mpeg1_encode_mb(MpegEncContext *s, /* compute cbp */ cbp = 0; - for(i=0;i<6;i++) { + for(i=0;i<mb_block_count;i++) { if (s->block_last_index[i] >= 0) - cbp |= 1 << (5 - i); + cbp |= 1 << (mb_block_count - 1 - i); } if (cbp == 0 && !first_mb && s->mv_type == MV_TYPE_16X16 && @@ -615,8 +614,14 @@ void mpeg1_encode_mb(MpegEncContext *s, } s->mv_bits+= get_bits_diff(s); } - if(cbp) - put_bits(&s->pb, mbPatTable[cbp][1], mbPatTable[cbp][0]); + if(cbp) { + if (s->chroma_y_shift) { + put_bits(&s->pb, mbPatTable[cbp][1], mbPatTable[cbp][0]); + } else { + put_bits(&s->pb, mbPatTable[cbp>>2][1], mbPatTable[cbp>>2][0]); + put_bits(&s->pb, 2, cbp & 3); + } + } s->f_count++; } else{ static const int mb_type_len[4]={0,3,4,2}; //bak,for,bi @@ -694,11 +699,17 @@ void mpeg1_encode_mb(MpegEncContext *s, } } s->mv_bits += get_bits_diff(s); - if(cbp) - put_bits(&s->pb, mbPatTable[cbp][1], mbPatTable[cbp][0]); + if(cbp) { + if (s->chroma_y_shift) { + put_bits(&s->pb, mbPatTable[cbp][1], mbPatTable[cbp][0]); + } else { + put_bits(&s->pb, mbPatTable[cbp>>2][1], mbPatTable[cbp>>2][0]); + put_bits(&s->pb, 2, cbp & 3); + } + } } - for(i=0;i<6;i++) { - if (cbp & (1 << (5 - i))) { + for(i=0;i<mb_block_count;i++) { + if (cbp & (1 << (mb_block_count - 1 - i))) { mpeg1_encode_block(s, block[i], i); } } @@ -710,6 +721,12 @@ void mpeg1_encode_mb(MpegEncContext *s, } } +void mpeg1_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y) +{ + if (s->chroma_format == CHROMA_420) mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 6); + else mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8); +} + // RAL: Parameter added: f_or_b_code static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code) { @@ -905,7 +922,7 @@ static void mpeg1_encode_block(MpegEncContext *s, /* DC coef */ if (s->mb_intra) { - component = (n <= 3 ? 0 : n - 4 + 1); + component = (n <= 3 ? 0 : (n&1) + 1); dc = block[0]; /* overflow is impossible */ diff = dc - s->last_dc[component]; encode_dc(s, diff, component); @@ -3249,7 +3266,7 @@ AVCodec mpeg2video_encoder = { MPV_encode_picture, MPV_encode_end, .supported_framerates= frame_rate_tab+1, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, -1}, .capabilities= CODEC_CAP_DELAY, }; #endif |