annotate ffmpeg/libavfilter/af_apad.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) 2012 Michael Niedermayer
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 /**
yading@10 23 * @file
yading@10 24 * audio pad filter.
yading@10 25 *
yading@10 26 * Based on af_aresample.c
yading@10 27 */
yading@10 28
yading@10 29 #include "libavutil/avstring.h"
yading@10 30 #include "libavutil/channel_layout.h"
yading@10 31 #include "libavutil/opt.h"
yading@10 32 #include "libavutil/samplefmt.h"
yading@10 33 #include "libavutil/avassert.h"
yading@10 34 #include "avfilter.h"
yading@10 35 #include "audio.h"
yading@10 36 #include "internal.h"
yading@10 37
yading@10 38 typedef struct {
yading@10 39 const AVClass *class;
yading@10 40 int64_t next_pts;
yading@10 41
yading@10 42 int packet_size;
yading@10 43 int64_t pad_len;
yading@10 44 int64_t whole_len;
yading@10 45 } APadContext;
yading@10 46
yading@10 47 #define OFFSET(x) offsetof(APadContext, x)
yading@10 48 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
yading@10 49
yading@10 50 static const AVOption apad_options[] = {
yading@10 51 { "packet_size", "set silence packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, { .i64 = 4096 }, 0, INT_MAX, A },
yading@10 52 { "pad_len", "number of samples of silence to add", OFFSET(pad_len), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, A },
yading@10 53 { "whole_len", "target number of samples in the audio stream", OFFSET(whole_len), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, A },
yading@10 54 { NULL },
yading@10 55 };
yading@10 56
yading@10 57 AVFILTER_DEFINE_CLASS(apad);
yading@10 58
yading@10 59 static av_cold int init(AVFilterContext *ctx)
yading@10 60 {
yading@10 61 APadContext *apad = ctx->priv;
yading@10 62
yading@10 63 apad->next_pts = AV_NOPTS_VALUE;
yading@10 64 if (apad->whole_len && apad->pad_len) {
yading@10 65 av_log(ctx, AV_LOG_ERROR, "Both whole and pad length are set, this is not possible\n");
yading@10 66 return AVERROR(EINVAL);
yading@10 67 }
yading@10 68
yading@10 69 return 0;
yading@10 70 }
yading@10 71
yading@10 72 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
yading@10 73 {
yading@10 74 AVFilterContext *ctx = inlink->dst;
yading@10 75 APadContext *apad = ctx->priv;
yading@10 76
yading@10 77 if (apad->whole_len)
yading@10 78 apad->whole_len -= frame->nb_samples;
yading@10 79
yading@10 80 apad->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base);
yading@10 81 return ff_filter_frame(ctx->outputs[0], frame);
yading@10 82 }
yading@10 83
yading@10 84 static int request_frame(AVFilterLink *outlink)
yading@10 85 {
yading@10 86 AVFilterContext *ctx = outlink->src;
yading@10 87 APadContext *apad = ctx->priv;
yading@10 88 int ret;
yading@10 89
yading@10 90 ret = ff_request_frame(ctx->inputs[0]);
yading@10 91
yading@10 92 if (ret == AVERROR_EOF) {
yading@10 93 int n_out = apad->packet_size;
yading@10 94 AVFrame *outsamplesref;
yading@10 95
yading@10 96 if (apad->whole_len > 0) {
yading@10 97 apad->pad_len = apad->whole_len;
yading@10 98 apad->whole_len = 0;
yading@10 99 }
yading@10 100 if (apad->pad_len > 0) {
yading@10 101 n_out = FFMIN(n_out, apad->pad_len);
yading@10 102 apad->pad_len -= n_out;
yading@10 103 }
yading@10 104
yading@10 105 if(!n_out)
yading@10 106 return AVERROR_EOF;
yading@10 107
yading@10 108 outsamplesref = ff_get_audio_buffer(outlink, n_out);
yading@10 109 if (!outsamplesref)
yading@10 110 return AVERROR(ENOMEM);
yading@10 111
yading@10 112 av_assert0(outsamplesref->sample_rate == outlink->sample_rate);
yading@10 113 av_assert0(outsamplesref->nb_samples == n_out);
yading@10 114
yading@10 115 av_samples_set_silence(outsamplesref->extended_data, 0,
yading@10 116 n_out,
yading@10 117 av_frame_get_channels(outsamplesref),
yading@10 118 outsamplesref->format);
yading@10 119
yading@10 120 outsamplesref->pts = apad->next_pts;
yading@10 121 if (apad->next_pts != AV_NOPTS_VALUE)
yading@10 122 apad->next_pts += av_rescale_q(n_out, (AVRational){1, outlink->sample_rate}, outlink->time_base);
yading@10 123
yading@10 124 return ff_filter_frame(outlink, outsamplesref);
yading@10 125 }
yading@10 126 return ret;
yading@10 127 }
yading@10 128
yading@10 129 static const AVFilterPad apad_inputs[] = {
yading@10 130 {
yading@10 131 .name = "default",
yading@10 132 .type = AVMEDIA_TYPE_AUDIO,
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 apad_outputs[] = {
yading@10 139 {
yading@10 140 .name = "default",
yading@10 141 .request_frame = request_frame,
yading@10 142 .type = AVMEDIA_TYPE_AUDIO,
yading@10 143 },
yading@10 144 { NULL },
yading@10 145 };
yading@10 146
yading@10 147 AVFilter avfilter_af_apad = {
yading@10 148 .name = "apad",
yading@10 149 .description = NULL_IF_CONFIG_SMALL("Pad audio with silence."),
yading@10 150 .init = init,
yading@10 151 .priv_size = sizeof(APadContext),
yading@10 152 .inputs = apad_inputs,
yading@10 153 .outputs = apad_outputs,
yading@10 154 .priv_class = &apad_class,
yading@10 155 };