mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-14 22:38:34 +00:00
Can dupe extension.
This commit is contained in:
parent
0e72120bdc
commit
604eb9b973
@ -311,6 +311,10 @@ static bool environment_cb(unsigned cmd, void *data)
|
||||
g_extern.system.timing_set = true;
|
||||
break;
|
||||
|
||||
case SNES_ENVIRONMENT_GET_CAN_DUPE:
|
||||
*(bool*)data = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -73,6 +73,8 @@ extern "C" {
|
||||
#define SNES_ENVIRONMENT_GET_OVERSCAN 3 // bool * -- Boolean value whether or not the implementation should use overscan.
|
||||
#define SNES_ENVIRONMENT_SET_TIMING 4 // const struct snes_system_timing * -- Set exact timings of the system.
|
||||
// Used primarily for video recording.
|
||||
#define SNES_ENVIRONMENT_GET_CAN_DUPE 5 // bool * -- Boolean value whether or not SSNES supports frame duping,
|
||||
// passing NULL to video frame callback.
|
||||
|
||||
struct snes_geometry
|
||||
{
|
||||
|
@ -430,12 +430,16 @@ bool ffemu_push_video(ffemu_t *handle, const struct ffemu_video_data *data)
|
||||
|
||||
// Tightly pack our frame to conserve memory. libsnes tends to use a very large pitch.
|
||||
struct ffemu_video_data attr_data = *data;
|
||||
attr_data.pitch = attr_data.width * handle->video.pix_size;
|
||||
|
||||
if (attr_data.is_dupe)
|
||||
attr_data.width = attr_data.height = attr_data.pitch = 0;
|
||||
else
|
||||
attr_data.pitch = attr_data.width * handle->video.pix_size;
|
||||
|
||||
fifo_write(handle->attr_fifo, &attr_data, sizeof(attr_data));
|
||||
|
||||
unsigned offset = 0;
|
||||
for (unsigned y = 0; y < data->height; y++, offset += data->pitch)
|
||||
for (unsigned y = 0; y < attr_data.height; y++, offset += data->pitch)
|
||||
fifo_write(handle->video_fifo, (const uint8_t*)data->data + offset, attr_data.pitch);
|
||||
|
||||
slock_unlock(handle->lock);
|
||||
@ -481,14 +485,17 @@ bool ffemu_push_audio(ffemu_t *handle, const struct ffemu_audio_data *data)
|
||||
|
||||
static bool ffemu_push_video_thread(ffemu_t *handle, const struct ffemu_video_data *data)
|
||||
{
|
||||
handle->video.sws_ctx = sws_getCachedContext(handle->video.sws_ctx, data->width, data->height, handle->video.fmt,
|
||||
handle->params.out_width, handle->params.out_height, handle->video.pix_fmt, SWS_POINT,
|
||||
NULL, NULL, NULL);
|
||||
if (!data->is_dupe)
|
||||
{
|
||||
handle->video.sws_ctx = sws_getCachedContext(handle->video.sws_ctx, data->width, data->height, handle->video.fmt,
|
||||
handle->params.out_width, handle->params.out_height, handle->video.pix_fmt, SWS_POINT,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
int linesize = data->pitch;
|
||||
int linesize = data->pitch;
|
||||
|
||||
sws_scale(handle->video.sws_ctx, (const uint8_t* const*)&data->data, &linesize, 0,
|
||||
data->height, handle->video.conv_frame->data, handle->video.conv_frame->linesize);
|
||||
sws_scale(handle->video.sws_ctx, (const uint8_t* const*)&data->data, &linesize, 0,
|
||||
data->height, handle->video.conv_frame->data, handle->video.conv_frame->linesize);
|
||||
}
|
||||
|
||||
handle->video.conv_frame->pts = handle->video.frame_cnt;
|
||||
|
||||
@ -600,8 +607,8 @@ bool ffemu_finalize(ffemu_t *handle)
|
||||
fifo_read(handle->attr_fifo, &attr_buf, sizeof(attr_buf));
|
||||
fifo_read(handle->video_fifo, video_buf, attr_buf.height * attr_buf.pitch);
|
||||
attr_buf.data = video_buf;
|
||||
|
||||
ffemu_push_video_thread(handle, &attr_buf);
|
||||
|
||||
did_work = true;
|
||||
}
|
||||
} while (did_work);
|
||||
|
@ -44,6 +44,7 @@ struct ffemu_video_data
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned pitch;
|
||||
bool is_dupe;
|
||||
};
|
||||
|
||||
struct ffemu_audio_data
|
||||
|
7
ssnes.c
7
ssnes.c
@ -161,23 +161,28 @@ static void video_frame(const uint16_t *data, unsigned width, unsigned height)
|
||||
if (!g_extern.video_active)
|
||||
return;
|
||||
|
||||
bool is_dupe = !data;
|
||||
adjust_crop(&data, &height);
|
||||
|
||||
// Slightly messy code,
|
||||
// but we really need to do processing before blocking on VSync for best possible scheduling.
|
||||
#ifdef HAVE_FFMPEG
|
||||
if (g_extern.recording && (!g_extern.filter.active || !g_settings.video.post_filter_record))
|
||||
if (g_extern.recording && (!g_extern.filter.active || !g_settings.video.post_filter_record || is_dupe))
|
||||
{
|
||||
struct ffemu_video_data ffemu_data = {
|
||||
.data = data,
|
||||
.pitch = lines_to_pitch(height),
|
||||
.width = width,
|
||||
.height = height,
|
||||
.is_dupe = is_dupe
|
||||
};
|
||||
ffemu_push_video(g_extern.rec, &ffemu_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
const char *msg = msg_queue_pull(g_extern.msg_queue);
|
||||
|
||||
#ifdef HAVE_DYLIB
|
||||
|
Loading…
Reference in New Issue
Block a user