[FFmpeg-devel] [PATCH 2/2] avformat/microdvd: export the declared frame rate
Clément Bœsch
u at pkh.me
Mon Mar 3 23:39:07 CET 2014
On Sun, Mar 02, 2014 at 10:36:42PM +0100, wm4 wrote:
> MicroDVD files are normally frame-based (i.e. there are no absolute
> timestamps), but can have an optional frame rate header. If this
> header is missing, the timestamps depend on the frame rate of the
> video they were created for.
>
> The demuxer will use a fallback frame rate if it's missing from the
> header. Currently, applications using libavformat can't know whether
> the time base is based on the fallback value, or if a frame rate
> header was present.
>
> This commit introduces a subfps AVOption for MicroDVD, and the
> demuxer sets it if and only if a frame rate header was present.
> ---
> libavformat/microdvddec.c | 29 ++++++++++++++++++++++++++++-
> 1 file changed, 28 insertions(+), 1 deletion(-)
>
> diff --git a/libavformat/microdvddec.c b/libavformat/microdvddec.c
> index 42c6de0..a705442 100644
> --- a/libavformat/microdvddec.c
> +++ b/libavformat/microdvddec.c
> @@ -24,12 +24,15 @@
> #include "internal.h"
> #include "subtitles.h"
> #include "libavutil/intreadwrite.h"
> +#include "libavutil/opt.h"
>
> #define MAX_LINESIZE 2048
>
>
> typedef struct {
> + const AVClass *class;
> FFDemuxSubtitlesQueue q;
> + AVRational frame_rate;
> } MicroDVDContext;
>
>
> @@ -80,6 +83,7 @@ static int microdvd_read_header(AVFormatContext *s)
> AVStream *st = avformat_new_stream(s, NULL);
> int i = 0;
> char line_buf[MAX_LINESIZE];
> + int has_real_fps = 0;
>
> if (!st)
> return AVERROR(ENOMEM);
> @@ -105,8 +109,10 @@ static int microdvd_read_header(AVFormatContext *s)
>
> if ((sscanf(line, "{%d}{}%6lf", &frame, &fps) == 2 ||
> sscanf(line, "{%d}{%*d}%6lf", &frame, &fps) == 2)
> - && frame <= 1 && fps > 3 && fps < 100)
> + && frame <= 1 && fps > 3 && fps < 100) {
> pts_info = av_d2q(fps, 100000);
> + has_real_fps = 1;
> + }
> if (!st->codec->extradata && sscanf(line, "{DEFAULT}{}%c", &c) == 1) {
> st->codec->extradata = av_strdup(line + 11);
> if (!st->codec->extradata)
> @@ -135,6 +141,11 @@ static int microdvd_read_header(AVFormatContext *s)
> sub->duration = get_duration(line);
> }
> ff_subtitles_queue_finalize(µdvd->q);
> + if (has_real_fps) {
> + microdvd->frame_rate = pts_info;
> + } else if (microdvd->frame_rate.num) {
> + pts_info = microdvd->frame_rate;
> + }
> avpriv_set_pts_info(st, 64, pts_info.den, pts_info.num);
> st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
> st->codec->codec_id = AV_CODEC_ID_MICRODVD;
> @@ -162,6 +173,21 @@ static int microdvd_read_close(AVFormatContext *s)
> return 0;
> }
>
> +
> +#define OFFSET(x) offsetof(MicroDVDContext, x)
> +#define SD AV_OPT_FLAG_SUBTITLE_PARAM|AV_OPT_FLAG_DECODING_PARAM
> +static const AVOption microdvd_options[] = {
> + { "subfps", "set the movie frame rate", OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL, {.dbl=0}, 0, INT_MAX, SD },
> + { NULL }
> +};
> +
> +static const AVClass microdvd_class = {
> + .class_name = "microdvddec",
> + .item_name = av_default_item_name,
> + .option = microdvd_options,
> + .version = LIBAVUTIL_VERSION_INT,
> +};
> +
> AVInputFormat ff_microdvd_demuxer = {
> .name = "microdvd",
> .long_name = NULL_IF_CONFIG_SMALL("MicroDVD subtitle format"),
> @@ -171,4 +197,5 @@ AVInputFormat ff_microdvd_demuxer = {
> .read_packet = microdvd_read_packet,
> .read_seek2 = microdvd_read_seek,
> .read_close = microdvd_read_close,
> + .priv_class = µdvd_class,
> };
Pushed with 3 changes: lavf micro bumped, added 2 comments, explicit that
the subfps is a fallback.
Thanks,
--
Clément B.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140303/80808514/attachment.asc>
More information about the ffmpeg-devel
mailing list