static bool video_frame(struct ff_frame *frame, void *opaque)
{
	struct ffmpeg_source *s = opaque;
	struct obs_source_frame obs_frame = {0};
	uint64_t pts;

	// Media ended
	if (frame == NULL) {
		if (s->is_clear_on_media_end)
			obs_source_output_video(s->source, NULL);
		return true;
	}

	pts = (uint64_t)(frame->pts * 1000000000.0L);

	obs_frame.timestamp = pts;
	obs_frame.width = frame->frame->width;
	obs_frame.height = frame->frame->height;

	enum video_format format =
			ffmpeg_to_obs_video_format(frame->frame->format);

	if (s->is_forcing_scale || format == VIDEO_FORMAT_NONE)
		return video_frame_scale(frame, s, &obs_frame);
	else if (s->is_hw_decoding)
		return video_frame_hwaccel(frame, s, &obs_frame);
	else
		return video_frame_direct(frame, s, &obs_frame);
}
/**
 * video_frame:
 * @data                 : pointer to data of the video frame.
 * @width                : width of the video frame.
 * @height               : height of the video frame.
 * @pitch                : pitch of the video frame.
 *
 * Video frame render callback function.
 **/
static void video_frame(const void *data, unsigned width,
      unsigned height, size_t pitch)
{
   unsigned output_width  = 0, output_height = 0, output_pitch = 0;
   const char *msg      = NULL;
   driver_t  *driver    = driver_get_ptr();
   global_t  *global    = global_get_ptr();
   settings_t *settings = config_get_ptr();

   if (!driver->video_active)
      return;

   video_driver_cached_frame_set(data, width, height, pitch);

   if (video_frame_scale(data, width, height, pitch))
   {
      data                        = driver->scaler_out;
      pitch                       = driver->scaler.out_stride;
   }

   /* Slightly messy code,
    * but we really need to do processing before blocking on VSync
    * for best possible scheduling.
    */
   if ((!video_driver_frame_filter_alive()
            || !settings->video.post_filter_record || !data
            || global->record.gpu_buffer)
      )
      recording_dump_frame(data, width, height, pitch);

   msg                = rarch_main_msg_queue_pull();

   driver->current_msg = msg;

   if (video_driver_frame_filter(data, width, height, pitch,
            &output_width, &output_height, &output_pitch))
   {
      data   = video_driver_frame_filter_get_buf_ptr();
      width  = output_width;
      height = output_height;
      pitch  = output_pitch;
   }

   if (!video_driver_frame(data, width, height, pitch, msg))
      driver->video_active = false;
}