Initial add of avi recording code for Qt GUI.

This commit is contained in:
mjbudd77 2021-04-28 21:40:46 -04:00
parent 69ed92eada
commit b78003dc00
12 changed files with 1414 additions and 5 deletions

View File

@ -436,8 +436,7 @@ set(SRC_DRIVERS_COMMON
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/vidblit.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/os_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/nes_ntsc.c
#${CMAKE_CURRENT_SOURCE_DIR}/drivers/videolog/nesvideos-piece.cpp
#${CMAKE_CURRENT_SOURCE_DIR}/drivers/videolog/rgbtorgb.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/videolog/rgbtorgb.cpp
)
set(SRC_DRIVERS_SDL
@ -483,6 +482,10 @@ set(SRC_DRIVERS_SDL
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/sdl-joystick.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/sdl-throttle.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/unix-netplay.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/AviRecord.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/avi/avi-utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/avi/fileio.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/avi/gwavi.cpp
)
set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL})

View File

@ -0,0 +1,58 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "Qt/AviRecord.h"
#include "Qt/avi/gwavi.h"
#include "Qt/nes_shm.h"
static gwavi_t *gwavi = NULL;
static bool recordEnable = false;
//**************************************************************************************
int aviRecordOpenFile( const char *filepath, int format, int width, int height )
{
if ( gwavi != NULL )
{
delete gwavi; gwavi = NULL;
}
gwavi = new gwavi_t();
recordEnable = true;
return 0;
}
//**************************************************************************************
int aviRecordAddFrame( void )
{
if ( !recordEnable )
{
return -1;
}
if ( gwavi == NULL )
{
return -1;
}
int numPixels, bufferSize;
numPixels = nes_shm->video.ncol * nes_shm->video.nrow;
bufferSize = numPixels * sizeof(uint32_t);
//gwavi->
return 0;
}
//**************************************************************************************
int aviRecordClose(void)
{
recordEnable = false;
if ( gwavi != NULL )
{
delete gwavi; gwavi = NULL;
}
return 0;
}
//**************************************************************************************

View File

@ -0,0 +1,9 @@
// AviRecord.h
//
int aviRecordOpenFile( const char *filepath, int format, int width, int height );
int aviRecordAddFrame( void );
int aviRecordClose(void);

View File

@ -63,6 +63,7 @@
#include "Qt/PaletteConf.h"
#include "Qt/PaletteEditor.h"
#include "Qt/GuiConf.h"
#include "Qt/AviRecord.h"
#include "Qt/MoviePlay.h"
#include "Qt/MovieOptions.h"
#include "Qt/TimingConf.h"
@ -1446,6 +1447,15 @@ void consoleWin_t::createMainMenu(void)
movieMenu->addAction(recAsMovAct);
// Movie -> Avi Record
act = new QAction(tr("A&VI Record"), this);
//act->setShortcut( QKeySequence(tr("Shift+F5")));
act->setCheckable(true);
act->setStatusTip(tr("AVI Record"));
connect(act, SIGNAL(triggered()), this, SLOT(aviOpen(void)) );
movieMenu->addAction(act);
//-----------------------------------------------------------------------
// Help
helpMenu = menubar->addMenu(tr("&Help"));
@ -3084,6 +3094,11 @@ void consoleWin_t::recordMovieAs(void)
return;
}
void consoleWin_t::aviOpen(void)
{
aviRecordOpenFile( NULL, 0, 256, 240 );
}
void consoleWin_t::aboutFCEUX(void)
{
AboutWindow *aboutWin;

View File

@ -357,6 +357,7 @@ class consoleWin_t : public QMainWindow
void mainMenuOpen(void);
void mainMenuClose(void);
void warnAmbiguousShortcut( QShortcut*);
void aviOpen(void);
};

Binary file not shown.

View File

