static int find_frame_rate_index(MpegEncContext *s){
int i;
- int64_t dmin= INT64_MAX;
- int64_t d;
+ AVRational bestq= (AVRational){0, 0};
+ AVRational ext;
+ AVRational target = av_inv_q(s->avctx->time_base);
for(i=1;i<14;i++) {
- int64_t n0= 1001LL/avpriv_frame_rate_tab[i].den*avpriv_frame_rate_tab[i].num*s->avctx->time_base.num;
- int64_t n1= 1001LL*s->avctx->time_base.den;
if(s->avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL && i>=9) break;
- d = FFABS(n0 - n1);
- if(d < dmin){
- dmin=d;
- s->frame_rate_index= i;
+ for (ext.num=1; ext.num <= 4; ext.num++) {
+ for (ext.den=1; ext.den <= 32; ext.den++) {
+ AVRational q = av_mul_q(ext, avpriv_frame_rate_tab[i]);
+
+ if(s->codec_id != AV_CODEC_ID_MPEG2VIDEO && (ext.den!=1 || ext.num!=1))
+ continue;
+ if(av_gcd(ext.den, ext.num) != 1)
+ continue;
+
+ if( bestq.num==0
+ || av_nearer_q(target, bestq, q) < 0
+ || ext.num==1 && ext.den==1 && av_nearer_q(target, bestq, q) == 0){
+ bestq = q;
+ s->frame_rate_index= i;
+ s->mpeg2_frame_rate_ext.num = ext.num;
+ s->mpeg2_frame_rate_ext.den = ext.den;
+ }
+ }
}
}
- if(dmin)
+ if(av_cmp_q(target, bestq))
return -1;
else
return 0;
put_bits(&s->pb, 1, 1); //marker
put_bits(&s->pb, 8, vbv_buffer_size >>10); //vbv buffer ext
put_bits(&s->pb, 1, s->low_delay);
- put_bits(&s->pb, 2, 0); // frame_rate_ext_n
- put_bits(&s->pb, 5, 0); // frame_rate_ext_d
+ put_bits(&s->pb, 2, s->mpeg2_frame_rate_ext.num-1); // frame_rate_ext_n
+ put_bits(&s->pb, 5, s->mpeg2_frame_rate_ext.den-1); // frame_rate_ext_d
}
put_header(s, GOP_START_CODE);
#define VE AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
#define COMMON_OPTS\
{ "gop_timecode", "MPEG GOP Timecode in hh:mm:ss[:;.]ff format", OFFSET(tc_opt_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, VE },\
- { "intra_vlc", "Use MPEG-2 intra VLC table.", OFFSET(intra_vlc_format), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },\
- { "drop_frame_timecode", "Timecode is in drop frame format.", OFFSET(drop_frame_timecode), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE}, \
- { "scan_offset", "Reserve space for SVCD scan offset user data.", OFFSET(scan_offset), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+ { "intra_vlc", "Use MPEG-2 intra VLC table.", OFFSET(intra_vlc_format), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },\
+ { "drop_frame_timecode", "Timecode is in drop frame format.", OFFSET(drop_frame_timecode), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE}, \
+ { "scan_offset", "Reserve space for SVCD scan offset user data.", OFFSET(scan_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
static const AVOption mpeg1_options[] = {
COMMON_OPTS
static const AVOption mpeg2_options[] = {
COMMON_OPTS
- { "non_linear_quant", "Use nonlinear quantizer.", OFFSET(q_scale_type), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
- { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+ { "non_linear_quant", "Use nonlinear quantizer.", OFFSET(q_scale_type), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+ { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
FF_MPV_COMMON_OPTS
{ NULL },
};
.init = encode_init,
.encode2 = ff_MPV_encode_picture,
.close = ff_MPV_encode_end,
- .supported_framerates = avpriv_frame_rate_tab + 1,
+ .supported_framerates = ff_mpeg2_frame_rate_tab,
.pix_fmts = (const enum PixelFormat[]){
PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE
},