forked from mia/Aegisub
Update ffms2 to r228. Removes the boost dependency.
Originally committed to SVN as r3690.
This commit is contained in:
parent
68de84b427
commit
e3583da740
10 changed files with 154 additions and 104 deletions
|
@ -22,7 +22,7 @@
|
||||||
#define FFMS_H
|
#define FFMS_H
|
||||||
|
|
||||||
// Version format: major - minor - micro - bump
|
// 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 <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ struct FFMS_TrackTimeBase {
|
||||||
int64_t Den;
|
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 {
|
struct FFMS_FrameInfo {
|
||||||
FFMS_FRAMEINFO_COMMON
|
FFMS_FRAMEINFO_COMMON
|
||||||
|
|
|
@ -28,6 +28,7 @@ extern "C" {
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <sstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "indexing.h"
|
#include "indexing.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
|
@ -119,9 +119,11 @@ TFrameInfo TFrameInfo::AudioFrameInfo(int64_t DTS, int64_t SampleStart, unsigned
|
||||||
void FFMS_Track::WriteTimecodes(const char *TimecodeFile) {
|
void FFMS_Track::WriteTimecodes(const char *TimecodeFile) {
|
||||||
ffms_fstream Timecodes(TimecodeFile, std::ios::out | std::ios::trunc);
|
ffms_fstream Timecodes(TimecodeFile, std::ios::out | std::ios::trunc);
|
||||||
|
|
||||||
if (!Timecodes.is_open())
|
if (!Timecodes.is_open()) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_TRACK, FFMS_ERROR_FILE_WRITE,
|
std::ostringstream buf;
|
||||||
boost::format("Failed to open '%1%' for writing") % TimecodeFile);
|
buf << "Failed to open '" << TimecodeFile << "' for writing";
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str());
|
||||||
|
}
|
||||||
|
|
||||||
Timecodes << "# timecode format v2\n";
|
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]) {
|
void FFMS_Index::CalculateFileSignature(const char *Filename, int64_t *Filesize, uint8_t Digest[20]) {
|
||||||
FILE *SFile = ffms_fopen(Filename,"rb");
|
FILE *SFile = ffms_fopen(Filename,"rb");
|
||||||
|
|
||||||
if (SFile == NULL)
|
if (SFile == NULL) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Failed to open '%1%' for hashing") % Filename);
|
buf << "Failed to open '" << Filename << "' for hashing";
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str());
|
||||||
|
}
|
||||||
|
|
||||||
const int BlockSize = 1024*1024;
|
const int BlockSize = 1024*1024;
|
||||||
std::vector<uint8_t> FileBuffer(BlockSize);
|
std::vector<uint8_t> FileBuffer(BlockSize);
|
||||||
|
@ -198,8 +202,9 @@ void FFMS_Index::CalculateFileSignature(const char *Filename, int64_t *Filesize,
|
||||||
if (ferror(SFile) && !feof(SFile)) {
|
if (ferror(SFile) && !feof(SFile)) {
|
||||||
av_sha1_final(ctx, Digest);
|
av_sha1_final(ctx, Digest);
|
||||||
fclose(SFile);
|
fclose(SFile);
|
||||||
throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Failed to read '%1%' for hashing") % Filename);
|
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);
|
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)) {
|
if (ferror(SFile) && !feof(SFile)) {
|
||||||
av_sha1_final(ctx, Digest);
|
av_sha1_final(ctx, Digest);
|
||||||
fclose(SFile);
|
fclose(SFile);
|
||||||
throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Failed to seek with offset %1% from file end in '%2%' for hashing") % BlockSize % Filename);
|
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);
|
av_sha1_update(ctx, &FileBuffer[0], BlockSize);
|
||||||
|
|
||||||
|
@ -218,8 +224,9 @@ void FFMS_Index::CalculateFileSignature(const char *Filename, int64_t *Filesize,
|
||||||
if (ferror(SFile)) {
|
if (ferror(SFile)) {
|
||||||
av_sha1_final(ctx, Digest);
|
av_sha1_final(ctx, Digest);
|
||||||
fclose(SFile);
|
fclose(SFile);
|
||||||
throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Failed to seek to end of '%1%' for hashing") % Filename);
|
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);
|
*Filesize = ftello(SFile);
|
||||||
fclose(SFile);
|
fclose(SFile);
|
||||||
|
@ -260,9 +267,11 @@ bool FFMS_Index::CompareFileSignature(const char *Filename) {
|
||||||
void FFMS_Index::WriteIndex(const char *IndexFile) {
|
void FFMS_Index::WriteIndex(const char *IndexFile) {
|
||||||
ffms_fstream IndexStream(IndexFile, std::ios::out | std::ios::binary | std::ios::trunc);
|
ffms_fstream IndexStream(IndexFile, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||||
|
|
||||||
if (!IndexStream.is_open())
|
if (!IndexStream.is_open()) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_WRITE,
|
std::ostringstream buf;
|
||||||
boost::format("Failed to open '%1%' for writing") % IndexFile);
|
buf << "Failed to open '" << IndexFile << "' for writing";
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str());
|
||||||
|
}
|
||||||
|
|
||||||
// Write the index file header
|
// Write the index file header
|
||||||
IndexHeader IH;
|
IndexHeader IH;
|
||||||
|
@ -295,26 +304,34 @@ void FFMS_Index::WriteIndex(const char *IndexFile) {
|
||||||
void FFMS_Index::ReadIndex(const char *IndexFile) {
|
void FFMS_Index::ReadIndex(const char *IndexFile) {
|
||||||
ffms_fstream Index(IndexFile, std::ios::in | std::ios::binary);
|
ffms_fstream Index(IndexFile, std::ios::in | std::ios::binary);
|
||||||
|
|
||||||
if (!Index.is_open())
|
if (!Index.is_open()) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Failed to open '%1%' for reading") % IndexFile);
|
buf << "Failed to open '" << IndexFile << "' for reading";
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str());
|
||||||
|
}
|
||||||
|
|
||||||
// Read the index file header
|
// Read the index file header
|
||||||
IndexHeader IH;
|
IndexHeader IH;
|
||||||
Index.read(reinterpret_cast<char *>(&IH), sizeof(IH));
|
Index.read(reinterpret_cast<char *>(&IH), sizeof(IH));
|
||||||
if (IH.Id != INDEXID)
|
if (IH.Id != INDEXID) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT,
|
std::ostringstream buf;
|
||||||
boost::format("'%1%' is not a valid index file") % IndexFile);
|
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)
|
if (IH.Version != FFMS_VERSION) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_VERSION,
|
std::ostringstream buf;
|
||||||
boost::format("'%1%' is not the expected index version") % IndexFile);
|
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() ||
|
if (IH.LAVUVersion != avutil_version() || IH.LAVFVersion != avformat_version() ||
|
||||||
IH.LAVCVersion != avcodec_version() || IH.LSWSVersion != swscale_version() ||
|
IH.LAVCVersion != avcodec_version() || IH.LSWSVersion != swscale_version() ||
|
||||||
IH.LPPVersion != postproc_version())
|
IH.LPPVersion != postproc_version()) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_VERSION,
|
std::ostringstream buf;
|
||||||
boost::format("A different FFmpeg build was used to create '%1%'") % IndexFile);
|
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()))
|
if (!(IH.Decoder & FFMS_GetEnabledSources()))
|
||||||
throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_NOT_AVAILABLE,
|
throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_NOT_AVAILABLE,
|
||||||
|
@ -337,8 +354,9 @@ void FFMS_Index::ReadIndex(const char *IndexFile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_UNKNOWN,
|
std::ostringstream buf;
|
||||||
boost::format("Unknown error while reading index information in '%1%'") % IndexFile);
|
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) {
|
FFMS_Indexer *FFMS_Indexer::CreateIndexer(const char *Filename) {
|
||||||
AVFormatContext *FormatContext = NULL;
|
AVFormatContext *FormatContext = NULL;
|
||||||
|
|
||||||
if (av_open_input_file(&FormatContext, Filename, NULL, 0, NULL) != 0)
|
if (av_open_input_file(&FormatContext, Filename, NULL, 0, NULL) != 0) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Can't open '%1%'") % Filename);
|
buf << "Can't open '" << Filename << "'";
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str());
|
||||||
|
}
|
||||||
|
|
||||||
// Do matroska indexing instead?
|
// Do matroska indexing instead?
|
||||||
if (!strcmp(FormatContext->iformat->name, "matroska")) {
|
if (!strcmp(FormatContext->iformat->name, "matroska")) {
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#include "audiosource.h"
|
#include "audiosource.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void FFLAVFAudio::Free(bool CloseCodec) {
|
void FFLAVFAudio::Free(bool CloseCodec) {
|
||||||
if (CloseCodec)
|
if (CloseCodec)
|
||||||
avcodec_close(CodecContext);
|
avcodec_close(CodecContext);
|
||||||
|
@ -124,18 +126,23 @@ void FFLAVFAudio::GetAudio(void *Buf, int64_t Start, int64_t Count) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
size_t CurrentAudioBlock;
|
size_t CurrentAudioBlock;
|
||||||
// Is seeking required to decode the requested samples?
|
|
||||||
// if (!(CurrentSample >= Start && CurrentSample <= CacheEnd)) {
|
|
||||||
if (CurrentSample != CacheEnd) {
|
if (CurrentSample != CacheEnd) {
|
||||||
PreDecBlocks = 15;
|
PreDecBlocks = 15;
|
||||||
CurrentAudioBlock = FFMAX((int64_t)Frames.FindClosestAudioKeyFrame(CacheEnd) - PreDecBlocks - 20, (int64_t)0);
|
CurrentAudioBlock = FFMAX((int64_t)Frames.FindClosestAudioKeyFrame(CacheEnd) - PreDecBlocks - 20, (int64_t)0);
|
||||||
|
|
||||||
|
if (CurrentAudioBlock <= PreDecBlocks) {
|
||||||
|
CurrentAudioBlock = 0;
|
||||||
|
PreDecBlocks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Did the seeking fail?
|
// Did the seeking fail?
|
||||||
if (av_seek_frame(FormatContext, AudioTrack, Frames[CurrentAudioBlock].DTS, AVSEEK_FLAG_BACKWARD) < 0)
|
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);
|
av_seek_frame(FormatContext, AudioTrack, Frames[CurrentAudioBlock].DTS, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY);
|
||||||
|
|
||||||
avcodec_flush_buffers(CodecContext);
|
avcodec_flush_buffers(CodecContext);
|
||||||
|
|
||||||
|
// Pretend we got to the first audio frame when PreDecBlocks = 0
|
||||||
|
if (PreDecBlocks > 0) {
|
||||||
AVPacket Packet;
|
AVPacket Packet;
|
||||||
InitNullPacket(Packet);
|
InitNullPacket(Packet);
|
||||||
|
|
||||||
|
@ -161,6 +168,7 @@ void FFLAVFAudio::GetAudio(void *Buf, int64_t Start, int64_t Count) {
|
||||||
|
|
||||||
av_free_packet(&Packet);
|
av_free_packet(&Packet);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
CurrentAudioBlock = Frames.FindClosestAudioKeyFrame(CurrentSample);
|
CurrentAudioBlock = Frames.FindClosestAudioKeyFrame(CurrentSample);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,17 +42,20 @@ FFMatroskaAudio::FFMatroskaAudio(const char *SourceFile, int Track, FFMS_Index *
|
||||||
Frames = (*Index)[Track];
|
Frames = (*Index)[Track];
|
||||||
|
|
||||||
MC.ST.fp = ffms_fopen(SourceFile, "rb");
|
MC.ST.fp = ffms_fopen(SourceFile, "rb");
|
||||||
if (MC.ST.fp == NULL)
|
if (MC.ST.fp == NULL) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Can't open '%1%': %2%") % SourceFile % strerror(errno));
|
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);
|
setvbuf(MC.ST.fp, NULL, _IOFBF, CACHESIZE);
|
||||||
|
|
||||||
MF = mkv_OpenEx(&MC.ST.base, 0, 0, ErrorMessage, sizeof(ErrorMessage));
|
MF = mkv_OpenEx(&MC.ST.base, 0, 0, ErrorMessage, sizeof(ErrorMessage));
|
||||||
if (MF == NULL) {
|
if (MF == NULL) {
|
||||||
fclose(MC.ST.fp);
|
fclose(MC.ST.fp);
|
||||||
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Can't parse Matroska file: %1%") % ErrorMessage);
|
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));
|
CS = cs_Create(MF, Track, ErrorMessage, sizeof(ErrorMessage));
|
||||||
if (CS == NULL) {
|
if (CS == NULL) {
|
||||||
Free(false);
|
Free(false);
|
||||||
throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED,
|
std::ostringstream buf;
|
||||||
boost::format("Can't create decompressor: %1%") % ErrorMessage);
|
buf << "Can't create decompressor: " << ErrorMessage;
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodecContext = avcodec_alloc_context();
|
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)
|
if (Codec == NULL)
|
||||||
throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
|
throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
|
||||||
"Audio codec not found");
|
"Audio codec not found");
|
||||||
|
@ -112,11 +116,15 @@ void FFMatroskaAudio::GetAudio(void *Buf, int64_t Start, int64_t Count) {
|
||||||
if (CacheEnd == Start + Count)
|
if (CacheEnd == Start + Count)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Is seeking required to decode the requested samples?
|
|
||||||
// if (!(CurrentSample >= Start && CurrentSample <= CacheEnd)) {
|
|
||||||
if (CurrentSample != CacheEnd) {
|
if (CurrentSample != CacheEnd) {
|
||||||
PreDecBlocks = 15;
|
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);
|
avcodec_flush_buffers(CodecContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,22 +32,25 @@ FFMatroskaIndexer::FFMatroskaIndexer(const char *Filename) : FFMS_Indexer(Filena
|
||||||
|
|
||||||
InitStdIoStream(&MC.ST);
|
InitStdIoStream(&MC.ST);
|
||||||
MC.ST.fp = ffms_fopen(SourceFile, "rb");
|
MC.ST.fp = ffms_fopen(SourceFile, "rb");
|
||||||
if (MC.ST.fp == NULL)
|
if (MC.ST.fp == NULL) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Can't open '%1%': %2%") % SourceFile % strerror(errno));
|
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);
|
setvbuf(MC.ST.fp, NULL, _IOFBF, CACHESIZE);
|
||||||
|
|
||||||
MF = mkv_OpenEx(&MC.ST.base, 0, 0, ErrorMessage, sizeof(ErrorMessage));
|
MF = mkv_OpenEx(&MC.ST.base, 0, 0, ErrorMessage, sizeof(ErrorMessage));
|
||||||
if (MF == NULL) {
|
if (MF == NULL) {
|
||||||
fclose(MC.ST.fp);
|
fclose(MC.ST.fp);
|
||||||
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Can't parse Matroska file: %1%") % ErrorMessage);
|
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++) {
|
for (unsigned int i = 0; i < mkv_GetNumTracks(MF); i++) {
|
||||||
TrackInfo *TI = mkv_GetTrackInfo(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) {
|
if (TI->CompEnabled) {
|
||||||
VideoContexts[i].CS = cs_Create(MF, i, ErrorMessage, sizeof(ErrorMessage));
|
VideoContexts[i].CS = cs_Create(MF, i, ErrorMessage, sizeof(ErrorMessage));
|
||||||
if (VideoContexts[i].CS == NULL)
|
if (VideoContexts[i].CS == NULL) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED,
|
std::ostringstream buf;
|
||||||
boost::format("Can't create decompressor: %1%") % ErrorMessage);
|
buf << "Can't create decompressor: " << ErrorMessage;
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoContexts[i].CodecContext = CodecContext;
|
VideoContexts[i].CodecContext = CodecContext;
|
||||||
|
@ -93,8 +98,7 @@ FFMS_Index *FFMatroskaIndexer::DoIndexing() {
|
||||||
|
|
||||||
if (IndexMask & (1 << i) && TI->Type == TT_AUDIO) {
|
if (IndexMask & (1 << i) && TI->Type == TT_AUDIO) {
|
||||||
AVCodecContext *AudioCodecContext = avcodec_alloc_context();
|
AVCodecContext *AudioCodecContext = avcodec_alloc_context();
|
||||||
AudioCodecContext->extradata = (uint8_t *)TI->CodecPrivate;
|
InitializeCodecContextFromMatroskaTrackInfo(TI, AudioCodecContext);
|
||||||
AudioCodecContext->extradata_size = TI->CodecPrivateSize;
|
|
||||||
AudioContexts[i].CodecContext = AudioCodecContext;
|
AudioContexts[i].CodecContext = AudioCodecContext;
|
||||||
|
|
||||||
if (TI->CompEnabled) {
|
if (TI->CompEnabled) {
|
||||||
|
@ -102,8 +106,9 @@ FFMS_Index *FFMatroskaIndexer::DoIndexing() {
|
||||||
if (AudioContexts[i].CS == NULL) {
|
if (AudioContexts[i].CS == NULL) {
|
||||||
av_freep(&AudioCodecContext);
|
av_freep(&AudioCodecContext);
|
||||||
AudioContexts[i].CodecContext = NULL;
|
AudioContexts[i].CodecContext = NULL;
|
||||||
throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED,
|
std::ostringstream buf;
|
||||||
boost::format("Can't create decompressor: %1%") % ErrorMessage);
|
buf << "Can't create decompressor: " << ErrorMessage;
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,17 +47,20 @@ FFMatroskaVideo::FFMatroskaVideo(const char *SourceFile, int Track,
|
||||||
Frames = (*Index)[VideoTrack];
|
Frames = (*Index)[VideoTrack];
|
||||||
|
|
||||||
MC.ST.fp = ffms_fopen(SourceFile, "rb");
|
MC.ST.fp = ffms_fopen(SourceFile, "rb");
|
||||||
if (MC.ST.fp == NULL)
|
if (MC.ST.fp == NULL) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Can't open '%1%': %2%") % SourceFile % strerror(errno));
|
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);
|
setvbuf(MC.ST.fp, NULL, _IOFBF, CACHESIZE);
|
||||||
|
|
||||||
MF = mkv_OpenEx(&MC.ST.base, 0, 0, ErrorMessage, sizeof(ErrorMessage));
|
MF = mkv_OpenEx(&MC.ST.base, 0, 0, ErrorMessage, sizeof(ErrorMessage));
|
||||||
if (MF == NULL) {
|
if (MF == NULL) {
|
||||||
fclose(MC.ST.fp);
|
fclose(MC.ST.fp);
|
||||||
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Can't parse Matroska file: %1%") % ErrorMessage);
|
buf << "Can't parse Matroska file: " << ErrorMessage;
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
TI = mkv_GetTrackInfo(MF, VideoTrack);
|
TI = mkv_GetTrackInfo(MF, VideoTrack);
|
||||||
|
@ -66,8 +69,9 @@ FFMatroskaVideo::FFMatroskaVideo(const char *SourceFile, int Track,
|
||||||
CS = cs_Create(MF, VideoTrack, ErrorMessage, sizeof(ErrorMessage));
|
CS = cs_Create(MF, VideoTrack, ErrorMessage, sizeof(ErrorMessage));
|
||||||
if (CS == NULL) {
|
if (CS == NULL) {
|
||||||
Free(false);
|
Free(false);
|
||||||
throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED,
|
std::ostringstream buf;
|
||||||
boost::format("Can't create decompressor: %1%") % ErrorMessage);
|
buf << "Can't create decompressor: " << ErrorMessage;
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 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 () {
|
FFMS_Exception::~FFMS_Exception() throw () {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,9 +134,11 @@ void ReadFrame(uint64_t FilePos, unsigned int &FrameSize, CompressedStream *CS,
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int ReadBytes = cs_ReadData(CS, Context.CSBuffer, sizeof(Context.CSBuffer));
|
int ReadBytes = cs_ReadData(CS, Context.CSBuffer, sizeof(Context.CSBuffer));
|
||||||
if (ReadBytes < 0)
|
if (ReadBytes < 0) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Error decompressing data: %1%") % cs_GetLastError(CS));
|
buf << "Error decompressing data: " << cs_GetLastError(CS);
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str());
|
||||||
|
}
|
||||||
|
|
||||||
if (ReadBytes == 0) {
|
if (ReadBytes == 0) {
|
||||||
FrameSize = DecompressedFrameSize;
|
FrameSize = DecompressedFrameSize;
|
||||||
|
@ -160,9 +159,11 @@ void ReadFrame(uint64_t FilePos, unsigned int &FrameSize, CompressedStream *CS,
|
||||||
DecompressedFrameSize += ReadBytes;
|
DecompressedFrameSize += ReadBytes;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (fseeko(Context.ST.fp, FilePos, SEEK_SET))
|
if (fseeko(Context.ST.fp, FilePos, SEEK_SET)) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_SEEKING,
|
std::ostringstream buf;
|
||||||
boost::format("fseek(): %1%") % strerror(errno));
|
buf << "fseek(): " << strerror(errno);
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_SEEKING, buf.str());
|
||||||
|
}
|
||||||
|
|
||||||
if (Context.BufferSize < FrameSize) {
|
if (Context.BufferSize < FrameSize) {
|
||||||
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,
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
|
||||||
"Unexpected EOF while reading frame");
|
"Unexpected EOF while reading frame");
|
||||||
} else {
|
} else {
|
||||||
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_SEEKING,
|
std::ostringstream buf;
|
||||||
boost::format("Error reading frame: %1%") % strerror(errno));
|
buf << "Error reading frame: " << strerror(errno);
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_SEEKING, buf.str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
|
||||||
|
@ -202,7 +204,7 @@ void InitNullPacket(AVPacket &pkt) {
|
||||||
|
|
||||||
bool IsNVOP(AVPacket &pkt) {
|
bool IsNVOP(AVPacket &pkt) {
|
||||||
const uint8_t MPEG4NVOP[] = { 0x00, 0x00, 0x01, 0xB6 };
|
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) {
|
void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames) {
|
||||||
|
@ -454,9 +456,11 @@ CComPtr<IMMContainer> HaaliOpenFile(const char *SourceFile, enum FFMS_Sources So
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext) {
|
void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext) {
|
||||||
if (av_open_input_file(&FormatContext, SourceFile, NULL, 0, NULL) != 0)
|
if (av_open_input_file(&FormatContext, SourceFile, NULL, 0, NULL) != 0) {
|
||||||
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
|
std::ostringstream buf;
|
||||||
boost::format("Couldn't open '%1'") % SourceFile);
|
buf << "Couldn't open '" << SourceFile << "'";
|
||||||
|
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, buf.str());
|
||||||
|
}
|
||||||
|
|
||||||
if (av_find_stream_info(FormatContext) < 0) {
|
if (av_find_stream_info(FormatContext) < 0) {
|
||||||
av_close_input_file(FormatContext);
|
av_close_input_file(FormatContext);
|
||||||
|
|
|
@ -22,9 +22,9 @@
|
||||||
#define UTILS_H
|
#define UTILS_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <boost/format.hpp>
|
|
||||||
#include "ffms.h"
|
#include "ffms.h"
|
||||||
#include "matroskaparser.h"
|
#include "matroskaparser.h"
|
||||||
|
|
||||||
|
@ -78,7 +78,6 @@ private:
|
||||||
public:
|
public:
|
||||||
FFMS_Exception(int ErrorType, int SubType, const char *Message = "");
|
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 std::string &Message);
|
||||||
FFMS_Exception(int ErrorType, int SubType, const boost::format &Message);
|
|
||||||
~FFMS_Exception() throw ();
|
~FFMS_Exception() throw ();
|
||||||
const std::string &GetErrorMessage() const;
|
const std::string &GetErrorMessage() const;
|
||||||
int CopyOut(FFMS_ErrorInfo *ErrorInfo) const;
|
int CopyOut(FFMS_ErrorInfo *ErrorInfo) const;
|
||||||
|
|
|
@ -32,6 +32,7 @@ extern "C" {
|
||||||
#include "ffmscompat.h"
|
#include "ffmscompat.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
#include "indexing.h"
|
#include "indexing.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "ffms.h"
|
#include "ffms.h"
|
||||||
|
|
Loading…
Reference in a new issue