diff --git a/record/ffemu.c b/record/ffemu.c index 065449a304..b5a632d16f 100644 --- a/record/ffemu.c +++ b/record/ffemu.c @@ -57,12 +57,14 @@ struct ffemu struct ffemu_params params; }; +// Currently hardcoded atm. :) static int map_audio_codec(ffemu_audio_codec codec) { (void)codec; - return CODEC_ID_FLAC; + return CODEC_ID_VORBIS; } +// Currently hardcoded atm. :) static int map_video_codec(ffemu_video_codec codec) { (void)codec; @@ -78,6 +80,8 @@ static int init_audio(struct audio_info *audio, struct ffemu_params *param) audio->codec = avcodec_alloc_context(); avcodec_get_context_defaults(audio->codec); + + // Hardcode this atm. audio->codec->global_quality = 100000; audio->codec->flags |= CODEC_FLAG_QSCALE; audio->codec->sample_rate = param->samplerate; @@ -100,6 +104,7 @@ static int init_audio(struct audio_info *audio, struct ffemu_params *param) return 0; } +// Hardcode. static void init_x264_param(AVCodecContext *c) { c->coder_type = 1; // coder = 1 @@ -141,6 +146,7 @@ static int init_video(struct video_info *video, struct ffemu_params *param) video->codec->height = param->out_height; video->codec->time_base = (AVRational) {param->fps.den, param->fps.num}; video->codec->crf = 25; + // Might have to change this later to account for RGB codecs. video->codec->pix_fmt = PIX_FMT_YUV420P; ///// Is this element in all recent ffmpeg versions? video->codec->thread_count = 4; @@ -151,6 +157,7 @@ static int init_video(struct video_info *video, struct ffemu_params *param) if (avcodec_open(video->codec, codec) != 0) return -1; + // Allocate a big buffer :p ffmpeg API doesn't seem to give us some clues how big this buffer should be. video->outbuf_size = 1000000; video->outbuf = av_malloc(video->outbuf_size); @@ -264,12 +271,14 @@ void ffemu_free(ffemu_t *handle) } } +// Need to make this thread based, but hey. int ffemu_push_video(ffemu_t *handle, const struct ffemu_video_data *data) { if (!handle->video.enabled) return -1; // This is deprecated, can't find a replacement... :( + // Hardcode pixel format for now (SNES) struct SwsContext *conv_ctx = sws_getContext(data->width, data->height, PIX_FMT_RGB555LE, handle->params.out_width, handle->params.out_height, PIX_FMT_YUV420P, handle->params.rescaler == FFEMU_RESCALER_LANCZOS ? SWS_LANCZOS : SWS_POINT, NULL, NULL, NULL); @@ -283,6 +292,9 @@ int ffemu_push_video(ffemu_t *handle, const struct ffemu_video_data *data) int outsize = avcodec_encode_video(handle->video.codec, handle->video.outbuf, handle->video.outbuf_size, handle->video.conv_frame); + if (outsize < 0) + return -1; + sws_freeContext(conv_ctx); AVPacket pkt; @@ -333,8 +345,10 @@ int ffemu_push_audio(ffemu_t *handle, const struct ffemu_audio_data *data) if (handle->audio.frames_in_buffer == (size_t)handle->audio.codec->frame_size) { - size_t out_size = avcodec_encode_audio(handle->audio.codec, handle->audio.outbuf, handle->audio.outbuf_size, handle->audio.buffer); - //fwrite(handle->audio.outbuf, 1, out_size, handle->audio.file); + int out_size = avcodec_encode_audio(handle->audio.codec, handle->audio.outbuf, handle->audio.outbuf_size, handle->audio.buffer); + if (out_size < 0) + return -1; + pkt.size = out_size; if (handle->audio.codec->coded_frame && handle->audio.codec->coded_frame->pts != AV_NOPTS_VALUE) { @@ -361,7 +375,7 @@ int ffemu_push_audio(ffemu_t *handle, const struct ffemu_audio_data *data) int ffemu_finalize(ffemu_t *handle) { - // Push out delayed frames. + // Push out delayed frames. (MPEG codecs) if (handle->video.enabled) { AVPacket pkt; @@ -390,6 +404,7 @@ int ffemu_finalize(ffemu_t *handle) } while (out_size > 0); } + // Write final data. av_write_trailer(handle->muxer.ctx); return 0; diff --git a/ssnes.c b/ssnes.c index 9130c14184..ee9160649e 100644 --- a/ssnes.c +++ b/ssnes.c @@ -88,7 +88,7 @@ static void video_frame(const uint16_t *data, unsigned width, unsigned height) ///////////// struct ffemu_video_data ffemu_data = { .data = data, - .pitch = 2048, + .pitch = height == 448 || height == 478 ? 1024 : 2048, .width = width, .height = height }; @@ -358,6 +358,8 @@ 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_rational ntsc_fps = {60000, 1001}; + struct ffemu_rational pal_fps = {50000, 1001}; //////// struct ffemu_params params = { .vcodec = FFEMU_VIDEO_H264, @@ -368,7 +370,7 @@ int main(int argc, char *argv[]) .channels = 2, .samplerate = 32040, .filename = "/tmp/ssnes.mkv", - .fps = {60000, 1001}, + .fps = snes_get_region() == SNES_REGION_NTSC ? ntsc_fps : pal_fps, .aspect_ratio = 4.0/3 }; g_extern.rec = ffemu_new(¶ms);