1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * This file is part of FFmpeg. 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12cabdff1aSopenharmony_ci * Lesser General Public License for more details. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17cabdff1aSopenharmony_ci */ 18cabdff1aSopenharmony_ci 19cabdff1aSopenharmony_ci#include <stdio.h> 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include "libavutil/hwcontext.h" 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_cistatic int test_derivation(AVBufferRef *src_ref, const char *src_name) 24cabdff1aSopenharmony_ci{ 25cabdff1aSopenharmony_ci enum AVHWDeviceType derived_type; 26cabdff1aSopenharmony_ci const char *derived_name; 27cabdff1aSopenharmony_ci AVBufferRef *derived_ref = NULL, *back_ref = NULL; 28cabdff1aSopenharmony_ci AVHWDeviceContext *src_dev, *derived_dev; 29cabdff1aSopenharmony_ci int err; 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci src_dev = (AVHWDeviceContext*)src_ref->data; 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci derived_type = AV_HWDEVICE_TYPE_NONE; 34cabdff1aSopenharmony_ci while (1) { 35cabdff1aSopenharmony_ci derived_type = av_hwdevice_iterate_types(derived_type); 36cabdff1aSopenharmony_ci if (derived_type == AV_HWDEVICE_TYPE_NONE) 37cabdff1aSopenharmony_ci break; 38cabdff1aSopenharmony_ci 39cabdff1aSopenharmony_ci derived_name = av_hwdevice_get_type_name(derived_type); 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_ci err = av_hwdevice_ctx_create_derived(&derived_ref, derived_type, 42cabdff1aSopenharmony_ci src_ref, 0); 43cabdff1aSopenharmony_ci if (err < 0) { 44cabdff1aSopenharmony_ci fprintf(stderr, "Unable to derive %s -> %s: %d.\n", 45cabdff1aSopenharmony_ci src_name, derived_name, err); 46cabdff1aSopenharmony_ci continue; 47cabdff1aSopenharmony_ci } 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_ci derived_dev = (AVHWDeviceContext*)derived_ref->data; 50cabdff1aSopenharmony_ci if (derived_dev->type != derived_type) { 51cabdff1aSopenharmony_ci fprintf(stderr, "Device derived as type %d has type %d.\n", 52cabdff1aSopenharmony_ci derived_type, derived_dev->type); 53cabdff1aSopenharmony_ci goto fail; 54cabdff1aSopenharmony_ci } 55cabdff1aSopenharmony_ci 56cabdff1aSopenharmony_ci if (derived_type == src_dev->type) { 57cabdff1aSopenharmony_ci if (derived_dev != src_dev) { 58cabdff1aSopenharmony_ci fprintf(stderr, "Derivation of %s from itself succeeded " 59cabdff1aSopenharmony_ci "but did not return the same device.\n", src_name); 60cabdff1aSopenharmony_ci goto fail; 61cabdff1aSopenharmony_ci } 62cabdff1aSopenharmony_ci av_buffer_unref(&derived_ref); 63cabdff1aSopenharmony_ci continue; 64cabdff1aSopenharmony_ci } 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_ci err = av_hwdevice_ctx_create_derived(&back_ref, src_dev->type, 67cabdff1aSopenharmony_ci derived_ref, 0); 68cabdff1aSopenharmony_ci if (err < 0) { 69cabdff1aSopenharmony_ci fprintf(stderr, "Derivation %s to %s succeeded, but derivation " 70cabdff1aSopenharmony_ci "back again failed: %d.\n", 71cabdff1aSopenharmony_ci src_name, derived_name, err); 72cabdff1aSopenharmony_ci goto fail; 73cabdff1aSopenharmony_ci } 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci if (back_ref->data != src_ref->data) { 76cabdff1aSopenharmony_ci fprintf(stderr, "Derivation %s to %s succeeded, but derivation " 77cabdff1aSopenharmony_ci "back again did not return the original device.\n", 78cabdff1aSopenharmony_ci src_name, derived_name); 79cabdff1aSopenharmony_ci goto fail; 80cabdff1aSopenharmony_ci } 81cabdff1aSopenharmony_ci 82cabdff1aSopenharmony_ci fprintf(stderr, "Successfully tested derivation %s -> %s.\n", 83cabdff1aSopenharmony_ci src_name, derived_name); 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_ci av_buffer_unref(&derived_ref); 86cabdff1aSopenharmony_ci av_buffer_unref(&back_ref); 87cabdff1aSopenharmony_ci } 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_ci return 0; 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_cifail: 92cabdff1aSopenharmony_ci av_buffer_unref(&derived_ref); 93cabdff1aSopenharmony_ci av_buffer_unref(&back_ref); 94cabdff1aSopenharmony_ci return -1; 95cabdff1aSopenharmony_ci} 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_cistatic int test_device(enum AVHWDeviceType type, const char *name, 98cabdff1aSopenharmony_ci const char *device, AVDictionary *opts, int flags) 99cabdff1aSopenharmony_ci{ 100cabdff1aSopenharmony_ci AVBufferRef *ref; 101cabdff1aSopenharmony_ci AVHWDeviceContext *dev; 102cabdff1aSopenharmony_ci int err; 103cabdff1aSopenharmony_ci 104cabdff1aSopenharmony_ci err = av_hwdevice_ctx_create(&ref, type, device, opts, flags); 105cabdff1aSopenharmony_ci if (err < 0) { 106cabdff1aSopenharmony_ci fprintf(stderr, "Failed to create %s device: %d.\n", name, err); 107cabdff1aSopenharmony_ci return 1; 108cabdff1aSopenharmony_ci } 109cabdff1aSopenharmony_ci 110cabdff1aSopenharmony_ci dev = (AVHWDeviceContext*)ref->data; 111cabdff1aSopenharmony_ci if (dev->type != type) { 112cabdff1aSopenharmony_ci fprintf(stderr, "Device created as type %d has type %d.\n", 113cabdff1aSopenharmony_ci type, dev->type); 114cabdff1aSopenharmony_ci av_buffer_unref(&ref); 115cabdff1aSopenharmony_ci return -1; 116cabdff1aSopenharmony_ci } 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_ci fprintf(stderr, "Device type %s successfully created.\n", name); 119cabdff1aSopenharmony_ci 120cabdff1aSopenharmony_ci err = test_derivation(ref, name); 121cabdff1aSopenharmony_ci 122cabdff1aSopenharmony_ci av_buffer_unref(&ref); 123cabdff1aSopenharmony_ci 124cabdff1aSopenharmony_ci return err; 125cabdff1aSopenharmony_ci} 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_cistatic const struct { 128cabdff1aSopenharmony_ci enum AVHWDeviceType type; 129cabdff1aSopenharmony_ci const char *possible_devices[5]; 130cabdff1aSopenharmony_ci} test_devices[] = { 131cabdff1aSopenharmony_ci { AV_HWDEVICE_TYPE_CUDA, 132cabdff1aSopenharmony_ci { "0", "1", "2" } }, 133cabdff1aSopenharmony_ci { AV_HWDEVICE_TYPE_DRM, 134cabdff1aSopenharmony_ci { "/dev/dri/card0", "/dev/dri/card1", 135cabdff1aSopenharmony_ci "/dev/dri/renderD128", "/dev/dri/renderD129" } }, 136cabdff1aSopenharmony_ci { AV_HWDEVICE_TYPE_DXVA2, 137cabdff1aSopenharmony_ci { "0", "1", "2" } }, 138cabdff1aSopenharmony_ci { AV_HWDEVICE_TYPE_D3D11VA, 139cabdff1aSopenharmony_ci { "0", "1", "2" } }, 140cabdff1aSopenharmony_ci { AV_HWDEVICE_TYPE_OPENCL, 141cabdff1aSopenharmony_ci { "0.0", "0.1", "1.0", "1.1" } }, 142cabdff1aSopenharmony_ci { AV_HWDEVICE_TYPE_VAAPI, 143cabdff1aSopenharmony_ci { "/dev/dri/renderD128", "/dev/dri/renderD129", ":0" } }, 144cabdff1aSopenharmony_ci}; 145cabdff1aSopenharmony_ci 146cabdff1aSopenharmony_cistatic int test_device_type(enum AVHWDeviceType type) 147cabdff1aSopenharmony_ci{ 148cabdff1aSopenharmony_ci enum AVHWDeviceType check; 149cabdff1aSopenharmony_ci const char *name; 150cabdff1aSopenharmony_ci int i, j, found, err; 151cabdff1aSopenharmony_ci 152cabdff1aSopenharmony_ci name = av_hwdevice_get_type_name(type); 153cabdff1aSopenharmony_ci if (!name) { 154cabdff1aSopenharmony_ci fprintf(stderr, "No name available for device type %d.\n", type); 155cabdff1aSopenharmony_ci return -1; 156cabdff1aSopenharmony_ci } 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_ci check = av_hwdevice_find_type_by_name(name); 159cabdff1aSopenharmony_ci if (check != type) { 160cabdff1aSopenharmony_ci fprintf(stderr, "Type %d maps to name %s maps to type %d.\n", 161cabdff1aSopenharmony_ci type, name, check); 162cabdff1aSopenharmony_ci return -1; 163cabdff1aSopenharmony_ci } 164cabdff1aSopenharmony_ci 165cabdff1aSopenharmony_ci found = 0; 166cabdff1aSopenharmony_ci 167cabdff1aSopenharmony_ci err = test_device(type, name, NULL, NULL, 0); 168cabdff1aSopenharmony_ci if (err < 0) { 169cabdff1aSopenharmony_ci fprintf(stderr, "Test failed for %s with default options.\n", name); 170cabdff1aSopenharmony_ci return -1; 171cabdff1aSopenharmony_ci } 172cabdff1aSopenharmony_ci if (err == 0) { 173cabdff1aSopenharmony_ci fprintf(stderr, "Test passed for %s with default options.\n", name); 174cabdff1aSopenharmony_ci ++found; 175cabdff1aSopenharmony_ci } 176cabdff1aSopenharmony_ci 177cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(test_devices); i++) { 178cabdff1aSopenharmony_ci if (test_devices[i].type != type) 179cabdff1aSopenharmony_ci continue; 180cabdff1aSopenharmony_ci 181cabdff1aSopenharmony_ci for (j = 0; test_devices[i].possible_devices[j]; j++) { 182cabdff1aSopenharmony_ci err = test_device(type, name, 183cabdff1aSopenharmony_ci test_devices[i].possible_devices[j], 184cabdff1aSopenharmony_ci NULL, 0); 185cabdff1aSopenharmony_ci if (err < 0) { 186cabdff1aSopenharmony_ci fprintf(stderr, "Test failed for %s with device %s.\n", 187cabdff1aSopenharmony_ci name, test_devices[i].possible_devices[j]); 188cabdff1aSopenharmony_ci return -1; 189cabdff1aSopenharmony_ci } 190cabdff1aSopenharmony_ci if (err == 0) { 191cabdff1aSopenharmony_ci fprintf(stderr, "Test passed for %s with device %s.\n", 192cabdff1aSopenharmony_ci name, test_devices[i].possible_devices[j]); 193cabdff1aSopenharmony_ci ++found; 194cabdff1aSopenharmony_ci } 195cabdff1aSopenharmony_ci } 196cabdff1aSopenharmony_ci } 197cabdff1aSopenharmony_ci 198cabdff1aSopenharmony_ci return !found; 199cabdff1aSopenharmony_ci} 200cabdff1aSopenharmony_ci 201cabdff1aSopenharmony_ciint main(void) 202cabdff1aSopenharmony_ci{ 203cabdff1aSopenharmony_ci enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE; 204cabdff1aSopenharmony_ci int pass, fail, skip, err; 205cabdff1aSopenharmony_ci 206cabdff1aSopenharmony_ci pass = fail = skip = 0; 207cabdff1aSopenharmony_ci while (1) { 208cabdff1aSopenharmony_ci type = av_hwdevice_iterate_types(type); 209cabdff1aSopenharmony_ci if (type == AV_HWDEVICE_TYPE_NONE) 210cabdff1aSopenharmony_ci break; 211cabdff1aSopenharmony_ci 212cabdff1aSopenharmony_ci err = test_device_type(type); 213cabdff1aSopenharmony_ci if (err == 0) 214cabdff1aSopenharmony_ci ++pass; 215cabdff1aSopenharmony_ci else if (err < 0) 216cabdff1aSopenharmony_ci ++fail; 217cabdff1aSopenharmony_ci else 218cabdff1aSopenharmony_ci ++skip; 219cabdff1aSopenharmony_ci } 220cabdff1aSopenharmony_ci 221cabdff1aSopenharmony_ci fprintf(stderr, "Attempted to test %d device types: " 222cabdff1aSopenharmony_ci "%d passed, %d failed, %d skipped.\n", 223cabdff1aSopenharmony_ci pass + fail + skip, pass, fail, skip); 224cabdff1aSopenharmony_ci 225cabdff1aSopenharmony_ci return fail > 0; 226cabdff1aSopenharmony_ci} 227