ashk43712

vmaf

Jun 19th, 2017
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 80.39 KB | None | 0 0
  1. From c6221675fce8057905439b80166535002e9f1431 Mon Sep 17 00:00:00 2001
  2. From: Ubuntu <ubuntu@ip-172-31-11-196.us-west-2.compute.internal>
  3. Date: Tue, 30 May 2017 05:03:20 +0000
  4. Subject: [PATCH 01/18] Added vf_vmaf.c and vmaf.h files
  5.  
  6. ---
  7. libavfilter/vf_vmaf.c | 418 ++++++++++++++++++++++++++++++++++++++++++++++++++
  8. libavfilter/vmaf.h | 33 ++++
  9. 2 files changed, 451 insertions(+)
  10. create mode 100644 libavfilter/vf_vmaf.c
  11. create mode 100644 libavfilter/vmaf.h
  12.  
  13. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  14. new file mode 100644
  15. index 0000000..53bb8a4
  16. --- /dev/null
  17. +++ b/libavfilter/vf_vmaf.c
  18. @@ -0,0 +1,418 @@
  19. +/*
  20. + * Copyright (c) 2011 Roger Pau Monné <roger.pau@entel.upc.edu>
  21. + * Copyright (c) 2011 Stefano Sabatini
  22. + * Copyright (c) 2013 Paul B Mahol
  23. + *
  24. + * This file is part of FFmpeg.
  25. + *
  26. + * FFmpeg is free software; you can redistribute it and/or
  27. + * modify it under the terms of the GNU Lesser General Public
  28. + * License as published by the Free Software Foundation; either
  29. + * version 2.1 of the License, or (at your option) any later version.
  30. + *
  31. + * FFmpeg is distributed in the hope that it will be useful,
  32. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  33. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  34. + * Lesser General Public License for more details.
  35. + *
  36. + * You should have received a copy of the GNU Lesser General Public
  37. + * License along with FFmpeg; if not, write to the Free Software
  38. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  39. + */
  40. +
  41. +/**
  42. + * @file
  43. + * Caculate the VMAF between two input videos.
  44. + */
  45. +
  46. +#include "libavutil/avstring.h"
  47. +#include "libavutil/opt.h"
  48. +#include "libavutil/pixdesc.h"
  49. +#include "avfilter.h"
  50. +#include "dualinput.h"
  51. +#include "drawutils.h"
  52. +#include "formats.h"
  53. +#include "internal.h"
  54. +#include "vmaf.h"
  55. +#include "video.h"
  56. +
  57. +typedef struct VMAFContext {
  58. + const AVClass *class;
  59. + FFDualInputContext dinput;
  60. + double mse, min_mse, max_mse, mse_comp[4];
  61. + uint64_t nb_frames;
  62. + FILE *stats_file;
  63. + char *stats_file_str;
  64. + int stats_version;
  65. + int stats_header_written;
  66. + int stats_add_max;
  67. + int max[4], average_max;
  68. + int is_rgb;
  69. + uint8_t rgba_map[4];
  70. + char comps[4];
  71. + int nb_components;
  72. + int planewidth[4];
  73. + int planeheight[4];
  74. + double planeweight[4];
  75. + VMAFDSPContext dsp;
  76. +} VMAFContext;
  77. +
  78. +#define OFFSET(x) offsetof(VMAFContext, x)
  79. +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
  80. +
  81. +static const AVOption vmaf_options[] = {
  82. + {"stats_file", "Set file where to store per-frame difference information", OFFSET(stats_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
  83. + {"f", "Set file where to store per-frame difference information", OFFSET(stats_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
  84. + {"stats_version", "Set the format version for the stats file.", OFFSET(stats_version), AV_OPT_TYPE_INT, {.i64=1}, 1, 2, FLAGS },
  85. + {"output_max", "Add raw stats (max values) to the output log.", OFFSET(stats_add_max), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
  86. + { NULL }
  87. +};
  88. +
  89. +AVFILTER_DEFINE_CLASS(vmaf);
  90. +
  91. +static inline unsigned pow_2(unsigned base)
  92. +{
  93. + return base*base;
  94. +}
  95. +
  96. +static inline double get_vmaf(double mse, uint64_t nb_frames, int max)
  97. +{
  98. + return 10.0 * log10(pow_2(max) / (mse / nb_frames));
  99. +}
  100. +
  101. +static uint64_t sse_line_8bit(const uint8_t *main_line, const uint8_t *ref_line, int outw)
  102. +{
  103. + int j;
  104. + unsigned m2 = 0;
  105. +
  106. + for (j = 0; j < outw; j++)
  107. + m2 += pow_2(main_line[j] - ref_line[j]);
  108. +
  109. + return m2;
  110. +}
  111. +
  112. +static uint64_t sse_line_16bit(const uint8_t *_main_line, const uint8_t *_ref_line, int outw)
  113. +{
  114. + int j;
  115. + uint64_t m2 = 0;
  116. + const uint16_t *main_line = (const uint16_t *) _main_line;
  117. + const uint16_t *ref_line = (const uint16_t *) _ref_line;
  118. +
  119. + for (j = 0; j < outw; j++)
  120. + m2 += pow_2(main_line[j] - ref_line[j]);
  121. +
  122. + return m2;
  123. +}
  124. +
  125. +static inline
  126. +void compute_images_mse(VMAFContext *s,
  127. + const uint8_t *main_data[4], const int main_linesizes[4],
  128. + const uint8_t *ref_data[4], const int ref_linesizes[4],
  129. + int w, int h, double mse[4])
  130. +{
  131. + int i, c;
  132. +
  133. + for (c = 0; c < s->nb_components; c++) {
  134. + const int outw = s->planewidth[c];
  135. + const int outh = s->planeheight[c];
  136. + const uint8_t *main_line = main_data[c];
  137. + const uint8_t *ref_line = ref_data[c];
  138. + const int ref_linesize = ref_linesizes[c];
  139. + const int main_linesize = main_linesizes[c];
  140. + uint64_t m = 0;
  141. + for (i = 0; i < outh; i++) {
  142. + m += s->dsp.sse_line(main_line, ref_line, outw);
  143. + ref_line += ref_linesize;
  144. + main_line += main_linesize;
  145. + }
  146. + mse[c] = m / (double)(outw * outh);
  147. + }
  148. +}
  149. +
  150. +static void set_meta(AVDictionary **metadata, const char *key, char comp, float d)
  151. +{
  152. + char value[128];
  153. + snprintf(value, sizeof(value), "%0.2f", d);
  154. + if (comp) {
  155. + char key2[128];
  156. + snprintf(key2, sizeof(key2), "%s%c", key, comp);
  157. + av_dict_set(metadata, key2, value, 0);
  158. + } else {
  159. + av_dict_set(metadata, key, value, 0);
  160. + }
  161. +}
  162. +
  163. +static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main,
  164. + const AVFrame *ref)
  165. +{
  166. + VMAFContext *s = ctx->priv;
  167. + double comp_mse[4], mse = 0;
  168. + int j, c;
  169. + AVDictionary **metadata = &main->metadata;
  170. +
  171. + compute_images_mse(s, (const uint8_t **)main->data, main->linesize,
  172. + (const uint8_t **)ref->data, ref->linesize,
  173. + main->width, main->height, comp_mse);
  174. +
  175. + for (j = 0; j < s->nb_components; j++)
  176. + mse += comp_mse[j] * s->planeweight[j];
  177. +
  178. + s->min_mse = FFMIN(s->min_mse, mse);
  179. + s->max_mse = FFMAX(s->max_mse, mse);
  180. +
  181. + s->mse += mse;
  182. + for (j = 0; j < s->nb_components; j++)
  183. + s->mse_comp[j] += comp_mse[j];
  184. + s->nb_frames++;
  185. +
  186. + for (j = 0; j < s->nb_components; j++) {
  187. + c = s->is_rgb ? s->rgba_map[j] : j;
  188. + set_meta(metadata, "lavfi.vmaf.mse.", s->comps[j], comp_mse[c]);
  189. + set_meta(metadata, "lavfi.vmaf.vmaf.", s->comps[j], get_vmaf(comp_mse[c], 1, s->max[c]));
  190. + }
  191. + set_meta(metadata, "lavfi.vmaf.mse_avg", 0, mse);
  192. + set_meta(metadata, "lavfi.vmaf.vmaf_avg", 0, get_vmaf(mse, 1, s->average_max));
  193. +
  194. + if (s->stats_file) {
  195. + if (s->stats_version == 2 && !s->stats_header_written) {
  196. + fprintf(s->stats_file, "vmaf_log_version:2 fields:n");
  197. + fprintf(s->stats_file, ",mse_avg");
  198. + for (j = 0; j < s->nb_components; j++) {
  199. + fprintf(s->stats_file, ",mse_%c", s->comps[j]);
  200. + }
  201. + fprintf(s->stats_file, ",vmaf_avg");
  202. + for (j = 0; j < s->nb_components; j++) {
  203. + fprintf(s->stats_file, ",vmaf_%c", s->comps[j]);
  204. + }
  205. + if (s->stats_add_max) {
  206. + fprintf(s->stats_file, ",max_avg");
  207. + for (j = 0; j < s->nb_components; j++) {
  208. + fprintf(s->stats_file, ",max_%c", s->comps[j]);
  209. + }
  210. + }
  211. + fprintf(s->stats_file, "\n");
  212. + s->stats_header_written = 1;
  213. + }
  214. + fprintf(s->stats_file, "n:%"PRId64" mse_avg:%0.2f ", s->nb_frames, mse);
  215. + for (j = 0; j < s->nb_components; j++) {
  216. + c = s->is_rgb ? s->rgba_map[j] : j;
  217. + fprintf(s->stats_file, "mse_%c:%0.2f ", s->comps[j], comp_mse[c]);
  218. + }
  219. + fprintf(s->stats_file, "vmaf_avg:%0.2f ", get_vmaf(mse, 1, s->average_max));
  220. + for (j = 0; j < s->nb_components; j++) {
  221. + c = s->is_rgb ? s->rgba_map[j] : j;
  222. + fprintf(s->stats_file, "vmaf_%c:%0.2f ", s->comps[j],
  223. + get_vmaf(comp_mse[c], 1, s->max[c]));
  224. + }
  225. + if (s->stats_version == 2 && s->stats_add_max) {
  226. + fprintf(s->stats_file, "max_avg:%d ", s->average_max);
  227. + for (j = 0; j < s->nb_components; j++) {
  228. + c = s->is_rgb ? s->rgba_map[j] : j;
  229. + fprintf(s->stats_file, "max_%c:%d ", s->comps[j], s->max[c]);
  230. + }
  231. + }
  232. + fprintf(s->stats_file, "\n");
  233. + }
  234. +
  235. + return main;
  236. +}
  237. +
  238. +static av_cold int init(AVFilterContext *ctx)
  239. +{
  240. + VMAFContext *s = ctx->priv;
  241. +
  242. + s->min_mse = +INFINITY;
  243. + s->max_mse = -INFINITY;
  244. +
  245. + if (s->stats_file_str) {
  246. + if (s->stats_version < 2 && s->stats_add_max) {
  247. + av_log(ctx, AV_LOG_ERROR,
  248. + "stats_add_max was specified but stats_version < 2.\n" );
  249. + return AVERROR(EINVAL);
  250. + }
  251. + if (!strcmp(s->stats_file_str, "-")) {
  252. + s->stats_file = stdout;
  253. + } else {
  254. + s->stats_file = fopen(s->stats_file_str, "w");
  255. + if (!s->stats_file) {
  256. + int err = AVERROR(errno);
  257. + char buf[128];
  258. + av_strerror(err, buf, sizeof(buf));
  259. + av_log(ctx, AV_LOG_ERROR, "Could not open stats file %s: %s\n",
  260. + s->stats_file_str, buf);
  261. + return err;
  262. + }
  263. + }
  264. + }
  265. +
  266. + s->dinput.process = do_vmaf;
  267. + return 0;
  268. +}
  269. +
  270. +static int query_formats(AVFilterContext *ctx)
  271. +{
  272. + static const enum AVPixelFormat pix_fmts[] = {
  273. + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16,
  274. +#define PF_NOALPHA(suf) AV_PIX_FMT_YUV420##suf, AV_PIX_FMT_YUV422##suf, AV_PIX_FMT_YUV444##suf
  275. +#define PF_ALPHA(suf) AV_PIX_FMT_YUVA420##suf, AV_PIX_FMT_YUVA422##suf, AV_PIX_FMT_YUVA444##suf
  276. +#define PF(suf) PF_NOALPHA(suf), PF_ALPHA(suf)
  277. + PF(P), PF(P9), PF(P10), PF_NOALPHA(P12), PF_NOALPHA(P14), PF(P16),
  278. + AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
  279. + AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P,
  280. + AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P,
  281. + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10,
  282. + AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16,
  283. + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP16,
  284. + AV_PIX_FMT_NONE
  285. + };
  286. +
  287. + AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
  288. + if (!fmts_list)
  289. + return AVERROR(ENOMEM);
  290. + return ff_set_common_formats(ctx, fmts_list);
  291. +}
  292. +
  293. +static int config_input_ref(AVFilterLink *inlink)
  294. +{
  295. + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
  296. + AVFilterContext *ctx = inlink->dst;
  297. + VMAFContext *s = ctx->priv;
  298. + double average_max;
  299. + unsigned sum;
  300. + int j;
  301. +
  302. + s->nb_components = desc->nb_components;
  303. + if (ctx->inputs[0]->w != ctx->inputs[1]->w ||
  304. + ctx->inputs[0]->h != ctx->inputs[1]->h) {
  305. + av_log(ctx, AV_LOG_ERROR, "Width and height of input videos must be same.\n");
  306. + return AVERROR(EINVAL);
  307. + }
  308. + if (ctx->inputs[0]->format != ctx->inputs[1]->format) {
  309. + av_log(ctx, AV_LOG_ERROR, "Inputs must be of same pixel format.\n");
  310. + return AVERROR(EINVAL);
  311. + }
  312. +
  313. + s->max[0] = (1 << desc->comp[0].depth) - 1;
  314. + s->max[1] = (1 << desc->comp[1].depth) - 1;
  315. + s->max[2] = (1 << desc->comp[2].depth) - 1;
  316. + s->max[3] = (1 << desc->comp[3].depth) - 1;
  317. +
  318. + s->is_rgb = ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0;
  319. + s->comps[0] = s->is_rgb ? 'r' : 'y' ;
  320. + s->comps[1] = s->is_rgb ? 'g' : 'u' ;
  321. + s->comps[2] = s->is_rgb ? 'b' : 'v' ;
  322. + s->comps[3] = 'a';
  323. +
  324. + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
  325. + s->planeheight[0] = s->planeheight[3] = inlink->h;
  326. + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
  327. + s->planewidth[0] = s->planewidth[3] = inlink->w;
  328. + sum = 0;
  329. + for (j = 0; j < s->nb_components; j++)
  330. + sum += s->planeheight[j] * s->planewidth[j];
  331. + average_max = 0;
  332. + for (j = 0; j < s->nb_components; j++) {
  333. + s->planeweight[j] = (double) s->planeheight[j] * s->planewidth[j] / sum;
  334. + average_max += s->max[j] * s->planeweight[j];
  335. + }
  336. + s->average_max = lrint(average_max);
  337. +
  338. + s->dsp.sse_line = desc->comp[0].depth > 8 ? sse_line_16bit : sse_line_8bit;
  339. + if (ARCH_X86)
  340. + ff_vmaf_init_x86(&s->dsp, desc->comp[0].depth);
  341. +
  342. + return 0;
  343. +}
  344. +
  345. +static int config_output(AVFilterLink *outlink)
  346. +{
  347. + AVFilterContext *ctx = outlink->src;
  348. + VMAFContext *s = ctx->priv;
  349. + AVFilterLink *mainlink = ctx->inputs[0];
  350. + int ret;
  351. +
  352. + outlink->w = mainlink->w;
  353. + outlink->h = mainlink->h;
  354. + outlink->time_base = mainlink->time_base;
  355. + outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio;
  356. + outlink->frame_rate = mainlink->frame_rate;
  357. + if ((ret = ff_dualinput_init(ctx, &s->dinput)) < 0)
  358. + return ret;
  359. +
  360. + return 0;
  361. +}
  362. +
  363. +static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
  364. +{
  365. + VMAFContext *s = inlink->dst->priv;
  366. + return ff_dualinput_filter_frame(&s->dinput, inlink, inpicref);
  367. +}
  368. +
  369. +static int request_frame(AVFilterLink *outlink)
  370. +{
  371. + VMAFContext *s = outlink->src->priv;
  372. + return ff_dualinput_request_frame(&s->dinput, outlink);
  373. +}
  374. +
  375. +static av_cold void uninit(AVFilterContext *ctx)
  376. +{
  377. + VMAFContext *s = ctx->priv;
  378. +
  379. + if (s->nb_frames > 0) {
  380. + int j;
  381. + char buf[256];
  382. +
  383. + buf[0] = 0;
  384. + for (j = 0; j < s->nb_components; j++) {
  385. + int c = s->is_rgb ? s->rgba_map[j] : j;
  386. + av_strlcatf(buf, sizeof(buf), " %c:%f", s->comps[j],
  387. + get_vmaf(s->mse_comp[c], s->nb_frames, s->max[c]));
  388. + }
  389. + av_log(ctx, AV_LOG_INFO, "VMAF%s average:%f min:%f max:%f\n",
  390. + buf,
  391. + get_vmaf(s->mse, s->nb_frames, s->average_max),
  392. + get_vmaf(s->max_mse, 1, s->average_max),
  393. + get_vmaf(s->min_mse, 1, s->average_max));
  394. + }
  395. +
  396. + ff_dualinput_uninit(&s->dinput);
  397. +
  398. + if (s->stats_file && s->stats_file != stdout)
  399. + fclose(s->stats_file);
  400. +}
  401. +
  402. +static const AVFilterPad vmaf_inputs[] = {
  403. + {
  404. + .name = "main",
  405. + .type = AVMEDIA_TYPE_VIDEO,
  406. + .filter_frame = filter_frame,
  407. + },{
  408. + .name = "reference",
  409. + .type = AVMEDIA_TYPE_VIDEO,
  410. + .filter_frame = filter_frame,
  411. + .config_props = config_input_ref,
  412. + },
  413. + { NULL }
  414. +};
  415. +
  416. +static const AVFilterPad vmaf_outputs[] = {
  417. + {
  418. + .name = "default",
  419. + .type = AVMEDIA_TYPE_VIDEO,
  420. + .config_props = config_output,
  421. + .request_frame = request_frame,
  422. + },
  423. + { NULL }
  424. +};
  425. +
  426. +AVFilter ff_vf_vmaf = {
  427. + .name = "vmaf",
  428. + .description = NULL_IF_CONFIG_SMALL("Calculate the VMAF between two video streams."),
  429. + .init = init,
  430. + .uninit = uninit,
  431. + .query_formats = query_formats,
  432. + .priv_size = sizeof(VMAFContext),
  433. + .priv_class = &vmaf_class,
  434. + .inputs = vmaf_inputs,
  435. + .outputs = vmaf_outputs,
  436. +};
  437. diff --git a/libavfilter/vmaf.h b/libavfilter/vmaf.h
  438. new file mode 100644
  439. index 0000000..ebfc38a
  440. --- /dev/null
  441. +++ b/libavfilter/vmaf.h
  442. @@ -0,0 +1,33 @@
  443. +/*
  444. + * Copyright (c) 2015 Ronald S. Bultje <rsbultje@gmail.com>
  445. + *
  446. + * This file is part of FFmpeg.
  447. + *
  448. + * FFmpeg is free software; you can redistribute it and/or
  449. + * modify it under the terms of the GNU Lesser General Public
  450. + * License as published by the Free Software Foundation; either
  451. + * version 2.1 of the License, or (at your option) any later version.
  452. + *
  453. + * FFmpeg is distributed in the hope that it will be useful,
  454. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  455. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  456. + * Lesser General Public License for more details.
  457. + *
  458. + * You should have received a copy of the GNU Lesser General Public
  459. + * License along with FFmpeg; if not, write to the Free Software
  460. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  461. + */
  462. +
  463. +#ifndef AVFILTER_VMAF_H
  464. +#define AVFILTER_VMAF_H
  465. +
  466. +#include <stddef.h>
  467. +#include <stdint.h>
  468. +
  469. +typedef struct VMAFDSPContext {
  470. + uint64_t (*sse_line)(const uint8_t *buf, const uint8_t *ref, int w);
  471. +} VMAFDSPContext;
  472. +
  473. +void ff_vmaf_init_x86(VMAFDSPContext *dsp, int bpp);
  474. +
  475. +#endif /* AVFILTER_VMAF_H */
  476. --
  477. 2.7.4
  478.  
  479.  
  480. From 5e508cbc321109cd17fdb00385f94b11d31e2e62 Mon Sep 17 00:00:00 2001
  481. From: Ubuntu <ubuntu@ip-172-31-11-196.us-west-2.compute.internal>
  482. Date: Tue, 30 May 2017 05:17:10 +0000
  483. Subject: [PATCH 02/18] made changes in makefile and allfilters.c
  484.  
  485. ---
  486. libavfilter/Makefile | 1 +
  487. libavfilter/allfilters.c | 1 +
  488. 2 files changed, 2 insertions(+)
  489.  
  490. diff --git a/libavfilter/Makefile b/libavfilter/Makefile
  491. index f7dfe8a..1c4bd56 100644
  492. --- a/libavfilter/Makefile
  493. +++ b/libavfilter/Makefile
  494. @@ -314,6 +314,7 @@ OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o
  495. OBJS-$(CONFIG_VIDSTABDETECT_FILTER) += vidstabutils.o vf_vidstabdetect.o
  496. OBJS-$(CONFIG_VIDSTABTRANSFORM_FILTER) += vidstabutils.o vf_vidstabtransform.o
  497. OBJS-$(CONFIG_VIGNETTE_FILTER) += vf_vignette.o
  498. +OBJS-$(CONFIG_VMAF_FILTER) += vf_vmaf.o dualinput.o framesync.o
  499. OBJS-$(CONFIG_VSTACK_FILTER) += vf_stack.o framesync.o
  500. OBJS-$(CONFIG_W3FDIF_FILTER) += vf_w3fdif.o
  501. OBJS-$(CONFIG_WAVEFORM_FILTER) += vf_waveform.o
  502. diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
  503. index cd35ae4..6894a6f 100644
  504. --- a/libavfilter/allfilters.c
  505. +++ b/libavfilter/allfilters.c
  506. @@ -325,6 +325,7 @@ static void register_all(void)
  507. REGISTER_FILTER(VIDSTABDETECT, vidstabdetect, vf);
  508. REGISTER_FILTER(VIDSTABTRANSFORM, vidstabtransform, vf);
  509. REGISTER_FILTER(VIGNETTE, vignette, vf);
  510. + REGISTER_FILTER(VMAF, vmaf, vf);
  511. REGISTER_FILTER(VSTACK, vstack, vf);
  512. REGISTER_FILTER(W3FDIF, w3fdif, vf);
  513. REGISTER_FILTER(WAVEFORM, waveform, vf);
  514. --
  515. 2.7.4
  516.  
  517.  
  518. From 18dc8e5d18eff4641b49a454bb1b761573658aad Mon Sep 17 00:00:00 2001
  519. From: Ubuntu <ubuntu@ip-172-31-11-196.us-west-2.compute.internal>
  520. Date: Tue, 30 May 2017 05:47:38 +0000
  521. Subject: [PATCH 03/18] removed unnecesarry content and modified query formats
  522.  
  523. ---
  524. libavfilter/vf_vmaf.c | 134 +-------------------------------------------------
  525. 1 file changed, 2 insertions(+), 132 deletions(-)
  526.  
  527. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  528. index 53bb8a4..a1ef6b7 100644
  529. --- a/libavfilter/vf_vmaf.c
  530. +++ b/libavfilter/vf_vmaf.c
  531. @@ -111,22 +111,6 @@ void compute_images_mse(VMAFContext *s,
  532. int w, int h, double mse[4])
  533. {
  534. int i, c;
  535. -
  536. - for (c = 0; c < s->nb_components; c++) {
  537. - const int outw = s->planewidth[c];
  538. - const int outh = s->planeheight[c];
  539. - const uint8_t *main_line = main_data[c];
  540. - const uint8_t *ref_line = ref_data[c];
  541. - const int ref_linesize = ref_linesizes[c];
  542. - const int main_linesize = main_linesizes[c];
  543. - uint64_t m = 0;
  544. - for (i = 0; i < outh; i++) {
  545. - m += s->dsp.sse_line(main_line, ref_line, outw);
  546. - ref_line += ref_linesize;
  547. - main_line += main_linesize;
  548. - }
  549. - mse[c] = m / (double)(outw * outh);
  550. - }
  551. }
  552.  
  553. static void set_meta(AVDictionary **metadata, const char *key, char comp, float d)
  554. @@ -154,66 +138,6 @@ static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main,
  555. (const uint8_t **)ref->data, ref->linesize,
  556. main->width, main->height, comp_mse);
  557.  
  558. - for (j = 0; j < s->nb_components; j++)
  559. - mse += comp_mse[j] * s->planeweight[j];
  560. -
  561. - s->min_mse = FFMIN(s->min_mse, mse);
  562. - s->max_mse = FFMAX(s->max_mse, mse);
  563. -
  564. - s->mse += mse;
  565. - for (j = 0; j < s->nb_components; j++)
  566. - s->mse_comp[j] += comp_mse[j];
  567. - s->nb_frames++;
  568. -
  569. - for (j = 0; j < s->nb_components; j++) {
  570. - c = s->is_rgb ? s->rgba_map[j] : j;
  571. - set_meta(metadata, "lavfi.vmaf.mse.", s->comps[j], comp_mse[c]);
  572. - set_meta(metadata, "lavfi.vmaf.vmaf.", s->comps[j], get_vmaf(comp_mse[c], 1, s->max[c]));
  573. - }
  574. - set_meta(metadata, "lavfi.vmaf.mse_avg", 0, mse);
  575. - set_meta(metadata, "lavfi.vmaf.vmaf_avg", 0, get_vmaf(mse, 1, s->average_max));
  576. -
  577. - if (s->stats_file) {
  578. - if (s->stats_version == 2 && !s->stats_header_written) {
  579. - fprintf(s->stats_file, "vmaf_log_version:2 fields:n");
  580. - fprintf(s->stats_file, ",mse_avg");
  581. - for (j = 0; j < s->nb_components; j++) {
  582. - fprintf(s->stats_file, ",mse_%c", s->comps[j]);
  583. - }
  584. - fprintf(s->stats_file, ",vmaf_avg");
  585. - for (j = 0; j < s->nb_components; j++) {
  586. - fprintf(s->stats_file, ",vmaf_%c", s->comps[j]);
  587. - }
  588. - if (s->stats_add_max) {
  589. - fprintf(s->stats_file, ",max_avg");
  590. - for (j = 0; j < s->nb_components; j++) {
  591. - fprintf(s->stats_file, ",max_%c", s->comps[j]);
  592. - }
  593. - }
  594. - fprintf(s->stats_file, "\n");
  595. - s->stats_header_written = 1;
  596. - }
  597. - fprintf(s->stats_file, "n:%"PRId64" mse_avg:%0.2f ", s->nb_frames, mse);
  598. - for (j = 0; j < s->nb_components; j++) {
  599. - c = s->is_rgb ? s->rgba_map[j] : j;
  600. - fprintf(s->stats_file, "mse_%c:%0.2f ", s->comps[j], comp_mse[c]);
  601. - }
  602. - fprintf(s->stats_file, "vmaf_avg:%0.2f ", get_vmaf(mse, 1, s->average_max));
  603. - for (j = 0; j < s->nb_components; j++) {
  604. - c = s->is_rgb ? s->rgba_map[j] : j;
  605. - fprintf(s->stats_file, "vmaf_%c:%0.2f ", s->comps[j],
  606. - get_vmaf(comp_mse[c], 1, s->max[c]));
  607. - }
  608. - if (s->stats_version == 2 && s->stats_add_max) {
  609. - fprintf(s->stats_file, "max_avg:%d ", s->average_max);
  610. - for (j = 0; j < s->nb_components; j++) {
  611. - c = s->is_rgb ? s->rgba_map[j] : j;
  612. - fprintf(s->stats_file, "max_%c:%d ", s->comps[j], s->max[c]);
  613. - }
  614. - }
  615. - fprintf(s->stats_file, "\n");
  616. - }
  617. -
  618. return main;
  619. }
  620.  
  621. @@ -252,17 +176,8 @@ static av_cold int init(AVFilterContext *ctx)
  622. static int query_formats(AVFilterContext *ctx)
  623. {
  624. static const enum AVPixelFormat pix_fmts[] = {
  625. - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16,
  626. -#define PF_NOALPHA(suf) AV_PIX_FMT_YUV420##suf, AV_PIX_FMT_YUV422##suf, AV_PIX_FMT_YUV444##suf
  627. -#define PF_ALPHA(suf) AV_PIX_FMT_YUVA420##suf, AV_PIX_FMT_YUVA422##suf, AV_PIX_FMT_YUVA444##suf
  628. -#define PF(suf) PF_NOALPHA(suf), PF_ALPHA(suf)
  629. - PF(P), PF(P9), PF(P10), PF_NOALPHA(P12), PF_NOALPHA(P14), PF(P16),
  630. - AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
  631. - AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P,
  632. - AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P,
  633. - AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10,
  634. - AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16,
  635. - AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP16,
  636. + AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
  637. + AV_PIX_FMT_YUV444P10LE, AV_PIX_FMT_YUV422P10LE, AV_PIX_FMT_YUV420P10LE,
  638. AV_PIX_FMT_NONE
  639. };
  640.  
  641. @@ -292,34 +207,6 @@ static int config_input_ref(AVFilterLink *inlink)
  642. return AVERROR(EINVAL);
  643. }
  644.  
  645. - s->max[0] = (1 << desc->comp[0].depth) - 1;
  646. - s->max[1] = (1 << desc->comp[1].depth) - 1;
  647. - s->max[2] = (1 << desc->comp[2].depth) - 1;
  648. - s->max[3] = (1 << desc->comp[3].depth) - 1;
  649. -
  650. - s->is_rgb = ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0;
  651. - s->comps[0] = s->is_rgb ? 'r' : 'y' ;
  652. - s->comps[1] = s->is_rgb ? 'g' : 'u' ;
  653. - s->comps[2] = s->is_rgb ? 'b' : 'v' ;
  654. - s->comps[3] = 'a';
  655. -
  656. - s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
  657. - s->planeheight[0] = s->planeheight[3] = inlink->h;
  658. - s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
  659. - s->planewidth[0] = s->planewidth[3] = inlink->w;
  660. - sum = 0;
  661. - for (j = 0; j < s->nb_components; j++)
  662. - sum += s->planeheight[j] * s->planewidth[j];
  663. - average_max = 0;
  664. - for (j = 0; j < s->nb_components; j++) {
  665. - s->planeweight[j] = (double) s->planeheight[j] * s->planewidth[j] / sum;
  666. - average_max += s->max[j] * s->planeweight[j];
  667. - }
  668. - s->average_max = lrint(average_max);
  669. -
  670. - s->dsp.sse_line = desc->comp[0].depth > 8 ? sse_line_16bit : sse_line_8bit;
  671. - if (ARCH_X86)
  672. - ff_vmaf_init_x86(&s->dsp, desc->comp[0].depth);
  673.  
  674. return 0;
  675. }
  676. @@ -358,23 +245,6 @@ static av_cold void uninit(AVFilterContext *ctx)
  677. {
  678. VMAFContext *s = ctx->priv;
  679.  
  680. - if (s->nb_frames > 0) {
  681. - int j;
  682. - char buf[256];
  683. -
  684. - buf[0] = 0;
  685. - for (j = 0; j < s->nb_components; j++) {
  686. - int c = s->is_rgb ? s->rgba_map[j] : j;
  687. - av_strlcatf(buf, sizeof(buf), " %c:%f", s->comps[j],
  688. - get_vmaf(s->mse_comp[c], s->nb_frames, s->max[c]));
  689. - }
  690. - av_log(ctx, AV_LOG_INFO, "VMAF%s average:%f min:%f max:%f\n",
  691. - buf,
  692. - get_vmaf(s->mse, s->nb_frames, s->average_max),
  693. - get_vmaf(s->max_mse, 1, s->average_max),
  694. - get_vmaf(s->min_mse, 1, s->average_max));
  695. - }
  696. -
  697. ff_dualinput_uninit(&s->dinput);
  698.  
  699. if (s->stats_file && s->stats_file != stdout)
  700. --
  701. 2.7.4
  702.  
  703.  
  704. From 7482bfaa0fecd167c464c621da44c168ee093acb Mon Sep 17 00:00:00 2001
  705. From: Ubuntu <ubuntu@ip-172-31-11-196.us-west-2.compute.internal>
  706. Date: Fri, 2 Jun 2017 13:02:13 +0000
  707. Subject: [PATCH 04/18] Indent properly and minor changes
  708.  
  709. ---
  710. libavfilter/vf_vmaf.c | 145 ++++++++++++++++++++++++++++++++------------------
  711. libavfilter/vmaf.h | 5 +-
  712. 2 files changed, 96 insertions(+), 54 deletions(-)
  713.  
  714. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  715. index a1ef6b7..be8a508 100644
  716. --- a/libavfilter/vf_vmaf.c
  717. +++ b/libavfilter/vf_vmaf.c
  718. @@ -1,7 +1,6 @@
  719. /*
  720. - * Copyright (c) 2011 Roger Pau Monné <roger.pau@entel.upc.edu>
  721. - * Copyright (c) 2011 Stefano Sabatini
  722. - * Copyright (c) 2013 Paul B Mahol
  723. + * Copyright (c) 2017 Ronald S. Bultje <rsbultje@gmail.com>
  724. + * Copyright (c) 2017 Ashish Pratap Singh <ashk43712@gmail.com>
  725. *
  726. * This file is part of FFmpeg.
  727. *
  728. @@ -70,73 +69,113 @@ static const AVOption vmaf_options[] = {
  729.  
  730. AVFILTER_DEFINE_CLASS(vmaf);
  731.  
  732. -static inline unsigned pow_2(unsigned base)
  733. + static inline
  734. +double compute_vmaf(VMAFContext *s,
  735. + const uint8_t *main_data[4], const int main_linesizes[4],
  736. + const uint8_t *ref_data[4], const int ref_linesizes[4],
  737. + int w, int h, double mse[4])
  738. {
  739. - return base*base;
  740. + int i, c;
  741. + return 0;
  742. }
  743.  
  744. -static inline double get_vmaf(double mse, uint64_t nb_frames, int max)
  745. +static void set_meta(AVDictionary **metadata, const char *key, float d)
  746. {
  747. - return 10.0 * log10(pow_2(max) / (mse / nb_frames));
  748. + char value[128];
  749. + snprintf(value, sizeof(value), "%0.7f", d);
  750. + av_dict_set(metadata,key,value,0);
  751. }
  752.  
  753. -static uint64_t sse_line_8bit(const uint8_t *main_line, const uint8_t *ref_line, int outw)
  754. +static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
  755. {
  756. - int j;
  757. - unsigned m2 = 0;
  758.  
  759. - for (j = 0; j < outw; j++)
  760. - m2 += pow_2(main_line[j] - ref_line[j]);
  761. + VMAFContext *s = ctx->priv;
  762.  
  763. - return m2;
  764. -}
  765. + AVDictionary **metadata = avpriv_frame_get_metadatap(main);
  766.  
  767. -static uint64_t sse_line_16bit(const uint8_t *_main_line, const uint8_t *_ref_line, int outw)
  768. -{
  769. - int j;
  770. - uint64_t m2 = 0;
  771. - const uint16_t *main_line = (const uint16_t *) _main_line;
  772. - const uint16_t *ref_line = (const uint16_t *) _ref_line;
  773. + int pipefd[2];
  774. + char buf[1001];
  775. + char str[20];
  776. + int w = main->width;
  777. + int h = main->height;
  778.  
  779. - for (j = 0; j < outw; j++)
  780. - m2 += pow_2(main_line[j] - ref_line[j]);
  781. + char *format = av_get_pix_fmt_name(main->format);
  782.  
  783. - return m2;
  784. -}
  785. + char *fifo1 = "t1.yuv";
  786. + char *fifo2 = "t2.yuv";
  787.  
  788. -static inline
  789. -void compute_images_mse(VMAFContext *s,
  790. - const uint8_t *main_data[4], const int main_linesizes[4],
  791. - const uint8_t *ref_data[4], const int ref_linesizes[4],
  792. - int w, int h, double mse[4])
  793. -{
  794. - int i, c;
  795. -}
  796. + char width[5],height[5];
  797. + sprintf(width, "%d", main->width);
  798. + sprintf(height, "%d", main->height);
  799.  
  800. -static void set_meta(AVDictionary **metadata, const char *key, char comp, float d)
  801. -{
  802. - char value[128];
  803. - snprintf(value, sizeof(value), "%0.2f", d);
  804. - if (comp) {
  805. - char key2[128];
  806. - snprintf(key2, sizeof(key2), "%s%c", key, comp);
  807. - av_dict_set(metadata, key2, value, 0);
  808. +
  809. + if(pipe(pipefd)==-1){
  810. + av_log(ctx, AV_LOG_ERROR, "Pipe creation failed.\n");
  811. + AVERROR(EINVAL);
  812. + }
  813. +
  814. + int pid = fork();
  815. +
  816. + if(pid == -1){
  817. + av_log(ctx, AV_LOG_ERROR, "Process creation failed.\n");
  818. + AVERROR(EINVAL);
  819. + }
  820. + else if ( pid == 0 ) {
  821. + close(pipefd[0]);
  822. + dup2(pipefd[1], 1);
  823. +
  824. + int ret = execlp(s->vmaf_dir,"python",format,width,height,fifo1,fifo2,"--out-fmt","text",(char*)NULL);
  825. + av_log(ctx, AV_LOG_ERROR, "No such file or directory.\n");
  826. + exit(0);
  827. } else {
  828. - av_dict_set(metadata, key, value, 0);
  829. +
  830. + FILE *fd1,*fd2;
  831. +
  832. + fd1 = fopen(fifo1, "wb");
  833. + uint8_t *ptr=main->data[0];
  834. + int y;
  835. + for (y=0; y<h; y) {
  836. + fwrite(ptr,w,1,fd1);
  837. + ptr = main->linesize[0];
  838. + }
  839. + fclose(fd1);
  840. +
  841. + fd2 = fopen(fifo2, "wb");
  842. + ptr=ref->data[0];
  843. + for (y=0; y<h; y) {
  844. + fwrite(ptr,w,1,fd2);
  845. + ptr = ref->linesize[0];
  846. + }
  847. + fclose(fd2);
  848. +
  849. + wait(NULL);
  850. + close(pipefd[1]);
  851. + read(pipefd[0], &buf, sizeof(buf));
  852. +
  853. + close(pipefd[0]);
  854. +
  855. + int len= strlen(buf);
  856. + char *ned = "VMAF_score";
  857. + char *find = strstr(buf,ned);
  858. + int i=0;
  859. + find = 11;
  860. + while(*find!=' '&&*find!='\n'){
  861. + str[i]=*find;
  862. + find;
  863. + }
  864. + str[i]='\0';
  865. +
  866. }
  867. -}
  868. + double d;
  869.  
  870. -static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main,
  871. - const AVFrame *ref)
  872. -{
  873. - VMAFContext *s = ctx->priv;
  874. - double comp_mse[4], mse = 0;
  875. - int j, c;
  876. - AVDictionary **metadata = &main->metadata;
  877. + sscanf(str, "%lf", &d);
  878. +
  879. + set_meta(metadata, "lavfi.vmaf.score.",d);
  880. + av_log(ctx, AV_LOG_INFO, "vmaf score for frame %d is %lf.\n",s->nb_frames,d);
  881. +
  882. + s->vmaf_sum = d;
  883.  
  884. - compute_images_mse(s, (const uint8_t **)main->data, main->linesize,
  885. - (const uint8_t **)ref->data, ref->linesize,
  886. - main->width, main->height, comp_mse);
  887. + s->nb_frames;
  888.  
  889. return main;
  890. }
  891. @@ -151,7 +190,7 @@ static av_cold int init(AVFilterContext *ctx)
  892. if (s->stats_file_str) {
  893. if (s->stats_version < 2 && s->stats_add_max) {
  894. av_log(ctx, AV_LOG_ERROR,
  895. - "stats_add_max was specified but stats_version < 2.\n" );
  896. + "stats_add_max was specified but stats_version < 2.\n" );
  897. return AVERROR(EINVAL);
  898. }
  899. if (!strcmp(s->stats_file_str, "-")) {
  900. diff --git a/libavfilter/vmaf.h b/libavfilter/vmaf.h
  901. index ebfc38a..4d1c722 100644
  902. --- a/libavfilter/vmaf.h
  903. +++ b/libavfilter/vmaf.h
  904. @@ -1,5 +1,6 @@
  905. /*
  906. - * Copyright (c) 2015 Ronald S. Bultje <rsbultje@gmail.com>
  907. + * Copyright (c) 2017 Ronald S. Bultje <rsbultje@gmail.com>
  908. + * Copyright (c) 2017 Ashishh Pratap Singh <ashk43712@gmail.com>
  909. *
  910. * This file is part of FFmpeg.
  911. *
  912. @@ -30,4 +31,6 @@ typedef struct VMAFDSPContext {
  913.  
  914. void ff_vmaf_init_x86(VMAFDSPContext *dsp, int bpp);
  915.  
  916. +double calculate_vmaf();
  917. +
  918. #endif /* AVFILTER_VMAF_H */
  919. --
  920. 2.7.4
  921.  
  922.  
  923. From 897b9db211be0f96a4b08f1da2c1bd3418361af2 Mon Sep 17 00:00:00 2001
  924. From: Ubuntu <ubuntu@ip-172-31-11-196.us-west-2.compute.internal>
  925. Date: Sat, 3 Jun 2017 09:07:05 +0000
  926. Subject: [PATCH 05/18] Added vmaf compute method
  927.  
  928. ---
  929. libavfilter/vf_vmaf.c | 128 +++++++++++++++-----------------------------------
  930. libavfilter/vmaf.h | 2 +-
  931. 2 files changed, 39 insertions(+), 91 deletions(-)
  932.  
  933. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  934. index be8a508..b011561 100644
  935. --- a/libavfilter/vf_vmaf.c
  936. +++ b/libavfilter/vf_vmaf.c
  937. @@ -38,20 +38,19 @@
  938. typedef struct VMAFContext {
  939. const AVClass *class;
  940. FFDualInputContext dinput;
  941. - double mse, min_mse, max_mse, mse_comp[4];
  942. uint64_t nb_frames;
  943. FILE *stats_file;
  944. char *stats_file_str;
  945. int stats_version;
  946. int stats_header_written;
  947. int stats_add_max;
  948. - int max[4], average_max;
  949. int is_rgb;
  950. uint8_t rgba_map[4];
  951. char comps[4];
  952. int nb_components;
  953. int planewidth[4];
  954. int planeheight[4];
  955. + double vmaf_sum;
  956. double planeweight[4];
  957. VMAFDSPContext dsp;
  958. } VMAFContext;
  959. @@ -69,14 +68,9 @@ static const AVOption vmaf_options[] = {
  960.  
  961. AVFILTER_DEFINE_CLASS(vmaf);
  962.  
  963. - static inline
  964. -double compute_vmaf(VMAFContext *s,
  965. - const uint8_t *main_data[4], const int main_linesizes[4],
  966. - const uint8_t *ref_data[4], const int ref_linesizes[4],
  967. - int w, int h, double mse[4])
  968. +static inline double get_vmaf(double vmaf_sum, uint64_t nb_frames)
  969. {
  970. - int i, c;
  971. - return 0;
  972. + return vmaf_sum/nb_frames;
  973. }
  974.  
  975. static void set_meta(AVDictionary **metadata, const char *key, float d)
  976. @@ -86,96 +80,53 @@ static void set_meta(AVDictionary **metadata, const char *key, float d)
  977. av_dict_set(metadata,key,value,0);
  978. }
  979.  
  980. -static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
  981. +double compute_vmaf_score(char *format, int width, int height, const uint8_t *main_data, const uint8_t *ref_data, int main_linesize, int ref_linesize)
  982. {
  983. -
  984. - VMAFContext *s = ctx->priv;
  985. -
  986. - AVDictionary **metadata = avpriv_frame_get_metadatap(main);
  987. -
  988. - int pipefd[2];
  989. - char buf[1001];
  990. - char str[20];
  991. - int w = main->width;
  992. - int h = main->height;
  993. -
  994. - char *format = av_get_pix_fmt_name(main->format);
  995. + int i, c;
  996.  
  997. char *fifo1 = "t1.yuv";
  998. char *fifo2 = "t2.yuv";
  999.  
  1000. - char width[5],height[5];
  1001. - sprintf(width, "%d", main->width);
  1002. - sprintf(height, "%d", main->height);
  1003. + FILE *fd1,*fd2;
  1004.  
  1005. + fd1 = fopen(fifo1, "wb");
  1006. + uint8_t *ptr = main_data;
  1007. + int y;
  1008. + for (y=0; y<height; y++) {
  1009. + fwrite(ptr,width,1,fd1);
  1010. + ptr += main_linesize;
  1011. + }
  1012. + fclose(fd1);
  1013.  
  1014. - if(pipe(pipefd)==-1){
  1015. - av_log(ctx, AV_LOG_ERROR, "Pipe creation failed.\n");
  1016. - AVERROR(EINVAL);
  1017. + fd2 = fopen(fifo2, "wb");
  1018. + ptr = ref_data;
  1019. + for (y=0; y<height; y++) {
  1020. + fwrite(ptr,width,1,fd2);
  1021. + ptr += ref_linesize;
  1022. }
  1023. + fclose(fd2);
  1024.  
  1025. - int pid = fork();
  1026. + return 0;
  1027. +}
  1028.  
  1029. - if(pid == -1){
  1030. - av_log(ctx, AV_LOG_ERROR, "Process creation failed.\n");
  1031. - AVERROR(EINVAL);
  1032. - }
  1033. - else if ( pid == 0 ) {
  1034. - close(pipefd[0]);
  1035. - dup2(pipefd[1], 1);
  1036. -
  1037. - int ret = execlp(s->vmaf_dir,"python",format,width,height,fifo1,fifo2,"--out-fmt","text",(char*)NULL);
  1038. - av_log(ctx, AV_LOG_ERROR, "No such file or directory.\n");
  1039. - exit(0);
  1040. - } else {
  1041. -
  1042. - FILE *fd1,*fd2;
  1043. -
  1044. - fd1 = fopen(fifo1, "wb");
  1045. - uint8_t *ptr=main->data[0];
  1046. - int y;
  1047. - for (y=0; y<h; y) {
  1048. - fwrite(ptr,w,1,fd1);
  1049. - ptr = main->linesize[0];
  1050. - }
  1051. - fclose(fd1);
  1052. +static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
  1053. +{
  1054.  
  1055. - fd2 = fopen(fifo2, "wb");
  1056. - ptr=ref->data[0];
  1057. - for (y=0; y<h; y) {
  1058. - fwrite(ptr,w,1,fd2);
  1059. - ptr = ref->linesize[0];
  1060. - }
  1061. - fclose(fd2);
  1062. -
  1063. - wait(NULL);
  1064. - close(pipefd[1]);
  1065. - read(pipefd[0], &buf, sizeof(buf));
  1066. -
  1067. - close(pipefd[0]);
  1068. -
  1069. - int len= strlen(buf);
  1070. - char *ned = "VMAF_score";
  1071. - char *find = strstr(buf,ned);
  1072. - int i=0;
  1073. - find = 11;
  1074. - while(*find!=' '&&*find!='\n'){
  1075. - str[i]=*find;
  1076. - find;
  1077. - }
  1078. - str[i]='\0';
  1079. + VMAFContext *s = ctx->priv;
  1080.  
  1081. - }
  1082. - double d;
  1083. + AVDictionary **metadata = avpriv_frame_get_metadatap(main);
  1084. +
  1085. + char *format = av_get_pix_fmt_name(main->format);
  1086. +
  1087. + double score = compute_vmaf_score(format,main->width,main->height,main->data[0],ref->data[0],main->linesize[0],ref->linesize[0]);
  1088.  
  1089. - sscanf(str, "%lf", &d);
  1090.  
  1091. - set_meta(metadata, "lavfi.vmaf.score.",d);
  1092. - av_log(ctx, AV_LOG_INFO, "vmaf score for frame %d is %lf.\n",s->nb_frames,d);
  1093. + set_meta(metadata, "lavfi.vmaf.score.",score);
  1094. + av_log(ctx, AV_LOG_INFO, "vmaf score for frame %lu is %lf.\n",s->nb_frames,score);
  1095.  
  1096. - s->vmaf_sum = d;
  1097. + s->vmaf_sum += score;
  1098.  
  1099. - s->nb_frames;
  1100. + s->nb_frames++;
  1101.  
  1102. return main;
  1103. }
  1104. @@ -184,9 +135,6 @@ static av_cold int init(AVFilterContext *ctx)
  1105. {
  1106. VMAFContext *s = ctx->priv;
  1107.  
  1108. - s->min_mse = +INFINITY;
  1109. - s->max_mse = -INFINITY;
  1110. -
  1111. if (s->stats_file_str) {
  1112. if (s->stats_version < 2 && s->stats_add_max) {
  1113. av_log(ctx, AV_LOG_ERROR,
  1114. @@ -231,9 +179,6 @@ static int config_input_ref(AVFilterLink *inlink)
  1115. const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
  1116. AVFilterContext *ctx = inlink->dst;
  1117. VMAFContext *s = ctx->priv;
  1118. - double average_max;
  1119. - unsigned sum;
  1120. - int j;
  1121.  
  1122. s->nb_components = desc->nb_components;
  1123. if (ctx->inputs[0]->w != ctx->inputs[1]->w ||
  1124. @@ -283,7 +228,10 @@ static int request_frame(AVFilterLink *outlink)
  1125. static av_cold void uninit(AVFilterContext *ctx)
  1126. {
  1127. VMAFContext *s = ctx->priv;
  1128. -
  1129. + if (s->nb_frames > 0) {
  1130. + av_log(ctx, AV_LOG_INFO, "VMAF average:%f\n",
  1131. + get_vmaf(s->vmaf_sum, s->nb_frames));
  1132. + }
  1133. ff_dualinput_uninit(&s->dinput);
  1134.  
  1135. if (s->stats_file && s->stats_file != stdout)
  1136. diff --git a/libavfilter/vmaf.h b/libavfilter/vmaf.h
  1137. index 4d1c722..61e381d 100644
  1138. --- a/libavfilter/vmaf.h
  1139. +++ b/libavfilter/vmaf.h
  1140. @@ -31,6 +31,6 @@ typedef struct VMAFDSPContext {
  1141.  
  1142. void ff_vmaf_init_x86(VMAFDSPContext *dsp, int bpp);
  1143.  
  1144. -double calculate_vmaf();
  1145. +double compute_vmaf_score(char *format, int width, int height, const uint8_t *main_data, const uint8_t *ref_data, int main_linesize, int ref_linesize);
  1146.  
  1147. #endif /* AVFILTER_VMAF_H */
  1148. --
  1149. 2.7.4
  1150.  
  1151.  
  1152. From cfdaaf032ee288ba61bebaf0268a2fb2201a5b88 Mon Sep 17 00:00:00 2001
  1153. From: Ubuntu <ubuntu@ip-172-31-11-196.us-west-2.compute.internal>
  1154. Date: Sun, 4 Jun 2017 08:54:14 +0000
  1155. Subject: [PATCH 06/18] Some minor changes
  1156.  
  1157. ---
  1158. libavfilter/vf_vmaf.c | 60 ++++++++++++++++++++++++++++++++++++++++-----------
  1159. libavfilter/vmaf.h | 11 ++++------
  1160. 2 files changed, 51 insertions(+), 20 deletions(-)
  1161.  
  1162. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  1163. index b011561..9fab982 100644
  1164. --- a/libavfilter/vf_vmaf.c
  1165. +++ b/libavfilter/vf_vmaf.c
  1166. @@ -24,6 +24,10 @@
  1167. * Caculate the VMAF between two input videos.
  1168. */
  1169.  
  1170. +#include <unistd.h>
  1171. +#include <stdio.h>
  1172. +#include <errno.h>
  1173. +#include <string.h>
  1174. #include "libavutil/avstring.h"
  1175. #include "libavutil/opt.h"
  1176. #include "libavutil/pixdesc.h"
  1177. @@ -32,13 +36,15 @@
  1178. #include "drawutils.h"
  1179. #include "formats.h"
  1180. #include "internal.h"
  1181. -#include "vmaf.h"
  1182. +#include "libvmaf.h"
  1183. #include "video.h"
  1184. +#include "vmaf.h"
  1185.  
  1186. typedef struct VMAFContext {
  1187. const AVClass *class;
  1188. FFDualInputContext dinput;
  1189. uint64_t nb_frames;
  1190. + char cwd[200],main_path[200],ref_path[200];
  1191. FILE *stats_file;
  1192. char *stats_file_str;
  1193. int stats_version;
  1194. @@ -80,33 +86,38 @@ static void set_meta(AVDictionary **metadata, const char *key, float d)
  1195. av_dict_set(metadata,key,value,0);
  1196. }
  1197.  
  1198. -double compute_vmaf_score(char *format, int width, int height, const uint8_t *main_data, const uint8_t *ref_data, int main_linesize, int ref_linesize)
  1199. +static double compute_vmaf_score(VMAFContext *s, AVFrame *main, const AVFrame *ref)
  1200. {
  1201. int i, c;
  1202.  
  1203. + char *format = av_get_pix_fmt_name(main->format);
  1204. + int w = main->width, h = main->height;
  1205. +
  1206. char *fifo1 = "t1.yuv";
  1207. char *fifo2 = "t2.yuv";
  1208.  
  1209. FILE *fd1,*fd2;
  1210.  
  1211. fd1 = fopen(fifo1, "wb");
  1212. - uint8_t *ptr = main_data;
  1213. + uint8_t *ptr = main->data[0];
  1214. int y;
  1215. - for (y=0; y<height; y++) {
  1216. - fwrite(ptr,width,1,fd1);
  1217. - ptr += main_linesize;
  1218. + for (y=0; y<h; y++) {
  1219. + fwrite(ptr,w,1,fd1);
  1220. + ptr += main->linesize[0];
  1221. }
  1222. fclose(fd1);
  1223.  
  1224. fd2 = fopen(fifo2, "wb");
  1225. - ptr = ref_data;
  1226. - for (y=0; y<height; y++) {
  1227. - fwrite(ptr,width,1,fd2);
  1228. - ptr += ref_linesize;
  1229. + ptr = ref->data[0];
  1230. + for (y=0; y<h; y++) {
  1231. + fwrite(ptr,w,1,fd2);
  1232. + ptr += ref->linesize[0];
  1233. }
  1234. fclose(fd2);
  1235.  
  1236. - return 0;
  1237. + //double vmaf_score = compute_vmaf(format,w,h,s->ref_path,s->main_path);
  1238. + return 0.0;
  1239. +
  1240. }
  1241.  
  1242. static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
  1243. @@ -116,9 +127,8 @@ static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
  1244.  
  1245. AVDictionary **metadata = avpriv_frame_get_metadatap(main);
  1246.  
  1247. - char *format = av_get_pix_fmt_name(main->format);
  1248.  
  1249. - double score = compute_vmaf_score(format,main->width,main->height,main->data[0],ref->data[0],main->linesize[0],ref->linesize[0]);
  1250. + double score = compute_vmaf_score(s,main,ref);
  1251.  
  1252.  
  1253. set_meta(metadata, "lavfi.vmaf.score.",score);
  1254. @@ -192,6 +202,30 @@ static int config_input_ref(AVFilterLink *inlink)
  1255. }
  1256.  
  1257.  
  1258. + getcwd(s->main_path, sizeof(s->main_path));
  1259. + // printf("%s\n",s->cwd);
  1260. + getcwd(s->ref_path, sizeof(s->ref_path));
  1261. + int len = strlen(s->main_path);
  1262. + s->main_path[len++] = 't';
  1263. + s->main_path[len++] = '1';
  1264. + s->main_path[len++] = '.';
  1265. + s->main_path[len++] = 'y';
  1266. + s->main_path[len++] = 'u';
  1267. + s->main_path[len++] = 'v';
  1268. + s->main_path[len] = '\0';
  1269. +
  1270. + len = strlen(s->ref_path);
  1271. +
  1272. + s->ref_path[len++] = 't';
  1273. + s->ref_path[len++] = '2';
  1274. + s->ref_path[len++] = '.';
  1275. + s->ref_path[len++] = 'y';
  1276. + s->ref_path[len++] = 'u';
  1277. + s->ref_path[len++] = 'v';
  1278. + s->ref_path[len] = '\0';
  1279. +
  1280. + av_log(ctx, AV_LOG_INFO, "directory is %s.\n",s->cwd);
  1281. +
  1282. return 0;
  1283. }
  1284.  
  1285. diff --git a/libavfilter/vmaf.h b/libavfilter/vmaf.h
  1286. index 61e381d..2e7cd8a 100644
  1287. --- a/libavfilter/vmaf.h
  1288. +++ b/libavfilter/vmaf.h
  1289. @@ -1,6 +1,5 @@
  1290. /*
  1291. - * Copyright (c) 2017 Ronald S. Bultje <rsbultje@gmail.com>
  1292. - * Copyright (c) 2017 Ashishh Pratap Singh <ashk43712@gmail.com>
  1293. + * Copyright (c) 2015 Ronald S. Bultje <rsbultje@gmail.com>
  1294. *
  1295. * This file is part of FFmpeg.
  1296. *
  1297. @@ -19,8 +18,8 @@
  1298. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  1299. */
  1300.  
  1301. -#ifndef AVFILTER_VMAF_H
  1302. -#define AVFILTER_VMAF_H
  1303. +#ifndef AVFILTER_PSNR_H
  1304. +#define AVFILTER_PSNR_H
  1305.  
  1306. #include <stddef.h>
  1307. #include <stdint.h>
  1308. @@ -29,8 +28,6 @@ typedef struct VMAFDSPContext {
  1309. uint64_t (*sse_line)(const uint8_t *buf, const uint8_t *ref, int w);
  1310. } VMAFDSPContext;
  1311.  
  1312. -void ff_vmaf_init_x86(VMAFDSPContext *dsp, int bpp);
  1313. -
  1314. -double compute_vmaf_score(char *format, int width, int height, const uint8_t *main_data, const uint8_t *ref_data, int main_linesize, int ref_linesize);
  1315. +void ff_psnr_init_x86(VMAFDSPContext *dsp, int bpp);
  1316.  
  1317. #endif /* AVFILTER_VMAF_H */
  1318. --
  1319. 2.7.4
  1320.  
  1321.  
  1322. From baf61f238d02dd3d85ab1e77b74a858c560c9396 Mon Sep 17 00:00:00 2001
  1323. From: ashk43712 <ashk43712@gmail.com>
  1324. Date: Sun, 4 Jun 2017 17:17:37 +0530
  1325. Subject: [PATCH 07/18] Made changes to configure
  1326.  
  1327. ---
  1328. configure | 4 ++++
  1329. 1 file changed, 4 insertions(+)
  1330.  
  1331. diff --git a/configure b/configure
  1332. index 5ae5227..4ea4db8 100755
  1333. --- a/configure
  1334. +++ b/configure
  1335. @@ -259,6 +259,7 @@ External library support:
  1336. --enable-libtwolame enable MP2 encoding via libtwolame [no]
  1337. --enable-libv4l2 enable libv4l2/v4l-utils [no]
  1338. --enable-libvidstab enable video stabilization using vid.stab [no]
  1339. + --enable-libvmaf enable vmaf filter via libvmaf [no]
  1340. --enable-libvo-amrwbenc enable AMR-WB encoding via libvo-amrwbenc [no]
  1341. --enable-libvorbis enable Vorbis en/decoding via libvorbis,
  1342. native implementation exists [no]
  1343. @@ -1569,6 +1570,7 @@ EXTERNAL_LIBRARY_LIST="
  1344. libtheora
  1345. libtwolame
  1346. libv4l2
  1347. + libvmaf
  1348. libvorbis
  1349. libvpx
  1350. libwavpack
  1351. @@ -2878,6 +2880,7 @@ libspeex_encoder_deps="libspeex"
  1352. libspeex_encoder_select="audio_frame_queue"
  1353. libtheora_encoder_deps="libtheora"
  1354. libtwolame_encoder_deps="libtwolame"
  1355. +libvmaf_filter_deps="libvmaf"
  1356. libvo_amrwbenc_encoder_deps="libvo_amrwbenc"
  1357. libvorbis_decoder_deps="libvorbis"
  1358. libvorbis_encoder_deps="libvorbis"
  1359. @@ -5845,6 +5848,7 @@ enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame
  1360. die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; }
  1361. enabled libv4l2 && require_pkg_config libv4l2 libv4l2.h v4l2_ioctl
  1362. enabled libvidstab && require_pkg_config "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit
  1363. +enabled libvmaf && require libvmaf libvmaf.h
  1364. enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
  1365. enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
  1366.  
  1367. --
  1368. 2.7.4
  1369.  
  1370.  
  1371. From 8effb6d454c2ed45e3e625a461bcbcc70b843e9b Mon Sep 17 00:00:00 2001
  1372. From: ashk43712 <ashk43712@gmail.com>
  1373. Date: Sun, 4 Jun 2017 19:35:27 +0530
  1374. Subject: [PATCH 08/18] libvmaf detected successfully
  1375.  
  1376. ---
  1377. configure | 3 ++-
  1378. 1 file changed, 2 insertions(+), 1 deletion(-)
  1379.  
  1380. diff --git a/configure b/configure
  1381. index 4ea4db8..5c995c7 100755
  1382. --- a/configure
  1383. +++ b/configure
  1384. @@ -5848,7 +5848,8 @@ enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame
  1385. die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; }
  1386. enabled libv4l2 && require_pkg_config libv4l2 libv4l2.h v4l2_ioctl
  1387. enabled libvidstab && require_pkg_config "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit
  1388. -enabled libvmaf && require libvmaf libvmaf.h
  1389. +enabled libvmaf { check_lib libvmaf libvmaf.h ||
  1390. + die "ERROR: libvmaf must be installed"; }
  1391. enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
  1392. enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
  1393.  
  1394. --
  1395. 2.7.4
  1396.  
  1397.  
  1398. From c536ec913efe0e1ff731fcb8455c9b307255d7d0 Mon Sep 17 00:00:00 2001
  1399. From: Ubuntu <ubuntu@ip-172-31-11-196.us-west-2.compute.internal>
  1400. Date: Sun, 4 Jun 2017 15:19:52 +0000
  1401. Subject: [PATCH 09/18] Uncommented the compute_vmaf function
  1402.  
  1403. ---
  1404. configure | 2 +-
  1405. libavfilter/vf_vmaf.c | 4 ++--
  1406. 2 files changed, 3 insertions(+), 3 deletions(-)
  1407.  
  1408. diff --git a/configure b/configure
  1409. index 5c995c7..23f7321 100755
  1410. --- a/configure
  1411. +++ b/configure
  1412. @@ -5848,7 +5848,7 @@ enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame
  1413. die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; }
  1414. enabled libv4l2 && require_pkg_config libv4l2 libv4l2.h v4l2_ioctl
  1415. enabled libvidstab && require_pkg_config "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit
  1416. -enabled libvmaf { check_lib libvmaf libvmaf.h ||
  1417. +enabled libvmaf { check_lib libvmaf "libvmaf.h" "compute_vmaf" ||
  1418. die "ERROR: libvmaf must be installed"; }
  1419. enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
  1420. enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
  1421. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  1422. index 9fab982..f45d052 100644
  1423. --- a/libavfilter/vf_vmaf.c
  1424. +++ b/libavfilter/vf_vmaf.c
  1425. @@ -115,8 +115,8 @@ static double compute_vmaf_score(VMAFContext *s, AVFrame *main, const AVFrame *r
  1426. }
  1427. fclose(fd2);
  1428.  
  1429. - //double vmaf_score = compute_vmaf(format,w,h,s->ref_path,s->main_path);
  1430. - return 0.0;
  1431. + double vmaf_score = compute_vmaf(format,w,h,s->ref_path,s->main_path);
  1432. + return vmaf_score;
  1433.  
  1434. }
  1435.  
  1436. --
  1437. 2.7.4
  1438.  
  1439.  
  1440. From 26ea8fffef7a485dba4ae5f4ce6705b541ecd7b8 Mon Sep 17 00:00:00 2001
  1441. From: ashk43712 <ashk43712@gmail.com>
  1442. Date: Mon, 5 Jun 2017 02:13:03 +0530
  1443. Subject: [PATCH 10/18] modified configure and vmaf.c
  1444.  
  1445. ---
  1446. configure | 5 +++--
  1447. libavfilter/vf_vmaf.c | 5 ++---
  1448. 2 files changed, 5 insertions(+), 5 deletions(-)
  1449.  
  1450. diff --git a/configure b/configure
  1451. index 23f7321..de04274 100755
  1452. --- a/configure
  1453. +++ b/configure
  1454. @@ -5848,8 +5848,9 @@ enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame
  1455. die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; }
  1456. enabled libv4l2 && require_pkg_config libv4l2 libv4l2.h v4l2_ioctl
  1457. enabled libvidstab && require_pkg_config "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit
  1458. -enabled libvmaf { check_lib libvmaf "libvmaf.h" "compute_vmaf" ||
  1459. - die "ERROR: libvmaf must be installed"; }
  1460. +enabled libvmaf && { use_pkg_config libvmaf "libvmaf.h" compute_vmaf ||
  1461. + { check_lib libvmaf "libvmaf.h" "compute_vmaf" -lvmaf &&
  1462. + warn "using libvmaf without pkg-config"; } }
  1463. enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
  1464. enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
  1465.  
  1466. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  1467. index f45d052..a2dda5d 100644
  1468. --- a/libavfilter/vf_vmaf.c
  1469. +++ b/libavfilter/vf_vmaf.c
  1470. @@ -23,7 +23,7 @@
  1471. * @file
  1472. * Caculate the VMAF between two input videos.
  1473. */
  1474. -
  1475. +#include "libvmaf.h"
  1476. #include <unistd.h>
  1477. #include <stdio.h>
  1478. #include <errno.h>
  1479. @@ -36,7 +36,6 @@
  1480. #include "drawutils.h"
  1481. #include "formats.h"
  1482. #include "internal.h"
  1483. -#include "libvmaf.h"
  1484. #include "video.h"
  1485. #include "vmaf.h"
  1486.  
  1487. @@ -114,7 +113,7 @@ static double compute_vmaf_score(VMAFContext *s, AVFrame *main, const AVFrame *r
  1488. ptr += ref->linesize[0];
  1489. }
  1490. fclose(fd2);
  1491. -
  1492. +
  1493. double vmaf_score = compute_vmaf(format,w,h,s->ref_path,s->main_path);
  1494. return vmaf_score;
  1495.  
  1496. --
  1497. 2.7.4
  1498.  
  1499.  
  1500. From 284c6e70bdc194b75a91b347f1336a280cf10073 Mon Sep 17 00:00:00 2001
  1501. From: ashk43712 <ashk43712@gmail.com>
  1502. Date: Tue, 6 Jun 2017 02:53:15 +0530
  1503. Subject: [PATCH 11/18] library integration and detection working
  1504.  
  1505. ---
  1506. configure | 2 +-
  1507. libavfilter/vf_vmaf.c | 4 +++-
  1508. 2 files changed, 4 insertions(+), 2 deletions(-)
  1509.  
  1510. diff --git a/configure b/configure
  1511. index de04274..8487f06 100755
  1512. --- a/configure
  1513. +++ b/configure
  1514. @@ -5849,7 +5849,7 @@ enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame
  1515. enabled libv4l2 && require_pkg_config libv4l2 libv4l2.h v4l2_ioctl
  1516. enabled libvidstab && require_pkg_config "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit
  1517. enabled libvmaf && { use_pkg_config libvmaf "libvmaf.h" compute_vmaf ||
  1518. - { check_lib libvmaf "libvmaf.h" "compute_vmaf" -lvmaf &&
  1519. + { check_lib libvmaf "libvmaf.h" "compute_vmaf" -lvmaf -lstdc++ -lpthread -lm &&
  1520. warn "using libvmaf without pkg-config"; } }
  1521. enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
  1522. enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
  1523. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  1524. index a2dda5d..fc1a1c0 100644
  1525. --- a/libavfilter/vf_vmaf.c
  1526. +++ b/libavfilter/vf_vmaf.c
  1527. @@ -113,8 +113,10 @@ static double compute_vmaf_score(VMAFContext *s, AVFrame *main, const AVFrame *r
  1528. ptr += ref->linesize[0];
  1529. }
  1530. fclose(fd2);
  1531. +
  1532. + char *model_path = "model/vmaf_v0.6.1.pkl";
  1533.  
  1534. - double vmaf_score = compute_vmaf(format,w,h,s->ref_path,s->main_path);
  1535. + double vmaf_score = compute_vmaf(format,w,h,s->ref_path,s->main_path,model_path);
  1536. return vmaf_score;
  1537.  
  1538. }
  1539. --
  1540. 2.7.4
  1541.  
  1542.  
  1543. From 31a413aa365d80dd0839bfd3b0a71a82058ee56c Mon Sep 17 00:00:00 2001
  1544. From: Ubuntu <ubuntu@ip-172-31-11-196.us-west-2.compute.internal>
  1545. Date: Tue, 6 Jun 2017 18:45:36 +0000
  1546. Subject: [PATCH 12/18] Added correct path for models
  1547.  
  1548. ---
  1549. libavfilter/vf_vmaf.c | 8 ++++++--
  1550. 1 file changed, 6 insertions(+), 2 deletions(-)
  1551.  
  1552. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  1553. index fc1a1c0..84ce64d 100644
  1554. --- a/libavfilter/vf_vmaf.c
  1555. +++ b/libavfilter/vf_vmaf.c
  1556. @@ -114,8 +114,8 @@ static double compute_vmaf_score(VMAFContext *s, AVFrame *main, const AVFrame *r
  1557. }
  1558. fclose(fd2);
  1559.  
  1560. - char *model_path = "model/vmaf_v0.6.1.pkl";
  1561. -
  1562. + char *model_path = "/usr/local/share/model/vmaf_v0.6.1.pkl";
  1563. +
  1564. double vmaf_score = compute_vmaf(format,w,h,s->ref_path,s->main_path,model_path);
  1565. return vmaf_score;
  1566.  
  1567. @@ -207,6 +207,7 @@ static int config_input_ref(AVFilterLink *inlink)
  1568. // printf("%s\n",s->cwd);
  1569. getcwd(s->ref_path, sizeof(s->ref_path));
  1570. int len = strlen(s->main_path);
  1571. + s->main_path[len++] = '/';
  1572. s->main_path[len++] = 't';
  1573. s->main_path[len++] = '1';
  1574. s->main_path[len++] = '.';
  1575. @@ -217,6 +218,7 @@ static int config_input_ref(AVFilterLink *inlink)
  1576.  
  1577. len = strlen(s->ref_path);
  1578.  
  1579. + s->ref_path[len++] = '/';
  1580. s->ref_path[len++] = 't';
  1581. s->ref_path[len++] = '2';
  1582. s->ref_path[len++] = '.';
  1583. @@ -267,6 +269,8 @@ static av_cold void uninit(AVFilterContext *ctx)
  1584. av_log(ctx, AV_LOG_INFO, "VMAF average:%f\n",
  1585. get_vmaf(s->vmaf_sum, s->nb_frames));
  1586. }
  1587. + remove("t1.yuv");
  1588. + remove("t2.yuv");
  1589. ff_dualinput_uninit(&s->dinput);
  1590.  
  1591. if (s->stats_file && s->stats_file != stdout)
  1592. --
  1593. 2.7.4
  1594.  
  1595.  
  1596. From c6c853833e0bfe182bda1c156aedb1f859045035 Mon Sep 17 00:00:00 2001
  1597. From: Ubuntu <ubuntu@ip-172-31-11-196.us-west-2.compute.internal>
  1598. Date: Wed, 7 Jun 2017 16:36:38 +0000
  1599. Subject: [PATCH 13/18] remove file lines
  1600.  
  1601. ---
  1602. libavfilter/vf_vmaf.c | 54 +--------------------------------------------------
  1603. 1 file changed, 1 insertion(+), 53 deletions(-)
  1604.  
  1605. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  1606. index 84ce64d..4b986c7 100644
  1607. --- a/libavfilter/vf_vmaf.c
  1608. +++ b/libavfilter/vf_vmaf.c
  1609. @@ -43,7 +43,6 @@ typedef struct VMAFContext {
  1610. const AVClass *class;
  1611. FFDualInputContext dinput;
  1612. uint64_t nb_frames;
  1613. - char cwd[200],main_path[200],ref_path[200];
  1614. FILE *stats_file;
  1615. char *stats_file_str;
  1616. int stats_version;
  1617. @@ -92,31 +91,9 @@ static double compute_vmaf_score(VMAFContext *s, AVFrame *main, const AVFrame *r
  1618. char *format = av_get_pix_fmt_name(main->format);
  1619. int w = main->width, h = main->height;
  1620.  
  1621. - char *fifo1 = "t1.yuv";
  1622. - char *fifo2 = "t2.yuv";
  1623. -
  1624. - FILE *fd1,*fd2;
  1625. -
  1626. - fd1 = fopen(fifo1, "wb");
  1627. - uint8_t *ptr = main->data[0];
  1628. - int y;
  1629. - for (y=0; y<h; y++) {
  1630. - fwrite(ptr,w,1,fd1);
  1631. - ptr += main->linesize[0];
  1632. - }
  1633. - fclose(fd1);
  1634. -
  1635. - fd2 = fopen(fifo2, "wb");
  1636. - ptr = ref->data[0];
  1637. - for (y=0; y<h; y++) {
  1638. - fwrite(ptr,w,1,fd2);
  1639. - ptr += ref->linesize[0];
  1640. - }
  1641. - fclose(fd2);
  1642. -
  1643. char *model_path = "/usr/local/share/model/vmaf_v0.6.1.pkl";
  1644.  
  1645. - double vmaf_score = compute_vmaf(format,w,h,s->ref_path,s->main_path,model_path);
  1646. + double vmaf_score = compute_vmaf(format,w,h,ref->data[0],main->data[0],model_path);
  1647. return vmaf_score;
  1648.  
  1649. }
  1650. @@ -202,33 +179,6 @@ static int config_input_ref(AVFilterLink *inlink)
  1651. return AVERROR(EINVAL);
  1652. }
  1653.  
  1654. -
  1655. - getcwd(s->main_path, sizeof(s->main_path));
  1656. - // printf("%s\n",s->cwd);
  1657. - getcwd(s->ref_path, sizeof(s->ref_path));
  1658. - int len = strlen(s->main_path);
  1659. - s->main_path[len++] = '/';
  1660. - s->main_path[len++] = 't';
  1661. - s->main_path[len++] = '1';
  1662. - s->main_path[len++] = '.';
  1663. - s->main_path[len++] = 'y';
  1664. - s->main_path[len++] = 'u';
  1665. - s->main_path[len++] = 'v';
  1666. - s->main_path[len] = '\0';
  1667. -
  1668. - len = strlen(s->ref_path);
  1669. -
  1670. - s->ref_path[len++] = '/';
  1671. - s->ref_path[len++] = 't';
  1672. - s->ref_path[len++] = '2';
  1673. - s->ref_path[len++] = '.';
  1674. - s->ref_path[len++] = 'y';
  1675. - s->ref_path[len++] = 'u';
  1676. - s->ref_path[len++] = 'v';
  1677. - s->ref_path[len] = '\0';
  1678. -
  1679. - av_log(ctx, AV_LOG_INFO, "directory is %s.\n",s->cwd);
  1680. -
  1681. return 0;
  1682. }
  1683.  
  1684. @@ -269,8 +219,6 @@ static av_cold void uninit(AVFilterContext *ctx)
  1685. av_log(ctx, AV_LOG_INFO, "VMAF average:%f\n",
  1686. get_vmaf(s->vmaf_sum, s->nb_frames));
  1687. }
  1688. - remove("t1.yuv");
  1689. - remove("t2.yuv");
  1690. ff_dualinput_uninit(&s->dinput);
  1691.  
  1692. if (s->stats_file && s->stats_file != stdout)
  1693. --
  1694. 2.7.4
  1695.  
  1696.  
  1697. From 63232da6c6871489592d517f6a3b4ebeffe31d8c Mon Sep 17 00:00:00 2001
  1698. From: ashk43712 <ashk43712@gmail.com>
  1699. Date: Sat, 10 Jun 2017 20:27:51 +0530
  1700. Subject: [PATCH 14/18] Added linked list of frames
  1701.  
  1702. ---
  1703. libavfilter/vf_vmaf.c | 84 +++++++++++++++++++++++++++++++++++++++++++++------
  1704. 1 file changed, 74 insertions(+), 10 deletions(-)
  1705.  
  1706. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  1707. index 4b986c7..26a310f 100644
  1708. --- a/libavfilter/vf_vmaf.c
  1709. +++ b/libavfilter/vf_vmaf.c
  1710. @@ -59,6 +59,18 @@ typedef struct VMAFContext {
  1711. VMAFDSPContext dsp;
  1712. } VMAFContext;
  1713.  
  1714. +struct VMAFFrame{
  1715. + uint8_t *ref_data, *main_data;
  1716. + int ref_stride, main_stride;
  1717. + struct VMAFFrame* next_frame;
  1718. +} VFrame;
  1719. +
  1720. +struct VMAFFrame* head = NULL;
  1721. +struct VMAFFrame* curr = NULL;
  1722. +
  1723. +char *format;
  1724. +int width, height;
  1725. +
  1726. #define OFFSET(x) offsetof(VMAFContext, x)
  1727. #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
  1728.  
  1729. @@ -84,16 +96,36 @@ static void set_meta(AVDictionary **metadata, const char *key, float d)
  1730. av_dict_set(metadata,key,value,0);
  1731. }
  1732.  
  1733. -static double compute_vmaf_score(VMAFContext *s, AVFrame *main, const AVFrame *ref)
  1734. -{
  1735. - int i, c;
  1736. +static int read_frame(uint8_t *ref_buf, int *ref_stride, uint8_t *main_buf, int *main_stride){
  1737. + if(curr == NULL){
  1738. + printf("All frame read\n");
  1739. + return -1;
  1740. + }
  1741. + printf("read frame started\n");
  1742. + ref_buf = curr->ref_data;
  1743. + ref_buf = curr->main_data;
  1744. + *ref_stride = curr->ref_stride;
  1745. + *main_stride = curr->main_stride;
  1746. + printf("%d\n",*ref_stride);
  1747. +
  1748. +
  1749. + curr == curr->next_frame;
  1750. + printf("read frame finished luckily\n");
  1751. + return 0;
  1752. +}
  1753. +
  1754.  
  1755. - char *format = av_get_pix_fmt_name(main->format);
  1756. - int w = main->width, h = main->height;
  1757. +static double compute_vmaf_score()
  1758. +{
  1759. + printf("inside compute vmaf1\n");
  1760. +
  1761. + printf("width=%d,height=%d,format=%s\n",width,height,format);
  1762.  
  1763. char *model_path = "/usr/local/share/model/vmaf_v0.6.1.pkl";
  1764.  
  1765. - double vmaf_score = compute_vmaf(format,w,h,ref->data[0],main->data[0],model_path);
  1766. + double vmaf_score;
  1767. + vmaf_score = compute_vmaf(format,width,height,read_frame,model_path);
  1768. + printf("compute vmaf competed\n");
  1769. return vmaf_score;
  1770.  
  1771. }
  1772. @@ -106,11 +138,32 @@ static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
  1773. AVDictionary **metadata = avpriv_frame_get_metadatap(main);
  1774.  
  1775.  
  1776. - double score = compute_vmaf_score(s,main,ref);
  1777. + //double score = compute_vmaf_score(s,main,ref);
  1778.  
  1779. -
  1780. - set_meta(metadata, "lavfi.vmaf.score.",score);
  1781. + double score = 0;
  1782. + //set_meta(metadata, "lavfi.vmaf.score.",score);
  1783. av_log(ctx, AV_LOG_INFO, "vmaf score for frame %lu is %lf.\n",s->nb_frames,score);
  1784. + static int p = 0;
  1785. +
  1786. + if(p == 0){
  1787. + head = (struct VMAFFrame*)malloc(sizeof(struct VMAFFrame));
  1788. + head->ref_data = ref->data[0];
  1789. + head->main_data = main->data[0];
  1790. + head->ref_stride = ref->linesize[0];
  1791. + head->main_data = main->linesize[0];
  1792. + curr = head;
  1793. + }
  1794. + else{
  1795. + struct VMAFFrame* new_node = (struct VMAFFrame*)malloc(sizeof(struct VMAFFrame));
  1796. + new_node->ref_data = ref->data[0];
  1797. + new_node->main_data = main->data[0];
  1798. + new_node->ref_stride = ref->linesize[0];
  1799. + new_node->main_data = main->linesize[0];
  1800. + curr->next_frame = new_node;
  1801. + curr = new_node;
  1802. + }
  1803. + p++;
  1804. +
  1805.  
  1806. s->vmaf_sum += score;
  1807.  
  1808. @@ -167,7 +220,6 @@ static int config_input_ref(AVFilterLink *inlink)
  1809. const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
  1810. AVFilterContext *ctx = inlink->dst;
  1811. VMAFContext *s = ctx->priv;
  1812. -
  1813. s->nb_components = desc->nb_components;
  1814. if (ctx->inputs[0]->w != ctx->inputs[1]->w ||
  1815. ctx->inputs[0]->h != ctx->inputs[1]->h) {
  1816. @@ -179,6 +231,10 @@ static int config_input_ref(AVFilterLink *inlink)
  1817. return AVERROR(EINVAL);
  1818. }
  1819.  
  1820. + format = av_get_pix_fmt_name(ctx->inputs[0]->format);
  1821. + width = ctx->inputs[0]->w;
  1822. + height = ctx->inputs[0]->h;
  1823. +
  1824. return 0;
  1825. }
  1826.  
  1827. @@ -212,9 +268,11 @@ static int request_frame(AVFilterLink *outlink)
  1828. return ff_dualinput_request_frame(&s->dinput, outlink);
  1829. }
  1830.  
  1831. +
  1832. static av_cold void uninit(AVFilterContext *ctx)
  1833. {
  1834. VMAFContext *s = ctx->priv;
  1835. +
  1836. if (s->nb_frames > 0) {
  1837. av_log(ctx, AV_LOG_INFO, "VMAF average:%f\n",
  1838. get_vmaf(s->vmaf_sum, s->nb_frames));
  1839. @@ -223,6 +281,12 @@ static av_cold void uninit(AVFilterContext *ctx)
  1840.  
  1841. if (s->stats_file && s->stats_file != stdout)
  1842. fclose(s->stats_file);
  1843. +
  1844. + double vmaf_score = compute_vmaf_score();
  1845. + printf("compute vmaf competed\n");
  1846. + printf("%d\n",vmaf_score);
  1847. +
  1848. + return 0;
  1849. }
  1850.  
  1851. static const AVFilterPad vmaf_inputs[] = {
  1852. --
  1853. 2.7.4
  1854.  
  1855.  
  1856. From 67cbf5e52d0c31552500c03daac03a6b5950aa24 Mon Sep 17 00:00:00 2001
  1857. From: ashk43712 <ashk43712@gmail.com>
  1858. Date: Wed, 14 Jun 2017 22:37:03 +0530
  1859. Subject: [PATCH 15/18] Added multi-threading, mutex and cond to filter
  1860.  
  1861. ---
  1862. libavfilter/vf_vmaf.c | 166 +++++++++++++++++++++++++++++---------------------
  1863. 1 file changed, 96 insertions(+), 70 deletions(-)
  1864.  
  1865. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  1866. index 26a310f..50390b5 100644
  1867. --- a/libavfilter/vf_vmaf.c
  1868. +++ b/libavfilter/vf_vmaf.c
  1869. @@ -23,11 +23,13 @@
  1870. * @file
  1871. * Caculate the VMAF between two input videos.
  1872. */
  1873. -#include "libvmaf.h"
  1874. +
  1875. #include <unistd.h>
  1876. #include <stdio.h>
  1877. #include <errno.h>
  1878. #include <string.h>
  1879. +#include <inttypes.h>
  1880. +#include <pthread.h>
  1881. #include "libavutil/avstring.h"
  1882. #include "libavutil/opt.h"
  1883. #include "libavutil/pixdesc.h"
  1884. @@ -38,6 +40,7 @@
  1885. #include "internal.h"
  1886. #include "video.h"
  1887. #include "vmaf.h"
  1888. +#include "libvmaf.h"
  1889.  
  1890. typedef struct VMAFContext {
  1891. const AVClass *class;
  1892. @@ -49,6 +52,10 @@ typedef struct VMAFContext {
  1893. int stats_header_written;
  1894. int stats_add_max;
  1895. int is_rgb;
  1896. + pthread_t thread;
  1897. + pthread_t main_thread_id;
  1898. + pthread_t vmaf_thread_id;
  1899. + pthread_attr_t attr;
  1900. uint8_t rgba_map[4];
  1901. char comps[4];
  1902. int nb_components;
  1903. @@ -59,17 +66,15 @@ typedef struct VMAFContext {
  1904. VMAFDSPContext dsp;
  1905. } VMAFContext;
  1906.  
  1907. -struct VMAFFrame{
  1908. - uint8_t *ref_data, *main_data;
  1909. - int ref_stride, main_stride;
  1910. - struct VMAFFrame* next_frame;
  1911. -} VFrame;
  1912. -
  1913. -struct VMAFFrame* head = NULL;
  1914. -struct VMAFFrame* curr = NULL;
  1915.  
  1916. -char *format;
  1917. -int width, height;
  1918. +static char *format;
  1919. +static int width, height;
  1920. +pthread_mutex_t lock;
  1921. +pthread_cond_t cond;
  1922. +int get_next = 0;
  1923. +int data_yes = 0;
  1924. +AVFrame *gmain;
  1925. +AVFrame *gref;
  1926.  
  1927. #define OFFSET(x) offsetof(VMAFContext, x)
  1928. #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
  1929. @@ -96,86 +101,94 @@ static void set_meta(AVDictionary **metadata, const char *key, float d)
  1930. av_dict_set(metadata,key,value,0);
  1931. }
  1932.  
  1933. -static int read_frame(uint8_t *ref_buf, int *ref_stride, uint8_t *main_buf, int *main_stride){
  1934. - if(curr == NULL){
  1935. - printf("All frame read\n");
  1936. - return -1;
  1937. +static void read_frame(uint8_t *ref_buf, int *ref_stride, uint8_t *main_buf, int *main_stride){
  1938. + pthread_mutex_lock(&lock);
  1939. + while(gref == NULL){
  1940. + pthread_cond_wait(&cond, &lock);
  1941. }
  1942. - printf("read frame started\n");
  1943. - ref_buf = curr->ref_data;
  1944. - ref_buf = curr->main_data;
  1945. - *ref_stride = curr->ref_stride;
  1946. - *main_stride = curr->main_stride;
  1947. - printf("%d\n",*ref_stride);
  1948. -
  1949. -
  1950. - curr == curr->next_frame;
  1951. - printf("read frame finished luckily\n");
  1952. - return 0;
  1953. -}
  1954. +
  1955. + *ref_stride = gref->linesize[0];
  1956. + *main_stride = gmain->linesize[0];
  1957.  
  1958. + ref_buf = malloc(sizeof(uint8_t));
  1959. + main_buf = malloc(sizeof(uint8_t));
  1960.  
  1961. -static double compute_vmaf_score()
  1962. -{
  1963. - printf("inside compute vmaf1\n");
  1964. -
  1965. - printf("width=%d,height=%d,format=%s\n",width,height,format);
  1966. -
  1967. - char *model_path = "/usr/local/share/model/vmaf_v0.6.1.pkl";
  1968. -
  1969. - double vmaf_score;
  1970. - vmaf_score = compute_vmaf(format,width,height,read_frame,model_path);
  1971. - printf("compute vmaf competed\n");
  1972. - return vmaf_score;
  1973. + memcpy(ref_buf, gref->data[0], sizeof(uint8_t));
  1974. + memcpy(main_buf, gmain->data[0], sizeof(uint8_t));
  1975. +
  1976. + gref = NULL;
  1977. + gmain = NULL;
  1978.  
  1979. + pthread_cond_signal(&cond);
  1980. + pthread_mutex_unlock(&lock);
  1981. }
  1982.  
  1983. static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
  1984. {
  1985. -
  1986. VMAFContext *s = ctx->priv;
  1987.  
  1988. AVDictionary **metadata = avpriv_frame_get_metadatap(main);
  1989.  
  1990. + pthread_mutex_lock(&lock);
  1991. + while(gref != NULL){
  1992. + pthread_cond_wait(&cond, &lock);
  1993. + }
  1994. +
  1995. + gref = malloc(sizeof(AVFrame));
  1996. + gmain = malloc(sizeof(AVFrame));
  1997.  
  1998. - //double score = compute_vmaf_score(s,main,ref);
  1999. + memcpy(gref, ref, sizeof(AVFrame));
  2000. + memcpy(gmain, main, sizeof(AVFrame));
  2001.  
  2002. + pthread_cond_signal(&cond);
  2003. + pthread_mutex_unlock(&lock);
  2004. +
  2005. +/*
  2006. double score = 0;
  2007. //set_meta(metadata, "lavfi.vmaf.score.",score);
  2008. - av_log(ctx, AV_LOG_INFO, "vmaf score for frame %lu is %lf.\n",s->nb_frames,score);
  2009. + //av_log(ctx, AV_LOG_INFO, "vmaf score for frame %lu is %lf.\n",s->nb_frames,score);
  2010. + //printf("v");
  2011. static int p = 0;
  2012. -
  2013. - if(p == 0){
  2014. - head = (struct VMAFFrame*)malloc(sizeof(struct VMAFFrame));
  2015. - head->ref_data = ref->data[0];
  2016. - head->main_data = main->data[0];
  2017. - head->ref_stride = ref->linesize[0];
  2018. - head->main_data = main->linesize[0];
  2019. - curr = head;
  2020. - }
  2021. - else{
  2022. - struct VMAFFrame* new_node = (struct VMAFFrame*)malloc(sizeof(struct VMAFFrame));
  2023. - new_node->ref_data = ref->data[0];
  2024. - new_node->main_data = main->data[0];
  2025. - new_node->ref_stride = ref->linesize[0];
  2026. - new_node->main_data = main->linesize[0];
  2027. - curr->next_frame = new_node;
  2028. - curr = new_node;
  2029. - }
  2030. - p++;
  2031. -
  2032. -
  2033. + p = 1;
  2034. s->vmaf_sum += score;
  2035.  
  2036. s->nb_frames++;
  2037. -
  2038. +*/
  2039. return main;
  2040. }
  2041.  
  2042. +static void compute_vmaf_score()
  2043. +{
  2044. + printf("inside compute vmaf6\n");
  2045. +
  2046. + printf("width=%d,height=%d,format=%s\n",width,height,format);
  2047. +
  2048. + char *model_path = "/usr/local/share/model/vmaf_v0.6.1.pkl";
  2049. +
  2050. + double vmaf_score;
  2051. +
  2052. + vmaf_score = compute_vmaf(format, width, height, read_frame, model_path);
  2053. + //printf("compute vmaf completed\n");
  2054. + return vmaf_score;
  2055. +}
  2056. +
  2057. +
  2058. +static void *BusyWork(void *t)
  2059. + {
  2060. + int i;
  2061. + long tid;
  2062. + double result=0.0;
  2063. + tid = (long)t;
  2064. + printf("busy\n");
  2065. + compute_vmaf_score();
  2066. + pthread_exit((void*) t);
  2067. + }
  2068. +
  2069. +
  2070. static av_cold int init(AVFilterContext *ctx)
  2071. {
  2072. VMAFContext *s = ctx->priv;
  2073. -
  2074. +
  2075. if (s->stats_file_str) {
  2076. if (s->stats_version < 2 && s->stats_add_max) {
  2077. av_log(ctx, AV_LOG_ERROR,
  2078. @@ -208,6 +221,8 @@ static int query_formats(AVFilterContext *ctx)
  2079. AV_PIX_FMT_YUV444P10LE, AV_PIX_FMT_YUV422P10LE, AV_PIX_FMT_YUV420P10LE,
  2080. AV_PIX_FMT_NONE
  2081. };
  2082. + printf("query formats\n");
  2083. + VMAFContext *s = ctx->priv;
  2084.  
  2085. AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
  2086. if (!fmts_list)
  2087. @@ -215,6 +230,7 @@ static int query_formats(AVFilterContext *ctx)
  2088. return ff_set_common_formats(ctx, fmts_list);
  2089. }
  2090.  
  2091. +
  2092. static int config_input_ref(AVFilterLink *inlink)
  2093. {
  2094. const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
  2095. @@ -231,10 +247,25 @@ static int config_input_ref(AVFilterLink *inlink)
  2096. return AVERROR(EINVAL);
  2097. }
  2098.  
  2099. + printf("inside config input ref\n");
  2100. +
  2101. format = av_get_pix_fmt_name(ctx->inputs[0]->format);
  2102. width = ctx->inputs[0]->w;
  2103. height = ctx->inputs[0]->h;
  2104.  
  2105. + /* Initialize mutex and condition variable objects */
  2106. + pthread_mutex_init(&lock, NULL);
  2107. + pthread_cond_init (&cond, NULL);
  2108. +
  2109. + pthread_attr_init(&s->attr);
  2110. + int d = 5;
  2111. +
  2112. + s->main_thread_id=pthread_self();
  2113. +
  2114. + int rc = pthread_create(&s->thread, &s->attr, BusyWork, (void *)d);
  2115. + s->vmaf_thread_id = s->thread;
  2116. +
  2117. +
  2118. return 0;
  2119. }
  2120.  
  2121. @@ -268,7 +299,6 @@ static int request_frame(AVFilterLink *outlink)
  2122. return ff_dualinput_request_frame(&s->dinput, outlink);
  2123. }
  2124.  
  2125. -
  2126. static av_cold void uninit(AVFilterContext *ctx)
  2127. {
  2128. VMAFContext *s = ctx->priv;
  2129. @@ -281,10 +311,6 @@ static av_cold void uninit(AVFilterContext *ctx)
  2130.  
  2131. if (s->stats_file && s->stats_file != stdout)
  2132. fclose(s->stats_file);
  2133. -
  2134. - double vmaf_score = compute_vmaf_score();
  2135. - printf("compute vmaf competed\n");
  2136. - printf("%d\n",vmaf_score);
  2137.  
  2138. return 0;
  2139. }
  2140. --
  2141. 2.7.4
  2142.  
  2143.  
  2144. From 0912925b28b3d0ad1985091c677ab758dcb71b6d Mon Sep 17 00:00:00 2001
  2145. From: ashk43712 <ashk43712@gmail.com>
  2146. Date: Fri, 16 Jun 2017 04:24:05 +0530
  2147. Subject: [PATCH 16/18] added main/ref copy data from avframe
  2148.  
  2149. ---
  2150. libavfilter/vf_vmaf.c | 38 ++++++++++++++++++++++++++++----------
  2151. 1 file changed, 28 insertions(+), 10 deletions(-)
  2152.  
  2153. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  2154. index 50390b5..4913c4c 100644
  2155. --- a/libavfilter/vf_vmaf.c
  2156. +++ b/libavfilter/vf_vmaf.c
  2157. @@ -72,7 +72,6 @@ static int width, height;
  2158. pthread_mutex_t lock;
  2159. pthread_cond_t cond;
  2160. int get_next = 0;
  2161. -int data_yes = 0;
  2162. AVFrame *gmain;
  2163. AVFrame *gref;
  2164.  
  2165. @@ -101,7 +100,7 @@ static void set_meta(AVDictionary **metadata, const char *key, float d)
  2166. av_dict_set(metadata,key,value,0);
  2167. }
  2168.  
  2169. -static void read_frame(uint8_t *ref_buf, int *ref_stride, uint8_t *main_buf, int *main_stride){
  2170. +static void read_frame(float *ref_data, int *ref_stride, float *main_data, int *main_stride){
  2171. pthread_mutex_lock(&lock);
  2172. while(gref == NULL){
  2173. pthread_cond_wait(&cond, &lock);
  2174. @@ -109,13 +108,31 @@ static void read_frame(uint8_t *ref_buf, int *ref_stride, uint8_t *main_buf, int
  2175.  
  2176. *ref_stride = gref->linesize[0];
  2177. *main_stride = gmain->linesize[0];
  2178. + printf("%d %d\n",*ref_stride,*main_stride);
  2179. + uint8_t *ptr = gref->data[0];
  2180. + float *ptr1 = ref_data;
  2181. +
  2182. + int i,j;
  2183. +
  2184. + for(i=0;i<height;i++){
  2185. + for(j=0;j<width;j++){
  2186. + ptr1[j] = (float)ptr[j];
  2187. + }
  2188. + ptr += *ref_stride;
  2189. + ptr1 += *ref_stride;
  2190. + }
  2191.  
  2192. - ref_buf = malloc(sizeof(uint8_t));
  2193. - main_buf = malloc(sizeof(uint8_t));
  2194. -
  2195. - memcpy(ref_buf, gref->data[0], sizeof(uint8_t));
  2196. - memcpy(main_buf, gmain->data[0], sizeof(uint8_t));
  2197. + ptr = gmain->data[0];
  2198. + ptr1 = main_data;
  2199.  
  2200. + for(i=0;i<height;i++){
  2201. + for(j=0;j<width;j++){
  2202. + ptr1[j] = (float)ptr[j];
  2203. + }
  2204. + ptr += *main_stride;
  2205. + ptr1 += *main_stride;
  2206. + }
  2207. +
  2208. gref = NULL;
  2209. gmain = NULL;
  2210.  
  2211. @@ -134,6 +151,8 @@ static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
  2212. pthread_cond_wait(&cond, &lock);
  2213. }
  2214.  
  2215. + int i,j;
  2216. +
  2217. gref = malloc(sizeof(AVFrame));
  2218. gmain = malloc(sizeof(AVFrame));
  2219.  
  2220. @@ -143,15 +162,13 @@ static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
  2221. pthread_cond_signal(&cond);
  2222. pthread_mutex_unlock(&lock);
  2223.  
  2224. -/*
  2225. - double score = 0;
  2226. +/* double score = 0;
  2227. //set_meta(metadata, "lavfi.vmaf.score.",score);
  2228. //av_log(ctx, AV_LOG_INFO, "vmaf score for frame %lu is %lf.\n",s->nb_frames,score);
  2229. //printf("v");
  2230. static int p = 0;
  2231. p = 1;
  2232. s->vmaf_sum += score;
  2233. -
  2234. s->nb_frames++;
  2235. */
  2236. return main;
  2237. @@ -269,6 +286,7 @@ static int config_input_ref(AVFilterLink *inlink)
  2238. return 0;
  2239. }
  2240.  
  2241. +
  2242. static int config_output(AVFilterLink *outlink)
  2243. {
  2244. AVFilterContext *ctx = outlink->src;
  2245. --
  2246. 2.7.4
  2247.  
  2248.  
  2249. From 811b3487c028ca7f7d491fbb6fcc1e80c5cb98c3 Mon Sep 17 00:00:00 2001
  2250. From: ashk43712 <ashk43712@gmail.com>
  2251. Date: Sat, 17 Jun 2017 03:22:59 +0530
  2252. Subject: [PATCH 17/18] all the frames read and vmaf score output successfully
  2253.  
  2254. ---
  2255. libavfilter/vf_vmaf.c | 169 +++++++++++++++++++++++---------------------------
  2256. 1 file changed, 78 insertions(+), 91 deletions(-)
  2257.  
  2258. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  2259. index 4913c4c..8d3ca03 100644
  2260. --- a/libavfilter/vf_vmaf.c
  2261. +++ b/libavfilter/vf_vmaf.c
  2262. @@ -52,10 +52,8 @@ typedef struct VMAFContext {
  2263. int stats_header_written;
  2264. int stats_add_max;
  2265. int is_rgb;
  2266. - pthread_t thread;
  2267. - pthread_t main_thread_id;
  2268. - pthread_t vmaf_thread_id;
  2269. - pthread_attr_t attr;
  2270. + pthread_t thread;
  2271. + pthread_attr_t attr;
  2272. uint8_t rgba_map[4];
  2273. char comps[4];
  2274. int nb_components;
  2275. @@ -71,7 +69,9 @@ static char *format;
  2276. static int width, height;
  2277. pthread_mutex_t lock;
  2278. pthread_cond_t cond;
  2279. -int get_next = 0;
  2280. +pthread_t main_thread_id;
  2281. +pthread_t vmaf_thread_id;
  2282. +int eof = 0;
  2283. AVFrame *gmain;
  2284. AVFrame *gref;
  2285.  
  2286. @@ -100,112 +100,98 @@ static void set_meta(AVDictionary **metadata, const char *key, float d)
  2287. av_dict_set(metadata,key,value,0);
  2288. }
  2289.  
  2290. -static void read_frame(float *ref_data, int *ref_stride, float *main_data, int *main_stride){
  2291. - pthread_mutex_lock(&lock);
  2292. - while(gref == NULL){
  2293. - pthread_cond_wait(&cond, &lock);
  2294. - }
  2295. -
  2296. +static int read_frame(float *ref_data, int *ref_stride, float *main_data, int *main_stride, double *score){
  2297. + if(eof == 1){
  2298. + return 1;
  2299. + }
  2300. + pthread_mutex_lock(&lock);
  2301. + while(gref == NULL){
  2302. + pthread_cond_wait(&cond, &lock);
  2303. + }
  2304. +
  2305. *ref_stride = gref->linesize[0];
  2306. *main_stride = gmain->linesize[0];
  2307. - printf("%d %d\n",*ref_stride,*main_stride);
  2308. - uint8_t *ptr = gref->data[0];
  2309. - float *ptr1 = ref_data;
  2310. -
  2311. - int i,j;
  2312. -
  2313. - for(i=0;i<height;i++){
  2314. - for(j=0;j<width;j++){
  2315. - ptr1[j] = (float)ptr[j];
  2316. - }
  2317. - ptr += *ref_stride;
  2318. - ptr1 += *ref_stride;
  2319. - }
  2320. -
  2321. - ptr = gmain->data[0];
  2322. - ptr1 = main_data;
  2323. -
  2324. - for(i=0;i<height;i++){
  2325. - for(j=0;j<width;j++){
  2326. - ptr1[j] = (float)ptr[j];
  2327. - }
  2328. - ptr += *main_stride;
  2329. - ptr1 += *main_stride;
  2330. - }
  2331. -
  2332. - gref = NULL;
  2333. - gmain = NULL;
  2334. -
  2335. - pthread_cond_signal(&cond);
  2336. - pthread_mutex_unlock(&lock);
  2337. +
  2338. + uint8_t *ptr = gref->data[0];
  2339. + float *ptr1 = ref_data;
  2340. +
  2341. + int i,j;
  2342. + for(i=0;i<height;i++){
  2343. + for(j=0;j<width;j++){
  2344. + ptr1[j] = (float)ptr[j];
  2345. + }
  2346. + ptr += *ref_stride;
  2347. + ptr1 += *ref_stride;
  2348. + }
  2349. +
  2350. + ptr = gmain->data[0];
  2351. + ptr1 = main_data;
  2352. +
  2353. + for(i=0;i<height;i++){
  2354. + for(j=0;j<width;j++){
  2355. + ptr1[j] = (float)ptr[j];
  2356. + }
  2357. + ptr += *main_stride;
  2358. + ptr1 += *main_stride;
  2359. + }
  2360. +
  2361. + gref = NULL;
  2362. + gmain = NULL;
  2363. +
  2364. + pthread_cond_signal(&cond);
  2365. + pthread_mutex_unlock(&lock);
  2366. +
  2367. + return eof;
  2368. }
  2369.  
  2370. +
  2371. static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
  2372. {
  2373. VMAFContext *s = ctx->priv;
  2374.  
  2375. AVDictionary **metadata = avpriv_frame_get_metadatap(main);
  2376.  
  2377. - pthread_mutex_lock(&lock);
  2378. - while(gref != NULL){
  2379. - pthread_cond_wait(&cond, &lock);
  2380. - }
  2381. -
  2382. - int i,j;
  2383. + pthread_mutex_lock(&lock);
  2384. + while(gref != NULL){
  2385. + pthread_cond_wait(&cond, &lock);
  2386. + }
  2387.  
  2388. - gref = malloc(sizeof(AVFrame));
  2389. - gmain = malloc(sizeof(AVFrame));
  2390. + gref = malloc(sizeof(AVFrame));
  2391. + gmain = malloc(sizeof(AVFrame));
  2392.  
  2393. - memcpy(gref, ref, sizeof(AVFrame));
  2394. - memcpy(gmain, main, sizeof(AVFrame));
  2395. + memcpy(gref, ref, sizeof(AVFrame));
  2396. + memcpy(gmain, main, sizeof(AVFrame));
  2397.  
  2398. - pthread_cond_signal(&cond);
  2399. - pthread_mutex_unlock(&lock);
  2400. + pthread_cond_signal(&cond);
  2401. + pthread_mutex_unlock(&lock);
  2402.  
  2403. -/* double score = 0;
  2404. - //set_meta(metadata, "lavfi.vmaf.score.",score);
  2405. - //av_log(ctx, AV_LOG_INFO, "vmaf score for frame %lu is %lf.\n",s->nb_frames,score);
  2406. - //printf("v");
  2407. - static int p = 0;
  2408. - p = 1;
  2409. - s->vmaf_sum += score;
  2410. - s->nb_frames++;
  2411. -*/
  2412. return main;
  2413. }
  2414.  
  2415. static void compute_vmaf_score()
  2416. {
  2417. - printf("inside compute vmaf6\n");
  2418. -
  2419. - printf("width=%d,height=%d,format=%s\n",width,height,format);
  2420.  
  2421. char *model_path = "/usr/local/share/model/vmaf_v0.6.1.pkl";
  2422.  
  2423. double vmaf_score;
  2424.  
  2425. - vmaf_score = compute_vmaf(format, width, height, read_frame, model_path);
  2426. - //printf("compute vmaf completed\n");
  2427. - return vmaf_score;
  2428. + vmaf_score = compute_vmaf(format, width, height, read_frame, model_path);
  2429. }
  2430.  
  2431. -
  2432. -static void *BusyWork(void *t)
  2433. - {
  2434. +static void *call_vmaf(void *t)
  2435. +{
  2436. int i;
  2437. long tid;
  2438. double result=0.0;
  2439. tid = (long)t;
  2440. - printf("busy\n");
  2441. - compute_vmaf_score();
  2442. + compute_vmaf_score();
  2443. pthread_exit((void*) t);
  2444. - }
  2445. -
  2446. +}
  2447.  
  2448. static av_cold int init(AVFilterContext *ctx)
  2449. {
  2450. VMAFContext *s = ctx->priv;
  2451. -
  2452. +
  2453. if (s->stats_file_str) {
  2454. if (s->stats_version < 2 && s->stats_add_max) {
  2455. av_log(ctx, AV_LOG_ERROR,
  2456. @@ -238,7 +224,6 @@ static int query_formats(AVFilterContext *ctx)
  2457. AV_PIX_FMT_YUV444P10LE, AV_PIX_FMT_YUV422P10LE, AV_PIX_FMT_YUV420P10LE,
  2458. AV_PIX_FMT_NONE
  2459. };
  2460. - printf("query formats\n");
  2461. VMAFContext *s = ctx->priv;
  2462.  
  2463. AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
  2464. @@ -264,24 +249,20 @@ static int config_input_ref(AVFilterLink *inlink)
  2465. return AVERROR(EINVAL);
  2466. }
  2467.  
  2468. - printf("inside config input ref\n");
  2469. -
  2470. - format = av_get_pix_fmt_name(ctx->inputs[0]->format);
  2471. - width = ctx->inputs[0]->w;
  2472. - height = ctx->inputs[0]->h;
  2473. + format = av_get_pix_fmt_name(ctx->inputs[0]->format);
  2474. + width = ctx->inputs[0]->w;
  2475. + height = ctx->inputs[0]->h;
  2476.  
  2477. - /* Initialize mutex and condition variable objects */
  2478. pthread_mutex_init(&lock, NULL);
  2479. pthread_cond_init (&cond, NULL);
  2480.  
  2481. - pthread_attr_init(&s->attr);
  2482. - int d = 5;
  2483. -
  2484. - s->main_thread_id=pthread_self();
  2485. -
  2486. - int rc = pthread_create(&s->thread, &s->attr, BusyWork, (void *)d);
  2487. - s->vmaf_thread_id = s->thread;
  2488. + pthread_attr_init(&s->attr);
  2489. + int d = 5;
  2490.  
  2491. + main_thread_id=pthread_self();
  2492. +
  2493. + int rc = pthread_create(&s->thread, &s->attr, call_vmaf, (void *)d);
  2494. + vmaf_thread_id = s->thread;
  2495.  
  2496. return 0;
  2497. }
  2498. @@ -330,7 +311,13 @@ static av_cold void uninit(AVFilterContext *ctx)
  2499. if (s->stats_file && s->stats_file != stdout)
  2500. fclose(s->stats_file);
  2501.  
  2502. - return 0;
  2503. + static int ptr = 0;
  2504. + if(ptr == 1){
  2505. + eof = 1;
  2506. + pthread_join(vmaf_thread_id, NULL);
  2507. + }
  2508. + ptr++;
  2509. + return 0;
  2510. }
  2511.  
  2512. static const AVFilterPad vmaf_inputs[] = {
  2513. --
  2514. 2.7.4
  2515.  
  2516.  
  2517. From 7254c6b820f299bcdb583b0487f30b6d40ffb51e Mon Sep 17 00:00:00 2001
  2518. From: ashk43712 <ashk43712@gmail.com>
  2519. Date: Mon, 19 Jun 2017 21:19:47 +0530
  2520. Subject: [PATCH 18/18] Removed printf messages and some bug fixes
  2521.  
  2522. ---
  2523. libavfilter/vf_vmaf.c | 2 --
  2524. 1 file changed, 2 deletions(-)
  2525.  
  2526. diff --git a/libavfilter/vf_vmaf.c b/libavfilter/vf_vmaf.c
  2527. index 8d3ca03..f080e67 100644
  2528. --- a/libavfilter/vf_vmaf.c
  2529. +++ b/libavfilter/vf_vmaf.c
  2530. @@ -144,7 +144,6 @@ static int read_frame(float *ref_data, int *ref_stride, float *main_data, int *m
  2531. return eof;
  2532. }
  2533.  
  2534. -
  2535. static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
  2536. {
  2537. VMAFContext *s = ctx->priv;
  2538. @@ -170,7 +169,6 @@ static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref)
  2539.  
  2540. static void compute_vmaf_score()
  2541. {
  2542. -
  2543. char *model_path = "/usr/local/share/model/vmaf_v0.6.1.pkl";
  2544.  
  2545. double vmaf_score;
  2546. --
  2547. 2.7.4
Add Comment
Please, Sign In to add comment