美文网首页
ffmpeg # -ss在ffmpeg中的单位是AV_TIME_

ffmpeg # -ss在ffmpeg中的单位是AV_TIME_

作者: FlyingPenguin | 来源:发表于2019-04-20 15:20 被阅读0次
ffmpeg -ss 10.800 -i input.flv -t 5 -c copy -vframes 600  -y out.mp4

-ss用于将文件seek到指定的时间点位置。
这条命令中的-ss的单位是什么? 实际命令行中-ss支持的格式 为:
http://ffmpeg.org/ffmpeg-utils.html#time-duration-syntax

The following examples are all valid time duration:
‘55’
55 seconds

‘12:03:45’
12 hours, 03 minutes and 45 seconds

‘23.189’
23.189 seconds

可见-ss中跟的就是真实的时间点

在ffmpeg代码中 又是以什么单位存在呢?
ffmpeg_opt.c中,OptionDef中

    { "ss",             HAS_ARG | OPT_TIME | OPT_OFFSET |
                        OPT_INPUT | OPT_OUTPUT,                      { .off = OFFSET(start_time) },
        "set the start time offset", "time_off" },

可见-ss对应的变量类型为OPT_TIME,保存在变量start_time中。

typedef struct OptionsContext {
    OptionGroup *g;

    /* input/output options */
    int64_t start_time;
    int64_t start_time_eof;
    int seek_timestamp;
    ...
    int64_t recording_time;
    int64_t stop_time;
    ...
} OptionsContext;

start_time中保存的是什么呢?
解析参数时:


else if (po->flags & OPT_TIME) {
        *(int64_t *)dst = parse_time_or_die(opt, arg, 1);
    }

最终调用的用于解析的函数如下:

int av_parse_time(int64_t *timeval, const char *timestr, int duration)
{
   ...
   int today = 0, negative = 0, microseconds = 0, suffix = 1000000;
   ...
    t *= suffix;
    t += microseconds;
    *timeval = negative ? -t : t;
    return 0;
}

可见最终解析的时间转换为1000000为单位,也就是微秒为单位
其实也就是单位是AV_TIME_BASE.

/**
 * Internal time base represented as integer
 */

#define AV_TIME_BASE            1000000

/**
 * Internal time base represented as fractional value
 */

#define AV_TIME_BASE_Q          (AVRational){1, AV_TIME_BASE}

也就是说OptionsContext中的start_time的单位是AV_TIME_BASE。
同样情况的还有:


所以,只要看到OptionsContext中的以上几个变量,应该知道它们的单位就是AV_TIME_BASE
只要能和这些变量发生赋值或加减操作的,单位肯定也是AV_TIME_BASE.

比如static int open_input_file(OptionsContext *o, const char *filename)
函数中的

...
    if (o->stop_time != INT64_MAX && o->recording_time != INT64_MAX) {
        o->stop_time = INT64_MAX;
        av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
    }
...
    if (o->start_time_eof != AV_NOPTS_VALUE) {
        if (o->start_time_eof >= 0) {
            av_log(NULL, AV_LOG_ERROR, "-sseof value must be negative; aborting\n");
            exit_program(1);
        }
        if (ic->duration > 0) {
        // 这里ic->duration可以和o->start_time_eof相加
        // 说明它的单位肯定也是AV_TIME_BASE
            o->start_time = o->start_time_eof + ic->duration;
            if (o->start_time < 0) {
                av_log(NULL, AV_LOG_WARNING, "-sseof value seeks to before start of file %s; ignored\n", filename);
                o->start_time = AV_NOPTS_VALUE;
            }
        } else
            av_log(NULL, AV_LOG_WARNING, "Cannot use -sseof, duration of %s not known\n", filename);
    }
...
    // 这里timestamp可被o->start_time赋值
    // 说明它的单位肯定也是AV_TIME_BASE
    timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
    /* add the stream start time */
    if (!o->seek_timestamp && ic->start_time != AV_NOPTS_VALUE)
        timestamp += ic->start_time;
...
    f = av_mallocz(sizeof(*f));
    if (!f)
        exit_program(1);
    input_files[nb_input_files - 1] = f;

    f->ctx        = ic;
    f->ist_index  = nb_input_streams - ic->nb_streams;
// 通过以下的赋值操作
// 可以看出InputFile的start_time、recording_time、
// input_ts_offset、ts_offset的单位肯定也是AV_TIME_BASE
    f->start_time = o->start_time;
    f->recording_time = o->recording_time;
    f->input_ts_offset = o->input_ts_offset;
    f->ts_offset  = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp);

References:

相关文章

网友评论

      本文标题:ffmpeg # -ss在ffmpeg中的单位是AV_TIME_

      本文链接:https://www.haomeiwen.com/subject/yetlgqtx.html