summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik de Castro Lopo <erikd@mega-nerd.com>2014-10-03 06:45:20 +1000
committerErik de Castro Lopo <erikd@mega-nerd.com>2014-10-03 06:45:28 +1000
commitd66f6754bf94bc8ba23d3579d0b5650cd380c9f0 (patch)
treeab38256d135f5b8b6924688e1b274d45d5aba1b0
parente8632477774f56b4fe7ccab525cad2ceab244b8a (diff)
downloadflac-d66f6754bf94bc8ba23d3579d0b5650cd380c9f0.tar.gz
src/flac/decode.c : Decoder buffering improvements on Windows.
On Windows, decoding flac files is also prone to producing fragmented files. Avoid fragmentation on NTFS by using Windows specific functions to tell Windows the size of the file beforehand. Patch-from: Janne Hyvärinen <cse@sci.fi>
-rw-r--r--src/flac/decode.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/flac/decode.c b/src/flac/decode.c
index 5e5e17ad..ed7eff81 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)) {