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.

828 lines
29KB

  1. /*
  2. * filter graphs
  3. * Copyright (c) 2008 Vitor Sessak
  4. * Copyright (c) 2007 Bobby Bingham
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with FFmpeg; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include <ctype.h>
  23. #include <string.h>
  24. #include "libavutil/audioconvert.h"
  25. #include "libavutil/avassert.h"
  26. #include "libavutil/pixdesc.h"
  27. #include "avfilter.h"
  28. #include "avfiltergraph.h"
  29. #include "formats.h"
  30. #include "internal.h"
  31. #include "libavutil/audioconvert.h"
  32. #include "libavutil/log.h"
  33. static const AVClass filtergraph_class = {
  34. .class_name = "AVFilterGraph",
  35. .item_name = av_default_item_name,
  36. .version = LIBAVUTIL_VERSION_INT,
  37. };
  38. AVFilterGraph *avfilter_graph_alloc(void)
  39. {
  40. AVFilterGraph *ret = av_mallocz(sizeof(AVFilterGraph));
  41. if (!ret)
  42. return NULL;
  43. #if FF_API_GRAPH_AVCLASS
  44. ret->av_class = &filtergraph_class;
  45. #endif
  46. return ret;
  47. }
  48. void avfilter_graph_free(AVFilterGraph **graph)
  49. {
  50. if (!*graph)
  51. return;
  52. for (; (*graph)->filter_count > 0; (*graph)->filter_count--)
  53. avfilter_free((*graph)->filters[(*graph)->filter_count - 1]);
  54. av_freep(&(*graph)->sink_links);
  55. av_freep(&(*graph)->scale_sws_opts);
  56. av_freep(&(*graph)->filters);
  57. av_freep(graph);
  58. }
  59. int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
  60. {
  61. AVFilterContext **filters = av_realloc(graph->filters,
  62. sizeof(AVFilterContext*) * (graph->filter_count+1));
  63. if (!filters)
  64. return AVERROR(ENOMEM);
  65. graph->filters = filters;
  66. graph->filters[graph->filter_count++] = filter;
  67. return 0;
  68. }
  69. int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt,
  70. const char *name, const char *args, void *opaque,
  71. AVFilterGraph *graph_ctx)
  72. {
  73. int ret;
  74. if ((ret = avfilter_open(filt_ctx, filt, name)) < 0)
  75. goto fail;
  76. if ((ret = avfilter_init_filter(*filt_ctx, args, opaque)) < 0)
  77. goto fail;
  78. if ((ret = avfilter_graph_add_filter(graph_ctx, *filt_ctx)) < 0)
  79. goto fail;
  80. return 0;
  81. fail:
  82. if (*filt_ctx)
  83. avfilter_free(*filt_ctx);
  84. *filt_ctx = NULL;
  85. return ret;
  86. }
  87. void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
  88. {
  89. graph->disable_auto_convert = flags;
  90. }
  91. int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
  92. {
  93. AVFilterContext *filt;
  94. int i, j;
  95. for (i = 0; i < graph->filter_count; i++) {
  96. filt = graph->filters[i];
  97. for (j = 0; j < filt->input_count; j++) {
  98. if (!filt->inputs[j] || !filt->inputs[j]->src) {
  99. av_log(log_ctx, AV_LOG_ERROR,
  100. "Input pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any source\n",
  101. filt->input_pads[j].name, filt->name, filt->filter->name);
  102. return AVERROR(EINVAL);
  103. }
  104. }
  105. for (j = 0; j < filt->output_count; j++) {
  106. if (!filt->outputs[j] || !filt->outputs[j]->dst) {
  107. av_log(log_ctx, AV_LOG_ERROR,
  108. "Output pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any destination\n",
  109. filt->output_pads[j].name, filt->name, filt->filter->name);
  110. return AVERROR(EINVAL);
  111. }
  112. }
  113. }
  114. return 0;
  115. }
  116. int ff_avfilter_graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
  117. {
  118. AVFilterContext *filt;
  119. int i, ret;
  120. for (i=0; i < graph->filter_count; i++) {
  121. filt = graph->filters[i];
  122. if (!filt->output_count) {
  123. if ((ret = avfilter_config_links(filt)))
  124. return ret;
  125. }
  126. }
  127. return 0;
  128. }
  129. AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
  130. {
  131. int i;
  132. for (i = 0; i < graph->filter_count; i++)
  133. if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
  134. return graph->filters[i];
  135. return NULL;
  136. }
  137. static int insert_conv_filter(AVFilterGraph *graph, AVFilterLink *link,
  138. const char *filt_name, const char *filt_args)
  139. {
  140. static int auto_count = 0, ret;
  141. char inst_name[32];
  142. AVFilterContext *filt_ctx;
  143. if (graph->disable_auto_convert) {
  144. av_log(NULL, AV_LOG_ERROR,
  145. "The filters '%s' and '%s' do not have a common format "
  146. "and automatic conversion is disabled.\n",
  147. link->src->name, link->dst->name);
  148. return AVERROR(EINVAL);
  149. }
  150. snprintf(inst_name, sizeof(inst_name), "auto-inserted %s %d",
  151. filt_name, auto_count++);
  152. if ((ret = avfilter_graph_create_filter(&filt_ctx,
  153. avfilter_get_by_name(filt_name),
  154. inst_name, filt_args, NULL, graph)) < 0)
  155. return ret;
  156. if ((ret = avfilter_insert_filter(link, filt_ctx, 0, 0)) < 0)
  157. return ret;
  158. filt_ctx->filter->query_formats(filt_ctx);
  159. if ( ((link = filt_ctx-> inputs[0]) &&
  160. !avfilter_merge_formats(link->in_formats, link->out_formats)) ||
  161. ((link = filt_ctx->outputs[0]) &&
  162. !avfilter_merge_formats(link->in_formats, link->out_formats))
  163. ) {
  164. av_log(NULL, AV_LOG_ERROR,
  165. "Impossible to convert between the formats supported by the filter "
  166. "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
  167. return AVERROR(EINVAL);
  168. }
  169. if (link->type == AVMEDIA_TYPE_AUDIO &&
  170. (((link = filt_ctx-> inputs[0]) &&
  171. (!ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts) ||
  172. !avfilter_merge_formats(link->in_packing, link->out_packing))) ||
  173. ((link = filt_ctx->outputs[0]) &&
  174. (!ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts) ||
  175. !avfilter_merge_formats(link->in_packing, link->out_packing))))
  176. ) {
  177. av_log(NULL, AV_LOG_ERROR,
  178. "Impossible to convert between the channel layouts/packing formats supported by the filter "
  179. "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
  180. return AVERROR(EINVAL);
  181. }
  182. return 0;
  183. }
  184. static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
  185. {
  186. int i, j, ret;
  187. char filt_args[128];
  188. AVFilterFormats *formats, *packing;
  189. AVFilterChannelLayouts *chlayouts;
  190. AVFilterFormats *samplerates;
  191. int scaler_count = 0, resampler_count = 0;
  192. /* ask all the sub-filters for their supported media formats */
  193. for (i = 0; i < graph->filter_count; i++) {
  194. if (graph->filters[i]->filter->query_formats)
  195. graph->filters[i]->filter->query_formats(graph->filters[i]);
  196. else
  197. avfilter_default_query_formats(graph->filters[i]);
  198. }
  199. /* go through and merge as many format lists as possible */
  200. for (i = 0; i < graph->filter_count; i++) {
  201. AVFilterContext *filter = graph->filters[i];
  202. for (j = 0; j < filter->input_count; j++) {
  203. AVFilterLink *link = filter->inputs[j];
  204. #if 0
  205. if (!link) continue;
  206. if (!link->in_formats || !link->out_formats)
  207. return AVERROR(EINVAL);
  208. if (link->type == AVMEDIA_TYPE_VIDEO &&
  209. !avfilter_merge_formats(link->in_formats, link->out_formats)) {
  210. /* couldn't merge format lists, auto-insert scale filter */
  211. snprintf(filt_args, sizeof(filt_args), "0:0:%s",
  212. graph->scale_sws_opts);
  213. if (ret = insert_conv_filter(graph, link, "scale", filt_args))
  214. return ret;
  215. }
  216. else if (link->type == AVMEDIA_TYPE_AUDIO) {
  217. if (!link->in_channel_layouts || !link->out_channel_layouts ||
  218. !link->in_packing || !link->out_packing)
  219. return AVERROR(EINVAL);
  220. /* Merge all three list before checking: that way, in all
  221. * three categories, aconvert will use a common format
  222. * whenever possible. */
  223. formats = avfilter_merge_formats(link->in_formats, link->out_formats);
  224. chlayouts = ff_merge_channel_layouts(link->in_channel_layouts , link->out_channel_layouts);
  225. samplerates = ff_merge_samplerates (link->in_samplerates, link->out_samplerates);
  226. packing = avfilter_merge_formats(link->in_packing, link->out_packing);
  227. if (!formats || !chlayouts || !packing || !samplerates)
  228. if (ret = insert_conv_filter(graph, link, "aconvert", NULL))
  229. return ret;
  230. #else
  231. int convert_needed = 0;
  232. if (!link)
  233. continue;
  234. if (link->in_formats != link->out_formats &&
  235. !avfilter_merge_formats(link->in_formats,
  236. link->out_formats))
  237. convert_needed = 1;
  238. if (link->type == AVMEDIA_TYPE_AUDIO) {
  239. if (link->in_channel_layouts != link->out_channel_layouts &&
  240. !ff_merge_channel_layouts(link->in_channel_layouts,
  241. link->out_channel_layouts))
  242. convert_needed = 1;
  243. if (link->in_samplerates != link->out_samplerates &&
  244. !ff_merge_samplerates(link->in_samplerates,
  245. link->out_samplerates))
  246. convert_needed = 1;
  247. }
  248. if (convert_needed) {
  249. AVFilterContext *convert;
  250. AVFilter *filter;
  251. AVFilterLink *inlink, *outlink;
  252. char scale_args[256];
  253. char inst_name[30];
  254. /* couldn't merge format lists. auto-insert conversion filter */
  255. switch (link->type) {
  256. case AVMEDIA_TYPE_VIDEO:
  257. snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
  258. scaler_count++);
  259. snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
  260. if ((ret = avfilter_graph_create_filter(&convert,
  261. avfilter_get_by_name("scale"),
  262. inst_name, scale_args, NULL,
  263. graph)) < 0)
  264. return ret;
  265. break;
  266. case AVMEDIA_TYPE_AUDIO:
  267. if (!(filter = avfilter_get_by_name("resample"))) {
  268. av_log(log_ctx, AV_LOG_ERROR, "'resample' filter "
  269. "not present, cannot convert audio formats.\n");
  270. return AVERROR(EINVAL);
  271. }
  272. snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
  273. resampler_count++);
  274. if ((ret = avfilter_graph_create_filter(&convert,
  275. avfilter_get_by_name("resample"),
  276. inst_name, NULL, NULL, graph)) < 0)
  277. return ret;
  278. break;
  279. default:
  280. return AVERROR(EINVAL);
  281. }
  282. if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
  283. return ret;
  284. convert->filter->query_formats(convert);
  285. inlink = convert->inputs[0];
  286. outlink = convert->outputs[0];
  287. if (!avfilter_merge_formats( inlink->in_formats, inlink->out_formats) ||
  288. !avfilter_merge_formats(outlink->in_formats, outlink->out_formats))
  289. ret |= AVERROR(ENOSYS);
  290. if (inlink->type == AVMEDIA_TYPE_AUDIO &&
  291. (!ff_merge_samplerates(inlink->in_samplerates,
  292. inlink->out_samplerates) ||
  293. !ff_merge_channel_layouts(inlink->in_channel_layouts,
  294. inlink->out_channel_layouts)))
  295. ret |= AVERROR(ENOSYS);
  296. if (outlink->type == AVMEDIA_TYPE_AUDIO &&
  297. (!ff_merge_samplerates(outlink->in_samplerates,
  298. outlink->out_samplerates) ||
  299. !ff_merge_channel_layouts(outlink->in_channel_layouts,
  300. outlink->out_channel_layouts)))
  301. ret |= AVERROR(ENOSYS);
  302. if (ret < 0) {
  303. av_log(log_ctx, AV_LOG_ERROR,
  304. "Impossible to convert between the formats supported by the filter "
  305. "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
  306. return ret;
  307. }
  308. #endif
  309. }
  310. }
  311. }
  312. return 0;
  313. }
  314. static int pick_format(AVFilterLink *link, AVFilterLink *ref)
  315. {
  316. if (!link || !link->in_formats)
  317. return 0;
  318. if (link->type == AVMEDIA_TYPE_VIDEO) {
  319. if(ref && ref->type == AVMEDIA_TYPE_VIDEO){
  320. int has_alpha= av_pix_fmt_descriptors[ref->format].nb_components % 2 == 0;
  321. enum PixelFormat best= PIX_FMT_NONE;
  322. int i;
  323. for (i=0; i<link->in_formats->format_count; i++) {
  324. enum PixelFormat p = link->in_formats->formats[i];
  325. best= avcodec_find_best_pix_fmt2(best, p, ref->format, has_alpha, NULL);
  326. }
  327. link->in_formats->formats[0] = best;
  328. }
  329. }
  330. link->in_formats->format_count = 1;
  331. link->format = link->in_formats->formats[0];
  332. if (link->type == AVMEDIA_TYPE_AUDIO) {
  333. if (!link->in_samplerates->format_count) {
  334. av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
  335. " the link between filters %s and %s.\n", link->src->name,
  336. link->dst->name);
  337. return AVERROR(EINVAL);
  338. }
  339. link->in_samplerates->format_count = 1;
  340. link->sample_rate = link->in_samplerates->formats[0];
  341. if (!link->in_channel_layouts->nb_channel_layouts) {
  342. av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
  343. "the link between filters %s and %s.\n", link->src->name,
  344. link->dst->name);
  345. return AVERROR(EINVAL);
  346. }
  347. link->in_channel_layouts->nb_channel_layouts = 1;
  348. link->channel_layout = link->in_channel_layouts->channel_layouts[0];
  349. }
  350. avfilter_formats_unref(&link->in_formats);
  351. avfilter_formats_unref(&link->out_formats);
  352. avfilter_formats_unref(&link->in_samplerates);
  353. avfilter_formats_unref(&link->out_samplerates);
  354. ff_channel_layouts_unref(&link->in_channel_layouts);
  355. ff_channel_layouts_unref(&link->out_channel_layouts);
  356. return 0;
  357. }
  358. #define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \
  359. do { \
  360. for (i = 0; i < filter->input_count; i++) { \
  361. AVFilterLink *link = filter->inputs[i]; \
  362. fmt_type fmt; \
  363. \
  364. if (!link->out_ ## list || link->out_ ## list->nb != 1) \
  365. continue; \
  366. fmt = link->out_ ## list->var[0]; \
  367. \
  368. for (j = 0; j < filter->output_count; j++) { \
  369. AVFilterLink *out_link = filter->outputs[j]; \
  370. list_type *fmts; \
  371. \
  372. if (link->type != out_link->type || \
  373. out_link->in_ ## list->nb == 1) \
  374. continue; \
  375. fmts = out_link->in_ ## list; \
  376. \
  377. if (!out_link->in_ ## list->nb) { \
  378. add_format(&out_link->in_ ##list, fmt); \
  379. break; \
  380. } \
  381. \
  382. for (k = 0; k < out_link->in_ ## list->nb; k++) \
  383. if (fmts->var[k] == fmt) { \
  384. fmts->var[0] = fmt; \
  385. fmts->nb = 1; \
  386. ret = 1; \
  387. break; \
  388. } \
  389. } \
  390. } \
  391. } while (0)
  392. static int reduce_formats_on_filter(AVFilterContext *filter)
  393. {
  394. int i, j, k, ret = 0;
  395. REDUCE_FORMATS(int, AVFilterFormats, formats, formats,
  396. format_count, avfilter_add_format);
  397. REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,
  398. format_count, avfilter_add_format);
  399. REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,
  400. channel_layouts, nb_channel_layouts, ff_add_channel_layout);
  401. return ret;
  402. }
  403. static void reduce_formats(AVFilterGraph *graph)
  404. {
  405. int i, reduced;
  406. do {
  407. reduced = 0;
  408. for (i = 0; i < graph->filter_count; i++)
  409. reduced |= reduce_formats_on_filter(graph->filters[i]);
  410. } while (reduced);
  411. }
  412. static void swap_samplerates_on_filter(AVFilterContext *filter)
  413. {
  414. AVFilterLink *link = NULL;
  415. int sample_rate;
  416. int i, j;
  417. for (i = 0; i < filter->input_count; i++) {
  418. link = filter->inputs[i];
  419. if (link->type == AVMEDIA_TYPE_AUDIO &&
  420. link->out_samplerates->format_count == 1)
  421. break;
  422. }
  423. if (i == filter->input_count)
  424. return;
  425. sample_rate = link->out_samplerates->formats[0];
  426. for (i = 0; i < filter->output_count; i++) {
  427. AVFilterLink *outlink = filter->outputs[i];
  428. int best_idx, best_diff = INT_MAX;
  429. if (outlink->type != AVMEDIA_TYPE_AUDIO ||
  430. outlink->in_samplerates->format_count < 2)
  431. continue;
  432. for (j = 0; j < outlink->in_samplerates->format_count; j++) {
  433. int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
  434. if (diff < best_diff) {
  435. best_diff = diff;
  436. best_idx = j;
  437. }
  438. }
  439. FFSWAP(int, outlink->in_samplerates->formats[0],
  440. outlink->in_samplerates->formats[best_idx]);
  441. }
  442. }
  443. static void swap_samplerates(AVFilterGraph *graph)
  444. {
  445. int i;
  446. for (i = 0; i < graph->filter_count; i++)
  447. swap_samplerates_on_filter(graph->filters[i]);
  448. }
  449. static void swap_channel_layouts_on_filter(AVFilterContext *filter)
  450. {
  451. AVFilterLink *link = NULL;
  452. uint64_t chlayout;
  453. int i, j;
  454. for (i = 0; i < filter->input_count; i++) {
  455. link = filter->inputs[i];
  456. if (link->type == AVMEDIA_TYPE_AUDIO &&
  457. link->out_channel_layouts->nb_channel_layouts == 1)
  458. break;
  459. }
  460. if (i == filter->input_count)
  461. return;
  462. chlayout = link->out_channel_layouts->channel_layouts[0];
  463. for (i = 0; i < filter->output_count; i++) {
  464. AVFilterLink *outlink = filter->outputs[i];
  465. int best_idx, best_score = INT_MIN;
  466. if (outlink->type != AVMEDIA_TYPE_AUDIO ||
  467. outlink->in_channel_layouts->nb_channel_layouts < 2)
  468. continue;
  469. for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {
  470. uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];
  471. int matched_channels = av_get_channel_layout_nb_channels(chlayout &
  472. out_chlayout);
  473. int extra_channels = av_get_channel_layout_nb_channels(out_chlayout &
  474. (~chlayout));
  475. int score = matched_channels - extra_channels;
  476. if (score > best_score) {
  477. best_score = score;
  478. best_idx = j;
  479. }
  480. }
  481. FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
  482. outlink->in_channel_layouts->channel_layouts[best_idx]);
  483. }
  484. }
  485. static void swap_channel_layouts(AVFilterGraph *graph)
  486. {
  487. int i;
  488. for (i = 0; i < graph->filter_count; i++)
  489. swap_channel_layouts_on_filter(graph->filters[i]);
  490. }
  491. static int pick_formats(AVFilterGraph *graph)
  492. {
  493. int i, j, ret;
  494. int change;
  495. do{
  496. change = 0;
  497. for (i = 0; i < graph->filter_count; i++) {
  498. AVFilterContext *filter = graph->filters[i];
  499. if (filter->input_count){
  500. for (j = 0; j < filter->input_count; j++){
  501. if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->format_count == 1) {
  502. pick_format(filter->inputs[j], NULL);
  503. change = 1;
  504. }
  505. }
  506. }
  507. if (filter->output_count){
  508. for (j = 0; j < filter->output_count; j++){
  509. if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->format_count == 1) {
  510. pick_format(filter->outputs[j], NULL);
  511. change = 1;
  512. }
  513. }
  514. }
  515. if (filter->input_count && filter->output_count && filter->inputs[0]->format>=0) {
  516. for (j = 0; j < filter->output_count; j++) {
  517. if(filter->outputs[j]->format<0) {
  518. pick_format(filter->outputs[j], filter->inputs[0]);
  519. change = 1;
  520. }
  521. }
  522. }
  523. }
  524. }while(change);
  525. for (i = 0; i < graph->filter_count; i++) {
  526. AVFilterContext *filter = graph->filters[i];
  527. for (j = 0; j < filter->input_count; j++)
  528. if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
  529. return ret;
  530. for (j = 0; j < filter->output_count; j++)
  531. if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
  532. return ret;
  533. }
  534. return 0;
  535. }
  536. int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
  537. {
  538. int ret;
  539. /* find supported formats from sub-filters, and merge along links */
  540. if ((ret = query_formats(graph, log_ctx)) < 0)
  541. return ret;
  542. /* Once everything is merged, it's possible that we'll still have
  543. * multiple valid media format choices. We try to minimize the amount
  544. * of format conversion inside filters */
  545. reduce_formats(graph);
  546. /* for audio filters, ensure the best sample rate and channel layout
  547. * is selected */
  548. swap_samplerates(graph);
  549. swap_channel_layouts(graph);
  550. if ((ret = pick_formats(graph)) < 0)
  551. return ret;
  552. return 0;
  553. }
  554. static int ff_avfilter_graph_config_pointers(AVFilterGraph *graph,
  555. AVClass *log_ctx)
  556. {
  557. unsigned i, j;
  558. int sink_links_count = 0, n = 0;
  559. AVFilterContext *f;
  560. AVFilterLink **sinks;
  561. for (i = 0; i < graph->filter_count; i++) {
  562. f = graph->filters[i];
  563. for (j = 0; j < f->input_count; j++) {
  564. f->inputs[j]->graph = graph;
  565. f->inputs[j]->age_index = -1;
  566. }
  567. for (j = 0; j < f->output_count; j++) {
  568. f->outputs[j]->graph = graph;
  569. f->outputs[j]->age_index= -1;
  570. }
  571. if (!f->output_count) {
  572. if (f->input_count > INT_MAX - sink_links_count)
  573. return AVERROR(EINVAL);
  574. sink_links_count += f->input_count;
  575. }
  576. }
  577. sinks = av_calloc(sink_links_count, sizeof(*sinks));
  578. if (!sinks)
  579. return AVERROR(ENOMEM);
  580. for (i = 0; i < graph->filter_count; i++) {
  581. f = graph->filters[i];
  582. if (!f->output_count) {
  583. for (j = 0; j < f->input_count; j++) {
  584. sinks[n] = f->inputs[j];
  585. f->inputs[j]->age_index = n++;
  586. }
  587. }
  588. }
  589. av_assert0(n == sink_links_count);
  590. graph->sink_links = sinks;
  591. graph->sink_links_count = sink_links_count;
  592. return 0;
  593. }
  594. int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
  595. {
  596. int ret;
  597. if ((ret = ff_avfilter_graph_check_validity(graphctx, log_ctx)))
  598. return ret;
  599. if ((ret = ff_avfilter_graph_config_formats(graphctx, log_ctx)))
  600. return ret;
  601. if ((ret = ff_avfilter_graph_config_links(graphctx, log_ctx)))
  602. return ret;
  603. if ((ret = ff_avfilter_graph_config_pointers(graphctx, log_ctx)))
  604. return ret;
  605. return 0;
  606. }
  607. int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
  608. {
  609. int i, r = AVERROR(ENOSYS);
  610. if(!graph)
  611. return r;
  612. if((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
  613. r=avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
  614. if(r != AVERROR(ENOSYS))
  615. return r;
  616. }
  617. if(res_len && res)
  618. res[0]= 0;
  619. for (i = 0; i < graph->filter_count; i++) {
  620. AVFilterContext *filter = graph->filters[i];
  621. if(!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)){
  622. r = avfilter_process_command(filter, cmd, arg, res, res_len, flags);
  623. if(r != AVERROR(ENOSYS)) {
  624. if((flags & AVFILTER_CMD_FLAG_ONE) || r<0)
  625. return r;
  626. }
  627. }
  628. }
  629. return r;
  630. }
  631. int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts)
  632. {
  633. int i;
  634. if(!graph)
  635. return 0;
  636. for (i = 0; i < graph->filter_count; i++) {
  637. AVFilterContext *filter = graph->filters[i];
  638. if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){
  639. AVFilterCommand **que = &filter->command_queue, *next;
  640. while(*que && (*que)->time <= ts)
  641. que = &(*que)->next;
  642. next= *que;
  643. *que= av_mallocz(sizeof(AVFilterCommand));
  644. (*que)->command = av_strdup(command);
  645. (*que)->arg = av_strdup(arg);
  646. (*que)->time = ts;
  647. (*que)->flags = flags;
  648. (*que)->next = next;
  649. if(flags & AVFILTER_CMD_FLAG_ONE)
  650. return 0;
  651. }
  652. }
  653. return 0;
  654. }
  655. static void heap_bubble_up(AVFilterGraph *graph,
  656. AVFilterLink *link, int index)
  657. {
  658. AVFilterLink **links = graph->sink_links;
  659. while (index) {
  660. int parent = (index - 1) >> 1;
  661. if (links[parent]->current_pts >= link->current_pts)
  662. break;
  663. links[index] = links[parent];
  664. links[index]->age_index = index;
  665. index = parent;
  666. }
  667. links[index] = link;
  668. link->age_index = index;
  669. }
  670. static void heap_bubble_down(AVFilterGraph *graph,
  671. AVFilterLink *link, int index)
  672. {
  673. AVFilterLink **links = graph->sink_links;
  674. while (1) {
  675. int child = 2 * index + 1;
  676. if (child >= graph->sink_links_count)
  677. break;
  678. if (child + 1 < graph->sink_links_count &&
  679. links[child + 1]->current_pts < links[child]->current_pts)
  680. child++;
  681. if (link->current_pts < links[child]->current_pts)
  682. break;
  683. links[index] = links[child];
  684. links[index]->age_index = index;
  685. index = child;
  686. }
  687. links[index] = link;
  688. link->age_index = index;
  689. }
  690. void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link)
  691. {
  692. heap_bubble_up (graph, link, link->age_index);
  693. heap_bubble_down(graph, link, link->age_index);
  694. }
  695. int avfilter_graph_request_oldest(AVFilterGraph *graph)
  696. {
  697. while (graph->sink_links_count) {
  698. AVFilterLink *oldest = graph->sink_links[0];
  699. int r = avfilter_request_frame(oldest);
  700. if (r != AVERROR_EOF)
  701. return r;
  702. /* EOF: remove the link from the heap */
  703. if (oldest->age_index < --graph->sink_links_count)
  704. heap_bubble_down(graph, graph->sink_links[graph->sink_links_count],
  705. oldest->age_index);
  706. oldest->age_index = -1;
  707. }
  708. return AVERROR_EOF;
  709. }