Can dupe extension.

This commit is contained in:
Themaister 2011-11-22 17:27:02 +01:00
parent 0e72120bdc
commit 604eb9b973
5 changed files with 29 additions and 10 deletions

View File

@ -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;
}

View File

@ -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
{

View File

@ -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);

View File

@ -44,6 +44,7 @@ struct ffemu_video_data
unsigned width;
unsigned height;
unsigned pitch;
bool is_dupe;
};
struct ffemu_audio_data

View File

@ -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