Commit 32e8b2e0 authored by michaelni's avatar michaelni

mpeg1 slice encoding support


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@1720 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent b14fd8bd
...@@ -275,12 +275,18 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) ...@@ -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 */ /* insert a fake P picture */
static void mpeg1_skip_picture(MpegEncContext *s, int pict_num) static void mpeg1_skip_picture(MpegEncContext *s, int pict_num)
{ {
unsigned int mb_incr;
/* mpeg1 picture header */ /* mpeg1 picture header */
put_header(s, PICTURE_START_CODE); put_header(s, PICTURE_START_CODE);
/* temporal reference */ /* temporal reference */
...@@ -299,9 +305,7 @@ static void mpeg1_skip_picture(MpegEncContext *s, int pict_num) ...@@ -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, 5, 1); /* quantizer scale */
put_bits(&s->pb, 1, 0); /* slice extra information */ put_bits(&s->pb, 1, 0); /* slice extra information */
mb_incr = 1; encode_mb_skip_run(s, 0);
put_bits(&s->pb, mbAddrIncrTable[mb_incr - 1][1],
mbAddrIncrTable[mb_incr - 1][0]);
/* empty macroblock */ /* empty macroblock */
put_bits(&s->pb, 3, 1); /* motion only */ put_bits(&s->pb, 3, 1); /* motion only */
...@@ -311,13 +315,7 @@ static void mpeg1_skip_picture(MpegEncContext *s, int pict_num) ...@@ -311,13 +315,7 @@ static void mpeg1_skip_picture(MpegEncContext *s, int pict_num)
put_bits(&s->pb, 1, 1); put_bits(&s->pb, 1, 1);
/* output a number of empty slice */ /* output a number of empty slice */
mb_incr = s->mb_width * s->mb_height - 1; encode_mb_skip_run(s, s->mb_width * s->mb_height - 2);
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]);
/* empty macroblock */ /* empty macroblock */
put_bits(&s->pb, 3, 1); /* motion only */ put_bits(&s->pb, 3, 1); /* motion only */
...@@ -334,6 +332,20 @@ static void common_init(MpegEncContext *s) ...@@ -334,6 +332,20 @@ static void common_init(MpegEncContext *s)
} }
#ifdef CONFIG_ENCODERS #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) void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
{ {
mpeg1_encode_sequence_header(s); mpeg1_encode_sequence_header(s);
...@@ -364,20 +376,18 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) ...@@ -364,20 +376,18 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
put_bits(&s->pb, 1, 0); /* extra bit picture */ put_bits(&s->pb, 1, 0); /* extra bit picture */
/* only one slice */ s->mb_y=0;
put_header(s, SLICE_MIN_START_CODE); ff_mpeg1_encode_slice_header(s);
put_bits(&s->pb, 5, s->qscale); /* quantizer scale */
put_bits(&s->pb, 1, 0); /* slice extra information */
} }
void mpeg1_encode_mb(MpegEncContext *s, void mpeg1_encode_mb(MpegEncContext *s,
DCTELEM block[6][64], DCTELEM block[6][64],
int motion_x, int motion_y) int motion_x, int motion_y)
{ {
int mb_incr, i, cbp, mb_x, mb_y; int i, cbp;
const int mb_x = s->mb_x;
mb_x = s->mb_x; const int mb_y = s->mb_y;
mb_y = s->mb_y; const int first_mb= mb_x == s->resync_mb_x && mb_y == s->resync_mb_y;
/* compute cbp */ /* compute cbp */
cbp = 0; cbp = 0;
...@@ -386,26 +396,22 @@ void mpeg1_encode_mb(MpegEncContext *s, ...@@ -386,26 +396,22 @@ void mpeg1_encode_mb(MpegEncContext *s,
cbp |= 1 << (5 - i); cbp |= 1 << (5 - i);
} }
// RAL: Skipped macroblocks for B frames... if (cbp == 0 && !first_mb && (mb_x != s->mb_width - 1 || mb_y != s->mb_height - 1) &&
if (cbp == 0 && (!((mb_x | mb_y) == 0 || (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 == 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->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->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->qscale -= s->dquant;
s->skip_count++; s->skip_count++;
s->misc_bits++; s->misc_bits++;
s->last_bits++; s->last_bits++;
} else { } else {
/* output mb incr */ if(first_mb){
mb_incr = s->mb_incr; assert(s->mb_skip_run == 0);
encode_mb_skip_run(s, s->mb_x);
while (mb_incr > 33) { }else{
put_bits(&s->pb, 11, 0x008); encode_mb_skip_run(s, s->mb_skip_run);
mb_incr -= 33;
} }
put_bits(&s->pb, mbAddrIncrTable[mb_incr - 1][1],
mbAddrIncrTable[mb_incr - 1][0]);
if (s->pict_type == I_TYPE) { if (s->pict_type == I_TYPE) {
if(s->dquant && cbp){ if(s->dquant && cbp){
...@@ -553,7 +559,7 @@ void mpeg1_encode_mb(MpegEncContext *s, ...@@ -553,7 +559,7 @@ void mpeg1_encode_mb(MpegEncContext *s,
mpeg1_encode_block(s, block[i], i); mpeg1_encode_block(s, block[i], i);
} }
} }
s->mb_incr = 1; s->mb_skip_run = 0;
if(s->mb_intra) if(s->mb_intra)
s->i_tex_bits+= get_bits_diff(s); s->i_tex_bits+= get_bits_diff(s);
else else
...@@ -888,7 +894,7 @@ static int mpeg_decode_mb(MpegEncContext *s, ...@@ -888,7 +894,7 @@ static int mpeg_decode_mb(MpegEncContext *s,
assert(s->mb_skiped==0); assert(s->mb_skiped==0);
if (--s->mb_incr != 0) { if (s->mb_skip_run-- != 0) {
/* skip mb */ /* skip mb */
s->mb_intra = 0; s->mb_intra = 0;
for(i=0;i<6;i++) for(i=0;i<6;i++)
...@@ -1795,10 +1801,8 @@ static int mpeg_decode_slice(AVCodecContext *avctx, ...@@ -1795,10 +1801,8 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
fprintf(stderr, "slice below image (%d >= %d)\n", start_code, s->mb_height); fprintf(stderr, "slice below image (%d >= %d)\n", start_code, s->mb_height);
return DECODE_SLICE_ERROR; return DECODE_SLICE_ERROR;
} }
s->last_dc[0] = 1 << (7 + s->intra_dc_precision);
s->last_dc[1] = s->last_dc[0]; ff_mpeg1_clean_buffers(s);
s->last_dc[2] = s->last_dc[0];
memset(s->last_mv, 0, sizeof(s->last_mv));
/* start frame decoding */ /* start frame decoding */
if (s->first_slice) { if (s->first_slice) {
...@@ -1863,8 +1867,9 @@ static int mpeg_decode_slice(AVCodecContext *avctx, ...@@ -1863,8 +1867,9 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
break; break;
} }
} }
s->mb_y = start_code; s->mb_y = start_code;
s->mb_incr= 1; s->mb_skip_run= 0;
for(;;) { for(;;) {
s->dsp.clear_blocks(s->block[0]); s->dsp.clear_blocks(s->block[0]);
...@@ -1892,20 +1897,20 @@ static int mpeg_decode_slice(AVCodecContext *avctx, ...@@ -1892,20 +1897,20 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
PRINT_QP("%2d", s->qscale); PRINT_QP("%2d", s->qscale);
/* skip mb handling */ /* skip mb handling */
if (s->mb_incr == 0) { if (s->mb_skip_run == -1) {
/* read again increment */ /* read again increment */
s->mb_incr = 1; s->mb_skip_run = 0;
for(;;) { for(;;) {
int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2); int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);
if (code < 0) if (code < 0)
goto eos; /* error = end of slice */ goto eos; /* error = end of slice */
if (code >= 33) { if (code >= 33) {
if (code == 33) { if (code == 33) {
s->mb_incr += 33; s->mb_skip_run += 33;
} }
/* otherwise, stuffing, nothing to do */ /* otherwise, stuffing, nothing to do */
} else { } else {
s->mb_incr += code; s->mb_skip_run += code;
break; break;
} }
} }
......
...@@ -2684,7 +2684,7 @@ static inline void copy_context_before_encode(MpegEncContext *d, MpegEncContext ...@@ -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? memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop?
/* mpeg1 */ /* mpeg1 */
d->mb_incr= s->mb_incr; d->mb_skip_run= s->mb_skip_run;
for(i=0; i<3; i++) for(i=0; i<3; i++)
d->last_dc[i]= s->last_dc[i]; d->last_dc[i]= s->last_dc[i];
...@@ -2710,7 +2710,7 @@ static inline void copy_context_after_encode(MpegEncContext *d, MpegEncContext * ...@@ -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? memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop?
/* mpeg1 */ /* mpeg1 */
d->mb_incr= s->mb_incr; d->mb_skip_run= s->mb_skip_run;
for(i=0; i<3; i++) for(i=0; i<3; i++)
d->last_dc[i]= s->last_dc[i]; d->last_dc[i]= s->last_dc[i];
...@@ -3023,7 +3023,7 @@ static void encode_picture(MpegEncContext *s, int picture_number) ...@@ -3023,7 +3023,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
s->current_picture_ptr->error[i] = 0; 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][0] = 0;
s->last_mv[0][0][1] = 0; s->last_mv[0][0][1] = 0;
s->last_mv[1][0][0] = 0; s->last_mv[1][0][0] = 0;
...@@ -3094,6 +3094,13 @@ static void encode_picture(MpegEncContext *s, int picture_number) ...@@ -3094,6 +3094,13 @@ static void encode_picture(MpegEncContext *s, int picture_number)
ff_mpeg4_clean_buffers(s); ff_mpeg4_clean_buffers(s);
is_gob_start=1; 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{ }else{
if(current_packet_size >= s->rtp_payload_size if(current_packet_size >= s->rtp_payload_size
&& s->mb_x==0 && s->mb_y>0 && s->mb_y%s->gob_index==0){ && s->mb_x==0 && s->mb_y>0 && s->mb_y%s->gob_index==0){
......
...@@ -338,7 +338,7 @@ typedef struct MpegEncContext { ...@@ -338,7 +338,7 @@ typedef struct MpegEncContext {
/* macroblock layer */ /* macroblock layer */
int mb_x, mb_y; int mb_x, mb_y;
int mb_incr; int mb_skip_run;
int mb_intra; int mb_intra;
uint8_t *mb_type; ///< Table for MB type uint8_t *mb_type; ///< Table for MB type
#define MB_TYPE_INTRA 0x01 #define MB_TYPE_INTRA 0x01
...@@ -685,6 +685,8 @@ void mpeg1_encode_mb(MpegEncContext *s, ...@@ -685,6 +685,8 @@ void mpeg1_encode_mb(MpegEncContext *s,
DCTELEM block[6][64], DCTELEM block[6][64],
int motion_x, int motion_y); int motion_x, int motion_y);
void ff_mpeg1_encode_init(MpegEncContext *s); void ff_mpeg1_encode_init(MpegEncContext *s);
void ff_mpeg1_encode_slice_header(MpegEncContext *s);
void ff_mpeg1_clean_buffers(MpegEncContext *s);
/** RLTable. */ /** RLTable. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment