mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-01-18 00:32:46 +00:00
more progress, but still borked
This commit is contained in:
parent
fe68295a3d
commit
4e77573683
4
Makefile
4
Makefile
@ -2,9 +2,9 @@ include config.mk
|
||||
|
||||
TARGET = ssnes
|
||||
|
||||
OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o dynamic.o
|
||||
OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o dynamic.o record/ffemu.o
|
||||
|
||||
LIBS = -lsamplerate
|
||||
LIBS = -lsamplerate -lavformat -lavutil -lavcodec -lswscale
|
||||
|
||||
ifeq ($(HAVE_RSOUND), 1)
|
||||
OBJ += audio/rsound.o
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <samplerate.h>
|
||||
#include "driver.h"
|
||||
#include <stdio.h>
|
||||
#include "record/ffemu.h"
|
||||
|
||||
|
||||
#define MAX_PLAYERS 2
|
||||
@ -81,6 +82,8 @@ struct global
|
||||
char savefile_name_srm[256];
|
||||
char config_path[256];
|
||||
char basename[256];
|
||||
|
||||
ffemu_t *rec;
|
||||
};
|
||||
|
||||
void parse_config(void);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/mathematics.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libswscale/swscale.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
@ -12,7 +13,11 @@ struct video_info
|
||||
{
|
||||
bool enabled;
|
||||
AVCodecContext *codec;
|
||||
AVFrame *frame;
|
||||
|
||||
AVFrame *conv_frame;
|
||||
uint8_t *conv_frame_buf;
|
||||
int64_t frame_count;
|
||||
|
||||
FILE *file;
|
||||
char *file_name;
|
||||
|
||||
@ -44,19 +49,18 @@ struct ffemu
|
||||
struct ffemu_params params;
|
||||
};
|
||||
|
||||
static int init_video(struct video_info *video, struct ffemu_params *param)
|
||||
{
|
||||
(void)video;
|
||||
(void)param;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int map_audio_codec(ffemu_audio_codec codec)
|
||||
{
|
||||
(void)codec;
|
||||
return CODEC_ID_AAC;
|
||||
}
|
||||
|
||||
static int map_video_codec(ffemu_video_codec codec)
|
||||
{
|
||||
(void)codec;
|
||||
return CODEC_ID_MPEG2VIDEO;
|
||||
}
|
||||
|
||||
static int init_audio(struct audio_info *audio, struct ffemu_params *param)
|
||||
{
|
||||
AVCodec *codec = avcodec_find_encoder(map_audio_codec(param->acodec));
|
||||
@ -87,6 +91,37 @@ static int init_audio(struct audio_info *audio, struct ffemu_params *param)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_video(struct video_info *video, struct ffemu_params *param)
|
||||
{
|
||||
AVCodec *codec = avcodec_find_encoder(map_video_codec(param->vcodec));
|
||||
if (!codec)
|
||||
return -1;
|
||||
|
||||
video->codec = avcodec_alloc_context();
|
||||
video->codec->bit_rate = 400000;
|
||||
video->codec->width = param->out_width;
|
||||
video->codec->height = param->out_height;
|
||||
video->codec->time_base = (AVRational) {param->fps.den, param->fps.num};
|
||||
video->codec->gop_size = 10;
|
||||
video->codec->max_b_frames = 1;
|
||||
video->codec->pix_fmt = PIX_FMT_YUV420P;
|
||||
|
||||
if (avcodec_open(video->codec, codec) != 0)
|
||||
return -1;
|
||||
|
||||
video->outbuf_size = 100000;
|
||||
video->outbuf = av_malloc(video->outbuf_size);
|
||||
|
||||
int size = avpicture_get_size(PIX_FMT_YUV420P, param->out_width, param->out_height);
|
||||
video->conv_frame_buf = av_malloc(size);
|
||||
video->conv_frame = avcodec_alloc_frame();
|
||||
avpicture_fill((AVPicture*)video->conv_frame, video->conv_frame_buf, PIX_FMT_YUV420P, param->out_width, param->out_height);
|
||||
|
||||
video->file = fopen("/tmp/video.mpg", "wb");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ffemu_t *ffemu_new(const struct ffemu_params *params)
|
||||
{
|
||||
avcodec_init();
|
||||
@ -136,8 +171,11 @@ void ffemu_free(ffemu_t *handle)
|
||||
av_free(handle->video.codec);
|
||||
}
|
||||
|
||||
if (handle->video.frame)
|
||||
av_free(handle->video.frame);
|
||||
if (handle->video.conv_frame)
|
||||
av_free(handle->video.conv_frame);
|
||||
|
||||
if (handle->video.conv_frame_buf)
|
||||
av_free(handle->video.conv_frame_buf);
|
||||
|
||||
if (handle->video.file)
|
||||
fclose(handle->video.file);
|
||||
@ -150,15 +188,35 @@ void ffemu_free(ffemu_t *handle)
|
||||
|
||||
int ffemu_push_video(ffemu_t *handle, const struct ffemu_video_data *data)
|
||||
{
|
||||
(void)handle;
|
||||
(void)data;
|
||||
if (!handle->video.enabled)
|
||||
return -1;
|
||||
|
||||
struct SwsContext *conv_ctx = sws_getContext(data->width, data->height, PIX_FMT_RGB555LE,
|
||||
handle->params.out_width, handle->params.out_height, PIX_FMT_YUV420P, SWS_BICUBIC,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
int linesize = data->pitch;
|
||||
|
||||
sws_scale(conv_ctx, (const uint8_t* const*)&data->data, &linesize, 0, handle->params.out_width, handle->video.conv_frame->data, handle->video.conv_frame->linesize);
|
||||
|
||||
handle->video.conv_frame->pts = handle->video.frame_count;
|
||||
handle->video.conv_frame->display_picture_number = handle->video.frame_count;
|
||||
handle->video.frame_count++;
|
||||
|
||||
int outsize = avcodec_encode_video(handle->video.codec, handle->video.outbuf, handle->video.outbuf_size, handle->video.conv_frame);
|
||||
|
||||
fwrite(handle->video.outbuf, 1, outsize, handle->video.file);
|
||||
|
||||
sws_freeContext(conv_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ffemu_push_audio(ffemu_t *handle, const struct ffemu_audio_data *data)
|
||||
{
|
||||
if (!handle->audio.enabled)
|
||||
return -1;
|
||||
|
||||
size_t written_frames = 0;
|
||||
while (written_frames < data->frames)
|
||||
{
|
||||
|
@ -39,6 +39,12 @@ typedef enum ffemu_container
|
||||
FFEMU_CONTAINER_MP4
|
||||
} ffemu_container;
|
||||
|
||||
struct ffemu_rational
|
||||
{
|
||||
unsigned num;
|
||||
unsigned den;
|
||||
};
|
||||
|
||||
// Parameters passed to ffemu_new()
|
||||
struct ffemu_params
|
||||
{
|
||||
@ -48,12 +54,13 @@ struct ffemu_params
|
||||
// Desired output resolution.
|
||||
unsigned out_width;
|
||||
unsigned out_height;
|
||||
float aspect_ratio;
|
||||
|
||||
// Pixel format for video input.
|
||||
ffemu_pixel_format format;
|
||||
|
||||
// FPS of video input.
|
||||
double fps;
|
||||
struct ffemu_rational fps;
|
||||
|
||||
// Relative video quality. 0 is lossless (if available), 10 is very low quality.
|
||||
// A value over 10 is codec defined if it will give even worse quality.
|
||||
@ -88,6 +95,7 @@ struct ffemu_video_data
|
||||
const void *data;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned pitch;
|
||||
};
|
||||
|
||||
struct ffemu_audio_data
|
||||
|
42
ssnes.c
42
ssnes.c
@ -29,6 +29,8 @@
|
||||
#include "hqflt/filters.h"
|
||||
#include "general.h"
|
||||
#include "dynamic.h"
|
||||
#include "record/ffemu.h"
|
||||
#include <assert.h>
|
||||
|
||||
struct global g_extern = {
|
||||
.video_active = true,
|
||||
@ -83,6 +85,16 @@ static void video_frame(const uint16_t *data, unsigned width, unsigned height)
|
||||
if ( !g_extern.video_active )
|
||||
return;
|
||||
|
||||
/////////////
|
||||
struct ffemu_video_data ffemu_data = {
|
||||
.data = data,
|
||||
.pitch = 2048,
|
||||
.width = width,
|
||||
.height = height
|
||||
};
|
||||
ffemu_push_video(g_extern.rec, &ffemu_data);
|
||||
/////////////
|
||||
|
||||
#ifdef HAVE_FILTER
|
||||
uint16_t output_filter[width * height * 4 * 4];
|
||||
uint16_t output[width * height];
|
||||
@ -130,6 +142,17 @@ static void audio_sample(uint16_t left, uint16_t right)
|
||||
if ( !g_extern.audio_active )
|
||||
return;
|
||||
|
||||
/////////
|
||||
static int16_t static_data[2];
|
||||
static_data[0] = left;
|
||||
static_data[1] = right;
|
||||
struct ffemu_audio_data ffemu_data = {
|
||||
.data = static_data,
|
||||
.frames = 1
|
||||
};
|
||||
ffemu_push_audio(g_extern.rec, &ffemu_data);
|
||||
//////////
|
||||
|
||||
static float data[AUDIO_CHUNK_SIZE_NONBLOCKING];
|
||||
static int data_ptr = 0;
|
||||
|
||||
@ -335,6 +358,21 @@ int main(int argc, char *argv[])
|
||||
load_save_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM);
|
||||
load_save_file(savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC);
|
||||
|
||||
////////
|
||||
struct ffemu_params params = {
|
||||
.vcodec = FFEMU_VIDEO_H264,
|
||||
.acodec = FFEMU_AUDIO_AAC,
|
||||
.out_width = 512,
|
||||
.out_height = 448,
|
||||
.channels = 2,
|
||||
.samplerate = 32040,
|
||||
.fps = {60000, 1001},
|
||||
.aspect_ratio = 4.0/3
|
||||
};
|
||||
g_extern.rec = ffemu_new(¶ms);
|
||||
assert(g_extern.rec);
|
||||
/////////
|
||||
|
||||
///// TODO: Modular friendly!!!
|
||||
for(;;)
|
||||
{
|
||||
@ -361,6 +399,10 @@ int main(int argc, char *argv[])
|
||||
psnes_run();
|
||||
}
|
||||
|
||||
///////////
|
||||
ffemu_free(g_extern.rec);
|
||||
///////////
|
||||
|
||||
save_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM);
|
||||
save_file(savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user