Added functionality to properly encode keyframes into AVI file for Qt GUI.
This commit is contained in:
parent
15c4a729b9
commit
8d3a27e1a5
|
@ -317,11 +317,13 @@ namespace VFW
|
|||
{
|
||||
static bool cmpSet = false;
|
||||
static COMPVARS cmpvars;
|
||||
static DWORD dwFlags = 0;
|
||||
//static DWORD dwFlags = 0;
|
||||
static BITMAPINFOHEADER bmapIn;
|
||||
static LPBITMAPINFOHEADER bmapOut = NULL;
|
||||
static DWORD frameNum = 0;
|
||||
static DWORD dwQuality = 0;
|
||||
static DWORD icErrCount = 0;
|
||||
static DWORD flagsOut = 0;
|
||||
static LPVOID outBuf = NULL;
|
||||
|
||||
static int chooseConfig(int width, int height)
|
||||
|
@ -371,7 +373,9 @@ static int chooseConfig(int width, int height)
|
|||
static int init( int width, int height )
|
||||
{
|
||||
void *h;
|
||||
ICINFO icInfo;
|
||||
DWORD dwFormatSize, dwCompressBufferSize;
|
||||
bool qualitySupported = false;
|
||||
|
||||
memset( &bmapIn, 0, sizeof(bmapIn));
|
||||
bmapIn.biSize = sizeof(BITMAPINFOHEADER);
|
||||
|
@ -384,6 +388,45 @@ static int init( int width, int height )
|
|||
|
||||
dwFormatSize = ICCompressGetFormatSize( cmpvars.hic, &bmapIn );
|
||||
|
||||
if ( ICGetInfo( cmpvars.hic, &icInfo, sizeof(icInfo) ) )
|
||||
{
|
||||
printf("Name : %ls\n" , icInfo.szName );
|
||||
printf("Flags: 0x%08X", icInfo.dwFlags );
|
||||
|
||||
if ( icInfo.dwFlags & VIDCF_CRUNCH )
|
||||
{
|
||||
printf(" VIDCF_CRUNCH ");
|
||||
}
|
||||
|
||||
if ( icInfo.dwFlags & VIDCF_TEMPORAL )
|
||||
{
|
||||
printf(" VIDCF_TEMPORAL ");
|
||||
}
|
||||
|
||||
if ( icInfo.dwFlags & VIDCF_TEMPORAL )
|
||||
{
|
||||
printf(" VIDCF_TEMPORAL ");
|
||||
}
|
||||
|
||||
if ( icInfo.dwFlags & VIDCF_QUALITY )
|
||||
{
|
||||
printf(" VIDCF_QUALITY ");
|
||||
qualitySupported = true;
|
||||
}
|
||||
|
||||
if ( icInfo.dwFlags & VIDCF_FASTTEMPORALC )
|
||||
{
|
||||
printf(" VIDCF_FASTTEMPORALC ");
|
||||
}
|
||||
|
||||
if ( icInfo.dwFlags & VIDCF_FASTTEMPORALD )
|
||||
{
|
||||
printf(" VIDCF_FASTTEMPORALD ");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
|
||||
//printf("Format Size:%i %zi\n", dwFormatSize, sizeof(BITMAPINFOHEADER));
|
||||
|
||||
h = GlobalAlloc(GHND, dwFormatSize);
|
||||
|
@ -402,12 +445,23 @@ static int init( int width, int height )
|
|||
outBuf = (LPVOID)GlobalLock(h);
|
||||
|
||||
//dwQuality = ICGetDefaultQuality( cmpvars.hic );
|
||||
dwQuality = cmpvars.lQ;
|
||||
if ( qualitySupported )
|
||||
{
|
||||
dwQuality = cmpvars.lQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwQuality = 0;
|
||||
}
|
||||
|
||||
//printf("Quality Setting: %i\n", dwQuality );
|
||||
|
||||
ICCompressBegin( cmpvars.hic, &bmapIn, bmapOut );
|
||||
|
||||
frameNum = 0;
|
||||
flagsOut = 0;
|
||||
icErrCount = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -429,12 +483,17 @@ static int close(void)
|
|||
static int encode_frame( unsigned char *inBuf, int width, int height )
|
||||
{
|
||||
DWORD ret;
|
||||
DWORD flagsOut = 0, reserved = 0;
|
||||
DWORD reserved = 0;
|
||||
int bytesWritten = 0;
|
||||
|
||||
if ( icErrCount > 10 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ICCompress(
|
||||
cmpvars.hic,
|
||||
dwFlags,
|
||||
0,
|
||||
bmapOut,
|
||||
outBuf,
|
||||
&bmapIn,
|
||||
|
@ -448,9 +507,15 @@ static int encode_frame( unsigned char *inBuf, int width, int height )
|
|||
|
||||
if ( ret == ICERR_OK )
|
||||
{
|
||||
//printf("Compressing Frame:%i Size:%i\n", frameNum, bmapOut->biSizeImage);
|
||||
//printf("Compressing Frame:%i Size:%i Flags:%08X\n",
|
||||
// frameNum, bmapOut->biSizeImage, flagsOut );
|
||||
bytesWritten = bmapOut->biSizeImage;
|
||||
gwavi->add_frame( (unsigned char*)outBuf, bytesWritten );
|
||||
gwavi->add_frame( (unsigned char*)outBuf, bytesWritten, flagsOut );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Compression Error Frame:%i\n", frameNum);
|
||||
icErrCount++;
|
||||
}
|
||||
|
||||
return bytesWritten;
|
||||
|
|
|
@ -465,7 +465,7 @@ gwavi_t::write_index(FILE *fp)
|
|||
long marker, t;
|
||||
unsigned int offset = 4;
|
||||
unsigned int r;
|
||||
char fourcc[8];
|
||||
//char fourcc[8];
|
||||
|
||||
if (offsets.size() == 0 )
|
||||
{
|
||||
|
@ -487,7 +487,7 @@ gwavi_t::write_index(FILE *fp)
|
|||
{
|
||||
//peak_chunk( fp, offset, fourcc, &r );
|
||||
|
||||
if ((offsets[i] & 0x80000000) == 0)
|
||||
if ( offsets[i].type == 0)
|
||||
{
|
||||
write_chars(fp, "00dc");
|
||||
//printf("Index: %u \n", offset );
|
||||
|
@ -495,23 +495,31 @@ gwavi_t::write_index(FILE *fp)
|
|||
else
|
||||
{
|
||||
write_chars(fp, "01wb");
|
||||
offsets[i] &= 0x7fffffff;
|
||||
}
|
||||
if (write_int(fp, 0x10) == -1)
|
||||
goto write_int_failed;
|
||||
|
||||
if ( offsets[i].keyFrame )
|
||||
{
|
||||
if (write_int(fp, 0x10) == -1)
|
||||
goto write_int_failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (write_int(fp, 0x00) == -1)
|
||||
goto write_int_failed;
|
||||
}
|
||||
if (write_int(fp, offset) == -1)
|
||||
goto write_int_failed;
|
||||
if (write_int(fp, offsets[i]) == -1)
|
||||
if (write_int(fp, offsets[i].len) == -1)
|
||||
goto write_int_failed;
|
||||
|
||||
r = offsets[i] % WORD_SIZE;
|
||||
r = offsets[i].len % WORD_SIZE;
|
||||
|
||||
if ( r > 0 )
|
||||
{
|
||||
r = WORD_SIZE - r;
|
||||
}
|
||||
|
||||
offset = offset + offsets[i] + 8 + r;
|
||||
offset = offset + offsets[i].len + 8 + r;
|
||||
}
|
||||
|
||||
if ((t = ftell(fp)) == -1) {
|
||||
|
|
|
@ -279,10 +279,10 @@ write_chars_bin_failed:
|
|||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
gwavi_t::add_frame( unsigned char *buffer, size_t len)
|
||||
gwavi_t::add_frame( unsigned char *buffer, size_t len, unsigned int flags)
|
||||
{
|
||||
size_t maxi_pad; /* if your frame is raggin, give it some paddin' */
|
||||
size_t t;
|
||||
size_t t, maxi_pad; /* if your frame is raggin, give it some paddin' */
|
||||
gwavi_index_rec_t idx;
|
||||
|
||||
if ( !buffer) {
|
||||
(void)fputs("gwavi and/or buffer argument cannot be NULL",
|
||||
|
@ -306,7 +306,11 @@ gwavi_t::add_frame( unsigned char *buffer, size_t len)
|
|||
|
||||
//printf("Frame Offset: %li\n", ftell(out) - movi_fpos );
|
||||
|
||||
offsets.push_back( (unsigned int)(len) );
|
||||
idx.len = len;
|
||||
idx.type = 0;
|
||||
idx.keyFrame = (flags & IF_KEYFRAME) ? 1 : 0;
|
||||
|
||||
offsets.push_back( idx );
|
||||
|
||||
if (write_chars_bin(out, "00dc", 4) == -1) {
|
||||
(void)fprintf(stderr, "gwavi_add_frame: write_chars_bin() "
|
||||
|
@ -346,8 +350,8 @@ gwavi_t::add_frame( unsigned char *buffer, size_t len)
|
|||
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;
|
||||
size_t t, maxi_pad; /* in case audio bleeds over the 4 byte boundary */
|
||||
gwavi_index_rec_t idx;
|
||||
|
||||
if ( !buffer)
|
||||
{
|
||||
|
@ -362,7 +366,11 @@ gwavi_t::add_audio( unsigned char *buffer, size_t len)
|
|||
maxi_pad = WORD_SIZE - maxi_pad;
|
||||
}
|
||||
|
||||
offsets.push_back( (unsigned int)((len) | 0x80000000) );
|
||||
idx.len = len;
|
||||
idx.type = 1;
|
||||
idx.keyFrame = 0;
|
||||
|
||||
offsets.push_back( idx );
|
||||
|
||||
if (write_chars_bin(out,"01wb",4) == -1)
|
||||
{
|
||||
|
|
|
@ -140,11 +140,24 @@ struct gwavi_audio_t
|
|||
unsigned int samples_per_second;
|
||||
};
|
||||
|
||||
struct gwavi_index_rec_t
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned char type;
|
||||
unsigned char keyFrame;
|
||||
unsigned char resv[2];
|
||||
};
|
||||
|
||||
#pragma pack( pop )
|
||||
|
||||
class gwavi_t
|
||||
{
|
||||
public:
|
||||
static const int WORD_SIZE = 2;
|
||||
static const unsigned int IF_LIST = 0x00000001;
|
||||
static const unsigned int IF_KEYFRAME = 0x00000010;
|
||||
static const unsigned int IF_NO_TIME = 0x00000100;
|
||||
|
||||
gwavi_t(void);
|
||||
~gwavi_t(void);
|
||||
|
||||
|
@ -154,7 +167,7 @@ class gwavi_t
|
|||
|
||||
int close(void);
|
||||
|
||||
int add_frame( unsigned char *buffer, size_t len);
|
||||
int add_frame( unsigned char *buffer, size_t len, unsigned int flags = IF_KEYFRAME);
|
||||
|
||||
int add_audio( unsigned char *buffer, size_t len);
|
||||
|
||||
|
@ -168,8 +181,6 @@ class gwavi_t
|
|||
|
||||
int printHeaders(void);
|
||||
|
||||
static const int WORD_SIZE = 2;
|
||||
|
||||
private:
|
||||
FILE *in;
|
||||
FILE *out;
|
||||
|
@ -179,7 +190,7 @@ class gwavi_t
|
|||
struct gwavi_stream_header_t stream_header_a;
|
||||
struct gwavi_stream_format_a_t stream_format_a;
|
||||
long marker;
|
||||
std::vector <unsigned int> offsets;
|
||||
std::vector <gwavi_index_rec_t> offsets;
|
||||
long movi_fpos;
|
||||
int bits_per_pixel;
|
||||
char fourcc[8];
|
||||
|
|
Loading…
Reference in New Issue