summaryrefslogtreecommitdiff
path: root/libavcodec/mpeg12.c
diff options
context:
space:
mode:
authorBaptiste Coudurier <baptiste.coudurier@gmail.com>2006-05-16 15:19:54 +0000
committerBaptiste Coudurier <baptiste.coudurier@gmail.com>2006-05-16 15:19:54 +0000
commit2d974017b03503c09082eff5558c3b2606dbcdaf (patch)
tree675a111c8620a323985d87f5e8d537a34132e0f8 /libavcodec/mpeg12.c
parentc2f69579bb9cb929fb2cfcba426f524f0f107169 (diff)
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.c69
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