int vmaf_read_pictures()

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;
}