diff --git a/cores/libretro-video-processor/video_processor_v4l2.c b/cores/libretro-video-processor/video_processor_v4l2.c index 59aa550a31..c6999ba841 100644 --- a/cores/libretro-video-processor/video_processor_v4l2.c +++ b/cores/libretro-video-processor/video_processor_v4l2.c @@ -24,12 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define LIBRARY_NAME "V4L2" -#define LIBRARY_VERSION "0.0.2" -#define VIDEO_BUFFERS 2 -#define AUDIO_SAMPLE_RATE 48000 -#define AUDIO_BUFSIZE 64 -#define ENVVAR_BUFLEN 1024 +#define LIBRARY_NAME "V4L2" +#define LIBRARY_VERSION "0.0.2" +#define VIDEO_BUFFERS 2 +#define AUDIO_SAMPLE_RATE 48000 +#define AUDIO_BUFSIZE 64 +#define ENVVAR_BUFLEN 1024 #include "libretro.h" @@ -60,8 +60,8 @@ #endif struct video_buffer { - void *start; - size_t len; + void *start; + size_t len; }; /* @@ -94,15 +94,18 @@ static retro_input_state_t VIDEOPROC_CORE_PREFIX(input_state_cb); #ifdef HAVE_ALSA static void audio_callback(void) { - int16_t audio_data[128]; + int16_t audio_data[128]; - if (audio_handle) + if (audio_handle) { - const int frames = snd_pcm_readi(audio_handle, + const int frames = snd_pcm_readi(audio_handle, audio_data, sizeof(audio_data) / 4); - VIDEOPROC_CORE_PREFIX(audio_sample_batch_cb)(audio_data, frames); - } + if (frames < 0) + snd_pcm_recover(audio_handle, frames, true); + else + VIDEOPROC_CORE_PREFIX(audio_sample_batch_cb)(audio_data, frames); + } } static void @@ -114,166 +117,166 @@ audio_set_state(bool enable) static void appendstr(char *dst, const char *src, size_t dstsize) { - size_t resid = dstsize - (strlen(dst) + 1); - if (resid == 0) - return; - strncat(dst, src, resid); + size_t resid = dstsize - (strlen(dst) + 1); + if (resid == 0) + return; + strncat(dst, src, resid); } static void enumerate_video_devices(char *buf, size_t buflen) { - memset(buf, 0, buflen); + memset(buf, 0, buflen); - appendstr(buf, "Video capture device; ", buflen); + appendstr(buf, "Video capture device; ", buflen); #ifdef HAVE_UDEV - /* Get a list of devices matching the "video4linux" subsystem from udev */ - int ndevs; - struct udev_device *dev; - struct udev_enumerate *enumerate; - struct udev_list_entry *devices, *dev_list_entry; - const char *path, *name; - struct udev *udev = udev_new(); + /* Get a list of devices matching the "video4linux" subsystem from udev */ + int ndevs; + struct udev_device *dev; + struct udev_enumerate *enumerate; + struct udev_list_entry *devices, *dev_list_entry; + const char *path, *name; + struct udev *udev = udev_new(); - if (!udev) + if (!udev) { - printf("Cannot create udev context\n"); - return; - } + printf("Cannot create udev context\n"); + return; + } - enumerate = udev_enumerate_new(udev); - if (!enumerate) + enumerate = udev_enumerate_new(udev); + if (!enumerate) { - printf("Cannot create enumerate context\n"); - udev_unref(udev); - return; - } + printf("Cannot create enumerate context\n"); + udev_unref(udev); + return; + } - udev_enumerate_add_match_subsystem(enumerate, "video4linux"); - udev_enumerate_scan_devices(enumerate); + udev_enumerate_add_match_subsystem(enumerate, "video4linux"); + udev_enumerate_scan_devices(enumerate); - devices = udev_enumerate_get_list_entry(enumerate); - if (!devices) + devices = udev_enumerate_get_list_entry(enumerate); + if (!devices) { - printf("Cannot get video device list\n"); - udev_enumerate_unref(enumerate); - udev_unref(udev); - return; - } + printf("Cannot get video device list\n"); + udev_enumerate_unref(enumerate); + udev_unref(udev); + return; + } - ndevs = 0; - udev_list_entry_foreach(dev_list_entry, devices) + ndevs = 0; + udev_list_entry_foreach(dev_list_entry, devices) { - path = udev_list_entry_get_name(dev_list_entry); - dev = udev_device_new_from_syspath(udev, path); - name = udev_device_get_devnode(dev); + path = udev_list_entry_get_name(dev_list_entry); + dev = udev_device_new_from_syspath(udev, path); + name = udev_device_get_devnode(dev); - if (strncmp(name, "/dev/video", strlen("/dev/video")) == 0) + if (strncmp(name, "/dev/video", strlen("/dev/video")) == 0) { - if (ndevs > 0) - appendstr(buf, "|", buflen); - appendstr(buf, name, buflen); - ndevs++; - } + if (ndevs > 0) + appendstr(buf, "|", buflen); + appendstr(buf, name, buflen); + ndevs++; + } - udev_device_unref(dev); - } + udev_device_unref(dev); + } - udev_enumerate_unref(enumerate); - udev_unref(udev); + udev_enumerate_unref(enumerate); + udev_unref(udev); #else - /* Just return a few options. We'll fail later if the device is not found. */ - appendstr(buf, "/dev/video0|/dev/video1|/dev/video2|/dev/video3", buflen); + /* Just return a few options. We'll fail later if the device is not found. */ + appendstr(buf, "/dev/video0|/dev/video1|/dev/video2|/dev/video3", buflen); #endif } static void enumerate_audio_devices(char *buf, size_t buflen) { - memset(buf, 0, buflen); + memset(buf, 0, buflen); - appendstr(buf, "Audio capture device; ", buflen); + appendstr(buf, "Audio capture device; ", buflen); #ifdef HAVE_ALSA - void **hints, **n; - char *ioid, *name; - int ndevs; + void **hints, **n; + char *ioid, *name; + int ndevs; - if (snd_device_name_hint(-1, "pcm", &hints) < 0) - return; + if (snd_device_name_hint(-1, "pcm", &hints) < 0) + return; - ndevs = 0; - for (n = hints; *n; n++) + ndevs = 0; + for (n = hints; *n; n++) { - name = snd_device_name_get_hint(*n, "NAME"); - ioid = snd_device_name_get_hint(*n, "IOID"); - if ((ioid == NULL || !strcmp(ioid, "Input")) && - (!strncmp(name, "hw:", strlen("hw:")) || + name = snd_device_name_get_hint(*n, "NAME"); + ioid = snd_device_name_get_hint(*n, "IOID"); + if ((ioid == NULL || !strcmp(ioid, "Input")) && + (!strncmp(name, "hw:", strlen("hw:")) || !strncmp(name, "default:", strlen("default:")))) { - if (ndevs > 0) - appendstr(buf, "|", buflen); - appendstr(buf, name, buflen); - ++ndevs; - } - free(name); - free(ioid); - } + if (ndevs > 0) + appendstr(buf, "|", buflen); + appendstr(buf, name, buflen); + ++ndevs; + } + free(name); + free(ioid); + } - snd_device_name_free_hint(hints); + snd_device_name_free_hint(hints); #endif } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_set_environment)(retro_environment_t cb) { - char video_devices[ENVVAR_BUFLEN]; - char audio_devices[ENVVAR_BUFLEN]; + char video_devices[ENVVAR_BUFLEN]; + char audio_devices[ENVVAR_BUFLEN]; - VIDEOPROC_CORE_PREFIX(environment_cb) = cb; + VIDEOPROC_CORE_PREFIX(environment_cb) = cb; #ifdef HAVE_ALSA - struct retro_audio_callback audio_cb; - audio_cb.callback = audio_callback; - audio_cb.set_state = audio_set_state; - VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK, &audio_cb); + struct retro_audio_callback audio_cb; + audio_cb.callback = audio_callback; + audio_cb.set_state = audio_set_state; + VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK, &audio_cb); #endif - enumerate_video_devices(video_devices, sizeof(video_devices)); - enumerate_audio_devices(audio_devices, sizeof(audio_devices)); + enumerate_video_devices(video_devices, sizeof(video_devices)); + enumerate_audio_devices(audio_devices, sizeof(audio_devices)); - struct retro_variable envvars[] = { - { "videoproc_videodev", video_devices }, - { "videoproc_audiodev", audio_devices }, - { NULL, NULL } - }; + struct retro_variable envvars[] = { + { "videoproc_videodev", video_devices }, + { "videoproc_audiodev", audio_devices }, + { NULL, NULL } + }; - VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_SET_VARIABLES, envvars); + VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_SET_VARIABLES, envvars); } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_set_video_refresh)(retro_video_refresh_t cb) { - VIDEOPROC_CORE_PREFIX(video_refresh_cb) = cb; + VIDEOPROC_CORE_PREFIX(video_refresh_cb) = cb; } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_set_audio_sample)(retro_audio_sample_t cb) { - VIDEOPROC_CORE_PREFIX(audio_sample_cb) = cb; + VIDEOPROC_CORE_PREFIX(audio_sample_cb) = cb; } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_set_audio_sample_batch)(retro_audio_sample_batch_t cb) { - VIDEOPROC_CORE_PREFIX(audio_sample_batch_cb) = cb; + VIDEOPROC_CORE_PREFIX(audio_sample_batch_cb) = cb; } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_set_input_poll)(retro_input_poll_t cb) { - VIDEOPROC_CORE_PREFIX(input_poll_cb) = cb; + VIDEOPROC_CORE_PREFIX(input_poll_cb) = cb; } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_set_input_state)(retro_input_state_t cb) { - VIDEOPROC_CORE_PREFIX(input_state_cb) = cb; + VIDEOPROC_CORE_PREFIX(input_state_cb) = cb; } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_init)(void) @@ -282,184 +285,184 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_init)(void) static bool open_devices(void) { - struct retro_variable videodev = { "videoproc_videodev", NULL }; - struct retro_variable audiodev = { "videoproc_audiodev", NULL }; - struct v4l2_capability caps; - int error; + struct retro_variable videodev = { "videoproc_videodev", NULL }; + struct retro_variable audiodev = { "videoproc_audiodev", NULL }; + struct v4l2_capability caps; + int error; - /* Get the video and audio capture device names from the environment */ - VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &videodev); - VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &audiodev); + /* Get the video and audio capture device names from the environment */ + VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &videodev); + VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &audiodev); - /* Video device is required */ - if (videodev.value == NULL) + /* Video device is required */ + if (videodev.value == NULL) { - printf("v4l2_videodev not defined\n"); - return false; - } + printf("v4l2_videodev not defined\n"); + return false; + } - /* Open the V4L2 device */ - video_fd = v4l2_open(videodev.value, O_RDWR, 0); - if (video_fd == -1) + /* Open the V4L2 device */ + video_fd = v4l2_open(videodev.value, O_RDWR, 0); + if (video_fd == -1) { - printf("Couldn't open %s: %s\n", videodev.value, strerror(errno)); - return false; - } + printf("Couldn't open %s: %s\n", videodev.value, strerror(errno)); + return false; + } - /* Query V4L2 device capabilities */ - error = v4l2_ioctl(video_fd, VIDIOC_QUERYCAP, &caps); - if (error != 0) + /* Query V4L2 device capabilities */ + error = v4l2_ioctl(video_fd, VIDIOC_QUERYCAP, &caps); + if (error != 0) { - printf("VIDIOC_QUERYCAP failed: %s\n", strerror(errno)); - v4l2_close(video_fd); - return false; - } + printf("VIDIOC_QUERYCAP failed: %s\n", strerror(errno)); + v4l2_close(video_fd); + return false; + } - printf("%s:\n", videodev.value); - printf(" Driver: %s\n", caps.driver); - printf(" Card: %s\n", caps.card); - printf(" Bus Info: %s\n", caps.bus_info); - printf(" Version: %u.%u.%u\n", (caps.version >> 16) & 0xff, + printf("%s:\n", videodev.value); + printf(" Driver: %s\n", caps.driver); + printf(" Card: %s\n", caps.card); + printf(" Bus Info: %s\n", caps.bus_info); + printf(" Version: %u.%u.%u\n", (caps.version >> 16) & 0xff, (caps.version >> 8) & 0xff, caps.version & 0xff); #ifdef HAVE_ALSA - if (audiodev.value) + if (audiodev.value) { - snd_pcm_hw_params_t *hw_params; - unsigned int rate; + snd_pcm_hw_params_t *hw_params; + unsigned int rate; - /* - * Open the audio capture device and configure it for 48kHz, 16-bit stereo - */ - error = snd_pcm_open(&audio_handle, audiodev.value, SND_PCM_STREAM_CAPTURE, 0); - if (error < 0) + /* + * Open the audio capture device and configure it for 48kHz, 16-bit stereo + */ + error = snd_pcm_open(&audio_handle, audiodev.value, SND_PCM_STREAM_CAPTURE, 0); + if (error < 0) { - printf("Couldn't open %s: %s\n", audiodev.value, snd_strerror(error)); - return false; - } + printf("Couldn't open %s: %s\n", audiodev.value, snd_strerror(error)); + return false; + } - error = snd_pcm_hw_params_malloc(&hw_params); - if (error) + error = snd_pcm_hw_params_malloc(&hw_params); + if (error) { - printf("Couldn't allocate hw param structure: %s\n", snd_strerror(error)); - return false; - } - error = snd_pcm_hw_params_any(audio_handle, hw_params); - if (error) + printf("Couldn't allocate hw param structure: %s\n", snd_strerror(error)); + return false; + } + error = snd_pcm_hw_params_any(audio_handle, hw_params); + if (error) { - printf("Couldn't initialize hw param structure: %s\n", snd_strerror(error)); - return false; - } - error = snd_pcm_hw_params_set_access(audio_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); - if (error) + printf("Couldn't initialize hw param structure: %s\n", snd_strerror(error)); + return false; + } + error = snd_pcm_hw_params_set_access(audio_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); + if (error) { - printf("Couldn't set hw param access type: %s\n", snd_strerror(error)); - return false; - } - error = snd_pcm_hw_params_set_format(audio_handle, hw_params, SND_PCM_FORMAT_S16_LE); - if (error) - { - printf("Couldn't set hw param format to SND_PCM_FORMAT_S16_LE: %s\n", snd_strerror(error)); - return false; - } - rate = AUDIO_SAMPLE_RATE; - error = snd_pcm_hw_params_set_rate_near(audio_handle, hw_params, &rate, 0); - if (error) + printf("Couldn't set hw param access type: %s\n", snd_strerror(error)); + return false; + } + error = snd_pcm_hw_params_set_format(audio_handle, hw_params, SND_PCM_FORMAT_S16_LE); + if (error) + { + printf("Couldn't set hw param format to SND_PCM_FORMAT_S16_LE: %s\n", snd_strerror(error)); + return false; + } + rate = AUDIO_SAMPLE_RATE; + error = snd_pcm_hw_params_set_rate_near(audio_handle, hw_params, &rate, 0); + if (error) { - printf("Couldn't set hw param sample rate to %u: %s\n", rate, snd_strerror(error)); - return false; - } - if (rate != AUDIO_SAMPLE_RATE) + printf("Couldn't set hw param sample rate to %u: %s\n", rate, snd_strerror(error)); + return false; + } + if (rate != AUDIO_SAMPLE_RATE) { - printf("Hardware doesn't support sample rate %u (returned %u)\n", AUDIO_SAMPLE_RATE, rate); - return false; - } - error = snd_pcm_hw_params_set_channels(audio_handle, hw_params, 2); - if (error) + printf("Hardware doesn't support sample rate %u (returned %u)\n", AUDIO_SAMPLE_RATE, rate); + return false; + } + error = snd_pcm_hw_params_set_channels(audio_handle, hw_params, 2); + if (error) { - printf("Couldn't set hw param channels to 2: %s\n", snd_strerror(error)); - return false; - } - error = snd_pcm_hw_params(audio_handle, hw_params); - if (error) + printf("Couldn't set hw param channels to 2: %s\n", snd_strerror(error)); + return false; + } + error = snd_pcm_hw_params(audio_handle, hw_params); + if (error) { - printf("Couldn't set hw params: %s\n", snd_strerror(error)); - return false; - } - snd_pcm_hw_params_free(hw_params); + printf("Couldn't set hw params: %s\n", snd_strerror(error)); + return false; + } + snd_pcm_hw_params_free(hw_params); - error = snd_pcm_prepare(audio_handle); - if (error) + error = snd_pcm_prepare(audio_handle); + if (error) { - printf("Couldn't prepare audio interface for use: %s\n", snd_strerror(error)); - return false; - } + printf("Couldn't prepare audio interface for use: %s\n", snd_strerror(error)); + return false; + } - printf("Using ALSA device %s for audio input\n", audiodev.value); - } + printf("Using ALSA device %s for audio input\n", audiodev.value); + } #endif - return true; + return true; } static void close_devices(void) { #ifdef HAVE_ALSA - if (audio_handle) + if (audio_handle) { - snd_pcm_close(audio_handle); - audio_handle = NULL; - } + snd_pcm_close(audio_handle); + audio_handle = NULL; + } #endif - if (video_fd != -1) + if (video_fd != -1) { - v4l2_close(video_fd); - video_fd = -1; - } + v4l2_close(video_fd); + video_fd = -1; + } } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_deinit)(void) { - close_devices(); + close_devices(); } RETRO_API unsigned VIDEOPROC_CORE_PREFIX(retro_api_version)(void) { - return RETRO_API_VERSION; + return RETRO_API_VERSION; } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_get_system_info)(struct retro_system_info *info) { - info->library_name = LIBRARY_NAME; - info->library_version = LIBRARY_VERSION; + info->library_name = LIBRARY_NAME; + info->library_version = LIBRARY_VERSION; info->valid_extensions = NULL; /* Anything is fine, we don't care. */ - info->need_fullpath = false; - info->block_extract = true; + info->need_fullpath = false; + info->block_extract = true; } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_get_system_av_info)(struct retro_system_av_info *info) { - struct v4l2_cropcap cc; - int error; + struct v4l2_cropcap cc; + int error; - /* - * Query the device cropping limits. If available, we can use this to find the capture pixel aspect. - */ - memset(&cc, 0, sizeof(cc)); - cc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - error = v4l2_ioctl(video_fd, VIDIOC_CROPCAP, &cc); - if (error == 0) - info->geometry.aspect_ratio = (double)cc.pixelaspect.denominator + /* + * Query the device cropping limits. If available, we can use this to find the capture pixel aspect. + */ + memset(&cc, 0, sizeof(cc)); + cc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + error = v4l2_ioctl(video_fd, VIDIOC_CROPCAP, &cc); + if (error == 0) + info->geometry.aspect_ratio = (double)cc.pixelaspect.denominator / (double)cc.pixelaspect.numerator; - info->geometry.base_width = info->geometry.max_width = video_format.fmt.pix.width; - info->geometry.base_height = info->geometry.max_height = video_format.fmt.pix.height; - info->timing.fps = (double)video_standard.frameperiod.denominator / + info->geometry.base_width = info->geometry.max_width = video_format.fmt.pix.width; + info->geometry.base_height = info->geometry.max_height = video_format.fmt.pix.height; + info->timing.fps = (double)video_standard.frameperiod.denominator / (double)video_standard.frameperiod.numerator; - info->timing.sample_rate = AUDIO_SAMPLE_RATE; + info->timing.sample_rate = AUDIO_SAMPLE_RATE; - printf("Resolution %ux%u %f fps\n", info->geometry.base_width, + printf("Resolution %ux%u %f fps\n", info->geometry.base_width, info->geometry.base_height, info->timing.fps); } @@ -469,62 +472,62 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_set_controller_port_device)(unsigned RETRO_API void VIDEOPROC_CORE_PREFIX(retro_reset)(void) { - close_devices(); - open_devices(); + close_devices(); + open_devices(); } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_run)(void) { - struct v4l2_buffer buf; - uint8_t *src; - uint16_t *dst; - int i, error; + struct v4l2_buffer buf; + uint8_t *src; + uint16_t *dst; + int i, error; - VIDEOPROC_CORE_PREFIX(input_poll_cb)(); + VIDEOPROC_CORE_PREFIX(input_poll_cb)(); - if (video_fd == -1) - return; + if (video_fd == -1) + return; - memset(&buf, 0, sizeof(buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; - error = v4l2_ioctl(video_fd, VIDIOC_DQBUF, &buf); - if (error != 0) + error = v4l2_ioctl(video_fd, VIDIOC_DQBUF, &buf); + if (error != 0) { - printf("VIDIOC_DQBUF failed: %s\n", strerror(errno)); - VIDEOPROC_CORE_PREFIX(video_refresh_cb)(NULL, 0, 0, 0); - return; - } + printf("VIDIOC_DQBUF failed: %s\n", strerror(errno)); + VIDEOPROC_CORE_PREFIX(video_refresh_cb)(NULL, 0, 0, 0); + return; + } - src = video_buffer[buf.index].start; - dst = conv_data; + src = video_buffer[buf.index].start; + dst = conv_data; - /* RGB24 to RGB565 */ - for (i = 0; i < video_format.fmt.pix.width * video_format.fmt.pix.height; i++, src += 3, dst += 1) - *dst = ((src[0] >> 3) << 11) | ((src[1] >> 2) << 5) | ((src[2] >> 3) << 0); + /* RGB24 to RGB565 */ + for (i = 0; i < video_format.fmt.pix.width * video_format.fmt.pix.height; i++, src += 3, dst += 1) + *dst = ((src[0] >> 3) << 11) | ((src[1] >> 2) << 5) | ((src[2] >> 3) << 0); - error = v4l2_ioctl(video_fd, VIDIOC_QBUF, &buf); - if (error != 0) - printf("VIDIOC_QBUF failed: %s\n", strerror(errno)); + error = v4l2_ioctl(video_fd, VIDIOC_QBUF, &buf); + if (error != 0) + printf("VIDIOC_QBUF failed: %s\n", strerror(errno)); - VIDEOPROC_CORE_PREFIX(video_refresh_cb)(conv_data, video_format.fmt.pix.width, + VIDEOPROC_CORE_PREFIX(video_refresh_cb)(conv_data, video_format.fmt.pix.width, video_format.fmt.pix.height, video_format.fmt.pix.width * 2); } RETRO_API size_t VIDEOPROC_CORE_PREFIX(retro_serialize_size)(void) { - return 0; + return 0; } RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_serialize)(void *data, size_t size) { - return false; + return false; } RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_unserialize)(const void *data, size_t size) { - return false; + return false; } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_cheat_reset)(void) @@ -537,189 +540,189 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_cheat_set)(unsigned index, bool enabl RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_load_game)(const struct retro_game_info *game) { - enum retro_pixel_format pixel_format; - struct v4l2_standard std; - struct v4l2_requestbuffers reqbufs; - struct v4l2_buffer buf; - struct v4l2_format fmt; - enum v4l2_buf_type type; - v4l2_std_id std_id; - uint32_t index; - bool std_found; - int error; + enum retro_pixel_format pixel_format; + struct v4l2_standard std; + struct v4l2_requestbuffers reqbufs; + struct v4l2_buffer buf; + struct v4l2_format fmt; + enum v4l2_buf_type type; + v4l2_std_id std_id; + uint32_t index; + bool std_found; + int error; - if (open_devices() == false) + if (open_devices() == false) { - printf("Couldn't open capture device\n"); - close_devices(); - return false; - } + printf("Couldn't open capture device\n"); + close_devices(); + return false; + } - memset(&fmt, 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - error = v4l2_ioctl(video_fd, VIDIOC_G_FMT, &fmt); + error = v4l2_ioctl(video_fd, VIDIOC_G_FMT, &fmt); - if (error != 0) + if (error != 0) { - printf("VIDIOC_G_FMT failed: %s\n", strerror(errno)); - return false; - } + printf("VIDIOC_G_FMT failed: %s\n", strerror(errno)); + return false; + } - fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; - error = v4l2_ioctl(video_fd, VIDIOC_S_FMT, &fmt); - if (error != 0) + fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; + error = v4l2_ioctl(video_fd, VIDIOC_S_FMT, &fmt); + if (error != 0) { - printf("VIDIOC_S_FMT failed: %s\n", strerror(errno)); - return false; - } + printf("VIDIOC_S_FMT failed: %s\n", strerror(errno)); + return false; + } - error = v4l2_ioctl(video_fd, VIDIOC_G_STD, &std_id); - if (error != 0) + error = v4l2_ioctl(video_fd, VIDIOC_G_STD, &std_id); + if (error != 0) { - printf("VIDIOC_G_STD failed: %s\n", strerror(errno)); - return false; - } - for (index = 0, std_found = false; ; index++) + printf("VIDIOC_G_STD failed: %s\n", strerror(errno)); + return false; + } + for (index = 0, std_found = false; ; index++) { - memset(&std, 0, sizeof(std)); - std.index = index; - error = v4l2_ioctl(video_fd, VIDIOC_ENUMSTD, &std); - if (error) - break; - if (std.id == std_id) + memset(&std, 0, sizeof(std)); + std.index = index; + error = v4l2_ioctl(video_fd, VIDIOC_ENUMSTD, &std); + if (error) + break; + if (std.id == std_id) { - video_standard = std; - std_found = true; - } - printf("VIDIOC_ENUMSTD[%u]: %s%s\n", index, std.name, std.id == std_id ? " [*]" : ""); - } - if (!std_found) + video_standard = std; + std_found = true; + } + printf("VIDIOC_ENUMSTD[%u]: %s%s\n", index, std.name, std.id == std_id ? " [*]" : ""); + } + if (!std_found) { - printf("VIDIOC_ENUMSTD did not contain std ID %08x\n", (unsigned)std_id); - return false; - } + printf("VIDIOC_ENUMSTD did not contain std ID %08x\n", (unsigned)std_id); + return false; + } - video_format = fmt; + video_format = fmt; - memset(&reqbufs, 0, sizeof(reqbufs)); - reqbufs.count = VIDEO_BUFFERS; - reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - reqbufs.memory = V4L2_MEMORY_MMAP; + memset(&reqbufs, 0, sizeof(reqbufs)); + reqbufs.count = VIDEO_BUFFERS; + reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + reqbufs.memory = V4L2_MEMORY_MMAP; - error = v4l2_ioctl(video_fd, VIDIOC_REQBUFS, &reqbufs); - if (error != 0) + error = v4l2_ioctl(video_fd, VIDIOC_REQBUFS, &reqbufs); + if (error != 0) { - printf("VIDIOC_REQBUFS failed: %s\n", strerror(errno)); - return false; - } - video_nbuffers = reqbufs.count; + printf("VIDIOC_REQBUFS failed: %s\n", strerror(errno)); + return false; + } + video_nbuffers = reqbufs.count; - for (index = 0; index < video_nbuffers; index++) + for (index = 0; index < video_nbuffers; index++) { - memset(&buf, 0, sizeof(buf)); - buf.index = index; - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; + memset(&buf, 0, sizeof(buf)); + buf.index = index; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; - error = v4l2_ioctl(video_fd, VIDIOC_QUERYBUF, &buf); - if (error != 0) + error = v4l2_ioctl(video_fd, VIDIOC_QUERYBUF, &buf); + if (error != 0) { - printf("VIDIOC_QUERYBUF failed for %u: %s\n", index, strerror(errno)); - return false; - } + printf("VIDIOC_QUERYBUF failed for %u: %s\n", index, strerror(errno)); + return false; + } - video_buffer[index].len = buf.length; - video_buffer[index].start = v4l2_mmap(NULL, buf.length, + video_buffer[index].len = buf.length; + video_buffer[index].start = v4l2_mmap(NULL, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, video_fd, buf.m.offset); - if (video_buffer[index].start == MAP_FAILED) + if (video_buffer[index].start == MAP_FAILED) { - printf("v4l2_mmap failed: %s\n", strerror(errno)); - return false; - } - } + printf("v4l2_mmap failed: %s\n", strerror(errno)); + return false; + } + } - for (index = 0; index < video_nbuffers; index++) + for (index = 0; index < video_nbuffers; index++) { - memset(&buf, 0, sizeof(buf)); - buf.index = index; - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; - - error = v4l2_ioctl(video_fd, VIDIOC_QBUF, &buf); - if (error != 0) + memset(&buf, 0, sizeof(buf)); + buf.index = index; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + + error = v4l2_ioctl(video_fd, VIDIOC_QBUF, &buf); + if (error != 0) { - printf("VIDIOC_QBUF failed for %u: %s\n", index, strerror(errno)); - return false; - } - } + printf("VIDIOC_QBUF failed for %u: %s\n", index, strerror(errno)); + return false; + } + } - conv_data = calloc(1, video_format.fmt.pix.width * video_format.fmt.pix.height * 2); - if (conv_data == NULL) + conv_data = calloc(1, video_format.fmt.pix.width * video_format.fmt.pix.height * 2); + if (conv_data == NULL) { - printf("Cannot allocate conversion buffer\n"); - return false; - } - printf("Allocated %u byte conversion buffer\n", + printf("Cannot allocate conversion buffer\n"); + return false; + } + printf("Allocated %u byte conversion buffer\n", video_format.fmt.pix.width * video_format.fmt.pix.height * 2); - pixel_format = RETRO_PIXEL_FORMAT_RGB565; - if (!VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &pixel_format)) + pixel_format = RETRO_PIXEL_FORMAT_RGB565; + if (!VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &pixel_format)) { - printf("Cannot set pixel format\n"); - return false; - } + printf("Cannot set pixel format\n"); + return false; + } - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - error = v4l2_ioctl(video_fd, VIDIOC_STREAMON, &type); - if (error != 0) + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + error = v4l2_ioctl(video_fd, VIDIOC_STREAMON, &type); + if (error != 0) { - printf("VIDIOC_STREAMON failed: %s\n", strerror(errno)); - return false; - } + printf("VIDIOC_STREAMON failed: %s\n", strerror(errno)); + return false; + } - return true; + return true; } RETRO_API void VIDEOPROC_CORE_PREFIX(retro_unload_game)(void) { - if (video_fd != -1) + if (video_fd != -1) { uint32_t index; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - int error = v4l2_ioctl(video_fd, VIDIOC_STREAMOFF, &type); - if (error != 0) - printf("VIDIOC_STREAMOFF failed: %s\n", strerror(errno)); + int error = v4l2_ioctl(video_fd, VIDIOC_STREAMOFF, &type); + if (error != 0) + printf("VIDIOC_STREAMOFF failed: %s\n", strerror(errno)); - for (index = 0; index < video_nbuffers; index++) - v4l2_munmap(video_buffer[index].start, video_buffer[index].len); - } - + for (index = 0; index < video_nbuffers; index++) + v4l2_munmap(video_buffer[index].start, video_buffer[index].len); + } + if (conv_data) free(conv_data); - conv_data = NULL; + conv_data = NULL; - close_devices(); + close_devices(); } RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_load_game_special)(unsigned game_type, const struct retro_game_info *info, size_t num_info) { - return false; + return false; } RETRO_API unsigned VIDEOPROC_CORE_PREFIX(retro_get_region)(void) { - return (video_standard.id & V4L2_STD_NTSC) != 0 ? RETRO_REGION_NTSC : RETRO_REGION_PAL; + return (video_standard.id & V4L2_STD_NTSC) != 0 ? RETRO_REGION_NTSC : RETRO_REGION_PAL; } RETRO_API void *VIDEOPROC_CORE_PREFIX(retro_get_memory_data)(unsigned id) { - return NULL; + return NULL; } RETRO_API size_t VIDEOPROC_CORE_PREFIX(retro_get_memory_size)(unsigned id) { - return 0; + return 0; }