00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/avassert.h"
00023 #include "libavutil/audioconvert.h"
00024
00025 #include "audio.h"
00026 #include "avfilter.h"
00027 #include "internal.h"
00028
00029 AVFilterBufferRef *ff_null_get_audio_buffer(AVFilterLink *link, int perms,
00030 int nb_samples)
00031 {
00032 return ff_get_audio_buffer(link->dst->outputs[0], perms, nb_samples);
00033 }
00034
00035 AVFilterBufferRef *ff_default_get_audio_buffer(AVFilterLink *link, int perms,
00036 int nb_samples)
00037 {
00038 AVFilterBufferRef *samplesref = NULL;
00039 uint8_t **data;
00040 int planar = av_sample_fmt_is_planar(link->format);
00041 int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
00042 int planes = planar ? nb_channels : 1;
00043 int linesize;
00044
00045 if (!(data = av_mallocz(sizeof(*data) * planes)))
00046 goto fail;
00047
00048 if (av_samples_alloc(data, &linesize, nb_channels, nb_samples, link->format, 0) < 0)
00049 goto fail;
00050
00051 samplesref = avfilter_get_audio_buffer_ref_from_arrays(data, linesize, perms,
00052 nb_samples, link->format,
00053 link->channel_layout);
00054 if (!samplesref)
00055 goto fail;
00056
00057 av_freep(&data);
00058
00059 fail:
00060 if (data)
00061 av_freep(&data[0]);
00062 av_freep(&data);
00063 return samplesref;
00064 }
00065
00066 AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
00067 int nb_samples)
00068 {
00069 AVFilterBufferRef *ret = NULL;
00070
00071 if (link->dstpad->get_audio_buffer)
00072 ret = link->dstpad->get_audio_buffer(link, perms, nb_samples);
00073
00074 if (!ret)
00075 ret = ff_default_get_audio_buffer(link, perms, nb_samples);
00076
00077 if (ret)
00078 ret->type = AVMEDIA_TYPE_AUDIO;
00079
00080 return ret;
00081 }
00082
00083 AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
00084 int linesize,int perms,
00085 int nb_samples,
00086 enum AVSampleFormat sample_fmt,
00087 uint64_t channel_layout)
00088 {
00089 int planes;
00090 AVFilterBuffer *samples = av_mallocz(sizeof(*samples));
00091 AVFilterBufferRef *samplesref = av_mallocz(sizeof(*samplesref));
00092
00093 if (!samples || !samplesref)
00094 goto fail;
00095
00096 samplesref->buf = samples;
00097 samplesref->buf->free = ff_avfilter_default_free_buffer;
00098 if (!(samplesref->audio = av_mallocz(sizeof(*samplesref->audio))))
00099 goto fail;
00100
00101 samplesref->audio->nb_samples = nb_samples;
00102 samplesref->audio->channel_layout = channel_layout;
00103
00104 planes = av_sample_fmt_is_planar(sample_fmt) ?
00105 av_get_channel_layout_nb_channels(channel_layout) : 1;
00106
00107
00108 samplesref->perms = perms | AV_PERM_READ;
00109
00110 samples->refcount = 1;
00111 samplesref->type = AVMEDIA_TYPE_AUDIO;
00112 samplesref->format = sample_fmt;
00113
00114 memcpy(samples->data, data,
00115 FFMIN(FF_ARRAY_ELEMS(samples->data), planes)*sizeof(samples->data[0]));
00116 memcpy(samplesref->data, samples->data, sizeof(samples->data));
00117
00118 samples->linesize[0] = samplesref->linesize[0] = linesize;
00119
00120 if (planes > FF_ARRAY_ELEMS(samples->data)) {
00121 samples-> extended_data = av_mallocz(sizeof(*samples->extended_data) *
00122 planes);
00123 samplesref->extended_data = av_mallocz(sizeof(*samplesref->extended_data) *
00124 planes);
00125
00126 if (!samples->extended_data || !samplesref->extended_data)
00127 goto fail;
00128
00129 memcpy(samples-> extended_data, data, sizeof(*data)*planes);
00130 memcpy(samplesref->extended_data, data, sizeof(*data)*planes);
00131 } else {
00132 samples->extended_data = samples->data;
00133 samplesref->extended_data = samplesref->data;
00134 }
00135
00136 samplesref->pts = AV_NOPTS_VALUE;
00137
00138 return samplesref;
00139
00140 fail:
00141 if (samples && samples->extended_data != samples->data)
00142 av_freep(&samples->extended_data);
00143 if (samplesref) {
00144 av_freep(&samplesref->audio);
00145 if (samplesref->extended_data != samplesref->data)
00146 av_freep(&samplesref->extended_data);
00147 }
00148 av_freep(&samplesref);
00149 av_freep(&samples);
00150 return NULL;
00151 }
00152
00153 void ff_null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
00154 {
00155 ff_filter_samples(link->dst->outputs[0], samplesref);
00156 }
00157
00158
00159 void ff_default_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
00160 {
00161 AVFilterLink *outlink = NULL;
00162
00163 if (inlink->dst->output_count)
00164 outlink = inlink->dst->outputs[0];
00165
00166 if (outlink) {
00167 outlink->out_buf = ff_default_get_audio_buffer(inlink, AV_PERM_WRITE,
00168 samplesref->audio->nb_samples);
00169 outlink->out_buf->pts = samplesref->pts;
00170 outlink->out_buf->audio->sample_rate = samplesref->audio->sample_rate;
00171 ff_filter_samples(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
00172 avfilter_unref_buffer(outlink->out_buf);
00173 outlink->out_buf = NULL;
00174 }
00175 avfilter_unref_buffer(samplesref);
00176 inlink->cur_buf = NULL;
00177 }
00178
00179 void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
00180 {
00181 void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
00182 AVFilterPad *dst = link->dstpad;
00183 int64_t pts;
00184
00185 FF_DPRINTF_START(NULL, filter_samples); ff_dlog_link(NULL, link, 1);
00186
00187 if (!(filter_samples = dst->filter_samples))
00188 filter_samples = ff_default_filter_samples;
00189
00190
00191 if ((dst->min_perms & samplesref->perms) != dst->min_perms ||
00192 dst->rej_perms & samplesref->perms) {
00193 int i, planar = av_sample_fmt_is_planar(samplesref->format);
00194 int planes = !planar ? 1:
00195 av_get_channel_layout_nb_channels(samplesref->audio->channel_layout);
00196
00197 av_log(link->dst, AV_LOG_DEBUG,
00198 "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n",
00199 samplesref->perms, link->dstpad->min_perms, link->dstpad->rej_perms);
00200
00201 link->cur_buf = ff_default_get_audio_buffer(link, dst->min_perms,
00202 samplesref->audio->nb_samples);
00203 link->cur_buf->pts = samplesref->pts;
00204 link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate;
00205
00206
00207 for (i = 0; i < 8 && samplesref->data[i]; i++)
00208 memcpy(link->cur_buf->data[i], samplesref->data[i], samplesref->linesize[0]);
00209 for (i = 0; i < planes; i++)
00210 memcpy(link->cur_buf->extended_data[i], samplesref->extended_data[i], samplesref->linesize[0]);
00211
00212 avfilter_unref_buffer(samplesref);
00213 } else
00214 link->cur_buf = samplesref;
00215
00216 pts = link->cur_buf->pts;
00217 filter_samples(link, link->cur_buf);
00218 ff_update_link_current_pts(link, pts);
00219 }