You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
8.0KB

  1. /*
  2. * Filter layer - default implementations
  3. * Copyright (c) 2007 Bobby Bingham
  4. *
  5. * This file is part of Libav.
  6. *
  7. * Libav 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. * Libav 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 Libav; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "libavutil/audioconvert.h"
  22. #include "libavutil/imgutils.h"
  23. #include "libavutil/samplefmt.h"
  24. #include "avfilter.h"
  25. #include "internal.h"
  26. /* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */
  27. void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
  28. {
  29. if (ptr->extended_data != ptr->data)
  30. av_freep(&ptr->extended_data);
  31. av_free(ptr->data[0]);
  32. av_free(ptr);
  33. }
  34. /* TODO: set the buffer's priv member to a context structure for the whole
  35. * filter chain. This will allow for a buffer pool instead of the constant
  36. * alloc & free cycle currently implemented. */
  37. AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
  38. {
  39. int linesize[4];
  40. uint8_t *data[4];
  41. AVFilterBufferRef *picref = NULL;
  42. // +2 is needed for swscaler, +16 to be SIMD-friendly
  43. if (av_image_alloc(data, linesize, w, h, link->format, 16) < 0)
  44. return NULL;
  45. picref = avfilter_get_video_buffer_ref_from_arrays(data, linesize,
  46. perms, w, h, link->format);
  47. if (!picref) {
  48. av_free(data[0]);
  49. return NULL;
  50. }
  51. return picref;
  52. }
  53. AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,
  54. int nb_samples)
  55. {
  56. AVFilterBufferRef *samplesref = NULL;
  57. uint8_t **data;
  58. int planar = av_sample_fmt_is_planar(link->format);
  59. int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
  60. int planes = planar ? nb_channels : 1;
  61. int linesize;
  62. if (!(data = av_mallocz(sizeof(*data) * planes)))
  63. goto fail;
  64. if (av_samples_alloc(data, &linesize, nb_channels, nb_samples, link->format, 0) < 0)
  65. goto fail;
  66. samplesref = avfilter_get_audio_buffer_ref_from_arrays(data, linesize, perms,
  67. nb_samples, link->format,
  68. link->channel_layout);
  69. if (!samplesref)
  70. goto fail;
  71. av_freep(&data);
  72. fail:
  73. if (data)
  74. av_freep(&data[0]);
  75. av_freep(&data);
  76. return samplesref;
  77. }
  78. void avfilter_default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
  79. {
  80. AVFilterLink *outlink = NULL;
  81. if (inlink->dst->output_count)
  82. outlink = inlink->dst->outputs[0];
  83. if (outlink) {
  84. outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
  85. avfilter_copy_buffer_ref_props(outlink->out_buf, picref);
  86. avfilter_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
  87. }
  88. }
  89. void avfilter_default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
  90. {
  91. AVFilterLink *outlink = NULL;
  92. if (inlink->dst->output_count)
  93. outlink = inlink->dst->outputs[0];
  94. if (outlink)
  95. avfilter_draw_slice(outlink, y, h, slice_dir);
  96. }
  97. void avfilter_default_end_frame(AVFilterLink *inlink)
  98. {
  99. AVFilterLink *outlink = NULL;
  100. if (inlink->dst->output_count)
  101. outlink = inlink->dst->outputs[0];
  102. avfilter_unref_buffer(inlink->cur_buf);
  103. inlink->cur_buf = NULL;
  104. if (outlink) {
  105. if (outlink->out_buf) {
  106. avfilter_unref_buffer(outlink->out_buf);
  107. outlink->out_buf = NULL;
  108. }
  109. avfilter_end_frame(outlink);
  110. }
  111. }
  112. /* FIXME: samplesref is same as link->cur_buf. Need to consider removing the redundant parameter. */
  113. void avfilter_default_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
  114. {
  115. AVFilterLink *outlink = NULL;
  116. if (inlink->dst->output_count)
  117. outlink = inlink->dst->outputs[0];
  118. if (outlink) {
  119. outlink->out_buf = avfilter_default_get_audio_buffer(inlink, AV_PERM_WRITE,
  120. samplesref->audio->nb_samples);
  121. outlink->out_buf->pts = samplesref->pts;
  122. outlink->out_buf->audio->sample_rate = samplesref->audio->sample_rate;
  123. avfilter_filter_samples(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
  124. avfilter_unref_buffer(outlink->out_buf);
  125. outlink->out_buf = NULL;
  126. }
  127. avfilter_unref_buffer(samplesref);
  128. inlink->cur_buf = NULL;
  129. }
  130. /**
  131. * default config_link() implementation for output video links to simplify
  132. * the implementation of one input one output video filters */
  133. int avfilter_default_config_output_link(AVFilterLink *link)
  134. {
  135. if (link->src->input_count && link->src->inputs[0]) {
  136. if (link->type == AVMEDIA_TYPE_VIDEO) {
  137. link->w = link->src->inputs[0]->w;
  138. link->h = link->src->inputs[0]->h;
  139. link->time_base = link->src->inputs[0]->time_base;
  140. } else if (link->type == AVMEDIA_TYPE_AUDIO) {
  141. link->channel_layout = link->src->inputs[0]->channel_layout;
  142. link->sample_rate = link->src->inputs[0]->sample_rate;
  143. }
  144. } else {
  145. /* XXX: any non-simple filter which would cause this branch to be taken
  146. * really should implement its own config_props() for this link. */
  147. return -1;
  148. }
  149. return 0;
  150. }
  151. /**
  152. * A helper for query_formats() which sets all links to the same list of
  153. * formats. If there are no links hooked to this filter, the list of formats is
  154. * freed.
  155. *
  156. * FIXME: this will need changed for filters with a mix of pad types
  157. * (video + audio, etc)
  158. */
  159. void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
  160. {
  161. int count = 0, i;
  162. for (i = 0; i < ctx->input_count; i++) {
  163. if (ctx->inputs[i]) {
  164. avfilter_formats_ref(formats, &ctx->inputs[i]->out_formats);
  165. count++;
  166. }
  167. }
  168. for (i = 0; i < ctx->output_count; i++) {
  169. if (ctx->outputs[i]) {
  170. avfilter_formats_ref(formats, &ctx->outputs[i]->in_formats);
  171. count++;
  172. }
  173. }
  174. if (!count) {
  175. av_free(formats->formats);
  176. av_free(formats->refs);
  177. av_free(formats);
  178. }
  179. }
  180. int avfilter_default_query_formats(AVFilterContext *ctx)
  181. {
  182. enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
  183. ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
  184. AVMEDIA_TYPE_VIDEO;
  185. avfilter_set_common_formats(ctx, avfilter_all_formats(type));
  186. return 0;
  187. }
  188. void avfilter_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
  189. {
  190. avfilter_start_frame(link->dst->outputs[0], picref);
  191. }
  192. void avfilter_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
  193. {
  194. avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir);
  195. }
  196. void avfilter_null_end_frame(AVFilterLink *link)
  197. {
  198. avfilter_end_frame(link->dst->outputs[0]);
  199. }
  200. void avfilter_null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
  201. {
  202. avfilter_filter_samples(link->dst->outputs[0], samplesref);
  203. }
  204. AVFilterBufferRef *avfilter_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
  205. {
  206. return avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h);
  207. }
  208. AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms,
  209. int nb_samples)
  210. {
  211. return avfilter_get_audio_buffer(link->dst->outputs[0], perms, nb_samples);
  212. }