X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmpeg12enc.c;h=441e9bbd78ccd93b2aa5f6a526cd98dc4f1577e0;hb=2f9d6ffda78725e11b351a7a5d69414a32010810;hp=b3ed3675a6b5fc62215f94c804a2abd76bbec86e;hpb=bd4640375e24fc0aa8846d9ee42cebe3c1fa9c12;p=ffmpeg diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c index b3ed3675a6b..441e9bbd78c 100644 --- a/libavcodec/mpeg12enc.c +++ b/libavcodec/mpeg12enc.c @@ -33,8 +33,9 @@ #include "mpeg12data.h" #include "bytestream.h" #include "timecode.h" +#include "libavutil/log.h" #include "libavutil/opt.h" - +#include "libavutil/avassert.h" static const uint8_t inv_non_linear_qscale[13] = { 0, 2, 4, 6, 8, @@ -142,6 +143,13 @@ static av_cold int encode_init(AVCodecContext *avctx) if(MPV_encode_init(avctx) < 0) return -1; +#if FF_API_MPEGVIDEO_GLOBAL_OPTS + if (avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) + s->drop_frame_timecode = 1; + if (avctx->flags & CODEC_FLAG_SVCD_SCAN_OFFSET) + s->scan_offset = 1; +#endif + if(find_frame_rate_index(s) < 0){ if(s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ av_log(avctx, AV_LOG_ERROR, "MPEG1/2 does not support %d/%d fps\n", avctx->time_base.den, avctx->time_base.num); @@ -174,8 +182,8 @@ static av_cold int encode_init(AVCodecContext *avctx) } } - s->tc.drop = !!(avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE); - if((avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) && s->frame_rate_index != 4){ + s->drop_frame_timecode = s->tc.drop = s->drop_frame_timecode || !!(avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE); + if (s->drop_frame_timecode && s->frame_rate_index != 4) { av_log(avctx, AV_LOG_ERROR, "Drop frame time code only allowed with 1001/30000 fps\n"); return -1; } @@ -292,13 +300,14 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) } put_header(s, GOP_START_CODE); - put_bits(&s->pb, 1, s->tc.drop); + put_bits(&s->pb, 1, s->drop_frame_timecode); /* drop frame flag */ /* time code : we must convert from the real frame rate to a fake mpeg frame rate in case of low frame rate */ fps = (framerate.num + framerate.den/2)/ framerate.den; time_code = s->current_picture_ptr->f.coded_picture_number + s->avctx->timecode_frame_start; s->gop_picture_number = s->current_picture_ptr->f.coded_picture_number; + av_assert0(s->drop_frame_timecode == s->tc.drop); if (s->tc.drop) time_code = ff_framenum_to_drop_timecode(time_code); put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24)); @@ -417,7 +426,7 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) put_bits(&s->pb, 1, s->progressive_frame); put_bits(&s->pb, 1, 0); //composite_display_flag } - if(s->flags & CODEC_FLAG_SVCD_SCAN_OFFSET){ + if (s->scan_offset) { int i; put_header(s, USER_START_CODE); @@ -929,17 +938,38 @@ static void mpeg1_encode_block(MpegEncContext *s, put_bits(&s->pb, table_vlc[112][1], table_vlc[112][0]); } -static const AVClass class = { - .class_name = "mpegvideo", - .item_name = av_default_item_name, - .version = LIBAVUTIL_VERSION_INT, - .option = (const AVOption[]){ - {TIMECODE_OPT(MpegEncContext, - AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)}, - {NULL} - }, +#define OFFSET(x) offsetof(MpegEncContext, x) +#define VE AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM +#define COMMON_OPTS\ + {TIMECODE_OPT(MpegEncContext,\ + AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)},\ + { "intra_vlc", "Use MPEG-2 intra VLC table.", OFFSET(intra_vlc_format), FF_OPT_TYPE_INT, { 0 }, 0, 1, VE },\ + { "drop_frame_timecode", "Timecode is in drop frame format.", OFFSET(drop_frame_timecode), FF_OPT_TYPE_INT, { 0 }, 0, 1, VE}, \ + { "scan_offset", "Reserve space for SVCD scan offset user data.", OFFSET(scan_offset), FF_OPT_TYPE_INT, { 0 }, 0, 1, VE }, + +static const AVOption mpeg1_options[] = { + COMMON_OPTS + { NULL }, +}; + +static const AVOption mpeg2_options[] = { + COMMON_OPTS + { "non_linear_quant", "Use nonlinear quantizer.", OFFSET(q_scale_type), FF_OPT_TYPE_INT, { 0 }, 0, 1, VE }, + { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), FF_OPT_TYPE_INT, { 0 }, 0, 1, VE }, + { NULL }, }; +#define mpeg12_class(x)\ +static const AVClass mpeg## x ##_class = {\ + .class_name = "mpeg" #x "video encoder",\ + .item_name = av_default_item_name,\ + .option = mpeg## x ##_options,\ + .version = LIBAVUTIL_VERSION_INT,\ +}; + +mpeg12_class(1) +mpeg12_class(2) + AVCodec ff_mpeg1video_encoder = { .name = "mpeg1video", .type = AVMEDIA_TYPE_VIDEO, @@ -952,7 +982,7 @@ AVCodec ff_mpeg1video_encoder = { .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, .capabilities= CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), - .priv_class = &class, + .priv_class = &mpeg1_class, }; AVCodec ff_mpeg2video_encoder = { @@ -967,5 +997,5 @@ AVCodec ff_mpeg2video_encoder = { .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE}, .capabilities= CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, .long_name= NULL_IF_CONFIG_SMALL("MPEG-2 video"), - .priv_class = &class, + .priv_class = &mpeg2_class, };