@ -0,0 +1,560 @@
/*
* Copyright (c) 2008-2011, Michael Kohn
* Copyright (c) 2013, Robin Hahling
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the author nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Set of functions useful to create an AVI file. It is used to write things
* such as AVI header and so on.
*/
#include <stdio.h>
#include <string.h>
#include "Qt/avi/gwavi.h"
int
gwavi_t::write_avi_header(FILE *out, struct gwavi_header_t *avi_header)
{
long marker, t;
if (write_chars_bin(out, "avih", 4) == -1) {
(void)fprintf(stderr, "write_avi_header: write_chars_bin() "
"failed\n");
return -1;
}
if ((marker = ftell(out)) == -1) {
perror("write_avi_header (ftell)");
return -1;
}
if (write_int(out, 0) == -1)
goto write_int_failed;
if (write_int(out, avi_header->time_delay) == -1)
goto write_int_failed;
if (write_int(out, avi_header->data_rate) == -1)
goto write_int_failed;
if (write_int(out, avi_header->reserved) == -1)
goto write_int_failed;
/* dwFlags */
if (write_int(out, avi_header->flags) == -1)
goto write_int_failed;
/* dwTotalFrames */
if (write_int(out, avi_header->number_of_frames) == -1)
goto write_int_failed;
if (write_int(out, avi_header->initial_frames) == -1)
goto write_int_failed;
if (write_int(out, avi_header->data_streams) == -1)
goto write_int_failed;
if (write_int(out, avi_header->buffer_size) == -1)
goto write_int_failed;
if (write_int(out, avi_header->width) == -1)
goto write_int_failed;
if (write_int(out, avi_header->height) == -1)
goto write_int_failed;
if (write_int(out, avi_header->time_scale) == -1)
goto write_int_failed;
if (write_int(out, avi_header->playback_data_rate) == -1)
goto write_int_failed;
if (write_int(out, avi_header->starting_time) == -1)
goto write_int_failed;
if (write_int(out, avi_header->data_length) == -1)
goto write_int_failed;
if ((t = ftell(out)) == -1) {
perror("write_avi_header (ftell)");
return -1;
}
if (fseek(out, marker, SEEK_SET) == -1) {
perror("write_avi_header (fseek)");
return -1;
}
if (write_int(out, (unsigned int)(t - marker - 4)) == -1)
goto write_int_failed;
if (fseek(out, t, SEEK_SET) == -1) {
perror("write_avi_header (fseek)");
return -1;
}
return 0;
write_int_failed:
(void)fprintf(stderr, "write_avi_header: write_int() failed\n");
return -1;
}
int
gwavi_t::write_stream_header(FILE *out, struct gwavi_stream_header_t *stream_header)
{
long marker, t;
if (write_chars_bin(out, "strh", 4) == -1)
goto write_chars_bin_failed;
if ((marker = ftell(out)) == -1) {
perror("write_stream_header (ftell)");
return -1;
}
if (write_int(out, 0) == -1)
goto write_int_failed;
if (write_chars_bin(out, stream_header->data_type, 4) == -1)
goto write_chars_bin_failed;
if (write_chars_bin(out, stream_header->codec, 4) == -1)
goto write_chars_bin_failed;
if (write_int(out, stream_header->flags) == -1)
goto write_int_failed;
if (write_int(out, stream_header->priority) == -1)
goto write_int_failed;
if (write_int(out, stream_header->initial_frames) == -1)
goto write_int_failed;
if (write_int(out, stream_header->time_scale) == -1)
goto write_int_failed;
if (write_int(out, stream_header->data_rate) == -1)
goto write_int_failed;
if (write_int(out, stream_header->start_time) == -1)
goto write_int_failed;
if (write_int(out, stream_header->data_length) == -1)
goto write_int_failed;
if (write_int(out, stream_header->buffer_size) == -1)
goto write_int_failed;
if (write_int(out, stream_header->video_quality) == -1)
goto write_int_failed;
if (write_int(out, stream_header->sample_size) == -1)
goto write_int_failed;
if (write_int(out, 0) == -1)
goto write_int_failed;
if (write_int(out, 0) == -1)
goto write_int_failed;
if ((t = ftell(out)) == -1) {
perror("write_stream_header (ftell)");
return -1;
}
if (fseek(out, marker, SEEK_SET) == -1) {
perror("write_stream_header (fseek)");
return -1;
}
write_int(out, (unsigned int)(t - marker - 4));
if (fseek(out, t, SEEK_SET) == -1){
perror("write_stream_header (fseek)");
return -1;
}
return 0;
write_int_failed:
(void)fprintf(stderr, "write_stream_header: write_int() failed\n");
return -1;
write_chars_bin_failed:
(void)fprintf(stderr, "write_stream_header: write_chars_bin() failed\n");
return -1;
}
int
gwavi_t::write_stream_format_v(FILE *out, struct gwavi_stream_format_v_t *stream_format_v)
{
long marker,t;
unsigned int i;
if (write_chars_bin(out, "strf", 4) == -1) {
(void)fprintf(stderr, "write_stream_format_v: write_chars_bin()"
" failed\n");
return -1;
}
if ((marker = ftell(out)) == -1) {
perror("write_stream_format_v (ftell)");
return -1;
}
if (write_int(out, 0) == -1)
goto write_int_failed;
if (write_int(out, stream_format_v->header_size) == -1)
goto write_int_failed;
if (write_int(out, stream_format_v->width) == -1)
goto write_int_failed;
if (write_int(out, stream_format_v->height) == -1)
goto write_int_failed;
if (write_short(out, stream_format_v->num_planes) == -1) {
(void)fprintf(stderr, "write_stream_format_v: write_short() "
"failed\n");
return -1;
}
if (write_short(out, stream_format_v->bits_per_pixel) == -1) {
(void)fprintf(stderr, "write_stream_format_v: write_short() "
"failed\n");
return -1;
}
if (write_int(out, stream_format_v->compression_type) == -1)
goto write_int_failed;
if (write_int(out, stream_format_v->image_size) == -1)
goto write_int_failed;
if (write_int(out, stream_format_v->x_pels_per_meter) == -1)
goto write_int_failed;
if (write_int(out, stream_format_v->y_pels_per_meter) == -1)
goto write_int_failed;
if (write_int(out, stream_format_v->colors_used) == -1)
goto write_int_failed;
if (write_int(out, stream_format_v->colors_important) == -1)
goto write_int_failed;
if (stream_format_v->colors_used != 0)
for (i = 0; i < stream_format_v->colors_used; i++) {
if (fputc(stream_format_v->palette[i] & 255, out)
== EOF)
goto fputc_failed;
if (fputc((stream_format_v->palette[i] >> 8) & 255, out)
== EOF)
goto fputc_failed;
if (fputc((stream_format_v->palette[i] >> 16) & 255, out)
== EOF)
goto fputc_failed;
if (fputc(0, out) == EOF)
goto fputc_failed;
}
if ((t = ftell(out)) == -1) {
perror("write_stream_format_v (ftell)");
return -1;
}
if (fseek(out,marker,SEEK_SET) == -1) {
perror("write_stream_format_v (fseek)");
return -1;
}
if (write_int(out, (unsigned int)(t - marker - 4)) == -1)
goto write_int_failed;
if (fseek(out, t, SEEK_SET) == -1) {
perror("write_stream_format_v (fseek)");
return -1;
}
return 0;
write_int_failed:
(void)fprintf(stderr, "write_stream_format_v: write_int() failed\n");
return -1;
fputc_failed:
(void)fprintf(stderr, "write_stream_format_v: fputc() failed\n");
return -1;
}
int
gwavi_t::write_stream_format_a(FILE *out, struct gwavi_stream_format_a_t *stream_format_a)
{
long marker, t;
if (write_chars_bin(out, "strf", 4) == -1) {
(void)fprintf(stderr, "write_stream_format_a: write_chars_bin()"
" failed\n");
return -1;
}
if ((marker = ftell(out)) == -1) {
perror("write_stream_format_a (ftell)");
return -1;
}
if (write_int(out, 0) == -1)
goto write_int_failed;
if (write_short(out, stream_format_a->format_type) == -1)
goto write_short_failed;
if (write_short(out, stream_format_a->channels) == -1)
goto write_short_failed;
if (write_int(out, stream_format_a->sample_rate) == -1)
goto write_int_failed;
if (write_int(out, stream_format_a->bytes_per_second) == -1)
goto write_int_failed;
if (write_short(out, stream_format_a->block_align) == -1)
goto write_short_failed;
if (write_short(out, stream_format_a->bits_per_sample) == -1)
goto write_short_failed;
if (write_short(out, stream_format_a->size) == -1)
goto write_short_failed;
if ((t = ftell(out)) == -1) {
perror("write_stream_format_a (ftell)");
return -1;
}
if (fseek(out, marker, SEEK_SET) == -1) {
perror("write_stream_format_a (fseek)");
return -1;
}
if (write_int(out, (unsigned int)(t - marker - 4)) == -1)
goto write_int_failed;
if (fseek(out, t, SEEK_SET) == -1) {
perror("write_stream_format_a (fseek)");
return -1;
}
return 0;
write_int_failed:
(void)fprintf(stderr, "write_stream_format_a: write_int() failed\n");
return -1;
write_short_failed:
(void)fprintf(stderr, "write_stream_format_a: write_short() failed\n");
return -1;
}
int
gwavi_t::write_avi_header_chunk(void)
{
long marker, t;
long sub_marker;
if (write_chars_bin(out, "LIST", 4) == -1)
goto write_chars_bin_failed;
if ((marker = ftell(out)) == -1)
goto ftell_failed;
if (write_int(out, 0) == -1)
goto write_int_failed;
if (write_chars_bin(out, "hdrl", 4) == -1)
goto write_chars_bin_failed;
if (write_avi_header(out, &avi_header) == -1) {
(void)fprintf(stderr, "write_avi_header_chunk: "
"write_avi_header() failed\n");
return -1;
}
if (write_chars_bin(out, "LIST", 4) == -1)
goto write_chars_bin_failed;
if ((sub_marker = ftell(out)) == -1)
goto ftell_failed;
if (write_int(out, 0) == -1)
goto write_int_failed;
if (write_chars_bin(out, "strl", 4) == -1)
goto write_chars_bin_failed;
if (write_stream_header(out, &stream_header_v) == -1) {
(void)fprintf(stderr, "write_avi_header_chunk: "
"write_stream_header failed\n");
return -1;
}
if (write_stream_format_v(out, &stream_format_v) == -1) {
(void)fprintf(stderr, "write_avi_header_chunk: "
"write_stream_format_v failed\n");
return -1;
}
if ((t = ftell(out)) == -1)
goto ftell_failed;
if (fseek(out, sub_marker, SEEK_SET) == -1)
goto fseek_failed;
if (write_int(out, (unsigned int)(t - sub_marker - 4)) == -1)
goto write_int_failed;
if (fseek(out, t, SEEK_SET) == -1)
goto fseek_failed;
if (avi_header.data_streams == 2) {
if (write_chars_bin(out, "LIST", 4) == -1)
goto write_chars_bin_failed;
if ((sub_marker = ftell(out)) == -1)
goto ftell_failed;
if (write_int(out, 0) == -1)
goto write_int_failed;
if (write_chars_bin(out, "strl", 4) == -1)
goto write_chars_bin_failed;
if (write_stream_header(out, &stream_header_a) == -1) {
(void)fprintf(stderr, "write_avi_header_chunk: "
"write_stream_header failed\n");
return -1;
}
if (write_stream_format_a(out, &stream_format_a) == -1) {
(void)fprintf(stderr, "write_avi_header_chunk: "
"write_stream_format_a failed\n");
return -1;
}
if ((t = ftell(out)) == -1)
goto ftell_failed;
if (fseek(out, sub_marker, SEEK_SET) == -1)
goto fseek_failed;
if (write_int(out, (unsigned int)(t - sub_marker - 4)) == -1)
goto write_int_failed;
if (fseek(out, t, SEEK_SET) == -1)
goto fseek_failed;
}
if ((t = ftell(out)) == -1)
goto ftell_failed;
if (fseek(out, marker, SEEK_SET) == -1)
goto fseek_failed;
if (write_int(out, (unsigned int)(t - marker - 4)) == -1)
goto write_int_failed;
if (fseek(out, t, SEEK_SET) == -1)
goto fseek_failed;
return 0;
ftell_failed:
perror("write_avi_header_chunk (ftell)");
return -1;
fseek_failed:
perror("write_avi_header_chunk (fseek)");
return -1;
write_int_failed:
(void)fprintf(stderr, "write_avi_header_chunk: write_int() failed\n");
return -1;
write_chars_bin_failed:
(void)fprintf(stderr, "write_avi_header_chunk: write_chars_bin() failed\n");
return -1;
}
int
gwavi_t::write_index(FILE *out, int count, unsigned int *offsets)
{
long marker, t;
unsigned int offset = 4;
if (offsets == 0)
return -1;
if (write_chars_bin(out, "idx1", 4) == -1) {
(void)fprintf(stderr, "write_index: write_chars_bin) failed\n");
return -1;
}
if ((marker = ftell(out)) == -1) {
perror("write_index (ftell)");
return -1;
}
if (write_int(out, 0) == -1)
goto write_int_failed;
for (t = 0; t < count; t++) {
if ((offsets[t] & 0x80000000) == 0)
write_chars(out, "00dc");
else {
write_chars(out, "01wb");
offsets[t] &= 0x7fffffff;
}
if (write_int(out, 0x10) == -1)
goto write_int_failed;
if (write_int(out, offset) == -1)
goto write_int_failed;
if (write_int(out, offsets[t]) == -1)
goto write_int_failed;
offset = offset + offsets[t] + 8;
}
if ((t = ftell(out)) == -1) {
perror("write_index (ftell)");
return -1;
}
if (fseek(out, marker, SEEK_SET) == -1) {
perror("write_index (fseek)");
return -1;
}
if (write_int(out, (unsigned int)(t - marker - 4)) == -1)
goto write_int_failed;
if (fseek(out, t, SEEK_SET) == -1) {
perror("write_index (fseek)");
return -1;
}
return 0;
write_int_failed:
(void)fprintf(stderr, "write_index: write_int() failed\n");
return -1;
}
/**
* Return 0 if fourcc is valid, 1 non-valid or -1 in case of errors.
*/
int
gwavi_t::check_fourcc(const char *fourcc)
{
int ret = 0;
/* list of fourccs from http://fourcc.org/codecs.php */
const char valid_fourcc[] =
"3IV1 3IV2 8BPS"
"AASC ABYR ADV1 ADVJ AEMI AFLC AFLI AJPG AMPG ANIM AP41 ASLC"
"ASV1 ASV2 ASVX AUR2 AURA AVC1 AVRN"
"BA81 BINK BLZ0 BT20 BTCV BW10 BYR1 BYR2"
"CC12 CDVC CFCC CGDI CHAM CJPG CMYK CPLA CRAM CSCD CTRX CVID"
"CWLT CXY1 CXY2 CYUV CYUY"
"D261 D263 DAVC DCL1 DCL2 DCL3 DCL4 DCL5 DIV3 DIV4 DIV5 DIVX"
"DM4V DMB1 DMB2 DMK2 DSVD DUCK DV25 DV50 DVAN DVCS DVE2 DVH1"
"DVHD DVSD DVSL DVX1 DVX2 DVX3 DX50 DXGM DXTC DXTN"
"EKQ0 ELK0 EM2V ES07 ESCP ETV1 ETV2 ETVC"
"FFV1 FLJP FMP4 FMVC FPS1 FRWA FRWD FVF1"
"GEOX GJPG GLZW GPEG GWLT"
"H260 H261 H262 H263 H264 H265 H266 H267 H268 H269"
"HDYC HFYU HMCR HMRR"
"I263 ICLB IGOR IJPG ILVC ILVR IPDV IR21 IRAW ISME"
"IV30 IV31 IV32 IV33 IV34 IV35 IV36 IV37 IV38 IV39 IV40 IV41"
"IV41 IV43 IV44 IV45 IV46 IV47 IV48 IV49 IV50"
"JBYR JPEG JPGL"
"KMVC"
"L261 L263 LBYR LCMW LCW2 LEAD LGRY LJ11 LJ22 LJ2K LJ44 LJPG"
"LMP2 LMP4 LSVC LSVM LSVX LZO1"
"M261 M263 M4CC M4S2 MC12 MCAM MJ2C MJPG MMES MP2A MP2T MP2V"
"MP42 MP43 MP4A MP4S MP4T MP4V MPEG MPG4 MPGI MR16 MRCA MRLE"
"MSVC MSZH"
"MTX1 MTX2 MTX3 MTX4 MTX5 MTX6 MTX7 MTX8 MTX9"
"MVI1 MVI2 MWV1"
"NAVI NDSC NDSM NDSP NDSS NDXC NDXH NDXP NDXS NHVU NTN1 NTN2"
"NVDS NVHS"
"NVS0 NVS1 NVS2 NVS3 NVS4 NVS5"
"NVT0 NVT1 NVT2 NVT3 NVT4 NVT5"
"PDVC PGVV PHMO PIM1 PIM2 PIMJ PIXL PJPG PVEZ PVMM PVW2"
"QPEG QPEQ"
"RGBT RLE RLE4 RLE8 RMP4 RPZA RT21 RV20 RV30 RV40 S422 SAN3"
"SDCC SEDG SFMC SMP4 SMSC SMSD SMSV SP40 SP44 SP54 SPIG SQZ2"
"STVA STVB STVC STVX STVY SV10 SVQ1 SVQ3"
"TLMS TLST TM20 TM2X TMIC TMOT TR20 TSCC TV10 TVJP TVMJ TY0N"
"TY2C TY2N"
"UCOD ULTI"
"V210 V261 V655 VCR1 VCR2 VCR3 VCR4 VCR5 VCR6 VCR7 VCR8 VCR9"
"VDCT VDOM VDTZ VGPX VIDS VIFP VIVO VIXL VLV1 VP30 VP31 VP40"
"VP50 VP60 VP61 VP62 VP70 VP80 VQC1 VQC2 VQJC VSSV VUUU VX1K"
"VX2K VXSP VYU9 VYUY"
"WBVC WHAM WINX WJPG WMV1 WMV2 WMV3 WMVA WNV1 WVC1"
"X263 X264 XLV0 XMPG XVID"
"XWV0 XWV1 XWV2 XWV3 XWV4 XWV5 XWV6 XWV7 XWV8 XWV9"
"XXAN"
"Y16 Y411 Y41P Y444 Y8 YC12 YUV8 YUV9 YUVP YUY2 YUYV YV12 YV16"
"YV92"
"ZLIB ZMBV ZPEG ZYGO ZYYY";
if (!fourcc) {
(void)fputs("fourcc cannot be NULL", stderr);
return -1;
}
if (strchr(fourcc, ' ') || !strstr(valid_fourcc, fourcc))
ret = 1;
return ret;
}

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2008-2011, Michael Kohn
* Copyright (c) 2013, Robin Hahling
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the author nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Usefull IO functions.
*/
#include <stdio.h>
#include "gwavi.h"
int
gwavi_t::write_int(FILE *out, unsigned int n)
{
unsigned char buffer[4];
buffer[0] = n;
buffer[1] = n >> 8;
buffer[2] = n >> 16;
buffer[3] = n >> 24;
if (fwrite(buffer, 1, 4, out) != 4)
return -1;
return 0;
}
int
gwavi_t::write_short(FILE *out, unsigned int n)
{
unsigned char buffer[2];
buffer[0] = n;
buffer[1] = n >> 8;
if (fwrite(buffer, 1, 2, out) != 2)
return -1;
return 0;
}
int
gwavi_t::write_chars(FILE *out, const char *s)
{
int t = 0;
while(s[t] != 0 && t < 255)
if (fputc(s[t++], out) == EOF)
return -1;
return 0;
}
int
gwavi_t::write_chars_bin(FILE *out, const char *s, int count)
{
if (fwrite(s, 1, count, out) != count)
return -1;
return 0;
}

