summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2003-03-30 19:26:01 +0000
committerMichael Niedermayer <michaelni@gmx.at>2003-03-30 19:26:01 +0000
commit9b8709d13526a055491e90c5767c501851cd9869 (patch)
tree3a7118a77d7ea9e8d982bf102eb56b8c82c88bba /libavcodec
parent5acaa5e1df0a6a9da5c87ba6edd7b0d8c4e95c88 (diff)
mpeg1 slice encoding support
Originally committed as revision 1720 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/mpeg12.c89
-rw-r--r--libavcodec/mpegvideo.c13
-rw-r--r--libavcodec/mpegvideo.h4
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. */