buffersink.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * Copyright (c) 2011 Stefano Sabatini
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. /**
  21. * @file
  22. * buffer sink
  23. */
  24. #include "libavutil/audio_fifo.h"
  25. #include "libavutil/audioconvert.h"
  26. #include "libavutil/fifo.h"
  27. #include "libavutil/mathematics.h"
  28. #include "audio.h"
  29. #include "avfilter.h"
  30. #include "buffersink.h"
  31. typedef struct {
  32. AVFifoBuffer *fifo; ///< FIFO buffer of frame references
  33. AVAudioFifo *audio_fifo; ///< FIFO for audio samples
  34. int64_t next_pts; ///< interpolating audio pts
  35. } BufferSinkContext;
  36. #define FIFO_INIT_SIZE 8
  37. static av_cold void uninit(AVFilterContext *ctx)
  38. {
  39. BufferSinkContext *sink = ctx->priv;
  40. while (sink->fifo && av_fifo_size(sink->fifo)) {
  41. AVFilterBufferRef *buf;
  42. av_fifo_generic_read(sink->fifo, &buf, sizeof(buf), NULL);
  43. avfilter_unref_buffer(buf);
  44. }
  45. av_fifo_free(sink->fifo);
  46. if (sink->audio_fifo)
  47. av_audio_fifo_free(sink->audio_fifo);
  48. }
  49. static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
  50. {
  51. BufferSinkContext *sink = ctx->priv;
  52. if (!(sink->fifo = av_fifo_alloc(FIFO_INIT_SIZE*sizeof(AVFilterBufferRef*)))) {
  53. av_log(ctx, AV_LOG_ERROR, "Failed to allocate fifo\n");
  54. return AVERROR(ENOMEM);
  55. }
  56. return 0;
  57. }
  58. static void write_buf(AVFilterContext *ctx, AVFilterBufferRef *buf)
  59. {
  60. BufferSinkContext *sink = ctx->priv;
  61. if (av_fifo_space(sink->fifo) < sizeof(AVFilterBufferRef *) &&
  62. (av_fifo_realloc2(sink->fifo, av_fifo_size(sink->fifo) * 2) < 0)) {
  63. av_log(ctx, AV_LOG_ERROR, "Error reallocating the FIFO.\n");
  64. return;
  65. }
  66. av_fifo_generic_write(sink->fifo, &buf, sizeof(buf), NULL);
  67. }
  68. static void end_frame(AVFilterLink *link)
  69. {
  70. write_buf(link->dst, link->cur_buf);
  71. link->cur_buf = NULL;
  72. }
  73. static void filter_samples(AVFilterLink *link, AVFilterBufferRef *buf)
  74. {
  75. write_buf(link->dst, buf);
  76. }
  77. int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
  78. {
  79. BufferSinkContext *sink = ctx->priv;
  80. AVFilterLink *link = ctx->inputs[0];
  81. int ret;
  82. if (!buf) {
  83. if (av_fifo_size(sink->fifo))
  84. return av_fifo_size(sink->fifo)/sizeof(*buf);
  85. else
  86. return avfilter_poll_frame(ctx->inputs[0]);
  87. }
  88. if (!av_fifo_size(sink->fifo) &&
  89. (ret = avfilter_request_frame(link)) < 0)
  90. return ret;
  91. if (!av_fifo_size(sink->fifo))
  92. return AVERROR(EINVAL);
  93. av_fifo_generic_read(sink->fifo, buf, sizeof(*buf), NULL);
  94. return 0;
  95. }
  96. static int read_from_fifo(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
  97. int nb_samples)
  98. {
  99. BufferSinkContext *s = ctx->priv;
  100. AVFilterLink *link = ctx->inputs[0];
  101. AVFilterBufferRef *buf;
  102. if (!(buf = ff_get_audio_buffer(link, AV_PERM_WRITE, nb_samples)))
  103. return AVERROR(ENOMEM);
  104. av_audio_fifo_read(s->audio_fifo, (void**)buf->extended_data, nb_samples);
  105. buf->pts = s->next_pts;
  106. s->next_pts += av_rescale_q(nb_samples, (AVRational){1, link->sample_rate},
  107. link->time_base);
  108. *pbuf = buf;
  109. return 0;
  110. }
  111. int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
  112. int nb_samples)
  113. {
  114. BufferSinkContext *s = ctx->priv;
  115. AVFilterLink *link = ctx->inputs[0];
  116. int ret = 0;
  117. if (!s->audio_fifo) {
  118. int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
  119. if (!(s->audio_fifo = av_audio_fifo_alloc(link->format, nb_channels, nb_samples)))
  120. return AVERROR(ENOMEM);
  121. }
  122. while (ret >= 0) {
  123. AVFilterBufferRef *buf;
  124. if (av_audio_fifo_size(s->audio_fifo) >= nb_samples)
  125. return read_from_fifo(ctx, pbuf, nb_samples);
  126. ret = av_buffersink_read(ctx, &buf);
  127. if (ret == AVERROR_EOF && av_audio_fifo_size(s->audio_fifo))
  128. return read_from_fifo(ctx, pbuf, av_audio_fifo_size(s->audio_fifo));
  129. else if (ret < 0)
  130. return ret;
  131. if (buf->pts != AV_NOPTS_VALUE) {
  132. s->next_pts = buf->pts -
  133. av_rescale_q(av_audio_fifo_size(s->audio_fifo),
  134. (AVRational){ 1, link->sample_rate },
  135. link->time_base);
  136. }
  137. ret = av_audio_fifo_write(s->audio_fifo, (void**)buf->extended_data,
  138. buf->audio->nb_samples);
  139. avfilter_unref_buffer(buf);
  140. }
  141. return ret;
  142. }
  143. AVFilter avfilter_vsink_buffer = {
  144. .name = "buffersink_old",
  145. .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
  146. .priv_size = sizeof(BufferSinkContext),
  147. .init = init,
  148. .uninit = uninit,
  149. .inputs = (AVFilterPad[]) {{ .name = "default",
  150. .type = AVMEDIA_TYPE_VIDEO,
  151. .end_frame = end_frame,
  152. .min_perms = AV_PERM_READ, },
  153. { .name = NULL }},
  154. .outputs = (AVFilterPad[]) {{ .name = NULL }},
  155. };
  156. AVFilter avfilter_asink_abuffer = {
  157. .name = "abuffersink_old",
  158. .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
  159. .priv_size = sizeof(BufferSinkContext),
  160. .init = init,
  161. .uninit = uninit,
  162. .inputs = (AVFilterPad[]) {{ .name = "default",
  163. .type = AVMEDIA_TYPE_AUDIO,
  164. .filter_samples = filter_samples,
  165. .min_perms = AV_PERM_READ, },
  166. { .name = NULL }},
  167. .outputs = (AVFilterPad[]) {{ .name = NULL }},
  168. };