1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2011 Stefano Sabatini 3cabdff1aSopenharmony_ci * Copyright (c) 2009 Giliard B. de Freitas <giliarde@gmail.com> 4cabdff1aSopenharmony_ci * Copyright (C) 2002 Gunnar Monell <gmo@linux.nu> 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include <unistd.h> 24cabdff1aSopenharmony_ci#include <fcntl.h> 25cabdff1aSopenharmony_ci#include <sys/ioctl.h> 26cabdff1aSopenharmony_ci#include <stdlib.h> 27cabdff1aSopenharmony_ci#include "fbdev_common.h" 28cabdff1aSopenharmony_ci#include "libavutil/common.h" 29cabdff1aSopenharmony_ci#include "avdevice.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_cistruct rgb_pixfmt_map_entry { 32cabdff1aSopenharmony_ci int bits_per_pixel; 33cabdff1aSopenharmony_ci int red_offset, green_offset, blue_offset, alpha_offset; 34cabdff1aSopenharmony_ci enum AVPixelFormat pixfmt; 35cabdff1aSopenharmony_ci}; 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_cistatic const struct rgb_pixfmt_map_entry rgb_pixfmt_map[] = { 38cabdff1aSopenharmony_ci // bpp, red_offset, green_offset, blue_offset, alpha_offset, pixfmt 39cabdff1aSopenharmony_ci { 32, 0, 8, 16, 24, AV_PIX_FMT_RGBA }, 40cabdff1aSopenharmony_ci { 32, 16, 8, 0, 24, AV_PIX_FMT_BGRA }, 41cabdff1aSopenharmony_ci { 32, 8, 16, 24, 0, AV_PIX_FMT_ARGB }, 42cabdff1aSopenharmony_ci { 32, 3, 2, 8, 0, AV_PIX_FMT_ABGR }, 43cabdff1aSopenharmony_ci { 24, 0, 8, 16, 0, AV_PIX_FMT_RGB24 }, 44cabdff1aSopenharmony_ci { 24, 16, 8, 0, 0, AV_PIX_FMT_BGR24 }, 45cabdff1aSopenharmony_ci { 16, 11, 5, 0, 0, AV_PIX_FMT_RGB565 }, 46cabdff1aSopenharmony_ci}; 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_cienum AVPixelFormat ff_get_pixfmt_from_fb_varinfo(struct fb_var_screeninfo *varinfo) 49cabdff1aSopenharmony_ci{ 50cabdff1aSopenharmony_ci int i; 51cabdff1aSopenharmony_ci 52cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(rgb_pixfmt_map); i++) { 53cabdff1aSopenharmony_ci const struct rgb_pixfmt_map_entry *entry = &rgb_pixfmt_map[i]; 54cabdff1aSopenharmony_ci if (entry->bits_per_pixel == varinfo->bits_per_pixel && 55cabdff1aSopenharmony_ci entry->red_offset == varinfo->red.offset && 56cabdff1aSopenharmony_ci entry->green_offset == varinfo->green.offset && 57cabdff1aSopenharmony_ci entry->blue_offset == varinfo->blue.offset) 58cabdff1aSopenharmony_ci return entry->pixfmt; 59cabdff1aSopenharmony_ci } 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_ci return AV_PIX_FMT_NONE; 62cabdff1aSopenharmony_ci} 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ciconst char* ff_fbdev_default_device() 65cabdff1aSopenharmony_ci{ 66cabdff1aSopenharmony_ci const char *dev = getenv("FRAMEBUFFER"); 67cabdff1aSopenharmony_ci if (!dev) 68cabdff1aSopenharmony_ci dev = "/dev/fb0"; 69cabdff1aSopenharmony_ci return dev; 70cabdff1aSopenharmony_ci} 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_ciint ff_fbdev_get_device_list(AVDeviceInfoList *device_list) 73cabdff1aSopenharmony_ci{ 74cabdff1aSopenharmony_ci struct fb_var_screeninfo varinfo; 75cabdff1aSopenharmony_ci struct fb_fix_screeninfo fixinfo; 76cabdff1aSopenharmony_ci char device_file[12]; 77cabdff1aSopenharmony_ci AVDeviceInfo *device = NULL; 78cabdff1aSopenharmony_ci int i, fd, ret = 0; 79cabdff1aSopenharmony_ci const char *default_device = ff_fbdev_default_device(); 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci if (!device_list) 82cabdff1aSopenharmony_ci return AVERROR(EINVAL); 83cabdff1aSopenharmony_ci 84cabdff1aSopenharmony_ci for (i = 0; i <= 31; i++) { 85cabdff1aSopenharmony_ci snprintf(device_file, sizeof(device_file), "/dev/fb%d", i); 86cabdff1aSopenharmony_ci 87cabdff1aSopenharmony_ci if ((fd = avpriv_open(device_file, O_RDWR)) < 0) { 88cabdff1aSopenharmony_ci int err = AVERROR(errno); 89cabdff1aSopenharmony_ci if (err != AVERROR(ENOENT)) 90cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "Could not open framebuffer device '%s': %s\n", 91cabdff1aSopenharmony_ci device_file, av_err2str(err)); 92cabdff1aSopenharmony_ci continue; 93cabdff1aSopenharmony_ci } 94cabdff1aSopenharmony_ci if (ioctl(fd, FBIOGET_VSCREENINFO, &varinfo) == -1) 95cabdff1aSopenharmony_ci goto fail_device; 96cabdff1aSopenharmony_ci if (ioctl(fd, FBIOGET_FSCREENINFO, &fixinfo) == -1) 97cabdff1aSopenharmony_ci goto fail_device; 98cabdff1aSopenharmony_ci 99cabdff1aSopenharmony_ci device = av_mallocz(sizeof(AVDeviceInfo)); 100cabdff1aSopenharmony_ci if (!device) { 101cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 102cabdff1aSopenharmony_ci goto fail_device; 103cabdff1aSopenharmony_ci } 104cabdff1aSopenharmony_ci device->device_name = av_strdup(device_file); 105cabdff1aSopenharmony_ci device->device_description = av_strdup(fixinfo.id); 106cabdff1aSopenharmony_ci if (!device->device_name || !device->device_description) { 107cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 108cabdff1aSopenharmony_ci goto fail_device; 109cabdff1aSopenharmony_ci } 110cabdff1aSopenharmony_ci 111cabdff1aSopenharmony_ci if ((ret = av_dynarray_add_nofree(&device_list->devices, 112cabdff1aSopenharmony_ci &device_list->nb_devices, device)) < 0) 113cabdff1aSopenharmony_ci goto fail_device; 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci if (default_device && !strcmp(device->device_name, default_device)) { 116cabdff1aSopenharmony_ci device_list->default_device = device_list->nb_devices - 1; 117cabdff1aSopenharmony_ci default_device = NULL; 118cabdff1aSopenharmony_ci } 119cabdff1aSopenharmony_ci close(fd); 120cabdff1aSopenharmony_ci continue; 121cabdff1aSopenharmony_ci 122cabdff1aSopenharmony_ci fail_device: 123cabdff1aSopenharmony_ci if (device) { 124cabdff1aSopenharmony_ci av_freep(&device->device_name); 125cabdff1aSopenharmony_ci av_freep(&device->device_description); 126cabdff1aSopenharmony_ci av_freep(&device); 127cabdff1aSopenharmony_ci } 128cabdff1aSopenharmony_ci if (fd >= 0) 129cabdff1aSopenharmony_ci close(fd); 130cabdff1aSopenharmony_ci if (ret < 0) 131cabdff1aSopenharmony_ci return ret; 132cabdff1aSopenharmony_ci } 133cabdff1aSopenharmony_ci return 0; 134cabdff1aSopenharmony_ci} 135