diff --git a/aegisub/libffms/include/ffms.h b/aegisub/libffms/include/ffms.h index 9eb7b071e..2a2652dcd 100644 --- a/aegisub/libffms/include/ffms.h +++ b/aegisub/libffms/include/ffms.h @@ -22,7 +22,7 @@ #define FFMS_H // Version format: major - minor - micro - bump -#define FFMS_VERSION ((2 << 24) | (11 << 16)| (0 << 8) | 5) +#define FFMS_VERSION ((2 << 24) | (13 << 16)| (0 << 8) | 1) #include @@ -195,7 +195,7 @@ struct FFMS_TrackTimeBase { int64_t Den; }; -#define FFMS_FRAMEINFO_COMMON int64_t DTS; int RepeatPict; bool KeyFrame; +#define FFMS_FRAMEINFO_COMMON int64_t DTS; int RepeatPict; int KeyFrame; struct FFMS_FrameInfo { FFMS_FRAMEINFO_COMMON diff --git a/aegisub/libffms/src/core/audiosource.h b/aegisub/libffms/src/core/audiosource.h index de6b9ee23..3c9ed16d7 100644 --- a/aegisub/libffms/src/core/audiosource.h +++ b/aegisub/libffms/src/core/audiosource.h @@ -28,6 +28,7 @@ extern "C" { #include #include +#include #include #include "indexing.h" #include "utils.h" diff --git a/aegisub/libffms/src/core/indexing.cpp b/aegisub/libffms/src/core/indexing.cpp index a183b0a03..3b45130c8 100644 --- a/aegisub/libffms/src/core/indexing.cpp +++ b/aegisub/libffms/src/core/indexing.cpp @@ -119,9 +119,11 @@ TFrameInfo TFrameInfo::AudioFrameInfo(int64_t DTS, int64_t SampleStart, unsigned void FFMS_Track::WriteTimecodes(const char *TimecodeFile) { ffms_fstream Timecodes(TimecodeFile, std::ios::out | std::ios::trunc); - if (!Timecodes.is_open()) - throw FFMS_Exception(FFMS_ERROR_TRACK, FFMS_ERROR_FILE_WRITE, - boost::format("Failed to open '%1%' for writing") % TimecodeFile); + if (!Timecodes.is_open()) { + std::ostringstream buf; + buf << "Failed to open '" << TimecodeFile << "' for writing"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } Timecodes << "# timecode format v2\n"; @@ -183,9 +185,11 @@ FFMS_Track::FFMS_Track(int64_t Num, int64_t Den, FFMS_TrackType TT) { void FFMS_Index::CalculateFileSignature(const char *Filename, int64_t *Filesize, uint8_t Digest[20]) { FILE *SFile = ffms_fopen(Filename,"rb"); - if (SFile == NULL) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_READ, - boost::format("Failed to open '%1%' for hashing") % Filename); + if (SFile == NULL) { + std::ostringstream buf; + buf << "Failed to open '" << Filename << "' for hashing"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } const int BlockSize = 1024*1024; std::vector FileBuffer(BlockSize); @@ -198,8 +202,9 @@ void FFMS_Index::CalculateFileSignature(const char *Filename, int64_t *Filesize, if (ferror(SFile) && !feof(SFile)) { av_sha1_final(ctx, Digest); fclose(SFile); - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_READ, - boost::format("Failed to read '%1%' for hashing") % Filename); + std::ostringstream buf; + buf << "Failed to read '" << Filename << "' for hashing"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); } av_sha1_update(ctx, &FileBuffer[0], BlockSize); @@ -209,8 +214,9 @@ void FFMS_Index::CalculateFileSignature(const char *Filename, int64_t *Filesize, if (ferror(SFile) && !feof(SFile)) { av_sha1_final(ctx, Digest); fclose(SFile); - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_READ, - boost::format("Failed to seek with offset %1% from file end in '%2%' for hashing") % BlockSize % Filename); + std::ostringstream buf; + buf << "Failed to seek with offset " << BlockSize << " from file end in '" << Filename << "' for hashing"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); } av_sha1_update(ctx, &FileBuffer[0], BlockSize); @@ -218,8 +224,9 @@ void FFMS_Index::CalculateFileSignature(const char *Filename, int64_t *Filesize, if (ferror(SFile)) { av_sha1_final(ctx, Digest); fclose(SFile); - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_READ, - boost::format("Failed to seek to end of '%1%' for hashing") % Filename); + std::ostringstream buf; + buf << "Failed to seek to end of '" << Filename << "' for hashing"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); } *Filesize = ftello(SFile); fclose(SFile); @@ -260,9 +267,11 @@ bool FFMS_Index::CompareFileSignature(const char *Filename) { void FFMS_Index::WriteIndex(const char *IndexFile) { ffms_fstream IndexStream(IndexFile, std::ios::out | std::ios::binary | std::ios::trunc); - if (!IndexStream.is_open()) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_WRITE, - boost::format("Failed to open '%1%' for writing") % IndexFile); + if (!IndexStream.is_open()) { + std::ostringstream buf; + buf << "Failed to open '" << IndexFile << "' for writing"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } // Write the index file header IndexHeader IH; @@ -295,26 +304,34 @@ void FFMS_Index::WriteIndex(const char *IndexFile) { void FFMS_Index::ReadIndex(const char *IndexFile) { ffms_fstream Index(IndexFile, std::ios::in | std::ios::binary); - if (!Index.is_open()) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_READ, - boost::format("Failed to open '%1%' for reading") % IndexFile); + if (!Index.is_open()) { + std::ostringstream buf; + buf << "Failed to open '" << IndexFile << "' for reading"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } // Read the index file header IndexHeader IH; Index.read(reinterpret_cast(&IH), sizeof(IH)); - if (IH.Id != INDEXID) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, - boost::format("'%1%' is not a valid index file") % IndexFile); + if (IH.Id != INDEXID) { + std::ostringstream buf; + buf << "'" << IndexFile << "' is not a valid index file"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } - if (IH.Version != FFMS_VERSION) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_VERSION, - boost::format("'%1%' is not the expected index version") % IndexFile); + if (IH.Version != FFMS_VERSION) { + std::ostringstream buf; + buf << "'" << IndexFile << "' is not the expected index version"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } if (IH.LAVUVersion != avutil_version() || IH.LAVFVersion != avformat_version() || IH.LAVCVersion != avcodec_version() || IH.LSWSVersion != swscale_version() || - IH.LPPVersion != postproc_version()) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_VERSION, - boost::format("A different FFmpeg build was used to create '%1%'") % IndexFile); + IH.LPPVersion != postproc_version()) { + std::ostringstream buf; + buf << "A different FFmpeg build was used to create '" << IndexFile << "'"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } if (!(IH.Decoder & FFMS_GetEnabledSources())) throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_NOT_AVAILABLE, @@ -337,8 +354,9 @@ void FFMS_Index::ReadIndex(const char *IndexFile) { } } catch (...) { - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_UNKNOWN, - boost::format("Unknown error while reading index information in '%1%'") % IndexFile); + std::ostringstream buf; + buf << "Unknown error while reading index information in '" << IndexFile << "'"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); } } @@ -380,9 +398,11 @@ void FFMS_Indexer::SetAudioNameCallback(TAudioNameCallback ANC, void *ANCPrivate FFMS_Indexer *FFMS_Indexer::CreateIndexer(const char *Filename) { AVFormatContext *FormatContext = NULL; - if (av_open_input_file(&FormatContext, Filename, NULL, 0, NULL) != 0) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - boost::format("Can't open '%1%'") % Filename); + if (av_open_input_file(&FormatContext, Filename, NULL, 0, NULL) != 0) { + std::ostringstream buf; + buf << "Can't open '" << Filename << "'"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } // Do matroska indexing instead? if (!strcmp(FormatContext->iformat->name, "matroska")) { diff --git a/aegisub/libffms/src/core/lavfaudio.cpp b/aegisub/libffms/src/core/lavfaudio.cpp index 22eb470ce..6e0eb42fc 100644 --- a/aegisub/libffms/src/core/lavfaudio.cpp +++ b/aegisub/libffms/src/core/lavfaudio.cpp @@ -20,6 +20,8 @@ #include "audiosource.h" + + void FFLAVFAudio::Free(bool CloseCodec) { if (CloseCodec) avcodec_close(CodecContext); @@ -124,42 +126,48 @@ void FFLAVFAudio::GetAudio(void *Buf, int64_t Start, int64_t Count) { return; size_t CurrentAudioBlock; - // Is seeking required to decode the requested samples? -// if (!(CurrentSample >= Start && CurrentSample <= CacheEnd)) { if (CurrentSample != CacheEnd) { PreDecBlocks = 15; CurrentAudioBlock = FFMAX((int64_t)Frames.FindClosestAudioKeyFrame(CacheEnd) - PreDecBlocks - 20, (int64_t)0); + if (CurrentAudioBlock <= PreDecBlocks) { + CurrentAudioBlock = 0; + PreDecBlocks = 0; + } + // Did the seeking fail? if (av_seek_frame(FormatContext, AudioTrack, Frames[CurrentAudioBlock].DTS, AVSEEK_FLAG_BACKWARD) < 0) av_seek_frame(FormatContext, AudioTrack, Frames[CurrentAudioBlock].DTS, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY); avcodec_flush_buffers(CodecContext); - AVPacket Packet; - InitNullPacket(Packet); + // Pretend we got to the first audio frame when PreDecBlocks = 0 + if (PreDecBlocks > 0) { + AVPacket Packet; + InitNullPacket(Packet); - // Establish where we actually are - // Trigger on packet dts difference since groups can otherwise be indistinguishable - int64_t LastDTS = - 1; - while (av_read_frame(FormatContext, &Packet) >= 0) { - if (Packet.stream_index == AudioTrack) { - if (LastDTS < 0) { - LastDTS = Packet.dts; - } else if (LastDTS != Packet.dts) { - for (size_t i = 0; i < Frames.size(); i++) - if (Frames[i].DTS == Packet.dts) { - // The current match was consumed - CurrentAudioBlock = i + 1; - break; - } + // Establish where we actually are + // Trigger on packet dts difference since groups can otherwise be indistinguishable + int64_t LastDTS = - 1; + while (av_read_frame(FormatContext, &Packet) >= 0) { + if (Packet.stream_index == AudioTrack) { + if (LastDTS < 0) { + LastDTS = Packet.dts; + } else if (LastDTS != Packet.dts) { + for (size_t i = 0; i < Frames.size(); i++) + if (Frames[i].DTS == Packet.dts) { + // The current match was consumed + CurrentAudioBlock = i + 1; + break; + } - av_free_packet(&Packet); - break; + av_free_packet(&Packet); + break; + } } - } - av_free_packet(&Packet); + av_free_packet(&Packet); + } } } else { CurrentAudioBlock = Frames.FindClosestAudioKeyFrame(CurrentSample); diff --git a/aegisub/libffms/src/core/matroskaaudio.cpp b/aegisub/libffms/src/core/matroskaaudio.cpp index 56e861da0..d8acc9a7b 100644 --- a/aegisub/libffms/src/core/matroskaaudio.cpp +++ b/aegisub/libffms/src/core/matroskaaudio.cpp @@ -42,17 +42,20 @@ FFMatroskaAudio::FFMatroskaAudio(const char *SourceFile, int Track, FFMS_Index * Frames = (*Index)[Track]; MC.ST.fp = ffms_fopen(SourceFile, "rb"); - if (MC.ST.fp == NULL) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - boost::format("Can't open '%1%': %2%") % SourceFile % strerror(errno)); + if (MC.ST.fp == NULL) { + std::ostringstream buf; + buf << "Can't open '" << SourceFile << "': " << strerror(errno); + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } setvbuf(MC.ST.fp, NULL, _IOFBF, CACHESIZE); MF = mkv_OpenEx(&MC.ST.base, 0, 0, ErrorMessage, sizeof(ErrorMessage)); if (MF == NULL) { fclose(MC.ST.fp); - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - boost::format("Can't parse Matroska file: %1%") % ErrorMessage); + std::ostringstream buf; + buf << "Can't parse Matroska file: " << ErrorMessage; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); } @@ -62,14 +65,15 @@ FFMatroskaAudio::FFMatroskaAudio(const char *SourceFile, int Track, FFMS_Index * CS = cs_Create(MF, Track, ErrorMessage, sizeof(ErrorMessage)); if (CS == NULL) { Free(false); - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED, - boost::format("Can't create decompressor: %1%") % ErrorMessage); + std::ostringstream buf; + buf << "Can't create decompressor: " << ErrorMessage; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); } } CodecContext = avcodec_alloc_context(); - Codec = avcodec_find_decoder(MatroskaToFFCodecID(TI->CodecID, TI->CodecPrivate)); + Codec = avcodec_find_decoder(MatroskaToFFCodecID(TI->CodecID, TI->CodecPrivate, 0, TI->AV.Audio.BitDepth)); if (Codec == NULL) throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, "Audio codec not found"); @@ -112,11 +116,15 @@ void FFMatroskaAudio::GetAudio(void *Buf, int64_t Start, int64_t Count) { if (CacheEnd == Start + Count) return; - // Is seeking required to decode the requested samples? -// if (!(CurrentSample >= Start && CurrentSample <= CacheEnd)) { if (CurrentSample != CacheEnd) { PreDecBlocks = 15; - PacketNumber = FFMAX((int64_t)Frames.FindClosestAudioKeyFrame(CacheEnd) - PreDecBlocks, (int64_t)0);; + PacketNumber = FFMAX((int64_t)Frames.FindClosestAudioKeyFrame(CacheEnd) - PreDecBlocks, (int64_t)0); + + if (PacketNumber <= PreDecBlocks) { + PacketNumber = 0; + PreDecBlocks = 0; + } + avcodec_flush_buffers(CodecContext); } diff --git a/aegisub/libffms/src/core/matroskaindexer.cpp b/aegisub/libffms/src/core/matroskaindexer.cpp index d9087d9d4..75729ec7f 100644 --- a/aegisub/libffms/src/core/matroskaindexer.cpp +++ b/aegisub/libffms/src/core/matroskaindexer.cpp @@ -32,22 +32,25 @@ FFMatroskaIndexer::FFMatroskaIndexer(const char *Filename) : FFMS_Indexer(Filena InitStdIoStream(&MC.ST); MC.ST.fp = ffms_fopen(SourceFile, "rb"); - if (MC.ST.fp == NULL) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - boost::format("Can't open '%1%': %2%") % SourceFile % strerror(errno)); + if (MC.ST.fp == NULL) { + std::ostringstream buf; + buf << "Can't open '" << SourceFile << "': " << strerror(errno); + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } setvbuf(MC.ST.fp, NULL, _IOFBF, CACHESIZE); MF = mkv_OpenEx(&MC.ST.base, 0, 0, ErrorMessage, sizeof(ErrorMessage)); if (MF == NULL) { fclose(MC.ST.fp); - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - boost::format("Can't parse Matroska file: %1%") % ErrorMessage); + std::ostringstream buf; + buf << "Can't parse Matroska file: " << ErrorMessage; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); } for (unsigned int i = 0; i < mkv_GetNumTracks(MF); i++) { TrackInfo *TI = mkv_GetTrackInfo(MF, i); - Codec[i] = avcodec_find_decoder(MatroskaToFFCodecID(TI->CodecID, TI->CodecPrivate)); + Codec[i] = avcodec_find_decoder(MatroskaToFFCodecID(TI->CodecID, TI->CodecPrivate, 0, TI->AV.Audio.BitDepth)); } } @@ -82,9 +85,11 @@ FFMS_Index *FFMatroskaIndexer::DoIndexing() { if (TI->CompEnabled) { VideoContexts[i].CS = cs_Create(MF, i, ErrorMessage, sizeof(ErrorMessage)); - if (VideoContexts[i].CS == NULL) - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED, - boost::format("Can't create decompressor: %1%") % ErrorMessage); + if (VideoContexts[i].CS == NULL) { + std::ostringstream buf; + buf << "Can't create decompressor: " << ErrorMessage; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } } VideoContexts[i].CodecContext = CodecContext; @@ -93,8 +98,7 @@ FFMS_Index *FFMatroskaIndexer::DoIndexing() { if (IndexMask & (1 << i) && TI->Type == TT_AUDIO) { AVCodecContext *AudioCodecContext = avcodec_alloc_context(); - AudioCodecContext->extradata = (uint8_t *)TI->CodecPrivate; - AudioCodecContext->extradata_size = TI->CodecPrivateSize; + InitializeCodecContextFromMatroskaTrackInfo(TI, AudioCodecContext); AudioContexts[i].CodecContext = AudioCodecContext; if (TI->CompEnabled) { @@ -102,8 +106,9 @@ FFMS_Index *FFMatroskaIndexer::DoIndexing() { if (AudioContexts[i].CS == NULL) { av_freep(&AudioCodecContext); AudioContexts[i].CodecContext = NULL; - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED, - boost::format("Can't create decompressor: %1%") % ErrorMessage); + std::ostringstream buf; + buf << "Can't create decompressor: " << ErrorMessage; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); } } diff --git a/aegisub/libffms/src/core/matroskavideo.cpp b/aegisub/libffms/src/core/matroskavideo.cpp index 56df418af..0c9510316 100644 --- a/aegisub/libffms/src/core/matroskavideo.cpp +++ b/aegisub/libffms/src/core/matroskavideo.cpp @@ -47,17 +47,20 @@ FFMatroskaVideo::FFMatroskaVideo(const char *SourceFile, int Track, Frames = (*Index)[VideoTrack]; MC.ST.fp = ffms_fopen(SourceFile, "rb"); - if (MC.ST.fp == NULL) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - boost::format("Can't open '%1%': %2%") % SourceFile % strerror(errno)); + if (MC.ST.fp == NULL) { + std::ostringstream buf; + buf << "Can't open '" << SourceFile << "': " << strerror(errno); + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } setvbuf(MC.ST.fp, NULL, _IOFBF, CACHESIZE); MF = mkv_OpenEx(&MC.ST.base, 0, 0, ErrorMessage, sizeof(ErrorMessage)); if (MF == NULL) { fclose(MC.ST.fp); - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - boost::format("Can't parse Matroska file: %1%") % ErrorMessage); + std::ostringstream buf; + buf << "Can't parse Matroska file: " << ErrorMessage; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); } TI = mkv_GetTrackInfo(MF, VideoTrack); @@ -66,8 +69,9 @@ FFMatroskaVideo::FFMatroskaVideo(const char *SourceFile, int Track, CS = cs_Create(MF, VideoTrack, ErrorMessage, sizeof(ErrorMessage)); if (CS == NULL) { Free(false); - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED, - boost::format("Can't create decompressor: %1%") % ErrorMessage); + std::ostringstream buf; + buf << "Can't create decompressor: " << ErrorMessage; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); } } diff --git a/aegisub/libffms/src/core/utils.cpp b/aegisub/libffms/src/core/utils.cpp index 6566b1b53..a552becc0 100644 --- a/aegisub/libffms/src/core/utils.cpp +++ b/aegisub/libffms/src/core/utils.cpp @@ -54,9 +54,6 @@ FFMS_Exception::FFMS_Exception(int ErrorType, int SubType, const char *Message) FFMS_Exception::FFMS_Exception(int ErrorType, int SubType, const std::string &Message) : _ErrorType(ErrorType), _SubType(SubType), _Message(Message) { } -FFMS_Exception::FFMS_Exception(int ErrorType, int SubType, const boost::format &Message) : _ErrorType(ErrorType), _SubType(SubType), _Message(Message.str()) { -} - FFMS_Exception::~FFMS_Exception() throw () { } @@ -137,9 +134,11 @@ void ReadFrame(uint64_t FilePos, unsigned int &FrameSize, CompressedStream *CS, for (;;) { int ReadBytes = cs_ReadData(CS, Context.CSBuffer, sizeof(Context.CSBuffer)); - if (ReadBytes < 0) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - boost::format("Error decompressing data: %1%") % cs_GetLastError(CS)); + if (ReadBytes < 0) { + std::ostringstream buf; + buf << "Error decompressing data: " << cs_GetLastError(CS); + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } if (ReadBytes == 0) { FrameSize = DecompressedFrameSize; @@ -160,9 +159,11 @@ void ReadFrame(uint64_t FilePos, unsigned int &FrameSize, CompressedStream *CS, DecompressedFrameSize += ReadBytes; } } else { - if (fseeko(Context.ST.fp, FilePos, SEEK_SET)) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_SEEKING, - boost::format("fseek(): %1%") % strerror(errno)); + if (fseeko(Context.ST.fp, FilePos, SEEK_SET)) { + std::ostringstream buf; + buf << "fseek(): " << strerror(errno); + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_SEEKING, buf.str()); + } if (Context.BufferSize < FrameSize) { Context.BufferSize = FrameSize; @@ -179,8 +180,9 @@ void ReadFrame(uint64_t FilePos, unsigned int &FrameSize, CompressedStream *CS, throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, "Unexpected EOF while reading frame"); } else { - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_SEEKING, - boost::format("Error reading frame: %1%") % strerror(errno)); + std::ostringstream buf; + buf << "Error reading frame: " << strerror(errno); + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_SEEKING, buf.str()); } } else { throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, @@ -202,7 +204,7 @@ void InitNullPacket(AVPacket &pkt) { bool IsNVOP(AVPacket &pkt) { const uint8_t MPEG4NVOP[] = { 0x00, 0x00, 0x01, 0xB6 }; - return pkt.size == 7 && !memcmp(pkt.data, MPEG4NVOP, 4); + return (pkt.size >= 4 && pkt.size <= 8) && !memcmp(pkt.data, MPEG4NVOP, 4); } void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames) { @@ -454,9 +456,11 @@ CComPtr HaaliOpenFile(const char *SourceFile, enum FFMS_Sources So #endif void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext) { - if (av_open_input_file(&FormatContext, SourceFile, NULL, 0, NULL) != 0) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - boost::format("Couldn't open '%1'") % SourceFile); + if (av_open_input_file(&FormatContext, SourceFile, NULL, 0, NULL) != 0) { + std::ostringstream buf; + buf << "Couldn't open '" << SourceFile << "'"; + throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str()); + } if (av_find_stream_info(FormatContext) < 0) { av_close_input_file(FormatContext); diff --git a/aegisub/libffms/src/core/utils.h b/aegisub/libffms/src/core/utils.h index 7d1a3ae72..5145c90a9 100644 --- a/aegisub/libffms/src/core/utils.h +++ b/aegisub/libffms/src/core/utils.h @@ -22,9 +22,9 @@ #define UTILS_H #include +#include #include #include -#include #include "ffms.h" #include "matroskaparser.h" @@ -78,7 +78,6 @@ private: public: FFMS_Exception(int ErrorType, int SubType, const char *Message = ""); FFMS_Exception(int ErrorType, int SubType, const std::string &Message); - FFMS_Exception(int ErrorType, int SubType, const boost::format &Message); ~FFMS_Exception() throw (); const std::string &GetErrorMessage() const; int CopyOut(FFMS_ErrorInfo *ErrorInfo) const; diff --git a/aegisub/libffms/src/core/videosource.h b/aegisub/libffms/src/core/videosource.h index 512845d99..867ddb6de 100644 --- a/aegisub/libffms/src/core/videosource.h +++ b/aegisub/libffms/src/core/videosource.h @@ -32,6 +32,7 @@ extern "C" { #include "ffmscompat.h" #include +#include #include "indexing.h" #include "utils.h" #include "ffms.h"