in libvmaf/src/libvmaf.c [654:745]
int vmaf_read_pictures(VmafContext *vmaf, VmafPicture *ref, VmafPicture *dist,
unsigned index)
{
if (!vmaf) return -EINVAL;
if (vmaf->flushed) return -EINVAL;
if (!ref != !dist) return -EINVAL;
if (!ref && !dist) return flush_context(vmaf);
int err = 0;
vmaf->pic_cnt++;
err = validate_pic_params(vmaf, ref, dist);
if (err) return err;
#ifdef HAVE_CUDA
err = check_ring_buffer(vmaf);
if (err) return err;
const unsigned hw_flags =
rfe_hw_flags(&vmaf->registered_feature_extractors);
VmafPicture ref_host = { 0 }, ref_device = { 0 };
err = translate_picture(vmaf, ref, &ref_host, &ref_device, hw_flags);
if (err) return err;
VmafPicture dist_host = { 0 }, dist_device = { 0 };
err = translate_picture(vmaf, dist, &dist_host, &dist_device, hw_flags);
#endif
for (unsigned i = 0; i < vmaf->registered_feature_extractors.cnt; i++) {
VmafFeatureExtractorContext *fex_ctx =
vmaf->registered_feature_extractors.fex_ctx[i];
if (!(fex_ctx->fex->flags & VMAF_FEATURE_EXTRACTOR_TEMPORAL)) {
if ((vmaf->cfg.n_subsample > 1) && (index % vmaf->cfg.n_subsample))
continue;
}
if (!(fex_ctx->fex->flags & VMAF_FEATURE_EXTRACTOR_CUDA) && vmaf->thread_pool) {
continue;
}
#ifdef HAVE_CUDA
ref = fex_ctx->fex->flags & VMAF_FEATURE_EXTRACTOR_CUDA ?
&ref_device : &ref_host;
dist = fex_ctx->fex->flags & VMAF_FEATURE_EXTRACTOR_CUDA ?
&dist_device : &dist_host;
#endif
err = vmaf_feature_extractor_context_extract(fex_ctx, ref, NULL, dist,
NULL, index,
vmaf->feature_collector);
if (err) return err;
}
#ifdef HAVE_CUDA
ref = &ref_host;
dist = &dist_host;
#endif
//multithreading for GPU does not yield performance benefits
//disabled for now
if (vmaf->thread_pool){
return threaded_read_pictures(vmaf, ref, dist, index);
}
#ifdef HAVE_CUDA
if (ref_host.priv)
err |= vmaf_picture_unref(&ref_host);
if (dist_host.priv)
err |= vmaf_picture_unref(&dist_host);
if (ref_device.priv) {
CHECK_CUDA(cuEventRecord(vmaf_cuda_picture_get_finished_event(&ref_device),
vmaf_cuda_picture_get_stream(&ref_device)));
//^FIXME: move to picture callback
err |= vmaf_picture_unref(&ref_device);
}
if (dist_device.priv) {
CHECK_CUDA(cuEventRecord(vmaf_cuda_picture_get_finished_event(&dist_device),
vmaf_cuda_picture_get_stream(&dist_device)));
//^FIXME: move to picture callback
err |= vmaf_picture_unref(&dist_device);
}
#else
err |= vmaf_picture_unref(ref);
err |= vmaf_picture_unref(dist);
#endif
return err;
}