[flac-dev] Patch to add buffering to decoding too

Janne Hyvärinen cse at sci.fi
Sat Sep 27 07:38:19 PDT 2014


The previous patch was bugged. The output file wasn't truncated to 
correct size and was a bit off from rounding the WAVE/AIFF header to 
smallest sector size. And RAW output didn't benefit from the change. And 
the existing functions didn't need changes as outputfilename was already 
known. Attached is a fixed and improved version.

-------------- next part --------------
diff --git a/src/flac/decode.c b/src/flac/decode.c
index 5e5e17a..ed7eff8 100644
--- a/src/flac/decode.c
+++ b/src/flac/decode.c
@@ -263,6 +263,23 @@ FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__
 void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred)
 {
 	if(0 != d->fout && d->fout != stdout) {
+#ifdef _WIN32
+		if(!error_occurred) {
+			FLAC__off_t written_size = ftello(d->fout);
+			if(written_size > 0) {
+				HANDLE fh = CreateFile_utf8(d->outfilename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+				if(fh != INVALID_HANDLE_VALUE) {
+					if(GetFileType(fh) == FILE_TYPE_DISK) {
+						LARGE_INTEGER size;
+						size.QuadPart = written_size;
+						if(SetFilePointerEx(fh, size, NULL, FILE_CURRENT)) /* correct the file size */
+							SetEndOfFile(fh); 
+					}
+					CloseHandle(fh);
+				}
+			}
+		}
+#endif
 		fclose(d->fout);
 		if(error_occurred)
 			flac_unlink(d->outfilename);
@@ -364,6 +381,32 @@ FLAC__bool DecoderSession_process(DecoderSession *d)
 		}
 	}
 
+#ifdef _WIN32
+	if(!d->analysis_mode && !d->test_only && d->total_samples > 0 && d->fout != stdout) {
+		HANDLE fh = CreateFile_utf8(d->outfilename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+		if(fh != INVALID_HANDLE_VALUE) {
+			if (GetFileType(fh) == FILE_TYPE_DISK) {
+				LARGE_INTEGER size;
+				size.QuadPart = d->total_samples * d->channels * ((d->bps+7)/8);
+				if(d->format != FORMAT_RAW) {
+					size.QuadPart += 512;
+					if(d->foreign_metadata) {
+						size_t i;
+						for(i = d->format==FORMAT_RF64?2:1; i < d->foreign_metadata->num_blocks; i++) {
+							if(i != d->foreign_metadata->format_block && i != d->foreign_metadata->audio_block)
+								size.QuadPart += d->foreign_metadata->blocks[i].size;
+						}
+					}
+				}
+
+				if(SetFilePointerEx(fh, size, NULL, FILE_CURRENT)) /* tell filesystem the expected filesize to eliminate fragmentation */
+					SetEndOfFile(fh); 
+			}
+			CloseHandle(fh);
+		}
+	}
+#endif
+
 	/* write the WAVE/AIFF headers if necessary */
 	if(!d->analysis_mode && !d->test_only && d->format != FORMAT_RAW) {
 		if(!write_iff_headers(d->fout, d, d->total_samples)) {


More information about the flac-dev mailing list