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
|
${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\
|
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=
|
NETOBJ=
|
||||||
#${NETDIR}/ztcp.o
|
#${NETDIR}/ztcp.o
|
||||||
@@ -150,7 +150,11 @@ uic.o: uic.c asm_call.h gblhdr.h
|
|||||||
vcache.o: vcache.asm macros.mac
|
vcache.o: vcache.asm macros.mac
|
||||||
version.o: version.c
|
version.o: version.c
|
||||||
zloader.o: zloader.c gblhdr.h
|
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
|
zstate.o: zstate.c asm_call.h gblhdr.h gblvars.h numconv.h
|
||||||
|
|
||||||
${CHIPDIR}/c4emu.o: ${CHIPDIR}/c4emu.c gblhdr.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__
|
#ifdef __UNIXSDL__
|
||||||
#include "gblhdr.h"
|
#include "gblhdr.h"
|
||||||
#define DIR_SLASH "/"
|
#define DIR_SLASH "/"
|
||||||
|
#define WRITE_BINARY "w"
|
||||||
#else
|
#else
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -38,10 +39,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#define DIR_SLASH "\\"
|
#define DIR_SLASH "\\"
|
||||||
|
#define WRITE_BINARY "wb"
|
||||||
#endif
|
#endif
|
||||||
#include "gblvars.h"
|
#include "gblvars.h"
|
||||||
#include "asm_call.h"
|
#include "asm_call.h"
|
||||||
#include "numconv.h"
|
#include "numconv.h"
|
||||||
|
#include "md.h"
|
||||||
|
|
||||||
#ifndef __WIN32__
|
#ifndef __WIN32__
|
||||||
#define mkdir(path) mkdir(path, (S_IRWXU|S_IRWXG|S_IRWXO)) //0777
|
#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_BUFFER_SAMPLES 12800
|
||||||
#define RAW_WIDTH 256
|
#define RAW_WIDTH 256
|
||||||
#define RAW_HEIGHT 224
|
#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
|
//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
|
//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
|
//59.948743718592964824120603015060 = SAMPLE_NTSC_HI*32000/SAMPLE_NTSC_LO *2
|
||||||
#define SAMPLE_NTSC_HI 31840000ULL
|
#define SAMPLE_NTSC_HI 31840000ULL
|
||||||
#define SAMPLE_NTSC_LO 59649ULL
|
#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
|
//0 = None; 1 Logging, but not now, 2 Log now
|
||||||
unsigned char AudioLogging;
|
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
|
struct
|
||||||
{
|
{
|
||||||
FILE *vp;
|
FILE *vp;
|
||||||
unsigned int *frame_buffer;
|
|
||||||
size_t frame_index;
|
|
||||||
|
|
||||||
FILE *ap;
|
FILE *ap;
|
||||||
unsigned short *sample_buffer;
|
unsigned short *sample_buffer;
|
||||||
@@ -1888,96 +1941,108 @@ static void raw_video_close()
|
|||||||
{
|
{
|
||||||
if (raw_vid.vp)
|
if (raw_vid.vp)
|
||||||
{
|
{
|
||||||
if (raw_vid.frame_buffer)
|
switch (MovieVideoMode)
|
||||||
{
|
{
|
||||||
if (raw_vid.frame_index)
|
case 1:
|
||||||
{
|
fclose(raw_vid.vp);
|
||||||
fwrite(raw_vid.frame_buffer, RAW_PIXEL_FRAME_SIZE, raw_vid.frame_index, raw_vid.vp);
|
break;
|
||||||
}
|
case 2: case 3: case 4:
|
||||||
|
pclose(raw_vid.vp);
|
||||||
free(raw_vid.frame_buffer);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(raw_vid.vp);
|
|
||||||
raw_vid.vp = 0;
|
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;
|
fwrite(raw_vid.sample_buffer, 2, raw_vid.sample_index, raw_vid.ap); //Sample is 2 bytes
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
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)
|
static bool raw_video_open(const char *video_filename, const char *audio_filename)
|
||||||
{
|
{
|
||||||
memset(&raw_vid, 0, sizeof(raw_vid));
|
switch (MovieVideoMode)
|
||||||
if ((raw_vid.vp = fopen(video_filename, "wb")))
|
|
||||||
{
|
{
|
||||||
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
|
raw_vid.sample_ntsc_hi = SAMPLE_NTSC_HI;
|
||||||
fwrite4(~0, raw_vid.ap); //file size - unknown till file close
|
raw_vid.sample_ntsc_lo = SAMPLE_NTSC_LO;
|
||||||
fputs("WAVEfmt ", raw_vid.ap); //format
|
raw_vid.sample_ntsc_balance = SAMPLE_NTSC_HI;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AudioLogging = 1;
|
||||||
|
return(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
raw_video_close();
|
|
||||||
}
|
}
|
||||||
|
raw_video_close();
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Used by raw videos for calculating sample rate in NTSC mode
|
|
||||||
//Code by Bisqwit
|
|
||||||
|
|
||||||
#define PIXEL (vidbuffer[(i*288) + j + 16])
|
#define PIXEL (vidbuffer[(i*288) + j + 16])
|
||||||
static void raw_video_write_frame()
|
static void raw_video_write_frame()
|
||||||
{
|
{
|
||||||
@@ -1985,26 +2050,15 @@ static void raw_video_write_frame()
|
|||||||
{
|
{
|
||||||
extern unsigned short *vidbuffer;
|
extern unsigned short *vidbuffer;
|
||||||
size_t i, j;
|
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)
|
//Use zsKnight's 16 to 32 bit color conversion (optimized by Nach)
|
||||||
for (i = 0; i < RAW_HEIGHT; i++)
|
for (i = 0; i < RAW_HEIGHT; i++)
|
||||||
{
|
{
|
||||||
unsigned int *scanline = pixel_dest + i*RAW_WIDTH;
|
|
||||||
for (j = 0; j < RAW_WIDTH; j++)
|
for (j = 0; j < RAW_WIDTH; j++)
|
||||||
{
|
{
|
||||||
scanline[j] = ((PIXEL&0xF800) << 8) | ((PIXEL&0x07E0) << 5) |
|
fwrite3(((PIXEL&0xF800) << 8) | ((PIXEL&0x07E0) << 5) | ((PIXEL&0x001F) << 3), raw_vid.vp);
|
||||||
((PIXEL&0x001F) << 3) | 0xFF000000;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
if (raw_vid.ap)
|
||||||
@@ -2052,6 +2106,7 @@ static void raw_video_write_frame()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user