removing broken framerate conversation hack in mpeg1/2

Originally committed as revision 2713 to svn://svn.ffmpeg.org/ffmpeg/trunk
pull/126/head
Michael Niedermayer 21 years ago
parent 8e78482542
commit 2c492e94fc
  1. 146
      libavcodec/mpeg12.c
  2. 25
      libavcodec/mpegvideo.c

@ -58,7 +58,6 @@ static void mpeg1_encode_block(MpegEncContext *s,
int component); int component);
static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code); // RAL: f_code parameter added static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code); // RAL: f_code parameter added
#endif //CONFIG_ENCODERS #endif //CONFIG_ENCODERS
static void mpeg1_skip_picture(MpegEncContext *s, int pict_num);
static inline int mpeg1_decode_block_inter(MpegEncContext *s, static inline int mpeg1_decode_block_inter(MpegEncContext *s,
DCTELEM *block, DCTELEM *block,
int n); int n);
@ -182,6 +181,46 @@ static void init_uni_ac_vlc(RLTable *rl, uint32_t *uni_ac_vlc_bits, uint8_t *uni
} }
} }
static int find_frame_rate_index(MpegEncContext *s){
int i;
int64_t dmin= INT64_MAX;
int64_t d;
for(i=1;i<14;i++) {
if(s->avctx->strict_std_compliance >= 0 && i>=9) break;
d = ABS(MPEG1_FRAME_RATE_BASE*(int64_t)s->avctx->frame_rate - frame_rate_tab[i]*(int64_t)s->avctx->frame_rate_base);
if(d < dmin){
dmin=d;
s->frame_rate_index= i;
}
}
if(dmin)
return -1;
else
return 0;
}
static int encode_init(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
if(MPV_encode_init(avctx) < 0)
return -1;
if(find_frame_rate_index(s) < 0){
if(s->strict_std_compliance >=0){
av_log(avctx, AV_LOG_ERROR, "MPEG1/2 doesnt support %d/%d fps\n", avctx->frame_rate, avctx->frame_rate_base);
return -1;
}else{
av_log(avctx, AV_LOG_INFO, "MPEG1/2 doesnt support %d/%d fps, there may be AV sync issues\n", avctx->frame_rate, avctx->frame_rate_base);
}
}
return 0;
}
static void put_header(MpegEncContext *s, int header) static void put_header(MpegEncContext *s, int header)
{ {
align_put_bits(&s->pb); align_put_bits(&s->pb);
@ -205,22 +244,6 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
if (s->current_picture.key_frame) { if (s->current_picture.key_frame) {
/* mpeg1 header repeated every gop */ /* mpeg1 header repeated every gop */
put_header(s, SEQ_START_CODE); put_header(s, SEQ_START_CODE);
/* search closest frame rate */
{
int i, dmin, d;
s->frame_rate_index = 0;
dmin = 0x7fffffff;
for(i=1;i<14;i++) {
if(s->avctx->strict_std_compliance >= 0 && i>=9) break;
d = abs(MPEG1_FRAME_RATE_BASE*(int64_t)s->avctx->frame_rate/s->avctx->frame_rate_base - frame_rate_tab[i]);
if (d < dmin) {
dmin = d;
s->frame_rate_index = i;
}
}
}
put_bits(&s->pb, 12, s->width); put_bits(&s->pb, 12, s->width);
put_bits(&s->pb, 12, s->height); put_bits(&s->pb, 12, s->height);
@ -299,8 +322,9 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
/* time code : we must convert from the real frame rate to a /* time code : we must convert from the real frame rate to a
fake mpeg frame rate in case of low frame rate */ fake mpeg frame rate in case of low frame rate */
fps = (frame_rate_tab[s->frame_rate_index] + MPEG1_FRAME_RATE_BASE/2)/ MPEG1_FRAME_RATE_BASE; fps = (frame_rate_tab[s->frame_rate_index] + MPEG1_FRAME_RATE_BASE/2)/ MPEG1_FRAME_RATE_BASE;
time_code = s->fake_picture_number; time_code = s->current_picture_ptr->coded_picture_number;
s->gop_picture_number = s->fake_picture_number;
s->gop_picture_number = time_code;
put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24)); put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24));
put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60)); put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60));
put_bits(&s->pb, 1, 1); put_bits(&s->pb, 1, 1);
@ -309,19 +333,6 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
put_bits(&s->pb, 1, 0); /* closed gop */ put_bits(&s->pb, 1, 0); /* closed gop */
put_bits(&s->pb, 1, 0); /* broken link */ put_bits(&s->pb, 1, 0); /* broken link */
} }
if (s->avctx->frame_rate < (23 * s->avctx->frame_rate_base) && s->picture_number > 0) {
/* insert empty P pictures to slow down to the desired
frame rate. Each fake pictures takes about 20 bytes */
fps = frame_rate_tab[s->frame_rate_index];
n = av_rescale((int64_t)s->picture_number * s->avctx->frame_rate_base, fps, s->avctx->frame_rate) / MPEG1_FRAME_RATE_BASE - 1;
while (s->fake_picture_number < n) {
mpeg1_skip_picture(s, s->fake_picture_number -
s->gop_picture_number);
s->fake_picture_number++;
}
}
} }
static inline void encode_mb_skip_run(MpegEncContext *s, int run){ static inline void encode_mb_skip_run(MpegEncContext *s, int run){
@ -332,49 +343,6 @@ static inline void encode_mb_skip_run(MpegEncContext *s, int run){
put_bits(&s->pb, mbAddrIncrTable[run][1], put_bits(&s->pb, mbAddrIncrTable[run][1],
mbAddrIncrTable[run][0]); mbAddrIncrTable[run][0]);
} }
/* insert a fake P picture */
static void mpeg1_skip_picture(MpegEncContext *s, int pict_num)
{
assert(s->codec_id == CODEC_ID_MPEG1VIDEO); // mpeg2 can do these repeat things
/* mpeg1 picture header */
put_header(s, PICTURE_START_CODE);
/* temporal reference */
put_bits(&s->pb, 10, pict_num & 0x3ff);
put_bits(&s->pb, 3, P_TYPE);
put_bits(&s->pb, 16, 0xffff); /* non constant bit rate */
put_bits(&s->pb, 1, 1); /* integer coordinates */
put_bits(&s->pb, 3, 1); /* forward_f_code */
put_bits(&s->pb, 1, 0); /* extra bit picture */
/* only one slice */
put_header(s, SLICE_MIN_START_CODE);
put_bits(&s->pb, 5, 1); /* quantizer scale */
put_bits(&s->pb, 1, 0); /* slice extra information */
encode_mb_skip_run(s, 0);
/* empty macroblock */
put_bits(&s->pb, 3, 1); /* motion only */
/* zero motion x & y */
put_bits(&s->pb, 1, 1);
put_bits(&s->pb, 1, 1);
/* output a number of empty slice */
encode_mb_skip_run(s, s->mb_width * s->mb_height - 2);
/* empty macroblock */
put_bits(&s->pb, 3, 1); /* motion only */
/* zero motion x & y */
put_bits(&s->pb, 1, 1);
put_bits(&s->pb, 1, 1);
}
#endif //CONFIG_ENCODERS #endif //CONFIG_ENCODERS
static void common_init(MpegEncContext *s) static void common_init(MpegEncContext *s)
@ -409,8 +377,6 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
// RAL: s->picture_number instead of s->fake_picture_number // RAL: s->picture_number instead of s->fake_picture_number
put_bits(&s->pb, 10, (s->picture_number - put_bits(&s->pb, 10, (s->picture_number -
s->gop_picture_number) & 0x3ff); s->gop_picture_number) & 0x3ff);
s->fake_picture_number++;
put_bits(&s->pb, 3, s->pict_type); put_bits(&s->pb, 3, s->pict_type);
s->vbv_delay_ptr= s->pb.buf + get_bit_count(&s->pb)/8; s->vbv_delay_ptr= s->pb.buf + get_bit_count(&s->pb)/8;
@ -2746,6 +2712,32 @@ AVCodec mpegvideo_decoder = {
.flush= ff_mpeg_flush, .flush= ff_mpeg_flush,
}; };
#ifdef CONFIG_ENCODERS
AVCodec mpeg1video_encoder = {
"mpeg1video",
CODEC_TYPE_VIDEO,
CODEC_ID_MPEG1VIDEO,
sizeof(MpegEncContext),
encode_init,
MPV_encode_picture,
MPV_encode_end,
};
#ifdef CONFIG_RISKY
AVCodec mpeg2video_encoder = {
"mpeg2video",
CODEC_TYPE_VIDEO,
CODEC_ID_MPEG2VIDEO,
sizeof(MpegEncContext),
encode_init,
MPV_encode_picture,
MPV_encode_end,
};
#endif
#endif
#ifdef HAVE_XVMC #ifdef HAVE_XVMC
static int mpeg_mc_decode_init(AVCodecContext *avctx){ static int mpeg_mc_decode_init(AVCodecContext *avctx){
Mpeg1Context *s; Mpeg1Context *s;

@ -940,7 +940,7 @@ int MPV_encode_init(AVCodecContext *avctx)
default: default:
return -1; return -1;
} }
{ /* set up some save defaults, some codecs might override them later */ { /* set up some save defaults, some codecs might override them later */
static int done=0; static int done=0;
if(!done){ if(!done){
@ -1026,7 +1026,6 @@ int MPV_encode_init(AVCodecContext *avctx)
s->picture_number = 0; s->picture_number = 0;
s->input_picture_number = 0; s->input_picture_number = 0;
s->picture_in_gop_number = 0; s->picture_in_gop_number = 0;
s->fake_picture_number = 0;
/* motion detector init */ /* motion detector init */
s->f_code = 1; s->f_code = 1;
s->b_code = 1; s->b_code = 1;
@ -5227,29 +5226,7 @@ static const AVOption mpeg4_options[] =
}; };
#ifdef CONFIG_ENCODERS #ifdef CONFIG_ENCODERS
AVCodec mpeg1video_encoder = {
"mpeg1video",
CODEC_TYPE_VIDEO,
CODEC_ID_MPEG1VIDEO,
sizeof(MpegEncContext),
MPV_encode_init,
MPV_encode_picture,
MPV_encode_end,
};
#ifdef CONFIG_RISKY #ifdef CONFIG_RISKY
AVCodec mpeg2video_encoder = {
"mpeg2video",
CODEC_TYPE_VIDEO,
CODEC_ID_MPEG2VIDEO,
sizeof(MpegEncContext),
MPV_encode_init,
MPV_encode_picture,
MPV_encode_end,
};
AVCodec h263_encoder = { AVCodec h263_encoder = {
"h263", "h263",
CODEC_TYPE_VIDEO, CODEC_TYPE_VIDEO,

Loading…
Cancel
Save