summaryrefslogtreecommitdiffstats
path: root/libhb/vce_common.c
blob: 21b4bb596114069d921675bbe50629476bad1c81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* vce_common.c
 *
 * Copyright (c) 2003-2018 HandBrake Team
 * This file is part of the HandBrake source code.
 * Homepage: <http://handbrake.fr/>.
 * It may be used under the terms of the GNU General Public License v2.
 * For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
 */

#ifdef USE_VCE
#include "AMF/core/Factory.h"
#include "AMF/components/VideoDecoderUVD.h"
#include "hb.h"

AMF_RESULT check_component_available(const wchar_t *componentID)
{
    amf_handle          library = NULL;
    AMFInit_Fn          init_fun;
    AMFFactory         *factory = NULL;
    AMFContext         *context = NULL;
    AMFComponent       *encoder = NULL;
    AMFCaps            *encoderCaps = NULL;
    AMF_RESULT          result = AMF_FAIL;

    hb_log("VCE: Checking for hardware availability.");
    
    library = hb_dlopen(AMF_DLL_NAMEA);
    if(!library)
    {
        result =  AMF_FAIL;
        hb_log("VCE: VCE Library not found.");
        goto clean;
    }

    init_fun = (AMFInit_Fn)(hb_dlsym(library, AMF_INIT_FUNCTION_NAME));
    if(!init_fun)
    {
        result = AMF_FAIL;
        hb_log("VCE: Load Library Failed");
        goto clean;
    }

    result = init_fun(AMF_FULL_VERSION, &factory);
    if(result != AMF_OK)
    {
        hb_log("VCE: Init Failed");
        goto clean;
    }

    result = factory->pVtbl->CreateContext(factory, &context);
    if(result != AMF_OK)
    {
        hb_log("VCE: Context Failed");
        goto clean;
    }

    result = context->pVtbl->InitDX11(context, NULL, AMF_DX11_1);
    if (result != AMF_OK) {
        result = context->pVtbl->InitDX9(context, NULL);
        if (result != AMF_OK) {
            hb_log("VCE: DX11 and DX9 Failed");
            goto clean;
        }
    }

    result = factory->pVtbl->CreateComponent(factory, context, componentID, &encoder);
    if(result != AMF_OK)
    {
        hb_log("VCE: Encoder not available");
        goto clean;
    }

    result = encoder->pVtbl->GetCaps(encoder, &encoderCaps);
    
    hb_log("VCE: Result = %d", result);

clean:
    if (encoderCaps)
    {
        encoderCaps->pVtbl->Clear(encoderCaps);
        encoderCaps->pVtbl->Release(encoderCaps);
        encoderCaps = NULL;
    }
    if (encoder)
    {
        encoder->pVtbl->Terminate(encoder);
        encoder->pVtbl->Release(encoder);
        encoder = NULL;
    }
    if (context)
    {
        context->pVtbl->Terminate(context);
        context->pVtbl->Release(context);
        context = NULL;
    }
    if(library)
    {
        hb_dlclose(library);
    }

    return result;
}

int hb_vce_h264_available()
{
    return (check_component_available(AMFVideoDecoderUVD_H264_AVC) == AMF_OK) ? 1 : 0;
}

int hb_vce_h265_available()
{
    return (check_component_available(AMFVideoDecoderHW_H265_HEVC) == AMF_OK) ? 1 : 0;
}

#else

int hb_vce_h264_available()
{
    return 0;
}

int hb_vce_h265_available()
{
    return 0;
}

#endif // USE_QSV