annotate ffmpeg/libavfilter/f_settb.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Copyright (c) 2010 Stefano Sabatini
yading@10 3 *
yading@10 4 * This file is part of FFmpeg.
yading@10 5 *
yading@10 6 * FFmpeg is free software; you can redistribute it and/or
yading@10 7 * modify it under the terms of the GNU Lesser General Public
yading@10 8 * License as published by the Free Software Foundation; either
yading@10 9 * version 2.1 of the License, or (at your option) any later version.
yading@10 10 *
yading@10 11 * FFmpeg is distributed in the hope that it will be useful,
yading@10 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 14 * Lesser General Public License for more details.
yading@10 15 *
yading@10 16 * You should have received a copy of the GNU Lesser General Public
yading@10 17 * License along with FFmpeg; if not, write to the Free Software
yading@10 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 19 */
yading@10 20
yading@10 21 /**
yading@10 22 * @file
yading@10 23 * Set timebase for the output link.
yading@10 24 */
yading@10 25
yading@10 26 #include <inttypes.h>
yading@10 27 #include <stdio.h>
yading@10 28
yading@10 29 #include "libavutil/avstring.h"
yading@10 30 #include "libavutil/eval.h"
yading@10 31 #include "libavutil/internal.h"
yading@10 32 #include "libavutil/mathematics.h"
yading@10 33 #include "libavutil/opt.h"
yading@10 34 #include "libavutil/rational.h"
yading@10 35 #include "avfilter.h"
yading@10 36 #include "internal.h"
yading@10 37 #include "audio.h"
yading@10 38 #include "video.h"
yading@10 39
yading@10 40 static const char *const var_names[] = {
yading@10 41 "AVTB", /* default timebase 1/AV_TIME_BASE */
yading@10 42 "intb", /* input timebase */
yading@10 43 "sr", /* sample rate */
yading@10 44 NULL
yading@10 45 };
yading@10 46
yading@10 47 enum var_name {
yading@10 48 VAR_AVTB,
yading@10 49 VAR_INTB,
yading@10 50 VAR_SR,
yading@10 51 VAR_VARS_NB
yading@10 52 };
yading@10 53
yading@10 54 typedef struct {
yading@10 55 const AVClass *class;
yading@10 56 char *tb_expr;
yading@10 57 double var_values[VAR_VARS_NB];
yading@10 58 } SetTBContext;
yading@10 59
yading@10 60 #define OFFSET(x) offsetof(SetTBContext, x)
yading@10 61 #define DEFINE_OPTIONS(filt_name, filt_type) \
yading@10 62 static const AVOption filt_name##_options[] = { \
yading@10 63 { "expr", "set expression determining the output timebase", OFFSET(tb_expr), AV_OPT_TYPE_STRING, {.str="intb"}, \
yading@10 64 .flags=AV_OPT_FLAG_##filt_type##_PARAM|AV_OPT_FLAG_FILTERING_PARAM }, \
yading@10 65 { "tb", "set expression determining the output timebase", OFFSET(tb_expr), AV_OPT_TYPE_STRING, {.str="intb"}, \
yading@10 66 .flags=AV_OPT_FLAG_##filt_type##_PARAM|AV_OPT_FLAG_FILTERING_PARAM }, \
yading@10 67 { NULL } \
yading@10 68 }
yading@10 69
yading@10 70 static int config_output_props(AVFilterLink *outlink)
yading@10 71 {
yading@10 72 AVFilterContext *ctx = outlink->src;
yading@10 73 SetTBContext *settb = ctx->priv;
yading@10 74 AVFilterLink *inlink = ctx->inputs[0];
yading@10 75 AVRational time_base;
yading@10 76 int ret;
yading@10 77 double res;
yading@10 78
yading@10 79 settb->var_values[VAR_AVTB] = av_q2d(AV_TIME_BASE_Q);
yading@10 80 settb->var_values[VAR_INTB] = av_q2d(inlink->time_base);
yading@10 81 settb->var_values[VAR_SR] = inlink->sample_rate;
yading@10 82
yading@10 83 outlink->w = inlink->w;
yading@10 84 outlink->h = inlink->h;
yading@10 85
yading@10 86 if ((ret = av_expr_parse_and_eval(&res, settb->tb_expr, var_names, settb->var_values,
yading@10 87 NULL, NULL, NULL, NULL, NULL, 0, NULL)) < 0) {
yading@10 88 av_log(ctx, AV_LOG_ERROR, "Invalid expression '%s' for timebase.\n", settb->tb_expr);
yading@10 89 return ret;
yading@10 90 }
yading@10 91 time_base = av_d2q(res, INT_MAX);
yading@10 92 if (time_base.num <= 0 || time_base.den <= 0) {
yading@10 93 av_log(ctx, AV_LOG_ERROR,
yading@10 94 "Invalid non-positive values for the timebase num:%d or den:%d.\n",
yading@10 95 time_base.num, time_base.den);
yading@10 96 return AVERROR(EINVAL);
yading@10 97 }
yading@10 98
yading@10 99 outlink->time_base = time_base;
yading@10 100 av_log(outlink->src, AV_LOG_VERBOSE, "tb:%d/%d -> tb:%d/%d\n",
yading@10 101 inlink ->time_base.num, inlink ->time_base.den,
yading@10 102 outlink->time_base.num, outlink->time_base.den);
yading@10 103
yading@10 104 return 0;
yading@10 105 }
yading@10 106
yading@10 107 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
yading@10 108 {
yading@10 109 AVFilterContext *ctx = inlink->dst;
yading@10 110 AVFilterLink *outlink = ctx->outputs[0];
yading@10 111
yading@10 112 if (av_cmp_q(inlink->time_base, outlink->time_base)) {
yading@10 113 int64_t orig_pts = frame->pts;
yading@10 114 frame->pts = av_rescale_q(frame->pts, inlink->time_base, outlink->time_base);
yading@10 115 av_log(ctx, AV_LOG_DEBUG, "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
yading@10 116 inlink ->time_base.num, inlink ->time_base.den, orig_pts,
yading@10 117 outlink->time_base.num, outlink->time_base.den, frame->pts);
yading@10 118 }
yading@10 119
yading@10 120 return ff_filter_frame(outlink, frame);
yading@10 121 }
yading@10 122
yading@10 123 #if CONFIG_SETTB_FILTER
yading@10 124
yading@10 125 DEFINE_OPTIONS(settb, VIDEO);
yading@10 126 AVFILTER_DEFINE_CLASS(settb);
yading@10 127
yading@10 128 static const AVFilterPad avfilter_vf_settb_inputs[] = {
yading@10 129 {
yading@10 130 .name = "default",
yading@10 131 .type = AVMEDIA_TYPE_VIDEO,
yading@10 132 .get_video_buffer = ff_null_get_video_buffer,
yading@10 133 .filter_frame = filter_frame,
yading@10 134 },
yading@10 135 { NULL }
yading@10 136 };
yading@10 137
yading@10 138 static const AVFilterPad avfilter_vf_settb_outputs[] = {
yading@10 139 {
yading@10 140 .name = "default",
yading@10 141 .type = AVMEDIA_TYPE_VIDEO,
yading@10 142 .config_props = config_output_props,
yading@10 143 },
yading@10 144 { NULL }
yading@10 145 };
yading@10 146
yading@10 147 AVFilter avfilter_vf_settb = {
yading@10 148 .name = "settb",
yading@10 149 .description = NULL_IF_CONFIG_SMALL("Set timebase for the video output link."),
yading@10 150
yading@10 151 .priv_size = sizeof(SetTBContext),
yading@10 152 .priv_class = &settb_class,
yading@10 153
yading@10 154 .inputs = avfilter_vf_settb_inputs,
yading@10 155 .outputs = avfilter_vf_settb_outputs,
yading@10 156 };
yading@10 157 #endif
yading@10 158
yading@10 159 #if CONFIG_ASETTB_FILTER
yading@10 160
yading@10 161 DEFINE_OPTIONS(asettb, AUDIO);
yading@10 162 AVFILTER_DEFINE_CLASS(asettb);
yading@10 163
yading@10 164 static const AVFilterPad avfilter_af_asettb_inputs[] = {
yading@10 165 {
yading@10 166 .name = "default",
yading@10 167 .type = AVMEDIA_TYPE_AUDIO,
yading@10 168 .get_audio_buffer = ff_null_get_audio_buffer,
yading@10 169 .filter_frame = filter_frame,
yading@10 170 },
yading@10 171 { NULL }
yading@10 172 };
yading@10 173
yading@10 174 static const AVFilterPad avfilter_af_asettb_outputs[] = {
yading@10 175 {
yading@10 176 .name = "default",
yading@10 177 .type = AVMEDIA_TYPE_AUDIO,
yading@10 178 .config_props = config_output_props,
yading@10 179 },
yading@10 180 { NULL }
yading@10 181 };
yading@10 182
yading@10 183 AVFilter avfilter_af_asettb = {
yading@10 184 .name = "asettb",
yading@10 185 .description = NULL_IF_CONFIG_SMALL("Set timebase for the audio output link."),
yading@10 186
yading@10 187 .priv_size = sizeof(SetTBContext),
yading@10 188 .inputs = avfilter_af_asettb_inputs,
yading@10 189 .outputs = avfilter_af_asettb_outputs,
yading@10 190 .priv_class = &asettb_class,
yading@10 191 };
yading@10 192 #endif