Movie encoding using mencoder now working.
This commit is contained in:
@@ -53,7 +53,7 @@ JMAOBJ=${JMADIR}/7zlzma.o ${JMADIR}/crc32.o ${JMADIR}/iiostrm.o\
|
||||
${JMADIR}/winout.o ${JMADIR}/zsnesjma.o
|
||||
|
||||
MAINOBJ=cfgload.o cfgparse.o endmem.o init.o initc.o uic.o patch.o ui.o vcache.o\
|
||||
version.o zmovie.o zstate.o debug.o zloader.o
|
||||
version.o zmovie.o zstate.o debug.o zloader.o md.o
|
||||
|
||||
NETOBJ=
|
||||
#${NETDIR}/ztcp.o
|
||||
@@ -150,7 +150,11 @@ uic.o: uic.c asm_call.h gblhdr.h
|
||||
vcache.o: vcache.asm macros.mac
|
||||
version.o: version.c
|
||||
zloader.o: zloader.c gblhdr.h
|
||||
zmovie.o: zmovie.c asm_call.h gblhdr.h gblvars.h numconv.h
|
||||
md.o: md.psr ${PSR}
|
||||
./${PSR} -D__UNIXSDL__ -cheader md.h -fname movie temppsr.c $<
|
||||
@CC@ -I. -O1 -o $@ -c temppsr.c
|
||||
rm -f temppsr.c
|
||||
zmovie.o: zmovie.c asm_call.h gblhdr.h gblvars.h numconv.h md.o
|
||||
zstate.o: zstate.c asm_call.h gblhdr.h gblvars.h numconv.h
|
||||
|
||||
${CHIPDIR}/c4emu.o: ${CHIPDIR}/c4emu.c gblhdr.h
|
||||
|
||||
9
zsnes/src/md.psr
Normal file
9
zsnes/src/md.psr
Normal file
@@ -0,0 +1,9 @@
|
||||
md_ntsc times 20 db "59649/995"
|
||||
md_pal times 5 db "50/1"
|
||||
md_prog times 50 db "mencoder"
|
||||
md_raw times 100 db "-demuxer rawvideo -rawvideo format=0x42475218:w=256:h=224:size=172032"
|
||||
md_other times 50 db "-aspect 4/3 -mc 0 -nosound"
|
||||
md_file times 50 db "video.avi"
|
||||
md_uncompressed times 125 db "$md_prog $md_other $md_raw:fps=$md_video_rate -ovc copy -o $md_file -"
|
||||
md_x264 times 125 db "$md_prog $md_other $md_raw:fps=$md_video_rate -ovc x264 -x264encopts qp_constant=0:frameref=15 -o $md_file -"
|
||||
md_ffv1 times 125 db "$md_prog $md_other $md_raw:fps=$md_video_rate -ovc lavc -lavcopts vcodec=ffv1:vstrict=-2 -o $md_file -"
|
||||
@@ -23,6 +23,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#ifdef __UNIXSDL__
|
||||
#include "gblhdr.h"
|
||||
#define DIR_SLASH "/"
|
||||
#define WRITE_BINARY "w"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -38,10 +39,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#define DIR_SLASH "\\"
|
||||
#define WRITE_BINARY "wb"
|
||||
#endif
|
||||
#include "gblvars.h"
|
||||
#include "asm_call.h"
|
||||
#include "numconv.h"
|
||||
#include "md.h"
|
||||
|
||||
#ifndef __WIN32__
|
||||
#define mkdir(path) mkdir(path, (S_IRWXU|S_IRWXG|S_IRWXO)) //0777
|
||||
@@ -1845,13 +1848,9 @@ Code for dumping raw video
|
||||
|
||||
*/
|
||||
|
||||
#define RAW_BUFFER_FRAMES 10
|
||||
#define RAW_BUFFER_SAMPLES 12800
|
||||
#define RAW_WIDTH 256
|
||||
#define RAW_HEIGHT 224
|
||||
#define RAW_PIXEL_SIZE 4
|
||||
#define RAW_FRAME_SIZE (RAW_WIDTH*RAW_HEIGHT)
|
||||
#define RAW_PIXEL_FRAME_SIZE (RAW_FRAME_SIZE*RAW_PIXEL_SIZE)
|
||||
|
||||
//NTSC FPS is 59.948743718592964824120603015060 in AVI that's a fraction of 59649/995
|
||||
//which equals 59.948743718592964824120603015075, so videos should not desync for several millinium
|
||||
@@ -1862,16 +1861,70 @@ Code for dumping raw video
|
||||
//59.948743718592964824120603015060 = SAMPLE_NTSC_HI*32000/SAMPLE_NTSC_LO *2
|
||||
#define SAMPLE_NTSC_HI 31840000ULL
|
||||
#define SAMPLE_NTSC_LO 59649ULL
|
||||
//Used by raw videos for calculating sample rate in NTSC mode
|
||||
//Code by Bisqwit
|
||||
|
||||
|
||||
//0 = None; 1 Logging, but not now, 2 Log now
|
||||
unsigned char AudioLogging;
|
||||
|
||||
extern unsigned char MovieVideoMode;
|
||||
extern unsigned char MovieAudioMode;
|
||||
|
||||
#define PICK_HELP(var) if (!strncmp(*str, "$"#var, strlen(#var)+1)) { *str += strlen(#var)+1; return(var); }
|
||||
|
||||
static char *pick_var(char **str)
|
||||
{
|
||||
PICK_HELP(md_prog);
|
||||
PICK_HELP(md_raw);
|
||||
PICK_HELP(md_other);
|
||||
PICK_HELP(md_file);
|
||||
if (!strncmp(*str, "$md_video_rate", strlen("$md_video_rate")))
|
||||
{
|
||||
*str += strlen("$md_video_rate");
|
||||
return(romispal ? md_pal : md_ntsc);
|
||||
}
|
||||
fprintf(stderr, "Unknown Variable: %s", *str);
|
||||
return("");
|
||||
}
|
||||
|
||||
FILE *open_movie_file()
|
||||
{
|
||||
char command[400], *p, *var;
|
||||
read_movie_vars("zmovie.cfg");
|
||||
|
||||
*command = 0;
|
||||
|
||||
switch (MovieVideoMode)
|
||||
{
|
||||
case 2: p = md_uncompressed; break;
|
||||
case 3: p = md_ffv1; break;
|
||||
case 4: p = md_x264; break;
|
||||
default: p = "$"; break;
|
||||
}
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if ((var = strchr(p, '$')))
|
||||
{
|
||||
strncat(command, p, var - p);
|
||||
strcat(command, pick_var(&var));
|
||||
p = var;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(command, p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
puts(command);
|
||||
return(popen(command, WRITE_BINARY));
|
||||
}
|
||||
|
||||
struct
|
||||
{
|
||||
FILE *vp;
|
||||
unsigned int *frame_buffer;
|
||||
size_t frame_index;
|
||||
|
||||
FILE *ap;
|
||||
unsigned short *sample_buffer;
|
||||
@@ -1888,96 +1941,108 @@ static void raw_video_close()
|
||||
{
|
||||
if (raw_vid.vp)
|
||||
{
|
||||
if (raw_vid.frame_buffer)
|
||||
switch (MovieVideoMode)
|
||||
{
|
||||
if (raw_vid.frame_index)
|
||||
{
|
||||
fwrite(raw_vid.frame_buffer, RAW_PIXEL_FRAME_SIZE, raw_vid.frame_index, raw_vid.vp);
|
||||
}
|
||||
|
||||
free(raw_vid.frame_buffer);
|
||||
case 1:
|
||||
fclose(raw_vid.vp);
|
||||
break;
|
||||
case 2: case 3: case 4:
|
||||
pclose(raw_vid.vp);
|
||||
break;
|
||||
}
|
||||
|
||||
fclose(raw_vid.vp);
|
||||
raw_vid.vp = 0;
|
||||
}
|
||||
|
||||
if (raw_vid.ap)
|
||||
if (raw_vid.ap)
|
||||
{
|
||||
if (raw_vid.sample_buffer)
|
||||
{
|
||||
if (raw_vid.sample_buffer)
|
||||
size_t file_size;
|
||||
if (raw_vid.sample_index)
|
||||
{
|
||||
size_t file_size;
|
||||
if (raw_vid.sample_index)
|
||||
{
|
||||
fwrite(raw_vid.sample_buffer, 2, raw_vid.frame_index, raw_vid.ap); //Sample is 2 bytes
|
||||
}
|
||||
|
||||
free(raw_vid.sample_buffer);
|
||||
|
||||
file_size = ftell(raw_vid.ap); //Get file size
|
||||
if (!fseek(raw_vid.ap, 4, SEEK_SET)) //Seek to after RIFF header
|
||||
{
|
||||
fwrite4(file_size - 8, raw_vid.ap); //Don't include header or this write, -8
|
||||
}
|
||||
if (!fseek(raw_vid.ap, raw_vid.aud_dsize_pos, SEEK_SET)) //Seek to where the audio data size goes
|
||||
{
|
||||
//Data size is remainder of file, which is file size, less current position, plus
|
||||
//The 4 bytes needed to hold the data size
|
||||
fwrite4(file_size - (raw_vid.aud_dsize_pos+4), raw_vid.ap);
|
||||
}
|
||||
fclose(raw_vid.ap);
|
||||
raw_vid.ap = 0;
|
||||
fwrite(raw_vid.sample_buffer, 2, raw_vid.sample_index, raw_vid.ap); //Sample is 2 bytes
|
||||
}
|
||||
AudioLogging = 0;
|
||||
|
||||
free(raw_vid.sample_buffer);
|
||||
|
||||
file_size = ftell(raw_vid.ap); //Get file size
|
||||
if (!fseek(raw_vid.ap, 4, SEEK_SET)) //Seek to after RIFF header
|
||||
{
|
||||
fwrite4(file_size - 8, raw_vid.ap); //Don't include header or this write, -8
|
||||
}
|
||||
if (!fseek(raw_vid.ap, raw_vid.aud_dsize_pos, SEEK_SET)) //Seek to where the audio data size goes
|
||||
{
|
||||
//Data size is remainder of file, which is file size, less current position, plus
|
||||
//The 4 bytes needed to hold the data size
|
||||
fwrite4(file_size - (raw_vid.aud_dsize_pos+4), raw_vid.ap);
|
||||
}
|
||||
fclose(raw_vid.ap);
|
||||
raw_vid.ap = 0;
|
||||
}
|
||||
AudioLogging = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool raw_video_open(const char *video_filename, const char *audio_filename)
|
||||
{
|
||||
memset(&raw_vid, 0, sizeof(raw_vid));
|
||||
if ((raw_vid.vp = fopen(video_filename, "wb")))
|
||||
switch (MovieVideoMode)
|
||||
{
|
||||
if ((raw_vid.frame_buffer = (unsigned int *)malloc(RAW_PIXEL_FRAME_SIZE*RAW_BUFFER_FRAMES)))
|
||||
case 1:
|
||||
raw_vid.vp = fopen(video_filename, "wb");
|
||||
break;
|
||||
|
||||
case 2: case 3: case 4:
|
||||
raw_vid.vp = open_movie_file();
|
||||
break;
|
||||
|
||||
default:
|
||||
return(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!MovieAudioMode && raw_vid.vp)
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
||||
if (!MovieVideoMode || raw_vid.vp)
|
||||
{
|
||||
if ((raw_vid.ap = fopen(audio_filename, "wb")))
|
||||
{
|
||||
if ((raw_vid.ap = fopen(audio_filename, "wb")))
|
||||
if ((raw_vid.sample_buffer = (unsigned short *)malloc(RAW_BUFFER_SAMPLES*sizeof(short))))
|
||||
{
|
||||
if ((raw_vid.sample_buffer = (unsigned short *)malloc(RAW_BUFFER_SAMPLES*sizeof(short))))
|
||||
fputs("RIFF", raw_vid.ap); //header
|
||||
fwrite4(~0, raw_vid.ap); //file size - unknown till file close
|
||||
fputs("WAVEfmt ", raw_vid.ap); //format
|
||||
fwrite4(0x12, raw_vid.ap); //fmt size
|
||||
fwrite2(1, raw_vid.ap); //fmt type (PCM)
|
||||
fwrite2(2, raw_vid.ap); //channels
|
||||
fwrite4(32000, raw_vid.ap); //sample rate
|
||||
fwrite4(32000*4, raw_vid.ap); //byte rate (sample rate*block align)
|
||||
fwrite2(16/8*2, raw_vid.ap); //block align (SignificantBitsPerSample / 8 * NumChannels)
|
||||
fwrite2(16, raw_vid.ap); //Significant bits per sample
|
||||
fwrite2(0, raw_vid.ap); //Extra format bytes
|
||||
fputs("data", raw_vid.ap); //data header
|
||||
raw_vid.aud_dsize_pos = ftell(raw_vid.ap); //Save current position for use later
|
||||
fwrite4(~0, raw_vid.ap); //data size - unknown till file close
|
||||
|
||||
if (!romispal)
|
||||
{
|
||||
fputs("RIFF", raw_vid.ap); //header
|
||||
fwrite4(~0, raw_vid.ap); //file size - unknown till file close
|
||||
fputs("WAVEfmt ", raw_vid.ap); //format
|
||||
fwrite4(0x12, raw_vid.ap); //fmt size
|
||||
fwrite2(1, raw_vid.ap); //fmt type (PCM)
|
||||
fwrite2(2, raw_vid.ap); //channels
|
||||
fwrite4(32000, raw_vid.ap); //sample rate
|
||||
fwrite4(32000*4, raw_vid.ap); //byte rate (sample rate*block align)
|
||||
fwrite2(16/8*2, raw_vid.ap); //block align (SignificantBitsPerSample / 8 * NumChannels)
|
||||
fwrite2(16, raw_vid.ap); //Significant bits per sample
|
||||
fwrite2(0, raw_vid.ap); //Extra format bytes
|
||||
fputs("data", raw_vid.ap); //data header
|
||||
raw_vid.aud_dsize_pos = ftell(raw_vid.ap); //Save current position for use later
|
||||
fwrite4(~0, raw_vid.ap); //data size - unknown till file close
|
||||
|
||||
if (!romispal)
|
||||
{
|
||||
raw_vid.sample_ntsc_hi = SAMPLE_NTSC_HI;
|
||||
raw_vid.sample_ntsc_lo = SAMPLE_NTSC_LO;
|
||||
raw_vid.sample_ntsc_balance = SAMPLE_NTSC_HI;
|
||||
}
|
||||
|
||||
AudioLogging = 1;
|
||||
return(true);
|
||||
raw_vid.sample_ntsc_hi = SAMPLE_NTSC_HI;
|
||||
raw_vid.sample_ntsc_lo = SAMPLE_NTSC_LO;
|
||||
raw_vid.sample_ntsc_balance = SAMPLE_NTSC_HI;
|
||||
}
|
||||
|
||||
AudioLogging = 1;
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
raw_video_close();
|
||||
}
|
||||
raw_video_close();
|
||||
return(false);
|
||||
}
|
||||
|
||||
//Used by raw videos for calculating sample rate in NTSC mode
|
||||
//Code by Bisqwit
|
||||
|
||||
#define PIXEL (vidbuffer[(i*288) + j + 16])
|
||||
static void raw_video_write_frame()
|
||||
{
|
||||
@@ -1985,26 +2050,15 @@ static void raw_video_write_frame()
|
||||
{
|
||||
extern unsigned short *vidbuffer;
|
||||
size_t i, j;
|
||||
unsigned int *pixel_dest = raw_vid.frame_buffer + raw_vid.frame_index*RAW_FRAME_SIZE;
|
||||
|
||||
//Use zsKnight's 16 to 32 bit color conversion (optimized by Nach)
|
||||
for (i = 0; i < RAW_HEIGHT; i++)
|
||||
{
|
||||
unsigned int *scanline = pixel_dest + i*RAW_WIDTH;
|
||||
for (j = 0; j < RAW_WIDTH; j++)
|
||||
{
|
||||
scanline[j] = ((PIXEL&0xF800) << 8) | ((PIXEL&0x07E0) << 5) |
|
||||
((PIXEL&0x001F) << 3) | 0xFF000000;
|
||||
fwrite3(((PIXEL&0xF800) << 8) | ((PIXEL&0x07E0) << 5) | ((PIXEL&0x001F) << 3), raw_vid.vp);
|
||||
}
|
||||
}
|
||||
|
||||
raw_vid.frame_index++;
|
||||
|
||||
if (raw_vid.frame_index == RAW_BUFFER_FRAMES)
|
||||
{
|
||||
fwrite(raw_vid.frame_buffer, RAW_PIXEL_FRAME_SIZE, RAW_BUFFER_FRAMES, raw_vid.vp);
|
||||
raw_vid.frame_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (raw_vid.ap)
|
||||
@@ -2052,6 +2106,7 @@ static void raw_video_write_frame()
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user