Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2025
45
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.86 KB | None | 0 0
  1. From 6cfbb2d26fd131d8fa4d69ea0d9a0c628be48bd5 Mon Sep 17 00:00:00 2001
  2. From: Paul B Mahol <[email protected]>
  3. Date: Wed, 22 Jan 2025 20:17:45 +0000
  4. Subject: [PATCH] avfilter: add pf2pf video filter
  5.  
  6. ---
  7. libavfilter/Makefile | 1 +
  8. libavfilter/allfilters.c | 1 +
  9. libavfilter/pf2pf_dst_depth_template.c | 49 +++++
  10. libavfilter/pf2pf_dst_endian_template.c | 30 +++
  11. libavfilter/pf2pf_src_depth_template.c | 39 ++++
  12. libavfilter/pf2pf_src_endian_template.c | 30 +++
  13. libavfilter/pf2pf_template.c | 113 +++++++++++
  14. libavfilter/vf_pf2pf.c | 251 ++++++++++++++++++++++++
  15. libavutil/imgutils.c | 3 +-
  16. 9 files changed, 515 insertions(+), 2 deletions(-)
  17. create mode 100644 libavfilter/pf2pf_dst_depth_template.c
  18. create mode 100644 libavfilter/pf2pf_dst_endian_template.c
  19. create mode 100644 libavfilter/pf2pf_src_depth_template.c
  20. create mode 100644 libavfilter/pf2pf_src_endian_template.c
  21. create mode 100644 libavfilter/pf2pf_template.c
  22. create mode 100644 libavfilter/vf_pf2pf.c
  23.  
  24. diff --git a/libavfilter/Makefile b/libavfilter/Makefile
  25. index b9089195f9..4d7bfeef41 100644
  26. --- a/libavfilter/Makefile
  27. +++ b/libavfilter/Makefile
  28. @@ -457,6 +457,7 @@ OBJS-$(CONFIG_PALETTEGEN_FILTER) += vf_palettegen.o palette.o
  29. OBJS-$(CONFIG_PALETTEUSE_FILTER) += vf_paletteuse.o framesync.o palette.o
  30. OBJS-$(CONFIG_PERMS_FILTER) += f_perms.o
  31. OBJS-$(CONFIG_PERSPECTIVE_FILTER) += vf_perspective.o
  32. +OBJS-$(CONFIG_PF2PF_FILTER) += vf_pf2pf.o
  33. OBJS-$(CONFIG_PHASE_FILTER) += vf_phase.o
  34. OBJS-$(CONFIG_PHOTOSENSITIVITY_FILTER) += vf_photosensitivity.o
  35. OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o
  36. diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
  37. index 3d435bc7a4..3bc6d62396 100644
  38. --- a/libavfilter/allfilters.c
  39. +++ b/libavfilter/allfilters.c
  40. @@ -430,6 +430,7 @@ extern const FFFilter ff_vf_palettegen;
  41. extern const FFFilter ff_vf_paletteuse;
  42. extern const FFFilter ff_vf_perms;
  43. extern const FFFilter ff_vf_perspective;
  44. +extern const FFFilter ff_vf_pf2pf;
  45. extern const FFFilter ff_vf_phase;
  46. extern const FFFilter ff_vf_photosensitivity;
  47. extern const FFFilter ff_vf_pixdesctest;
  48. diff --git a/libavfilter/pf2pf_dst_depth_template.c b/libavfilter/pf2pf_dst_depth_template.c
  49. new file mode 100644
  50. index 0000000000..d632acdd58
  51. --- /dev/null
  52. +++ b/libavfilter/pf2pf_dst_depth_template.c
  53. @@ -0,0 +1,49 @@
  54. +/*
  55. + * This file is part of FFmpeg.
  56. + *
  57. + * FFmpeg is free software; you can redistribute it and/or
  58. + * modify it under the terms of the GNU Lesser General Public
  59. + * License as published by the Free Software Foundation; either
  60. + * version 2.1 of the License, or (at your option) any later version.
  61. + *
  62. + * FFmpeg is distributed in the hope that it will be useful,
  63. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  64. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  65. + * Lesser General Public License for more details.
  66. + *
  67. + * You should have received a copy of the GNU Lesser General Public
  68. + * License along with FFmpeg; if not, write to the Free Software
  69. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  70. + */
  71. +
  72. +#include "avfilter.h"
  73. +#include "video.h"
  74. +
  75. +#undef dtype
  76. +#undef DST_F
  77. +#undef DWP
  78. +#undef DRP
  79. +#if DST_DEPTH == 8
  80. +#define dtype uint8_t
  81. +#define DST_F u8
  82. +#define DWP(x, y) ((x)[0] = (y))
  83. +#define DRP(x) ((x)[0])
  84. +#elif DST_DEPTH == 16
  85. +#define dtype uint16_t
  86. +#define DST_F u16
  87. +#if DST_E == 0
  88. +#define DWP(x, y) AV_WL16((x), (y))
  89. +#define DRP(x) AV_RL16(x)
  90. +#elif DST_E == 1
  91. +#define DWP(x, y) AV_WB16((x), (y))
  92. +#define DRP(x) AV_RB16(x)
  93. +#endif
  94. +#endif
  95. +
  96. +#undef SRC_DEPTH
  97. +#define SRC_DEPTH 8
  98. +#include "pf2pf_src_depth_template.c"
  99. +
  100. +#undef SRC_DEPTH
  101. +#define SRC_DEPTH 16
  102. +#include "pf2pf_src_depth_template.c"
  103. diff --git a/libavfilter/pf2pf_dst_endian_template.c b/libavfilter/pf2pf_dst_endian_template.c
  104. new file mode 100644
  105. index 0000000000..1007ce6a80
  106. --- /dev/null
  107. +++ b/libavfilter/pf2pf_dst_endian_template.c
  108. @@ -0,0 +1,30 @@
  109. +/*
  110. + * This file is part of FFmpeg.
  111. + *
  112. + * FFmpeg is free software; you can redistribute it and/or
  113. + * modify it under the terms of the GNU Lesser General Public
  114. + * License as published by the Free Software Foundation; either
  115. + * version 2.1 of the License, or (at your option) any later version.
  116. + *
  117. + * FFmpeg is distributed in the hope that it will be useful,
  118. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  119. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  120. + * Lesser General Public License for more details.
  121. + *
  122. + * You should have received a copy of the GNU Lesser General Public
  123. + * License along with FFmpeg; if not, write to the Free Software
  124. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  125. + */
  126. +
  127. +#include "avfilter.h"
  128. +#include "video.h"
  129. +
  130. +#undef DST_E
  131. +#define DST_E 0
  132. +#include "pf2pf_src_endian_template.c"
  133. +
  134. +#if DST_DEPTH == 16
  135. +#undef DST_E
  136. +#define DST_E 1
  137. +#include "pf2pf_src_endian_template.c"
  138. +#endif
  139. diff --git a/libavfilter/pf2pf_src_depth_template.c b/libavfilter/pf2pf_src_depth_template.c
  140. new file mode 100644
  141. index 0000000000..cf5cf4cb1e
  142. --- /dev/null
  143. +++ b/libavfilter/pf2pf_src_depth_template.c
  144. @@ -0,0 +1,39 @@
  145. +/*
  146. + * This file is part of FFmpeg.
  147. + *
  148. + * FFmpeg is free software; you can redistribute it and/or
  149. + * modify it under the terms of the GNU Lesser General Public
  150. + * License as published by the Free Software Foundation; either
  151. + * version 2.1 of the License, or (at your option) any later version.
  152. + *
  153. + * FFmpeg is distributed in the hope that it will be useful,
  154. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  155. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  156. + * Lesser General Public License for more details.
  157. + *
  158. + * You should have received a copy of the GNU Lesser General Public
  159. + * License along with FFmpeg; if not, write to the Free Software
  160. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  161. + */
  162. +
  163. +#include "avfilter.h"
  164. +#include "video.h"
  165. +
  166. +#undef stype
  167. +#undef SRC_F
  168. +#undef SRP
  169. +#if SRC_DEPTH == 8
  170. +#define stype uint8_t
  171. +#define SRC_F u8
  172. +#define SRP(x) ((x)[0])
  173. +#elif SRC_DEPTH == 16
  174. +#define stype uint16_t
  175. +#define SRC_F u16
  176. +#if SRC_E == 0
  177. +#define SRP(x) AV_RL16((x))
  178. +#elif SRC_E == 1
  179. +#define SRP(x) AV_RB16((x))
  180. +#endif
  181. +#endif
  182. +
  183. +#include "pf2pf_template.c"
  184. diff --git a/libavfilter/pf2pf_src_endian_template.c b/libavfilter/pf2pf_src_endian_template.c
  185. new file mode 100644
  186. index 0000000000..6c3d0d30f5
  187. --- /dev/null
  188. +++ b/libavfilter/pf2pf_src_endian_template.c
  189. @@ -0,0 +1,30 @@
  190. +/*
  191. + * This file is part of FFmpeg.
  192. + *
  193. + * FFmpeg is free software; you can redistribute it and/or
  194. + * modify it under the terms of the GNU Lesser General Public
  195. + * License as published by the Free Software Foundation; either
  196. + * version 2.1 of the License, or (at your option) any later version.
  197. + *
  198. + * FFmpeg is distributed in the hope that it will be useful,
  199. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  200. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  201. + * Lesser General Public License for more details.
  202. + *
  203. + * You should have received a copy of the GNU Lesser General Public
  204. + * License along with FFmpeg; if not, write to the Free Software
  205. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  206. + */
  207. +
  208. +#include "avfilter.h"
  209. +#include "video.h"
  210. +
  211. +#undef SRC_E
  212. +#define SRC_E 0
  213. +#include "pf2pf_dst_depth_template.c"
  214. +
  215. +#if SRC_DEPTH == 16
  216. +#undef SRC_E
  217. +#define SRC_E 1
  218. +#include "pf2pf_dst_depth_template.c"
  219. +#endif
  220. diff --git a/libavfilter/pf2pf_template.c b/libavfilter/pf2pf_template.c
  221. new file mode 100644
  222. index 0000000000..e9760bf938
  223. --- /dev/null
  224. +++ b/libavfilter/pf2pf_template.c
  225. @@ -0,0 +1,113 @@
  226. +/*
  227. + * This file is part of FFmpeg.
  228. + *
  229. + * FFmpeg is free software; you can redistribute it and/or
  230. + * modify it under the terms of the GNU Lesser General Public
  231. + * License as published by the Free Software Foundation; either
  232. + * version 2.1 of the License, or (at your option) any later version.
  233. + *
  234. + * FFmpeg is distributed in the hope that it will be useful,
  235. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  236. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  237. + * Lesser General Public License for more details.
  238. + *
  239. + * You should have received a copy of the GNU Lesser General Public
  240. + * License along with FFmpeg; if not, write to the Free Software
  241. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  242. + */
  243. +
  244. +#include "avfilter.h"
  245. +#include "video.h"
  246. +
  247. +#if SRC_DEPTH > 8 || SRC_E == 0
  248. +#define fn3(a,b,c,d,e) a##_##b##_##c##_to_##d##_##e
  249. +#define fn2(a,b,c,d,e) fn3(a,b,c,d,e)
  250. +#define fn(a) fn2(a, SRC_F, SRC_E, DST_F, DST_E)
  251. +
  252. +static void fn(pf2pf_loop)(uint8_t **dstp,
  253. + const uint8_t **srcp,
  254. + const int *dst_linesizep,
  255. + const int *src_linesizep,
  256. + const int w, const int h,
  257. + const int dst_plane,
  258. + const int dst_step, const int dst_shift,
  259. + const int dst_offset, const int dst_depth,
  260. + const int src_plane,
  261. + const int src_step, const int src_shift,
  262. + const int src_offset, const int src_depth)
  263. +{
  264. + const ptrdiff_t dst_linesize = dst_linesizep[dst_plane];
  265. + const ptrdiff_t src_linesize = src_linesizep[src_plane];
  266. + const unsigned dst_mask = (1U << dst_depth) - 1;
  267. + const unsigned src_mask = (1U << src_depth) - 1;
  268. + const unsigned dst_rshift = FFMAX(src_depth - dst_depth, 0);
  269. + const unsigned dst_lshift = dst_shift + FFMAX(dst_depth-src_depth, 0);
  270. + const uint8_t *src = srcp[src_plane];
  271. + uint8_t *dst = dstp[dst_plane];
  272. +
  273. + for (int y = 0; y < h; y++) {
  274. + for (int x = 0, i = 0, j = 0; x < w; x++) {
  275. + unsigned odst = DRP(dst + i + dst_offset);
  276. + DWP(dst + i + dst_offset, odst | (((((SRP(src + j + src_offset) >> src_shift) & src_mask) >> dst_rshift) & dst_mask) << dst_lshift));
  277. + i += dst_step;
  278. + j += src_step;
  279. + }
  280. +
  281. + dst += dst_linesize;
  282. + src += src_linesize;
  283. + }
  284. +}
  285. +
  286. +static int fn(pf2pf)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  287. +{
  288. + PF2PFContext *s = ctx->priv;
  289. + const int nb_components = s->dst_desc->nb_components;
  290. + const int *linesize = s->linesize;
  291. + ThreadData *td = arg;
  292. + AVFrame *restrict out = td->out;
  293. + AVFrame *restrict in = td->in;
  294. + const int w = in->width;
  295. + const int h = in->height;
  296. + const int start = (h * jobnr) / nb_jobs;
  297. + const int end = (h * (jobnr+1)) / nb_jobs;
  298. +
  299. + for (int comp = 0; comp < nb_components; comp++) {
  300. + if (out->data[comp]) {
  301. + uint8_t *dst_data = out->data[comp] + start * out->linesize[comp];
  302. +
  303. + for (int y = start; y < end; y++) {
  304. + memset(dst_data, 0, linesize[comp]);
  305. + dst_data += out->linesize[comp];
  306. + }
  307. + }
  308. + }
  309. +
  310. + for (int comp = 0; comp < nb_components; comp++) {
  311. + const int dst_plane = s->dst_desc->comp[comp].plane;
  312. + const int dst_step = s->dst_desc->comp[comp].step;
  313. + const int dst_shift = s->dst_desc->comp[comp].shift;
  314. + const int dst_offset= s->dst_desc->comp[comp].offset;
  315. + const int dst_depth = s->dst_desc->comp[comp].depth;
  316. + const int src_plane = s->src_desc->comp[comp].plane;
  317. + const int src_step = s->src_desc->comp[comp].step;
  318. + const int src_shift = s->src_desc->comp[comp].shift;
  319. + const int src_offset= s->src_desc->comp[comp].offset;
  320. + const int src_depth = s->src_desc->comp[comp].depth;
  321. + uint8_t *dst_data[4] = {NULL}, *src_data[4] = {NULL};
  322. +
  323. + for (int i = 0; i < 4; i++) {
  324. + if (out->data[i])
  325. + dst_data[i] = out->data[i] + start * out->linesize[i];
  326. + if (in->data[i])
  327. + src_data[i] = in->data[i] + start * in->linesize[i];
  328. + }
  329. +
  330. + fn(pf2pf_loop)((uint8_t **)dst_data, (const uint8_t **)src_data, out->linesize, in->linesize,
  331. + w, end - start,
  332. + dst_plane, dst_step, dst_shift, dst_offset, dst_depth,
  333. + src_plane, src_step, src_shift, src_offset, src_depth);
  334. + }
  335. +
  336. + return 0;
  337. +}
  338. +#endif
  339. diff --git a/libavfilter/vf_pf2pf.c b/libavfilter/vf_pf2pf.c
  340. new file mode 100644
  341. index 0000000000..f0a8c51b0b
  342. --- /dev/null
  343. +++ b/libavfilter/vf_pf2pf.c
  344. @@ -0,0 +1,251 @@
  345. +/*
  346. + * This file is part of FFmpeg.
  347. + *
  348. + * FFmpeg is free software; you can redistribute it and/or
  349. + * modify it under the terms of the GNU Lesser General Public
  350. + * License as published by the Free Software Foundation; either
  351. + * version 2.1 of the License, or (at your option) any later version.
  352. + *
  353. + * FFmpeg is distributed in the hope that it will be useful,
  354. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  355. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  356. + * Lesser General Public License for more details.
  357. + *
  358. + * You should have received a copy of the GNU Lesser General Public
  359. + * License along with FFmpeg; if not, write to the Free Software
  360. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  361. + */
  362. +
  363. +#include "libavutil/imgutils.h"
  364. +#include "libavutil/intreadwrite.h"
  365. +#include "libavutil/opt.h"
  366. +#include "libavutil/pixdesc.h"
  367. +#include "libavutil/pixfmt.h"
  368. +#include "avfilter.h"
  369. +#include "video.h"
  370. +#include "filters.h"
  371. +#include "formats.h"
  372. +
  373. +typedef struct PF2PFContext {
  374. + const AVClass *class;
  375. +
  376. + const AVPixFmtDescriptor *dst_desc, *src_desc;
  377. +
  378. + int linesize[4];
  379. + int format;
  380. + int pass;
  381. +
  382. + int (*do_pf2pf)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
  383. +} PF2PFContext;
  384. +
  385. +#define OFFSET(x) offsetof(PF2PFContext, x)
  386. +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
  387. +
  388. +static const AVOption pf2pf_options[] = {
  389. + { "format", "set the pixel format", OFFSET(format), AV_OPT_TYPE_PIXEL_FMT, {.i64=AV_PIX_FMT_NONE}, AV_PIX_FMT_NONE, AV_PIX_FMT_NB-1, FLAGS },
  390. + {NULL}
  391. +};
  392. +
  393. +AVFILTER_DEFINE_CLASS(pf2pf);
  394. +
  395. +static int query_formats(const AVFilterContext *ctx,
  396. + AVFilterFormatsConfig **cfg_in,
  397. + AVFilterFormatsConfig **cfg_out)
  398. +{
  399. + const PF2PFContext *s = ctx->priv;
  400. + AVFilterFormats *formats;
  401. + int ret;
  402. +
  403. + formats = ff_all_formats(AVMEDIA_TYPE_VIDEO);
  404. + if (!formats)
  405. + return AVERROR(ENOMEM);
  406. +
  407. + if ((ret = ff_formats_ref(formats, &cfg_in[0]->formats)) < 0)
  408. + return ret;
  409. +
  410. + if (s->format != AV_PIX_FMT_NONE) {
  411. + formats = NULL;
  412. +
  413. + ret = ff_add_format(&formats, s->format);
  414. + if (ret)
  415. + return ret;
  416. +
  417. + return ff_formats_ref(formats, &cfg_out[0]->formats);
  418. + }
  419. +
  420. + formats = ff_all_formats(AVMEDIA_TYPE_VIDEO);
  421. + if (!formats)
  422. + return AVERROR(ENOMEM);
  423. +
  424. + return ff_formats_ref(formats, &cfg_out[0]->formats);
  425. +}
  426. +
  427. +typedef struct ThreadData {
  428. + AVFrame *in, *out;
  429. +} ThreadData;
  430. +
  431. +#define DST_DEPTH 8
  432. +#include "pf2pf_dst_endian_template.c"
  433. +
  434. +#undef DST_DEPTH
  435. +#define DST_DEPTH 16
  436. +#include "pf2pf_dst_endian_template.c"
  437. +
  438. +static int config_output(AVFilterLink *outlink)
  439. +{
  440. + AVFilterContext *ctx = outlink->src;
  441. + AVFilterLink *inlink = ctx->inputs[0];
  442. + PF2PFContext *s = ctx->priv;
  443. + int ret;
  444. +
  445. + if (outlink->format == inlink->format) {
  446. + s->pass = 1;
  447. + return 0;
  448. + }
  449. +
  450. + s->dst_desc = av_pix_fmt_desc_get(outlink->format);
  451. + s->src_desc = av_pix_fmt_desc_get(inlink->format);
  452. +
  453. + if ((ret = av_image_fill_linesizes(s->linesize, outlink->format, inlink->w)) < 0)
  454. + return ret;
  455. +
  456. + if (s->dst_desc->comp[0].depth > 8) {
  457. + if (s->src_desc->comp[0].depth > 8) {
  458. + if (s->dst_desc->flags & AV_PIX_FMT_FLAG_BE) {
  459. + if (s->src_desc->flags & AV_PIX_FMT_FLAG_BE) {
  460. + s->do_pf2pf = pf2pf_u16_1_to_u16_1;
  461. + } else {
  462. + s->do_pf2pf = pf2pf_u16_0_to_u16_1;
  463. + }
  464. + } else {
  465. + if (s->src_desc->flags & AV_PIX_FMT_FLAG_BE) {
  466. + s->do_pf2pf = pf2pf_u16_1_to_u16_0;
  467. + } else {
  468. + s->do_pf2pf = pf2pf_u16_0_to_u16_0;
  469. + }
  470. + }
  471. + } else {
  472. + if (s->dst_desc->flags & AV_PIX_FMT_FLAG_BE) {
  473. + s->do_pf2pf = pf2pf_u8_0_to_u16_1;
  474. + } else {
  475. + s->do_pf2pf = pf2pf_u8_0_to_u16_0;
  476. + }
  477. + }
  478. + } else {
  479. + if (s->src_desc->comp[0].depth > 8) {
  480. + if (s->src_desc->flags & AV_PIX_FMT_FLAG_BE) {
  481. + s->do_pf2pf = pf2pf_u16_1_to_u8_0;
  482. + } else {
  483. + s->do_pf2pf = pf2pf_u16_0_to_u8_0;
  484. + }
  485. + } else {
  486. + s->do_pf2pf = pf2pf_u8_0_to_u8_0;
  487. + }
  488. + }
  489. +
  490. + return 0;
  491. +}
  492. +
  493. +static int filter_frame(AVFilterLink *inlink, AVFrame *in)
  494. +{
  495. + AVFilterContext *ctx = inlink->dst;
  496. + AVFilterLink *outlink = ctx->outputs[0];
  497. + PF2PFContext *s = ctx->priv;
  498. + AVFrame *out;
  499. +
  500. + if (s->pass) {
  501. + out = in;
  502. + } else {
  503. + ThreadData td;
  504. + int nb_jobs;
  505. +
  506. + out = ff_get_video_buffer(outlink, in->width, in->height);
  507. + if (!out) {
  508. + av_frame_free(&in);
  509. + return AVERROR(ENOMEM);
  510. + }
  511. +
  512. + td.in = in;
  513. + td.out = out;
  514. +
  515. + nb_jobs = in->height;
  516. +
  517. + ff_filter_execute(ctx, s->do_pf2pf, &td, NULL,
  518. + FFMIN(nb_jobs, ff_filter_get_nb_threads(ctx)));
  519. +
  520. + av_frame_copy_props(out, in);
  521. + av_frame_free(&in);
  522. + }
  523. +
  524. + return ff_filter_frame(outlink, out);
  525. +}
  526. +
  527. +static int activate(AVFilterContext *ctx)
  528. +{
  529. + AVFilterLink *inlink = ctx->inputs[0];
  530. + AVFilterLink *outlink = ctx->outputs[0];
  531. + AVFrame *in;
  532. + int ret;
  533. +
  534. + FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
  535. +
  536. + ret = ff_inlink_consume_frame(inlink, &in);
  537. + if (ret < 0)
  538. + return ret;
  539. + if (ret > 0)
  540. + return filter_frame(inlink, in);
  541. +
  542. + FF_FILTER_FORWARD_STATUS(inlink, outlink);
  543. + FF_FILTER_FORWARD_WANTED(outlink, inlink);
  544. +
  545. + return FFERROR_NOT_READY;
  546. +}
  547. +
  548. +static AVFrame *get_in_video_buffer(AVFilterLink *inlink, int w, int h)
  549. +{
  550. + AVFilterContext *ctx = inlink->dst;
  551. + PF2PFContext *s = ctx->priv;
  552. +
  553. + return s->pass ?
  554. + ff_null_get_video_buffer (inlink, w, h) :
  555. + ff_default_get_video_buffer(inlink, w, h);
  556. +}
  557. +
  558. +static AVFrame *get_out_video_buffer(AVFilterLink *outlink, int w, int h)
  559. +{
  560. + AVFilterContext *ctx = outlink->src;
  561. + PF2PFContext *s = ctx->priv;
  562. +
  563. + return s->pass ?
  564. + ff_null_get_video_buffer (outlink, w, h) :
  565. + ff_default_get_video_buffer(outlink, w, h);
  566. +}
  567. +
  568. +static const AVFilterPad inputs[] = {
  569. + {
  570. + .name = "default",
  571. + .type = AVMEDIA_TYPE_VIDEO,
  572. + .get_buffer.video = get_in_video_buffer,
  573. + },
  574. +};
  575. +
  576. +static const AVFilterPad outputs[] = {
  577. + {
  578. + .name = "default",
  579. + .type = AVMEDIA_TYPE_VIDEO,
  580. + .config_props = config_output,
  581. + .get_buffer.video = get_out_video_buffer,
  582. + },
  583. +};
  584. +
  585. +const FFFilter ff_vf_pf2pf = {
  586. + .p.name = "pf2pf",
  587. + .p.description = NULL_IF_CONFIG_SMALL("Switch video pixel format."),
  588. + .p.priv_class = &pf2pf_class,
  589. + .priv_size = sizeof(PF2PFContext),
  590. + .activate = activate,
  591. + FILTER_QUERY_FUNC2(query_formats),
  592. + FILTER_INPUTS(inputs),
  593. + FILTER_OUTPUTS(outputs),
  594. + .p.flags = AVFILTER_FLAG_SLICE_THREADS,
  595. +};
  596. diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c
  597. index 119372e418..2b1dc10215 100644
  598. --- a/libavutil/imgutils.c
  599. +++ b/libavutil/imgutils.c
  600. @@ -35,12 +35,11 @@
  601. void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4],
  602. const AVPixFmtDescriptor *pixdesc)
  603. {
  604. - int i;
  605. memset(max_pixsteps, 0, 4*sizeof(max_pixsteps[0]));
  606. if (max_pixstep_comps)
  607. memset(max_pixstep_comps, 0, 4*sizeof(max_pixstep_comps[0]));
  608.  
  609. - for (i = 0; i < 4; i++) {
  610. + for (int i = 0; i < pixdesc->nb_components; i++) {
  611. const AVComponentDescriptor *comp = &(pixdesc->comp[i]);
  612. if (comp->step > max_pixsteps[comp->plane]) {
  613. max_pixsteps[comp->plane] = comp->step;
  614. --
  615. 2.47.1
  616.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement