From 9b8709d13526a055491e90c5767c501851cd9869 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 30 Mar 2003 19:26:01 +0000 Subject: [PATCH] mpeg1 slice encoding support Originally committed as revision 1720 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/mpeg12.c | 89 ++++++++++++++++++++++-------------------- libavcodec/mpegvideo.c | 13 ++++-- libavcodec/mpegvideo.h | 4 +- 3 files changed, 60 insertions(+), 46 deletions(-) diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 729b2f04f0..a25d7c0601 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -275,12 +275,18 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) } } +static inline void encode_mb_skip_run(MpegEncContext *s, int run){ + while (run >= 33) { + put_bits(&s->pb, 11, 0x008); + run -= 33; + } + put_bits(&s->pb, mbAddrIncrTable[run][1], + mbAddrIncrTable[run][0]); +} /* insert a fake P picture */ static void mpeg1_skip_picture(MpegEncContext *s, int pict_num) { - unsigned int mb_incr; - /* mpeg1 picture header */ put_header(s, PICTURE_START_CODE); /* temporal reference */ @@ -299,9 +305,7 @@ static void mpeg1_skip_picture(MpegEncContext *s, int pict_num) put_bits(&s->pb, 5, 1); /* quantizer scale */ put_bits(&s->pb, 1, 0); /* slice extra information */ - mb_incr = 1; - put_bits(&s->pb, mbAddrIncrTable[mb_incr - 1][1], - mbAddrIncrTable[mb_incr - 1][0]); + encode_mb_skip_run(s, 0); /* empty macroblock */ put_bits(&s->pb, 3, 1); /* motion only */ @@ -311,13 +315,7 @@ static void mpeg1_skip_picture(MpegEncContext *s, int pict_num) put_bits(&s->pb, 1, 1); /* output a number of empty slice */ - mb_incr = s->mb_width * s->mb_height - 1; - while (mb_incr > 33) { - put_bits(&s->pb, 11, 0x008); - mb_incr -= 33; - } - put_bits(&s->pb, mbAddrIncrTable[mb_incr - 1][1], - mbAddrIncrTable[mb_incr - 1][0]); + encode_mb_skip_run(s, s->mb_width * s->mb_height - 2); /* empty macroblock */ put_bits(&s->pb, 3, 1); /* motion only */ @@ -334,6 +332,20 @@ static void common_init(MpegEncContext *s) } #ifdef CONFIG_ENCODERS + +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_bits(&s->pb, 1, 0); /* slice extra information */ +} + +void ff_mpeg1_clean_buffers(MpegEncContext *s){ + s->last_dc[0] = 1 << (7 + s->intra_dc_precision); + s->last_dc[1] = s->last_dc[0]; + s->last_dc[2] = s->last_dc[0]; + memset(s->last_mv, 0, sizeof(s->last_mv)); +} + void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) { mpeg1_encode_sequence_header(s); @@ -364,20 +376,18 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) put_bits(&s->pb, 1, 0); /* extra bit picture */ - /* only one slice */ - put_header(s, SLICE_MIN_START_CODE); - put_bits(&s->pb, 5, s->qscale); /* quantizer scale */ - put_bits(&s->pb, 1, 0); /* slice extra information */ + s->mb_y=0; + ff_mpeg1_encode_slice_header(s); } void mpeg1_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y) { - int mb_incr, i, cbp, mb_x, mb_y; - - mb_x = s->mb_x; - mb_y = s->mb_y; + int i, cbp; + const int mb_x = s->mb_x; + const int mb_y = s->mb_y; + const int first_mb= mb_x == s->resync_mb_x && mb_y == s->resync_mb_y; /* compute cbp */ cbp = 0; @@ -386,26 +396,22 @@ void mpeg1_encode_mb(MpegEncContext *s, cbp |= 1 << (5 - i); } - // RAL: Skipped macroblocks for B frames... - if (cbp == 0 && (!((mb_x | mb_y) == 0 || (mb_x == s->mb_width - 1 && mb_y == s->mb_height - 1))) && + if (cbp == 0 && !first_mb && (mb_x != s->mb_width - 1 || mb_y != s->mb_height - 1) && ((s->pict_type == P_TYPE && (motion_x | motion_y) == 0) || (s->pict_type == B_TYPE && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) | ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) { - s->mb_incr++; + s->mb_skip_run++; s->qscale -= s->dquant; s->skip_count++; s->misc_bits++; s->last_bits++; } else { - /* output mb incr */ - mb_incr = s->mb_incr; - - while (mb_incr > 33) { - put_bits(&s->pb, 11, 0x008); - mb_incr -= 33; + if(first_mb){ + assert(s->mb_skip_run == 0); + encode_mb_skip_run(s, s->mb_x); + }else{ + encode_mb_skip_run(s, s->mb_skip_run); } - put_bits(&s->pb, mbAddrIncrTable[mb_incr - 1][1], - mbAddrIncrTable[mb_incr - 1][0]); if (s->pict_type == I_TYPE) { if(s->dquant && cbp){ @@ -553,7 +559,7 @@ void mpeg1_encode_mb(MpegEncContext *s, mpeg1_encode_block(s, block[i], i); } } - s->mb_incr = 1; + s->mb_skip_run = 0; if(s->mb_intra) s->i_tex_bits+= get_bits_diff(s); else @@ -888,7 +894,7 @@ static int mpeg_decode_mb(MpegEncContext *s, assert(s->mb_skiped==0); - if (--s->mb_incr != 0) { + if (s->mb_skip_run-- != 0) { /* skip mb */ s->mb_intra = 0; for(i=0;i<6;i++) @@ -1795,10 +1801,8 @@ static int mpeg_decode_slice(AVCodecContext *avctx, fprintf(stderr, "slice below image (%d >= %d)\n", start_code, s->mb_height); return DECODE_SLICE_ERROR; } - s->last_dc[0] = 1 << (7 + s->intra_dc_precision); - s->last_dc[1] = s->last_dc[0]; - s->last_dc[2] = s->last_dc[0]; - memset(s->last_mv, 0, sizeof(s->last_mv)); + + ff_mpeg1_clean_buffers(s); /* start frame decoding */ if (s->first_slice) { @@ -1863,8 +1867,9 @@ static int mpeg_decode_slice(AVCodecContext *avctx, break; } } + s->mb_y = start_code; - s->mb_incr= 1; + s->mb_skip_run= 0; for(;;) { s->dsp.clear_blocks(s->block[0]); @@ -1892,20 +1897,20 @@ static int mpeg_decode_slice(AVCodecContext *avctx, PRINT_QP("%2d", s->qscale); /* skip mb handling */ - if (s->mb_incr == 0) { + if (s->mb_skip_run == -1) { /* read again increment */ - s->mb_incr = 1; + s->mb_skip_run = 0; for(;;) { int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2); if (code < 0) goto eos; /* error = end of slice */ if (code >= 33) { if (code == 33) { - s->mb_incr += 33; + s->mb_skip_run += 33; } /* otherwise, stuffing, nothing to do */ } else { - s->mb_incr += code; + s->mb_skip_run += code; break; } } diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 7f7730b1d2..53c2d50c25 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -2684,7 +2684,7 @@ static inline void copy_context_before_encode(MpegEncContext *d, MpegEncContext memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop? /* mpeg1 */ - d->mb_incr= s->mb_incr; + d->mb_skip_run= s->mb_skip_run; for(i=0; i<3; i++) d->last_dc[i]= s->last_dc[i]; @@ -2710,7 +2710,7 @@ static inline void copy_context_after_encode(MpegEncContext *d, MpegEncContext * memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop? /* mpeg1 */ - d->mb_incr= s->mb_incr; + d->mb_skip_run= s->mb_skip_run; for(i=0; i<3; i++) d->last_dc[i]= s->last_dc[i]; @@ -3023,7 +3023,7 @@ static void encode_picture(MpegEncContext *s, int picture_number) s->current_picture_ptr->error[i] = 0; } - s->mb_incr = 1; + s->mb_skip_run = 0; s->last_mv[0][0][0] = 0; s->last_mv[0][0][1] = 0; s->last_mv[1][0][0] = 0; @@ -3094,6 +3094,13 @@ static void encode_picture(MpegEncContext *s, int picture_number) ff_mpeg4_clean_buffers(s); is_gob_start=1; } + }else if(s->codec_id==CODEC_ID_MPEG1VIDEO){ + if( current_packet_size >= s->rtp_payload_size + && s->mb_y + s->mb_x>0 && s->mb_skip_run==0){ + ff_mpeg1_encode_slice_header(s); + ff_mpeg1_clean_buffers(s); + is_gob_start=1; + } }else{ if(current_packet_size >= s->rtp_payload_size && s->mb_x==0 && s->mb_y>0 && s->mb_y%s->gob_index==0){ diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 924daac92c..7d4754565e 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -338,7 +338,7 @@ typedef struct MpegEncContext { /* macroblock layer */ int mb_x, mb_y; - int mb_incr; + int mb_skip_run; int mb_intra; uint8_t *mb_type; ///< Table for MB type #define MB_TYPE_INTRA 0x01 @@ -685,6 +685,8 @@ void mpeg1_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y); void ff_mpeg1_encode_init(MpegEncContext *s); +void ff_mpeg1_encode_slice_header(MpegEncContext *s); +void ff_mpeg1_clean_buffers(MpegEncContext *s); /** RLTable. */ -- GitLab