View File

@ -0,0 +1,503 @@
/*
* Copyright (c) 2008-2011, Michael Kohn
* Copyright (c) 2013, Robin Hahling
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the author nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This is the file containing gwavi library functions.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "gwavi.h"
/**
* This is the first function you should call when using gwavi library.
* It allocates memory for a gwavi_t structure and returns it and takes care of
* initializing the AVI header with the provided information.
*
* When you're done creating your AVI file, you should call gwavi_close()
* function to free memory allocated for the gwavi_t structure and properly
* close the output file.
*
* @param filename This is the name of the AVI file which will be generated by
* this library.
* @param width Width of a frame.
* @param height Height of a frame.
* @param fourcc FourCC representing the codec of the video encoded stream. a
* FourCC is a sequence of four chars used to uniquely identify data formats.
* For more information, you can visit www.fourcc.org.
* @param fps Number of frames per second of your video. It needs to be > 0.
* @param audio This parameter is optionnal. It is used for the audio track. If
* you do not want to add an audio track to your AVI file, simply pass NULL for
* this argument.
*
* @return Structure containing required information in order to create the AVI
* file. If an error occured, NULL is returned.
*/
gwavi_t::gwavi_t(void)
{
out = NULL;
memset( &avi_header , 0, sizeof(struct gwavi_header_t) );
memset( &stream_header_v, 0, sizeof(struct gwavi_stream_header_t) );
memset( &stream_format_v, 0, sizeof(struct gwavi_stream_format_v_t) );
memset( &stream_header_a, 0, sizeof(struct gwavi_stream_header_t) );
memset( &stream_format_a, 0, sizeof(struct gwavi_stream_format_a_t) );
marker = 0;
offsets_ptr = 0;
offsets_len = 0;
offsets_start = 0;
offsets = 0;
offset_count = 0;
}
int
gwavi_t::open(const char *filename, unsigned int width, unsigned int height,
const char *fourcc, unsigned int fps, struct gwavi_audio_t *audio)
{
if (check_fourcc(fourcc) != 0)
(void)fprintf(stderr, "WARNING: given fourcc does not seem to "
"be valid: %s\n", fourcc);
if (fps < 1)
{
return -1;
}
if ((out = fopen(filename, "wb+")) == NULL)
{
perror("gwavi_open: failed to open file for writing");
return -1;
}
/* set avi header */
avi_header.time_delay= 1000000 / fps;
avi_header.data_rate = width * height * 3;
avi_header.flags = 0x10;
if (audio)
avi_header.data_streams = 2;
else
avi_header.data_streams = 1;
/* this field gets updated when calling gwavi_close() */
avi_header.number_of_frames = 0;
avi_header.width = width;
avi_header.height = height;
avi_header.buffer_size = (width * height * 3);
/* set stream header */
(void)strcpy(stream_header_v.data_type, "vids");
(void)memcpy(stream_header_v.codec, fourcc, 4);
stream_header_v.time_scale = 1;
stream_header_v.data_rate = fps;
stream_header_v.buffer_size = (width * height * 3);
stream_header_v.data_length = 0;
/* set stream format */
stream_format_v.header_size = 40;
stream_format_v.width = width;
stream_format_v.height = height;
stream_format_v.num_planes = 1;
stream_format_v.bits_per_pixel = 24;
stream_format_v.compression_type =
((unsigned int)fourcc[3] << 24) +
((unsigned int)fourcc[2] << 16) +
((unsigned int)fourcc[1] << 8) +
((unsigned int)fourcc[0]);
stream_format_v.image_size = width * height * 3;
stream_format_v.colors_used = 0;
stream_format_v.colors_important = 0;
stream_format_v.palette = 0;
stream_format_v.palette_count = 0;
if (audio)
{
/* set stream header */
memcpy(stream_header_a.data_type, "auds", 4);
stream_header_a.codec[0] = 1;
stream_header_a.codec[1] = 0;
stream_header_a.codec[2] = 0;
stream_header_a.codec[3] = 0;
stream_header_a.time_scale = 1;
stream_header_a.data_rate = audio->samples_per_second;
stream_header_a.buffer_size =
audio->channels * (audio->bits / 8) * audio->samples_per_second;
/* when set to -1, drivers use default quality value */
stream_header_a.audio_quality = -1;
stream_header_a.sample_size =
(audio->bits / 8) * audio->channels;
/* set stream format */
stream_format_a.format_type = 1;
stream_format_a.channels = audio->channels;
stream_format_a.sample_rate = audio->samples_per_second;
stream_format_a.bytes_per_second =
audio->channels * (audio->bits / 8) * audio->samples_per_second;
stream_format_a.block_align =
audio->channels * (audio->bits / 8);
stream_format_a.bits_per_sample = audio->bits;
stream_format_a.size = 0;
}
if (write_chars_bin(out, "RIFF", 4) == -1)
goto write_chars_bin_failed;
if (write_int(out, 0) == -1) {
(void)fprintf(stderr, "gwavi_info: write_int() failed\n");
return -1;
}
if (write_chars_bin(out, "AVI ", 4) == -1)
goto write_chars_bin_failed;
if (write_avi_header_chunk() == -1) {
(void)fprintf(stderr, "gwavi_info: write_avi_header_chunk "
"failed\n");
return -1;
}
if (write_chars_bin(out, "LIST", 4) == -1)
goto write_chars_bin_failed;
if ((marker = ftell(out)) == -1) {
perror("gwavi_info (ftell)");
return -1;
}
if (write_int(out, 0) == -1) {
(void)fprintf(stderr, "gwavi_info: write_int() failed\n");
return -1;
}
if (write_chars_bin(out, "movi", 4) == -1)
goto write_chars_bin_failed;
offsets_len = 1024;
if ((offsets = (unsigned int *)malloc((size_t)offsets_len *
sizeof(unsigned int)))
== NULL) {
(void)fprintf(stderr, "gwavi_info: could not allocate memory "
"for gwavi offsets table\n");
return -1;
}
offsets_ptr = 0;
return 0;
write_chars_bin_failed:
(void)fprintf(stderr, "gwavi_open: write_chars_bin() failed\n");
return -1;
}
/**
* This function allows you to add an encoded video frame to the AVI file.
*
* @param gwavi Main gwavi structure initialized with gwavi_open()-
* @param buffer Video buffer size.
* @param len Video buffer length.
*
* @return 0 on success, -1 on error.
*/
int
gwavi_t::add_frame( unsigned char *buffer, size_t len)
{
size_t maxi_pad; /* if your frame is raggin, give it some paddin' */
size_t t;
if ( !buffer) {
(void)fputs("gwavi and/or buffer argument cannot be NULL",
stderr);
return -1;
}
if (len < 256)
(void)fprintf(stderr, "WARNING: specified buffer len seems "
"rather small: %d. Are you sure about this?\n",
(int)len);
offset_count++;
stream_header_v.data_length++;
maxi_pad = len % 4;
if (maxi_pad > 0)
maxi_pad = 4 - maxi_pad;
if (offset_count >= offsets_len) {
offsets_len += 1024;
offsets = (unsigned int *)realloc(offsets,
(size_t)offsets_len *
sizeof(unsigned int));
}
offsets[offsets_ptr++] = (unsigned int)(len + maxi_pad);
if (write_chars_bin(out, "00dc", 4) == -1) {
(void)fprintf(stderr, "gwavi_add_frame: write_chars_bin() "
"failed\n");
return -1;
}
if (write_int(out, (unsigned int)(len + maxi_pad)) == -1) {
(void)fprintf(stderr, "gwavi_add_frame: write_int() failed\n");
return -1;
}
if ((t = fwrite(buffer, 1, len, out)) != len) {
(void)fprintf(stderr, "gwavi_add_frame: fwrite() failed\n");
return -1;
}
for (t = 0; t < maxi_pad; t++)
{
if (fputc(0, out) == EOF) {
(void)fprintf(stderr, "gwavi_add_frame: fputc() failed\n");
return -1;
}
}
return 0;
}
/**
* This function allows you to add the audio track to your AVI file.
*
* @param gwavi Main gwavi structure initialized with gwavi_open()-
* @param buffer Audio buffer size.
* @param len Audio buffer length.
*
* @return 0 on success, -1 on error.
*/
int
gwavi_t::add_audio( unsigned char *buffer, size_t len)
{
size_t maxi_pad; /* in case audio bleeds over the 4 byte boundary */
size_t t;
if ( !buffer) {
(void)fputs("gwavi and/or buffer argument cannot be NULL",
stderr);
return -1;
}
offset_count++;
maxi_pad = len % 4;
if (maxi_pad > 0)
maxi_pad = 4 - maxi_pad;
if (offset_count >= offsets_len) {
offsets_len += 1024;
offsets = (unsigned int *)realloc(offsets,
(size_t)offsets_len *
sizeof(unsigned int));
}
offsets[offsets_ptr++] =
(unsigned int)((len + maxi_pad) | 0x80000000);
if (write_chars_bin(out,"01wb",4) == -1) {
(void)fprintf(stderr, "gwavi_add_audio: write_chars_bin() "
"failed\n");
return -1;
}
if (write_int(out,(unsigned int)(len + maxi_pad)) == -1) {
(void)fprintf(stderr, "gwavi_add_audio: write_int() failed\n");
return -1;
}
if ((t = fwrite(buffer, 1, len, out)) != len ) {
(void)fprintf(stderr, "gwavi_add_audio: fwrite() failed\n");
return -1;
}
for (t = 0; t < maxi_pad; t++)
if (fputc(0,out) == EOF) {
(void)fprintf(stderr, "gwavi_add_audio: fputc() failed\n");
return -1;
}
stream_header_a.data_length += (unsigned int)(len + maxi_pad);
return 0;
}
/**
* This function should be called when the program is done adding video and/or
* audio frames to the AVI file. It frees memory allocated for gwavi_open() for
* the main gwavi_t structure. It also properly closes the output file.
*
* @param gwavi Main gwavi structure initialized with gwavi_open()-
*
* @return 0 on success, -1 on error.
*/
int
gwavi_t::close(void)
{
long t;
if ((t = ftell(out)) == -1)
goto ftell_failed;
if (fseek(out, marker, SEEK_SET) == -1)
goto fseek_failed;
if (write_int(out, (unsigned int)(t - marker - 4)) == -1) {
(void)fprintf(stderr, "gwavi_close: write_int() failed\n");
return -1;
}
if (fseek(out,t,SEEK_SET) == -1)
goto fseek_failed;
if (write_index(out, offset_count, offsets) == -1) {
(void)fprintf(stderr, "gwavi_close: write_index() failed\n");
return -1;
}
free(offsets);
/* reset some avi header fields */
avi_header.number_of_frames = stream_header_v.data_length;
if ((t = ftell(out)) == -1)
goto ftell_failed;
if (fseek(out, 12, SEEK_SET) == -1)
goto fseek_failed;
if (write_avi_header_chunk() == -1) {
(void)fprintf(stderr, "gwavi_close: write_avi_header_chunk() "
"failed\n");
return -1;
}
if (fseek(out, t, SEEK_SET) == -1)
goto fseek_failed;
if ((t = ftell(out)) == -1)
goto ftell_failed;
if (fseek(out, 4, SEEK_SET) == -1)
goto fseek_failed;
if (write_int(out, (unsigned int)(t - 8)) == -1) {
(void)fprintf(stderr, "gwavi_close: write_int() failed\n");
return -1;
}
if (fseek(out, t, SEEK_SET) == -1)
goto fseek_failed;
if (stream_format_v.palette != 0)
free(stream_format_v.palette);
if (fclose(out) == EOF) {
perror("gwavi_close (fclose)");
return -1;
}
return 0;
ftell_failed:
perror("gwavi_close: (ftell)");
return -1;
fseek_failed:
perror("gwavi_close (fseek)");
return -1;
}
/**
* This function allows you to reset the framerate. In a standard use case, you
* should not need to call it. However, if you need to, you can call it to reset
* the framerate after you are done adding frames to your AVI file and before
* you call gwavi_close().
*
* @param gwavi Main gwavi structure initialized with gwavi_open()-
* @param fps Number of frames per second of your video.
*
* @return 0 on success, -1 on error.
*/
int
gwavi_t::set_framerate(unsigned int fps)
{
stream_header_v.data_rate = fps;
avi_header.time_delay = (10000000 / fps);
return 0;
}
/**
* This function allows you to reset the video codec. In a standard use case,
* you should not need to call it. However, if you need to, you can call it to
* reset the video codec after you are done adding frames to your AVI file and
* before you call gwavi_close().
*
* @param gwavi Main gwavi structure initialized with gwavi_open()-
* @param fourcc FourCC representing the codec of the video encoded stream. a
*
* @return 0 on success, -1 on error.
*/
int
gwavi_t::set_codec( const char *fourcc)
{
if (check_fourcc(fourcc) != 0)
(void)fprintf(stderr, "WARNING: given fourcc does not seem to "
"be valid: %s\n", fourcc);
memcpy(stream_header_v.codec, fourcc, 4);
stream_format_v.compression_type =
((unsigned int)fourcc[3] << 24) +
((unsigned int)fourcc[2] << 16) +
((unsigned int)fourcc[1] << 8) +
((unsigned int)fourcc[0]);
return 0;
}
/**
* This function allows you to reset the video size. In a standard use case, you
* should not need to call it. However, if you need to, you can call it to reset
* the video height and width set in the AVI file after you are done adding
* frames to your AVI file and before you call gwavi_close().
*
* @param gwavi Main gwavi structure initialized with gwavi_open()-
* @param width Width of a frame.
* @param height Height of a frame.
*
* @return 0 on success, -1 on error.
*/
int
gwavi_t::set_size( unsigned int width, unsigned int height)
{
unsigned int size = (width * height * 3);
avi_header.data_rate = size;
avi_header.width = width;
avi_header.height = height;
avi_header.buffer_size = size;
stream_header_v.buffer_size = size;
stream_format_v.width = width;
stream_format_v.height = height;
stream_format_v.image_size = size;
return 0;
}

