From fd11108206c792ec664944cc00b668f932674b0a Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 17 Feb 2020 16:20:07 +0000 Subject: [PATCH 1/3] Enhance capturing to handle unchanged screens more efficiently(jmarsh) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4329 --- include/hardware.h | 1 + src/gui/render.cpp | 1 + src/hardware/hardware.cpp | 97 +++++++++++++++++++++------------------ 3 files changed, 55 insertions(+), 44 deletions(-) diff --git a/include/hardware.h b/include/hardware.h index a2e86ba0..0f5093ed 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -48,6 +48,7 @@ FILE * OpenCaptureFile(const char * type,const char * ext); void CAPTURE_AddWave(Bit32u freq, Bitu len, Bit16s * data); #define CAPTURE_FLAG_DBLW 0x1 #define CAPTURE_FLAG_DBLH 0x2 +#define CAPTURE_FLAG_DUPLICATE 0x4 void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, float fps, const Bit8u * data, const Bit8u * pal); void CAPTURE_AddMidi(bool sysex, Bitu len, Bit8u * data); diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 40d823bd..51c321cc 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -216,6 +216,7 @@ void RENDER_EndUpdate( bool abort ) { if (render.src.dblw) flags|=CAPTURE_FLAG_DBLW; if (render.src.dblh) flags|=CAPTURE_FLAG_DBLH; } + if (render.scale.outWrite==NULL) flags|=CAPTURE_FLAG_DUPLICATE; float fps = render.src.fps; pitch = render.scale.cachePitch; if (render.frameskip.max) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index c8281001..62c06446 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -291,7 +291,7 @@ private: bool AddChunk(const AVIChunk &ck, const AVIIndexEntry &entry, const void *data, size_t length) { long pos = ftell(handle); // in case writing fails if (fwrite(&ck,sizeof(ck),1,handle)==1 && \ - fwrite(data,length,1,handle)==1) + fwrite(data,1,length,handle)==length) { if (length&1) { // chunks must be aligned to 2-bytes fseek(handle,1,SEEK_CUR); @@ -446,6 +446,7 @@ static struct { float fps; int bufSize; void *buf; + int gop; } video; #endif } capture; @@ -749,56 +750,64 @@ void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, capture.video.height = height; capture.video.bpp = bpp; capture.video.fps = fps; + capture.video.gop = 0; + flags &= ~CAPTURE_FLAG_DUPLICATE; } - int codecFlags; - if (capture.video.avi_out->frames % 300 == 0) - codecFlags = 1; - else codecFlags = 0; - if (!capture.video.codec->PrepareCompressFrame( codecFlags, format, (char *)pal, capture.video.buf, capture.video.bufSize)) - goto skip_video; + int codecFlags,written; + codecFlags = 0; + if (flags & CAPTURE_FLAG_DUPLICATE) written = 0; + else { + if (capture.video.gop >= 300) + capture.video.gop = 0; + if (capture.video.gop==0) + codecFlags = 1; + if (!capture.video.codec->PrepareCompressFrame( codecFlags, format, (char *)pal, capture.video.buf, capture.video.bufSize)) + goto skip_video; - for (i=0;i> 1)*pitch); - else - srcLine=(data+(i >> 0)*pitch); - if (flags & CAPTURE_FLAG_DBLW) { - Bitu x; - Bitu countWidth = width >> 1; - switch ( bpp) { - case 8: - for (x=0;x> 1)*pitch); + else + srcLine=(data+(i >> 0)*pitch); + if (flags & CAPTURE_FLAG_DBLW) { + Bitu x; + Bitu countWidth = width >> 1; + switch ( bpp) { + case 8: + for (x=0;xCompressLines(2, rowPointer); + i++; + } else + capture.video.codec->CompressLines(1, &srcLine); } - if (flags & CAPTURE_FLAG_DBLH) { - const void *rowPointer[2]; - rowPointer[0]=rowPointer[1]=srcLine; - capture.video.codec->CompressLines(2, rowPointer); - i++; - } else - capture.video.codec->CompressLines(1, &srcLine); + written = capture.video.codec->FinishCompressFrame(); + if (written < 0) + goto skip_video; } - int written = capture.video.codec->FinishCompressFrame(); - if (written < 0) - goto skip_video; if (capture.video.avi_out->AddVideo(capture.video.buf, written, codecFlags & 1 ? AVII_KEYFRAME : 0)) { // LOG_MSG("Frame %d video %d audio %d",capture.video.avi_out->frames, written, capture.video.audioused *4 ); + capture.video.gop++; if (!capture.video.audioused) return; Bitu samples = capture.video.audioused; capture.video.audioused = 0; From 57bf045cc84de2f12dbea071fe8e9cba89f9fe31 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 22 Feb 2020 12:06:40 +0000 Subject: [PATCH 2/3] some big endian improvents and drive_fat fixes. (jmarsh) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4330 --- include/mem.h | 43 +++++++++++++++++++------- src/dos/drive_fat.cpp | 70 ++++++++++++++++++++++++++----------------- 2 files changed, 75 insertions(+), 38 deletions(-) diff --git a/include/mem.h b/include/mem.h index 99b082e8..7393b778 100644 --- a/include/mem.h +++ b/include/mem.h @@ -57,20 +57,39 @@ MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where); Working on big or little endian machines */ -#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) - static INLINE Bit8u host_readb(HostPt off) { return off[0]; } + +static INLINE void host_writeb(HostPt off,Bit8u val) { + off[0]=val; +} + +// use __builtin_bswap* for gcc >= 4.3 +#if defined(WORDS_BIGENDIAN) && defined(__GNUC__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + +static INLINE Bit16u host_readw(HostPt off) { + return __builtin_bswap16(*(Bit16u *)off); +} +static INLINE Bit32u host_readd(HostPt off) { + return __builtin_bswap32(*(Bit32u *)off); +} +static INLINE void host_writew(HostPt off, Bit16u val) { + *(Bit16u *)off = __builtin_bswap16(val); +} +static INLINE void host_writed(HostPt off, Bit32u val) { + *(Bit32u *)off = __builtin_bswap32(val); +} + +#elif defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) + static INLINE Bit16u host_readw(HostPt off) { return off[0] | (off[1] << 8); } static INLINE Bit32u host_readd(HostPt off) { return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24); } -static INLINE void host_writeb(HostPt off,Bit8u val) { - off[0]=val; -} static INLINE void host_writew(HostPt off,Bit16u val) { off[0]=(Bit8u)(val); off[1]=(Bit8u)(val >> 8); @@ -84,18 +103,12 @@ static INLINE void host_writed(HostPt off,Bit32u val) { #else -static INLINE Bit8u host_readb(HostPt off) { - return *(Bit8u *)off; -} static INLINE Bit16u host_readw(HostPt off) { return *(Bit16u *)off; } static INLINE Bit32u host_readd(HostPt off) { return *(Bit32u *)off; } -static INLINE void host_writeb(HostPt off,Bit8u val) { - *(Bit8u *)(off)=val; -} static INLINE void host_writew(HostPt off,Bit16u val) { *(Bit16u *)(off)=val; } @@ -118,6 +131,14 @@ static INLINE void var_write(Bit32u * var, Bit32u val) { host_writed((HostPt)var, val); } +static INLINE Bit16u var_read(Bit16u * var) { + return host_readw((HostPt)var); +} + +static INLINE Bit32u var_read(Bit32u * var) { + return host_readd((HostPt)var); +} + /* The Folowing six functions are slower but they recognize the paged memory system */ Bit8u mem_readb(PhysPt pt); diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index e75b47c1..d6517039 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -223,20 +223,12 @@ bool fatFile::Write(Bit8u * data, Bit16u *size) { if(loadedSector) myDrive->writeSector(currentSector, sectorBuffer); currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); - if(currentSector == 0) { - /* EOC reached before EOF - try to increase file allocation */ - myDrive->appendCluster(firstCluster); - /* Try getting sector again */ - currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); - if(currentSector == 0) { - /* No can do. lets give up and go home. We must be out of room */ - loadedSector = false; - goto finalizeWrite; - } + if(currentSector == 0) loadedSector = false; + else { + curSectOff = 0; + myDrive->readSector(currentSector, sectorBuffer); + loadedSector = true; } - curSectOff = 0; - myDrive->readSector(currentSector, sectorBuffer); - loadedSector = true; } --sizedec; } @@ -333,7 +325,7 @@ Bit32u fatDrive::getClusterValue(Bit32u clustNum) { switch(fattype) { case FAT12: - clustValue = *((Bit16u *)&fatSectBuffer[fatentoff]); + clustValue = var_read((Bit16u *)&fatSectBuffer[fatentoff]); if(clustNum & 0x1) { clustValue >>= 4; } else { @@ -341,10 +333,10 @@ Bit32u fatDrive::getClusterValue(Bit32u clustNum) { } break; case FAT16: - clustValue = *((Bit16u *)&fatSectBuffer[fatentoff]); + clustValue = var_read((Bit16u *)&fatSectBuffer[fatentoff]); break; case FAT32: - clustValue = *((Bit32u *)&fatSectBuffer[fatentoff]); + clustValue = var_read((Bit32u *)&fatSectBuffer[fatentoff]); break; } @@ -380,7 +372,7 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { switch(fattype) { case FAT12: { - Bit16u tmpValue = *((Bit16u *)&fatSectBuffer[fatentoff]); + Bit16u tmpValue = var_read((Bit16u *)&fatSectBuffer[fatentoff]); if(clustNum & 0x1) { clustValue &= 0xfff; clustValue <<= 4; @@ -392,14 +384,14 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { tmpValue &= 0xf000; tmpValue |= (Bit16u)clustValue; } - *((Bit16u *)&fatSectBuffer[fatentoff]) = tmpValue; + var_write((Bit16u *)&fatSectBuffer[fatentoff], tmpValue); break; } case FAT16: - *((Bit16u *)&fatSectBuffer[fatentoff]) = (Bit16u)clustValue; + var_write((Bit16u *)&fatSectBuffer[fatentoff], (Bit16u)clustValue); break; case FAT32: - *((Bit32u *)&fatSectBuffer[fatentoff]) = clustValue; + var_write((Bit32u *)&fatSectBuffer[fatentoff], clustValue); break; } for(int fc=0;fcRead_AbsoluteSector(0+partSectOff,&bootbuffer); + bootbuffer.bytespersector = var_read(&bootbuffer.bytespersector); + bootbuffer.reservedsectors = var_read(&bootbuffer.reservedsectors); + bootbuffer.rootdirentries = var_read(&bootbuffer.rootdirentries); + bootbuffer.totalsectorcount = var_read(&bootbuffer.totalsectorcount); + bootbuffer.sectorsperfat = var_read(&bootbuffer.sectorsperfat); + bootbuffer.sectorspertrack = var_read(&bootbuffer.sectorspertrack); + bootbuffer.headcount = var_read(&bootbuffer.headcount); + bootbuffer.hiddensectorcount = var_read(&bootbuffer.hiddensectorcount); + bootbuffer.totalsecdword = var_read(&bootbuffer.totalsecdword); + if (!is_hdd) { /* Identify floppy format */ if ((bootbuffer.nearjmp[0] == 0x69 || bootbuffer.nearjmp[0] == 0xe9 || @@ -1039,6 +1043,18 @@ char* trimString(char* str) { return removeTrailingSpaces(removeLeadingSpaces(str)); } +static void copyDirEntry(const direntry *src, direntry *dst) { + memcpy(dst, src, 14); // single byte fields + var_write(&dst->crtTime, src->crtTime); + var_write(&dst->crtDate, src->crtDate); + var_write(&dst->accessDate, src->accessDate); + var_write(&dst->hiFirstClust, src->hiFirstClust); + var_write(&dst->modTime, src->modTime); + var_write(&dst->modDate, src->modDate); + var_write(&dst->loFirstClust, src->loFirstClust); + var_write(&dst->entrysize, src->entrysize); +} + bool fatDrive::FindNextInternal(Bit32u dirClustNumber, DOS_DTA &dta, direntry *foundEntry) { direntry sectbuf[16]; /* 16 directory entries per sector */ Bit32u logentsector; /* Logical entry sector */ @@ -1110,11 +1126,11 @@ nextfile: /* Compare name to search pattern */ if(!WildFileCmp(find_name,srch_pattern)) goto nextfile; - //dta.SetResult(find_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].crtDate, sectbuf[entryoffset].crtTime, sectbuf[entryoffset].attrib); + copyDirEntry(§buf[entryoffset], foundEntry); - dta.SetResult(find_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].modDate, sectbuf[entryoffset].modTime, sectbuf[entryoffset].attrib); + //dta.SetResult(find_name, foundEntry->entrysize, foundEntry->crtDate, foundEntry->crtTime, foundEntry->attrib); - memcpy(foundEntry, §buf[entryoffset], sizeof(direntry)); + dta.SetResult(find_name, foundEntry->entrysize, foundEntry->modDate, foundEntry->modTime, foundEntry->attrib); return true; } @@ -1189,7 +1205,7 @@ bool fatDrive::directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s --entNum; } - memcpy(useEntry, §buf[entryoffset],sizeof(direntry)); + copyDirEntry(§buf[entryoffset], useEntry); return true; } @@ -1223,9 +1239,9 @@ bool fatDrive::directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s --entNum; } if(tmpsector != 0) { - memcpy(§buf[entryoffset], useEntry, sizeof(direntry)); + copyDirEntry(useEntry, §buf[entryoffset]); writeSector(tmpsector, sectbuf); - return true; + return true; } else { return false; } @@ -1264,7 +1280,7 @@ bool fatDrive::addDirectoryEntry(Bit32u dirClustNumber, direntry useEntry) { /* Deleted file entry or end of directory list */ if ((sectbuf[entryoffset].entryname[0] == 0xe5) || (sectbuf[entryoffset].entryname[0] == 0x00)) { - sectbuf[entryoffset] = useEntry; + copyDirEntry(&useEntry, §buf[entryoffset]); writeSector(tmpsector,sectbuf); break; } From 28ebbd3bedc48d7807efabd2eed1adb06fd58ed5 Mon Sep 17 00:00:00 2001 From: Patryk Obara Date: Sat, 22 Feb 2020 20:59:59 +0100 Subject: [PATCH 3/3] =?UTF-8?q?Revert=20"Enhance=20capturing=20to=20handle?= =?UTF-8?q?=20unchanged=20screens=20(=E2=80=A6)"=20r4329?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit fd11108206c792ec664944cc00b668f932674b0a. --- include/hardware.h | 1 - src/gui/render.cpp | 1 - src/hardware/hardware.cpp | 97 ++++++++++++++++++--------------------- 3 files changed, 44 insertions(+), 55 deletions(-) diff --git a/include/hardware.h b/include/hardware.h index 0f5093ed..a2e86ba0 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -48,7 +48,6 @@ FILE * OpenCaptureFile(const char * type,const char * ext); void CAPTURE_AddWave(Bit32u freq, Bitu len, Bit16s * data); #define CAPTURE_FLAG_DBLW 0x1 #define CAPTURE_FLAG_DBLH 0x2 -#define CAPTURE_FLAG_DUPLICATE 0x4 void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, float fps, const Bit8u * data, const Bit8u * pal); void CAPTURE_AddMidi(bool sysex, Bitu len, Bit8u * data); diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 51c321cc..40d823bd 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -216,7 +216,6 @@ void RENDER_EndUpdate( bool abort ) { if (render.src.dblw) flags|=CAPTURE_FLAG_DBLW; if (render.src.dblh) flags|=CAPTURE_FLAG_DBLH; } - if (render.scale.outWrite==NULL) flags|=CAPTURE_FLAG_DUPLICATE; float fps = render.src.fps; pitch = render.scale.cachePitch; if (render.frameskip.max) diff --git a/src/hardware/hardware.cpp b/src/hardware/hardware.cpp index 62c06446..c8281001 100644 --- a/src/hardware/hardware.cpp +++ b/src/hardware/hardware.cpp @@ -291,7 +291,7 @@ private: bool AddChunk(const AVIChunk &ck, const AVIIndexEntry &entry, const void *data, size_t length) { long pos = ftell(handle); // in case writing fails if (fwrite(&ck,sizeof(ck),1,handle)==1 && \ - fwrite(data,1,length,handle)==length) + fwrite(data,length,1,handle)==1) { if (length&1) { // chunks must be aligned to 2-bytes fseek(handle,1,SEEK_CUR); @@ -446,7 +446,6 @@ static struct { float fps; int bufSize; void *buf; - int gop; } video; #endif } capture; @@ -750,64 +749,56 @@ void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, capture.video.height = height; capture.video.bpp = bpp; capture.video.fps = fps; - capture.video.gop = 0; - flags &= ~CAPTURE_FLAG_DUPLICATE; } - int codecFlags,written; - codecFlags = 0; - if (flags & CAPTURE_FLAG_DUPLICATE) written = 0; - else { - if (capture.video.gop >= 300) - capture.video.gop = 0; - if (capture.video.gop==0) - codecFlags = 1; - if (!capture.video.codec->PrepareCompressFrame( codecFlags, format, (char *)pal, capture.video.buf, capture.video.bufSize)) - goto skip_video; + int codecFlags; + if (capture.video.avi_out->frames % 300 == 0) + codecFlags = 1; + else codecFlags = 0; + if (!capture.video.codec->PrepareCompressFrame( codecFlags, format, (char *)pal, capture.video.buf, capture.video.bufSize)) + goto skip_video; - for (i=0;i> 1)*pitch); - else - srcLine=(data+(i >> 0)*pitch); - if (flags & CAPTURE_FLAG_DBLW) { - Bitu x; - Bitu countWidth = width >> 1; - switch ( bpp) { - case 8: - for (x=0;x> 1)*pitch); + else + srcLine=(data+(i >> 0)*pitch); + if (flags & CAPTURE_FLAG_DBLW) { + Bitu x; + Bitu countWidth = width >> 1; + switch ( bpp) { + case 8: + for (x=0;xCompressLines(2, rowPointer); - i++; - } else - capture.video.codec->CompressLines(1, &srcLine); + srcLine=doubleRow; } - written = capture.video.codec->FinishCompressFrame(); - if (written < 0) - goto skip_video; + if (flags & CAPTURE_FLAG_DBLH) { + const void *rowPointer[2]; + rowPointer[0]=rowPointer[1]=srcLine; + capture.video.codec->CompressLines(2, rowPointer); + i++; + } else + capture.video.codec->CompressLines(1, &srcLine); } + int written = capture.video.codec->FinishCompressFrame(); + if (written < 0) + goto skip_video; if (capture.video.avi_out->AddVideo(capture.video.buf, written, codecFlags & 1 ? AVII_KEYFRAME : 0)) { // LOG_MSG("Frame %d video %d audio %d",capture.video.avi_out->frames, written, capture.video.audioused *4 ); - capture.video.gop++; if (!capture.video.audioused) return; Bitu samples = capture.video.audioused; capture.video.audioused = 0;