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>
This commit is contained in:
Erik de Castro Lopo 2014-10-03 06:45:20 +10:00
parent e863247777
commit d66f6754bf

View File

@ -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)) {