168
src/drivers/Qt/avi/gwavi.h Normal file
View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 2008-2011, Michael Kohn
* Copyright (c) 2013, Robin Hahling
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the author nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef H_GWAVI
#define H_GWAVI
#include <stdint.h> /* for size_t */
#include <stddef.h> /* for size_t */
/* structures */
struct gwavi_header_t
{
unsigned int time_delay; /* dwMicroSecPerFrame */
unsigned int data_rate; /* dwMaxBytesPerSec */
unsigned int reserved;
unsigned int flags; /* dwFlags */
unsigned int number_of_frames; /* dwTotalFrames */
unsigned int initial_frames; /* dwInitialFrames */
unsigned int data_streams; /* dwStreams */
unsigned int buffer_size; /* dwSuggestedBufferSize */
unsigned int width; /* dwWidth */
unsigned int height; /* dwHeight */
unsigned int time_scale;
unsigned int playback_data_rate;
unsigned int starting_time;
unsigned int data_length;
};
struct gwavi_stream_header_t
{
char data_type[5]; /* fccType */
char codec[5]; /* fccHandler */
unsigned int flags; /* dwFlags */
unsigned int priority;
unsigned int initial_frames;/* dwInitialFrames */
unsigned int time_scale; /* dwScale */
unsigned int data_rate; /* dwRate */
unsigned int start_time; /* dwStart */
unsigned int data_length; /* dwLength */
unsigned int buffer_size; /* dwSuggestedBufferSize */
unsigned int video_quality; /* dwQuality */
/**
* Value between 0-10000. If set to -1, drivers use default quality
* value.
*/
int audio_quality;
unsigned int sample_size; /* dwSampleSize */
};
struct gwavi_stream_format_v_t
{
unsigned int header_size;
unsigned int width;
unsigned int height;
unsigned short int num_planes;
unsigned short int bits_per_pixel;
unsigned int compression_type;
unsigned int image_size;
unsigned int x_pels_per_meter;
unsigned int y_pels_per_meter;
unsigned int colors_used;
unsigned int colors_important;
unsigned int *palette;
unsigned int palette_count;
};
struct gwavi_stream_format_a_t
{
unsigned short format_type;
unsigned int channels;
unsigned int sample_rate;
unsigned int bytes_per_second;
unsigned int block_align;
unsigned int bits_per_sample;
unsigned short size;
};
struct gwavi_audio_t
{
unsigned int channels;
unsigned int bits;
unsigned int samples_per_second;
};
class gwavi_t
{
public:
gwavi_t(void);
int open(const char *filename, unsigned int width,
unsigned int height, const char *fourcc, unsigned int fps,
struct gwavi_audio_t *audio);
int close(void);
int add_frame( unsigned char *buffer, size_t len);
int add_audio( unsigned char *buffer, size_t len);
int set_codec(const char *fourcc);
int set_size( unsigned int width, unsigned int height);
int set_framerate(unsigned int fps);
private:
FILE *out;
struct gwavi_header_t avi_header;
struct gwavi_stream_header_t stream_header_v;
struct gwavi_stream_format_v_t stream_format_v;
struct gwavi_stream_header_t stream_header_a;
struct gwavi_stream_format_a_t stream_format_a;
long marker;
int offsets_ptr;
int offsets_len;
long offsets_start;
unsigned int *offsets;
int offset_count;
// helper functions
int write_avi_header(FILE *out, struct gwavi_header_t *avi_header);
int write_stream_header(FILE *out,
struct gwavi_stream_header_t *stream_header);
int write_stream_format_v(FILE *out,
struct gwavi_stream_format_v_t *stream_format_v);
int write_stream_format_a(FILE *out,
struct gwavi_stream_format_a_t *stream_format_a);
int write_avi_header_chunk(void);
int write_index(FILE *out, int count, unsigned int *offsets);
int check_fourcc(const char *fourcc);
int write_int(FILE *out, unsigned int n);
int write_short(FILE *out, unsigned int n);
int write_chars(FILE *out, const char *s);
int write_chars_bin(FILE *out, const char *s, int count);
};
#endif /* ndef H_GWAVI */

View File

@ -939,8 +939,8 @@ int fceuWrapperMemoryCleanup(void)
*/
void
FCEUD_Update(uint8 *XBuf,
int32 *Buffer,
int Count)
int32 *Buffer,
int Count)
{
int blitDone = 0;
//extern int FCEUDnetplay;

View File

@ -34,6 +34,7 @@
#include "common/configSys.h"
#include "Qt/sdl-video.h"
#include "Qt/AviRecord.h"
#include "Qt/fceuWrapper.h"
#ifdef CREATE_AVI
@ -478,7 +479,7 @@ BlitScreen(uint8 *XBuf)
}
nes_shm->blitUpdated = 1;
//guiPixelBufferReDraw();
aviRecordAddFrame();
#ifdef CREATE_AVI
{ int fps = FCEUI_GetDesiredFPS();