asrc_abuffer.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. /*
  2. * Copyright (c) 2010 S.N. Hemanth Meenakshisundaram
  3. * Copyright (c) 2011 Mina Nagy Zaki
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /**
  22. * @file
  23. * memory buffer source for audio
  24. */
  25. #include "libavutil/audioconvert.h"
  26. #include "libavutil/avstring.h"
  27. #include "libavutil/fifo.h"
  28. #include "asrc_abuffer.h"
  29. #include "internal.h"
  30. typedef struct {
  31. // Audio format of incoming buffers
  32. int sample_rate;
  33. unsigned int sample_format;
  34. int64_t channel_layout;
  35. int packing_format;
  36. // FIFO buffer of audio buffer ref pointers
  37. AVFifoBuffer *fifo;
  38. // Normalization filters
  39. AVFilterContext *aconvert;
  40. AVFilterContext *aresample;
  41. } ABufferSourceContext;
  42. #define FIFO_SIZE 8
  43. static void buf_free(AVFilterBuffer *ptr)
  44. {
  45. av_free(ptr);
  46. return;
  47. }
  48. static void set_link_source(AVFilterContext *src, AVFilterLink *link)
  49. {
  50. link->src = src;
  51. link->srcpad = &(src->output_pads[0]);
  52. src->outputs[0] = link;
  53. }
  54. static int reconfigure_filter(ABufferSourceContext *abuffer, AVFilterContext *filt_ctx)
  55. {
  56. int ret;
  57. AVFilterLink * const inlink = filt_ctx->inputs[0];
  58. AVFilterLink * const outlink = filt_ctx->outputs[0];
  59. inlink->format = abuffer->sample_format;
  60. inlink->channel_layout = abuffer->channel_layout;
  61. inlink->planar = abuffer->packing_format;
  62. inlink->sample_rate = abuffer->sample_rate;
  63. filt_ctx->filter->uninit(filt_ctx);
  64. memset(filt_ctx->priv, 0, filt_ctx->filter->priv_size);
  65. if ((ret = filt_ctx->filter->init(filt_ctx, NULL , NULL)) < 0)
  66. return ret;
  67. if ((ret = inlink->srcpad->config_props(inlink)) < 0)
  68. return ret;
  69. return outlink->srcpad->config_props(outlink);
  70. }
  71. static int insert_filter(ABufferSourceContext *abuffer,
  72. AVFilterLink *link, AVFilterContext **filt_ctx,
  73. const char *filt_name)
  74. {
  75. int ret;
  76. if ((ret = avfilter_open(filt_ctx, avfilter_get_by_name(filt_name), NULL)) < 0)
  77. return ret;
  78. link->src->outputs[0] = NULL;
  79. if ((ret = avfilter_link(link->src, 0, *filt_ctx, 0)) < 0) {
  80. link->src->outputs[0] = link;
  81. return ret;
  82. }
  83. set_link_source(*filt_ctx, link);
  84. if ((ret = reconfigure_filter(abuffer, *filt_ctx)) < 0) {
  85. avfilter_free(*filt_ctx);
  86. return ret;
  87. }
  88. return 0;
  89. }
  90. static void remove_filter(AVFilterContext **filt_ctx)
  91. {
  92. AVFilterLink *outlink = (*filt_ctx)->outputs[0];
  93. AVFilterContext *src = (*filt_ctx)->inputs[0]->src;
  94. (*filt_ctx)->outputs[0] = NULL;
  95. avfilter_free(*filt_ctx);
  96. *filt_ctx = NULL;
  97. set_link_source(src, outlink);
  98. }
  99. static inline void log_input_change(void *ctx, AVFilterLink *link, AVFilterBufferRef *ref)
  100. {
  101. char old_layout_str[16], new_layout_str[16];
  102. av_get_channel_layout_string(old_layout_str, sizeof(old_layout_str),
  103. -1, link->channel_layout);
  104. av_get_channel_layout_string(new_layout_str, sizeof(new_layout_str),
  105. -1, ref->audio->channel_layout);
  106. av_log(ctx, AV_LOG_INFO,
  107. "Audio input format changed: "
  108. "%s:%s:%d -> %s:%s:%d, normalizing\n",
  109. av_get_sample_fmt_name(link->format),
  110. old_layout_str, (int)link->sample_rate,
  111. av_get_sample_fmt_name(ref->format),
  112. new_layout_str, ref->audio->sample_rate);
  113. }
  114. int av_asrc_buffer_add_audio_buffer_ref(AVFilterContext *ctx,
  115. AVFilterBufferRef *samplesref,
  116. int av_unused flags)
  117. {
  118. ABufferSourceContext *abuffer = ctx->priv;
  119. AVFilterLink *link;
  120. int ret, logged = 0;
  121. if (av_fifo_space(abuffer->fifo) < sizeof(samplesref)) {
  122. av_log(ctx, AV_LOG_ERROR,
  123. "Buffering limit reached. Please consume some available frames "
  124. "before adding new ones.\n");
  125. return AVERROR(EINVAL);
  126. }
  127. // Normalize input
  128. link = ctx->outputs[0];
  129. if (samplesref->audio->sample_rate != link->sample_rate) {
  130. log_input_change(ctx, link, samplesref);
  131. logged = 1;
  132. abuffer->sample_rate = samplesref->audio->sample_rate;
  133. if (!abuffer->aresample) {
  134. ret = insert_filter(abuffer, link, &abuffer->aresample, "aresample");
  135. if (ret < 0) return ret;
  136. } else {
  137. link = abuffer->aresample->outputs[0];
  138. if (samplesref->audio->sample_rate == link->sample_rate)
  139. remove_filter(&abuffer->aresample);
  140. else
  141. if ((ret = reconfigure_filter(abuffer, abuffer->aresample)) < 0)
  142. return ret;
  143. }
  144. }
  145. link = ctx->outputs[0];
  146. if (samplesref->format != link->format ||
  147. samplesref->audio->channel_layout != link->channel_layout ||
  148. samplesref->audio->planar != link->planar) {
  149. if (!logged) log_input_change(ctx, link, samplesref);
  150. abuffer->sample_format = samplesref->format;
  151. abuffer->channel_layout = samplesref->audio->channel_layout;
  152. abuffer->packing_format = samplesref->audio->planar;
  153. if (!abuffer->aconvert) {
  154. ret = insert_filter(abuffer, link, &abuffer->aconvert, "aconvert");
  155. if (ret < 0) return ret;
  156. } else {
  157. link = abuffer->aconvert->outputs[0];
  158. if (samplesref->format == link->format &&
  159. samplesref->audio->channel_layout == link->channel_layout &&
  160. samplesref->audio->planar == link->planar
  161. )
  162. remove_filter(&abuffer->aconvert);
  163. else
  164. if ((ret = reconfigure_filter(abuffer, abuffer->aconvert)) < 0)
  165. return ret;
  166. }
  167. }
  168. if (sizeof(samplesref) != av_fifo_generic_write(abuffer->fifo, &samplesref,
  169. sizeof(samplesref), NULL)) {
  170. av_log(ctx, AV_LOG_ERROR, "Error while writing to FIFO\n");
  171. return AVERROR(EINVAL);
  172. }
  173. return 0;
  174. }
  175. int av_asrc_buffer_add_samples(AVFilterContext *ctx,
  176. uint8_t *data[8], int linesize[8],
  177. int nb_samples, int sample_rate,
  178. int sample_fmt, int64_t channel_layout, int planar,
  179. int64_t pts, int av_unused flags)
  180. {
  181. AVFilterBufferRef *samplesref;
  182. samplesref = avfilter_get_audio_buffer_ref_from_arrays(
  183. data, linesize, AV_PERM_WRITE,
  184. nb_samples,
  185. sample_fmt, channel_layout, planar);
  186. if (!samplesref)
  187. return AVERROR(ENOMEM);
  188. samplesref->buf->free = buf_free;
  189. samplesref->pts = pts;
  190. samplesref->audio->sample_rate = sample_rate;
  191. return av_asrc_buffer_add_audio_buffer_ref(ctx, samplesref, 0);
  192. }
  193. int av_asrc_buffer_add_buffer(AVFilterContext *ctx,
  194. uint8_t *buf, int buf_size, int sample_rate,
  195. int sample_fmt, int64_t channel_layout, int planar,
  196. int64_t pts, int av_unused flags)
  197. {
  198. uint8_t *data[8];
  199. int linesize[8];
  200. int nb_channels = av_get_channel_layout_nb_channels(channel_layout),
  201. nb_samples = buf_size / nb_channels / av_get_bytes_per_sample(sample_fmt);
  202. av_samples_fill_arrays(data, linesize,
  203. buf, nb_channels, nb_samples,
  204. sample_fmt, 16);
  205. return av_asrc_buffer_add_samples(ctx,
  206. data, linesize, nb_samples,
  207. sample_rate,
  208. sample_fmt, channel_layout, planar,
  209. pts, flags);
  210. }
  211. static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque)
  212. {
  213. ABufferSourceContext *abuffer = ctx->priv;
  214. char *arg = NULL, *ptr, chlayout_str[16];
  215. char *args = av_strdup(args0);
  216. int ret;
  217. arg = av_strtok(args, ":", &ptr);
  218. #define ADD_FORMAT(fmt_name) \
  219. if (!arg) \
  220. goto arg_fail; \
  221. if ((ret = ff_parse_##fmt_name(&abuffer->fmt_name, arg, ctx)) < 0) { \
  222. av_freep(&args); \
  223. return ret; \
  224. } \
  225. if (*args) \
  226. arg = av_strtok(NULL, ":", &ptr)
  227. ADD_FORMAT(sample_rate);
  228. ADD_FORMAT(sample_format);
  229. ADD_FORMAT(channel_layout);
  230. ADD_FORMAT(packing_format);
  231. abuffer->fifo = av_fifo_alloc(FIFO_SIZE*sizeof(AVFilterBufferRef*));
  232. if (!abuffer->fifo) {
  233. av_log(ctx, AV_LOG_ERROR, "Failed to allocate fifo, filter init failed.\n");
  234. return AVERROR(ENOMEM);
  235. }
  236. av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str),
  237. -1, abuffer->channel_layout);
  238. av_log(ctx, AV_LOG_INFO, "format:%s layout:%s rate:%d\n",
  239. av_get_sample_fmt_name(abuffer->sample_format), chlayout_str,
  240. abuffer->sample_rate);
  241. av_freep(&args);
  242. return 0;
  243. arg_fail:
  244. av_log(ctx, AV_LOG_ERROR, "Invalid arguments, must be of the form "
  245. "sample_rate:sample_fmt:channel_layout:packing\n");
  246. av_freep(&args);
  247. return AVERROR(EINVAL);
  248. }
  249. static av_cold void uninit(AVFilterContext *ctx)
  250. {
  251. ABufferSourceContext *abuffer = ctx->priv;
  252. av_fifo_free(abuffer->fifo);
  253. }
  254. static int query_formats(AVFilterContext *ctx)
  255. {
  256. ABufferSourceContext *abuffer = ctx->priv;
  257. AVFilterFormats *formats;
  258. formats = NULL;
  259. avfilter_add_format(&formats, abuffer->sample_format);
  260. avfilter_set_common_sample_formats(ctx, formats);
  261. formats = NULL;
  262. avfilter_add_format(&formats, abuffer->channel_layout);
  263. avfilter_set_common_channel_layouts(ctx, formats);
  264. formats = NULL;
  265. avfilter_add_format(&formats, abuffer->packing_format);
  266. avfilter_set_common_packing_formats(ctx, formats);
  267. return 0;
  268. }
  269. static int config_output(AVFilterLink *outlink)
  270. {
  271. ABufferSourceContext *abuffer = outlink->src->priv;
  272. outlink->sample_rate = abuffer->sample_rate;
  273. return 0;
  274. }
  275. static int request_frame(AVFilterLink *outlink)
  276. {
  277. ABufferSourceContext *abuffer = outlink->src->priv;
  278. AVFilterBufferRef *samplesref;
  279. if (!av_fifo_size(abuffer->fifo)) {
  280. av_log(outlink->src, AV_LOG_ERROR,
  281. "request_frame() called with no available frames!\n");
  282. return AVERROR(EINVAL);
  283. }
  284. av_fifo_generic_read(abuffer->fifo, &samplesref, sizeof(samplesref), NULL);
  285. avfilter_filter_samples(outlink, avfilter_ref_buffer(samplesref, ~0));
  286. avfilter_unref_buffer(samplesref);
  287. return 0;
  288. }
  289. static int poll_frame(AVFilterLink *outlink)
  290. {
  291. ABufferSourceContext *abuffer = outlink->src->priv;
  292. return av_fifo_size(abuffer->fifo)/sizeof(AVFilterBufferRef*);
  293. }
  294. AVFilter avfilter_asrc_abuffer = {
  295. .name = "abuffer",
  296. .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."),
  297. .priv_size = sizeof(ABufferSourceContext),
  298. .query_formats = query_formats,
  299. .init = init,
  300. .uninit = uninit,
  301. .inputs = (const AVFilterPad[]) {{ .name = NULL }},
  302. .outputs = (const AVFilterPad[]) {{ .name = "default",
  303. .type = AVMEDIA_TYPE_AUDIO,
  304. .request_frame = request_frame,
  305. .poll_frame = poll_frame,
  306. .config_props = config_output, },
  307. { .name = NULL}},
  308. };