mirror of https://github.com/odrling/Aegisub
Update ffms to r140.
Originally committed to SVN as r3367.
This commit is contained in:
parent
d615fcb3ad
commit
fc29062da1
|
@ -21,6 +21,9 @@
|
|||
#ifndef FFMS_H
|
||||
#define FFMS_H
|
||||
|
||||
// Version format: major - minor - micro
|
||||
#define FFMS_VERSION ((2 << 16) | (0 << 8) | 11)
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -43,11 +46,18 @@
|
|||
# define FFMS_API(ret) EXTERN_C ret FFMS_CC
|
||||
#endif
|
||||
|
||||
FFMS_CLASS_TYPE FFVideo;
|
||||
FFMS_CLASS_TYPE FFAudio;
|
||||
FFMS_CLASS_TYPE FFIndexer;
|
||||
FFMS_CLASS_TYPE FFIndex;
|
||||
FFMS_CLASS_TYPE FFTrack;
|
||||
FFMS_CLASS_TYPE FFMS_VideoSource;
|
||||
FFMS_CLASS_TYPE FFMS_AudioSource;
|
||||
FFMS_CLASS_TYPE FFMS_Indexer;
|
||||
FFMS_CLASS_TYPE FFMS_Index;
|
||||
FFMS_CLASS_TYPE FFMS_Track;
|
||||
|
||||
enum FFMS_Sources {
|
||||
FFMS_SOURCE_LAVF = 0x00,
|
||||
FFMS_SOURCE_MATROSKA = 0x01,
|
||||
FFMS_SOURCE_HAALIMPEG = 0x02,
|
||||
FFMS_SOURCE_HAALIOGG = 0x04
|
||||
};
|
||||
|
||||
enum FFMS_CPUFeatures {
|
||||
FFMS_CPU_CAPS_MMX = 0x01,
|
||||
|
@ -119,7 +129,7 @@ enum FFMS_Resizers {
|
|||
FFMS_RESIZER_SPLINE = 0x400
|
||||
};
|
||||
|
||||
struct FFAVFrame {
|
||||
struct FFMS_Frame {
|
||||
uint8_t *Data[4];
|
||||
int Linesize[4];
|
||||
int EncodedWidth;
|
||||
|
@ -135,18 +145,18 @@ struct FFAVFrame {
|
|||
char PictType;
|
||||
};
|
||||
|
||||
struct FFTrackTimeBase {
|
||||
struct FFMS_TrackTimeBase {
|
||||
int64_t Num;
|
||||
int64_t Den;
|
||||
};
|
||||
|
||||
#define FFMS_FRAMEINFO_COMMON int64_t DTS; int RepeatPict; bool KeyFrame;
|
||||
|
||||
struct FFFrameInfo {
|
||||
struct FFMS_FrameInfo {
|
||||
FFMS_FRAMEINFO_COMMON
|
||||
};
|
||||
|
||||
struct FFVideoProperties {
|
||||
struct FFMS_VideoProperties {
|
||||
int Width;
|
||||
int Height;
|
||||
int FPSDenominator;
|
||||
|
@ -165,7 +175,7 @@ struct FFVideoProperties {
|
|||
double LastTime;
|
||||
};
|
||||
|
||||
struct FFAudioProperties {
|
||||
struct FFMS_AudioProperties {
|
||||
int SampleFormat;
|
||||
int SampleRate;
|
||||
int BitsPerSample;
|
||||
|
@ -176,48 +186,63 @@ struct FFAudioProperties {
|
|||
double LastTime;
|
||||
};
|
||||
|
||||
#ifdef FFMS_BETA_10_COMPAT
|
||||
typedef FFMS_VideoSource FFVideo;
|
||||
typedef FFMS_AudioSource FFAudio;
|
||||
typedef FFMS_Indexer FFIndexer;
|
||||
typedef FFMS_Index FFIndex;
|
||||
typedef FFMS_Track FFTrack;
|
||||
typedef FFMS_Frame FFAVFrame;
|
||||
typedef FFMS_TrackTimeBase FFTrackTimeBase;
|
||||
typedef FFMS_FrameInfo FFFrameInfo;
|
||||
typedef FFMS_VideoProperties FFVideoProperties;
|
||||
typedef FFMS_AudioProperties FFAudioProperties;
|
||||
#endif
|
||||
|
||||
typedef int (FFMS_CC *TIndexCallback)(int64_t Current, int64_t Total, void *ICPrivate);
|
||||
typedef int (FFMS_CC *TAudioNameCallback)(const char *SourceFile, int Track, const FFAudioProperties *AP, char *FileName, int FNSize, void *Private);
|
||||
typedef int (FFMS_CC *TAudioNameCallback)(const char *SourceFile, int Track, const FFMS_AudioProperties *AP, char *FileName, int FNSize, void *Private);
|
||||
|
||||
// Most functions return 0 on success
|
||||
// Functions without error message output can be assumed to never fail in a graceful way
|
||||
FFMS_API(void) FFMS_Init(int CPUFeatures);
|
||||
FFMS_API(int) FFMS_GetLogLevel();
|
||||
FFMS_API(void) FFMS_SetLogLevel(int Level);
|
||||
FFMS_API(FFVideo *) FFMS_CreateVideoSource(const char *SourceFile, int Track, FFIndex *Index, const char *PP, int Threads, int SeekMode, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(FFAudio *) FFMS_CreateAudioSource(const char *SourceFile, int Track, FFIndex *Index, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(void) FFMS_DestroyVideoSource(FFVideo *V);
|
||||
FFMS_API(void) FFMS_DestroyAudioSource(FFAudio *A);
|
||||
FFMS_API(const FFVideoProperties *) FFMS_GetVideoProperties(FFVideo *V);
|
||||
FFMS_API(const FFAudioProperties *) FFMS_GetAudioProperties(FFAudio *A);
|
||||
FFMS_API(const FFAVFrame *) FFMS_GetFrame(FFVideo *V, int n, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(const FFAVFrame *) FFMS_GetFrameByTime(FFVideo *V, double Time, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_GetAudio(FFAudio *A, void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_SetOutputFormatV(FFVideo *V, int64_t TargetFormats, int Width, int Height, int Resizer, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(void) FFMS_ResetOutputFormatV(FFVideo *V);
|
||||
FFMS_API(void) FFMS_DestroyIndex(FFIndex *Index);
|
||||
FFMS_API(int) FFMS_GetFirstTrackOfType(FFIndex *Index, int TrackType, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_GetFirstIndexedTrackOfType(FFIndex *Index, int TrackType, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_GetNumTracks(FFIndex *Index);
|
||||
FFMS_API(int) FFMS_GetNumTracksI(FFIndexer *Indexer);
|
||||
FFMS_API(int) FFMS_GetTrackType(FFTrack *T);
|
||||
FFMS_API(int) FFMS_GetTrackTypeI(FFIndexer *Indexer, int Track);
|
||||
FFMS_API(const char *) FFMS_GetCodecNameI(FFIndexer *Indexer, int Track);
|
||||
FFMS_API(int) FFMS_GetNumFrames(FFTrack *T);
|
||||
FFMS_API(const FFFrameInfo *) FFMS_GetFrameInfo(FFTrack *T, int Frame);
|
||||
FFMS_API(FFTrack *) FFMS_GetTrackFromIndex(FFIndex *Index, int Track);
|
||||
FFMS_API(FFTrack *) FFMS_GetTrackFromVideo(FFVideo *V);
|
||||
FFMS_API(FFTrack *) FFMS_GetTrackFromAudio(FFAudio *A);
|
||||
FFMS_API(const FFTrackTimeBase *) FFMS_GetTimeBase(FFTrack *T);
|
||||
FFMS_API(int) FFMS_WriteTimecodes(FFTrack *T, const char *TimecodeFile, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(FFIndex *) FFMS_MakeIndex(const char *SourceFile, int IndexMask, int DumpMask, TAudioNameCallback ANC, void *ANCPrivate, bool IgnoreDecodeErrors, TIndexCallback IC, void *ICPrivate, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_DefaultAudioFilename(const char *SourceFile, int Track, const FFAudioProperties *AP, char *FileName, int FNSize, void *Private);
|
||||
FFMS_API(FFIndexer *) FFMS_CreateIndexer(const char *SourceFile, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(FFIndex *) FFMS_DoIndexing(FFIndexer *Indexer, int IndexMask, int DumpMask, TAudioNameCallback ANC, void *ANCPrivate, bool IgnoreDecodeErrors, TIndexCallback IC, void *ICPrivate, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(void) FFMS_CancelIndexing(FFIndexer *Indexer);
|
||||
FFMS_API(FFIndex *) FFMS_ReadIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_IndexBelongsToFile(FFIndex *Index, const char *SourceFile, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_WriteIndex(const char *IndexFile, FFIndex *Index, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(FFMS_VideoSource *) FFMS_CreateVideoSource(const char *SourceFile, int Track, FFMS_Index *Index, const char *PP, int Threads, int SeekMode, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(FFMS_AudioSource *) FFMS_CreateAudioSource(const char *SourceFile, int Track, FFMS_Index *Index, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(void) FFMS_DestroyVideoSource(FFMS_VideoSource *V);
|
||||
FFMS_API(void) FFMS_DestroyAudioSource(FFMS_AudioSource *A);
|
||||
FFMS_API(const FFMS_VideoProperties *) FFMS_GetVideoProperties(FFMS_VideoSource *V);
|
||||
FFMS_API(const FFMS_AudioProperties *) FFMS_GetAudioProperties(FFMS_AudioSource *A);
|
||||
FFMS_API(const FFMS_Frame *) FFMS_GetFrame(FFMS_VideoSource *V, int n, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(const FFMS_Frame *) FFMS_GetFrameByTime(FFMS_VideoSource *V, double Time, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_GetAudio(FFMS_AudioSource *A, void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_SetOutputFormatV(FFMS_VideoSource *V, int64_t TargetFormats, int Width, int Height, int Resizer, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(void) FFMS_ResetOutputFormatV(FFMS_VideoSource *V);
|
||||
FFMS_API(void) FFMS_DestroyIndex(FFMS_Index *Index);
|
||||
FFMS_API(int) FFMS_GetFirstTrackOfType(FFMS_Index *Index, int TrackType, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_GetFirstIndexedTrackOfType(FFMS_Index *Index, int TrackType, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_GetNumTracks(FFMS_Index *Index);
|
||||
FFMS_API(int) FFMS_GetNumTracksI(FFMS_Indexer *Indexer);
|
||||
FFMS_API(int) FFMS_GetTrackType(FFMS_Track *T);
|
||||
FFMS_API(int) FFMS_GetTrackTypeI(FFMS_Indexer *Indexer, int Track);
|
||||
FFMS_API(const char *) FFMS_GetCodecNameI(FFMS_Indexer *Indexer, int Track);
|
||||
FFMS_API(int) FFMS_GetNumFrames(FFMS_Track *T);
|
||||
FFMS_API(const FFMS_FrameInfo *) FFMS_GetFrameInfo(FFMS_Track *T, int Frame);
|
||||
FFMS_API(FFMS_Track *) FFMS_GetTrackFromIndex(FFMS_Index *Index, int Track);
|
||||
FFMS_API(FFMS_Track *) FFMS_GetTrackFromVideo(FFMS_VideoSource *V);
|
||||
FFMS_API(FFMS_Track *) FFMS_GetTrackFromAudio(FFMS_AudioSource *A);
|
||||
FFMS_API(const FFMS_TrackTimeBase *) FFMS_GetTimeBase(FFMS_Track *T);
|
||||
FFMS_API(int) FFMS_WriteTimecodes(FFMS_Track *T, const char *TimecodeFile, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(FFMS_Index *) FFMS_MakeIndex(const char *SourceFile, int IndexMask, int DumpMask, TAudioNameCallback ANC, void *ANCPrivate, bool IgnoreDecodeErrors, TIndexCallback IC, void *ICPrivate, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_DefaultAudioFilename(const char *SourceFile, int Track, const FFMS_AudioProperties *AP, char *FileName, int FNSize, void *Private);
|
||||
FFMS_API(FFMS_Indexer *) FFMS_CreateIndexer(const char *SourceFile, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(FFMS_Index *) FFMS_DoIndexing(FFMS_Indexer *Indexer, int IndexMask, int DumpMask, TAudioNameCallback ANC, void *ANCPrivate, bool IgnoreDecodeErrors, TIndexCallback IC, void *ICPrivate, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(void) FFMS_CancelIndexing(FFMS_Indexer *Indexer);
|
||||
FFMS_API(FFMS_Index *) FFMS_ReadIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_IndexBelongsToFile(FFMS_Index *Index, const char *SourceFile, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_WriteIndex(const char *IndexFile, FFMS_Index *Index, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_API(int) FFMS_GetPixFmt(const char *Name);
|
||||
FFMS_API(int) FFMS_GetPresentSources();
|
||||
FFMS_API(int) FFMS_GetEnabledSources();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -93,15 +93,15 @@ int64_t TAudioCache::FillRequest(int64_t Start, int64_t Samples, uint8_t *Dst) {
|
|||
return FFMIN(Ret, Start + Samples);
|
||||
}
|
||||
|
||||
/* FFAudio base class */
|
||||
/* FFMS_AudioSource base class */
|
||||
|
||||
FFAudio::FFAudio(const char *SourceFile, FFIndex *Index, char *ErrorMsg, unsigned MsgSize) : DecodingBuffer(AVCODEC_MAX_AUDIO_FRAME_SIZE * 10) {
|
||||
FFMS_AudioSource::FFMS_AudioSource(const char *SourceFile, FFMS_Index *Index, char *ErrorMsg, unsigned MsgSize) : DecodingBuffer(AVCODEC_MAX_AUDIO_FRAME_SIZE * 10) {
|
||||
if (Index->CompareFileSignature(SourceFile, ErrorMsg, MsgSize))
|
||||
throw ErrorMsg;
|
||||
|
||||
CurrentSample = 0;
|
||||
}
|
||||
|
||||
FFAudio::~FFAudio() {
|
||||
FFMS_AudioSource::~FFMS_AudioSource() {
|
||||
|
||||
}
|
||||
|
|
|
@ -68,36 +68,36 @@ public:
|
|||
int64_t FillRequest(int64_t Start, int64_t Samples, uint8_t *Dst);
|
||||
};
|
||||
|
||||
class FFAudio {
|
||||
class FFMS_AudioSource {
|
||||
protected:
|
||||
TAudioCache AudioCache;
|
||||
int64_t CurrentSample;
|
||||
std::vector<uint8_t> DecodingBuffer;
|
||||
FFTrack Frames;
|
||||
FFMS_Track Frames;
|
||||
AVCodecContext *CodecContext;
|
||||
int AudioTrack;
|
||||
FFAudioProperties AP;
|
||||
FFMS_AudioProperties AP;
|
||||
public:
|
||||
FFAudio(const char *SourceFile, FFIndex *Index, char *ErrorMsg, unsigned MsgSize);
|
||||
virtual ~FFAudio();
|
||||
FFTrack *GetFFTrack() { return &Frames; }
|
||||
const FFAudioProperties& GetFFAudioProperties() { return AP; }
|
||||
FFMS_AudioSource(const char *SourceFile, FFMS_Index *Index, char *ErrorMsg, unsigned MsgSize);
|
||||
virtual ~FFMS_AudioSource();
|
||||
FFMS_Track *GetFFTrack() { return &Frames; }
|
||||
const FFMS_AudioProperties& GetAudioProperties() { return AP; }
|
||||
virtual int GetAudio(void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize) = 0;
|
||||
};
|
||||
|
||||
class FFLAVFAudio : public FFAudio {
|
||||
class FFLAVFAudio : public FFMS_AudioSource {
|
||||
private:
|
||||
AVFormatContext *FormatContext;
|
||||
|
||||
int DecodeNextAudioBlock(int64_t *Count, char *ErrorMsg, unsigned MsgSize);
|
||||
void Free(bool CloseCodec);
|
||||
public:
|
||||
FFLAVFAudio(const char *SourceFile, int Track, FFIndex *Index, char *ErrorMsg, unsigned MsgSize);
|
||||
FFLAVFAudio(const char *SourceFile, int Track, FFMS_Index *Index, char *ErrorMsg, unsigned MsgSize);
|
||||
~FFLAVFAudio();
|
||||
int GetAudio(void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize);
|
||||
};
|
||||
|
||||
class FFMatroskaAudio : public FFAudio {
|
||||
class FFMatroskaAudio : public FFMS_AudioSource {
|
||||
private:
|
||||
MatroskaFile *MF;
|
||||
MatroskaReaderContext MC;
|
||||
|
@ -107,14 +107,14 @@ private:
|
|||
int DecodeNextAudioBlock(int64_t *Count, int AudioBlock, char *ErrorMsg, unsigned MsgSize);
|
||||
void Free(bool CloseCodec);
|
||||
public:
|
||||
FFMatroskaAudio(const char *SourceFile, int Track, FFIndex *Index, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMatroskaAudio(const char *SourceFile, int Track, FFMS_Index *Index, char *ErrorMsg, unsigned MsgSize);
|
||||
~FFMatroskaAudio();
|
||||
int GetAudio(void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize);
|
||||
};
|
||||
|
||||
#ifdef HAALISOURCE
|
||||
|
||||
class FFHaaliAudio : public FFAudio {
|
||||
class FFHaaliAudio : public FFMS_AudioSource {
|
||||
private:
|
||||
CComPtr<IMMContainer> pMMC;
|
||||
std::vector<uint8_t> CodecPrivate;
|
||||
|
@ -122,7 +122,7 @@ private:
|
|||
void Free(bool CloseCodec);
|
||||
int DecodeNextAudioBlock(int64_t *AFirstStartTime, int64_t *Count, char *ErrorMsg, unsigned MsgSize);
|
||||
public:
|
||||
FFHaaliAudio(const char *SourceFile, int Track, FFIndex *Index, int SourceMode, char *ErrorMsg, unsigned MsgSize);
|
||||
FFHaaliAudio(const char *SourceFile, int Track, FFMS_Index *Index, int SourceMode, char *ErrorMsg, unsigned MsgSize);
|
||||
~FFHaaliAudio();
|
||||
int GetAudio(void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize);
|
||||
};
|
||||
|
|
|
@ -83,9 +83,9 @@ Done:
|
|||
return Ret;
|
||||
}
|
||||
|
||||
FFHaaliAudio::FFHaaliAudio(const char *SourceFile, int Track, FFIndex *Index,
|
||||
FFHaaliAudio::FFHaaliAudio(const char *SourceFile, int Track, FFMS_Index *Index,
|
||||
int SourceMode, char *ErrorMsg, unsigned MsgSize)
|
||||
: FFAudio(SourceFile, Index, ErrorMsg, MsgSize) {
|
||||
: FFMS_AudioSource(SourceFile, Index, ErrorMsg, MsgSize) {
|
||||
AVCodec *Codec = NULL;
|
||||
CodecContext = NULL;
|
||||
AudioTrack = Track;
|
||||
|
@ -96,9 +96,9 @@ FFHaaliAudio::FFHaaliAudio(const char *SourceFile, int Track, FFIndex *Index,
|
|||
throw ErrorMsg;
|
||||
}
|
||||
|
||||
CLSID clsid = HAALI_TS_Parser;
|
||||
CLSID clsid = HAALI_MPEG_PARSER;
|
||||
if (SourceMode == 1)
|
||||
clsid = HAALI_OGM_Parser;
|
||||
clsid = HAALI_OGG_PARSER;
|
||||
|
||||
if (FAILED(pMMC.CoCreateInstance(clsid))) {
|
||||
snprintf(ErrorMsg, MsgSize, "Can't create parser");
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
|
||||
|
||||
FFHaaliIndexer::FFHaaliIndexer(const char *Filename, int SourceMode, char *ErrorMsg, unsigned MsgSize) : FFIndexer(Filename, ErrorMsg, MsgSize) {
|
||||
FFHaaliIndexer::FFHaaliIndexer(const char *Filename, int SourceMode, char *ErrorMsg, unsigned MsgSize) : FFMS_Indexer(Filename, ErrorMsg, MsgSize) {
|
||||
SourceFile = Filename;
|
||||
this->SourceMode = SourceMode;
|
||||
memset(TrackType, FFMS_TYPE_UNKNOWN, sizeof(TrackType));
|
||||
|
@ -33,9 +33,9 @@ FFHaaliIndexer::FFHaaliIndexer(const char *Filename, int SourceMode, char *Error
|
|||
memset(CodecPrivateSize, 0, sizeof(CodecPrivateSize));
|
||||
Duration = 0;
|
||||
|
||||
CLSID clsid = HAALI_TS_Parser;
|
||||
CLSID clsid = HAALI_MPEG_PARSER;
|
||||
if (SourceMode == 1)
|
||||
clsid = HAALI_OGM_Parser;
|
||||
clsid = HAALI_OGG_PARSER;
|
||||
|
||||
if (FAILED(pMMC.CoCreateInstance(clsid))) {
|
||||
snprintf(ErrorMsg, MsgSize, "Can't create parser");
|
||||
|
@ -116,17 +116,17 @@ FFHaaliIndexer::FFHaaliIndexer(const char *Filename, int SourceMode, char *Error
|
|||
}
|
||||
}
|
||||
|
||||
FFIndex *FFHaaliIndexer::DoIndexing(char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_Index *FFHaaliIndexer::DoIndexing(char *ErrorMsg, unsigned MsgSize) {
|
||||
std::vector<SharedAudioContext> AudioContexts(NumTracks, SharedAudioContext(true));
|
||||
std::vector<SharedVideoContext> VideoContexts(NumTracks, SharedVideoContext(true));
|
||||
|
||||
std::auto_ptr<FFIndex> TrackIndices(new FFIndex(Filesize, Digest));
|
||||
TrackIndices->Decoder = 2;
|
||||
std::auto_ptr<FFMS_Index> TrackIndices(new FFMS_Index(Filesize, Digest));
|
||||
TrackIndices->Decoder = FFMS_SOURCE_HAALIMPEG;
|
||||
if (SourceMode == 1)
|
||||
TrackIndices->Decoder = 3;
|
||||
TrackIndices->Decoder = FFMS_SOURCE_HAALIOGG;
|
||||
|
||||
for (int i = 0; i < NumTracks; i++) {
|
||||
TrackIndices->push_back(FFTrack(1, 1000000, TrackType[i]));
|
||||
TrackIndices->push_back(FFMS_Track(1, 1000000, TrackType[i]));
|
||||
|
||||
if (TrackType[i] == FFMS_TYPE_VIDEO && Codec[i] && (VideoContexts[i].Parser = av_parser_init(Codec[i]->id))) {
|
||||
|
||||
|
|
|
@ -31,9 +31,9 @@ void FFHaaliVideo::Free(bool CloseCodec) {
|
|||
}
|
||||
|
||||
FFHaaliVideo::FFHaaliVideo(const char *SourceFile, int Track,
|
||||
FFIndex *Index, const char *PP,
|
||||
FFMS_Index *Index, const char *PP,
|
||||
int Threads, int SourceMode, char *ErrorMsg, unsigned MsgSize)
|
||||
: FFVideo(SourceFile, Index, ErrorMsg, MsgSize) {
|
||||
: FFMS_VideoSource(SourceFile, Index, ErrorMsg, MsgSize) {
|
||||
|
||||
BitStreamFilter = NULL;
|
||||
AVCodec *Codec = NULL;
|
||||
|
@ -46,9 +46,9 @@ FFHaaliVideo::FFHaaliVideo(const char *SourceFile, int Track,
|
|||
throw ErrorMsg;
|
||||
}
|
||||
|
||||
CLSID clsid = HAALI_TS_Parser;
|
||||
CLSID clsid = HAALI_MPEG_PARSER;
|
||||
if (SourceMode == 1)
|
||||
clsid = HAALI_OGM_Parser;
|
||||
clsid = HAALI_OGG_PARSER;
|
||||
|
||||
if (FAILED(pMMC.CoCreateInstance(clsid))) {
|
||||
snprintf(ErrorMsg, MsgSize, "Can't create parser");
|
||||
|
@ -249,10 +249,9 @@ Done:
|
|||
return 0;
|
||||
}
|
||||
|
||||
FFAVFrame *FFHaaliVideo::GetFrame(int n, char *ErrorMsg, unsigned MsgSize) {
|
||||
// PPFrame always holds frame LastFrameNum even if no PP is applied
|
||||
FFMS_Frame *FFHaaliVideo::GetFrame(int n, char *ErrorMsg, unsigned MsgSize) {
|
||||
if (LastFrameNum == n)
|
||||
return OutputFrame(DecodeFrame, ErrorMsg, MsgSize);
|
||||
return &LocalFrame;
|
||||
|
||||
bool HasSeeked = false;
|
||||
int SeekOffset = 0;
|
||||
|
|
|
@ -27,9 +27,9 @@ void FFLAVFAudio::Free(bool CloseCodec) {
|
|||
av_close_input_file(FormatContext);
|
||||
}
|
||||
|
||||
FFLAVFAudio::FFLAVFAudio(const char *SourceFile, int Track, FFIndex *Index,
|
||||
FFLAVFAudio::FFLAVFAudio(const char *SourceFile, int Track, FFMS_Index *Index,
|
||||
char *ErrorMsg, unsigned MsgSize)
|
||||
: FFAudio(SourceFile, Index, ErrorMsg, MsgSize){
|
||||
: FFMS_AudioSource(SourceFile, Index, ErrorMsg, MsgSize){
|
||||
FormatContext = NULL;
|
||||
AVCodec *Codec = NULL;
|
||||
AudioTrack = Track;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
|
||||
|
||||
FFLAVFIndexer::FFLAVFIndexer(const char *Filename, AVFormatContext *FormatContext, char *ErrorMsg, unsigned MsgSize) : FFIndexer(Filename, ErrorMsg, MsgSize) {
|
||||
FFLAVFIndexer::FFLAVFIndexer(const char *Filename, AVFormatContext *FormatContext, char *ErrorMsg, unsigned MsgSize) : FFMS_Indexer(Filename, ErrorMsg, MsgSize) {
|
||||
SourceFile = Filename;
|
||||
this->FormatContext = FormatContext;
|
||||
|
||||
|
@ -37,15 +37,15 @@ FFLAVFIndexer::~FFLAVFIndexer() {
|
|||
av_close_input_file(FormatContext);
|
||||
}
|
||||
|
||||
FFIndex *FFLAVFIndexer::DoIndexing(char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_Index *FFLAVFIndexer::DoIndexing(char *ErrorMsg, unsigned MsgSize) {
|
||||
std::vector<SharedAudioContext> AudioContexts(FormatContext->nb_streams, SharedAudioContext(false));
|
||||
std::vector<SharedVideoContext> VideoContexts(FormatContext->nb_streams, SharedVideoContext(false));
|
||||
|
||||
std::auto_ptr<FFIndex> TrackIndices(new FFIndex(Filesize, Digest));
|
||||
TrackIndices->Decoder = 0;
|
||||
std::auto_ptr<FFMS_Index> TrackIndices(new FFMS_Index(Filesize, Digest));
|
||||
TrackIndices->Decoder = FFMS_SOURCE_LAVF;
|
||||
|
||||
for (unsigned int i = 0; i < FormatContext->nb_streams; i++) {
|
||||
TrackIndices->push_back(FFTrack((int64_t)FormatContext->streams[i]->time_base.num * 1000,
|
||||
TrackIndices->push_back(FFMS_Track((int64_t)FormatContext->streams[i]->time_base.num * 1000,
|
||||
FormatContext->streams[i]->time_base.den,
|
||||
static_cast<FFMS_TrackType>(FormatContext->streams[i]->codec->codec_type)));
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@ void FFLAVFVideo::Free(bool CloseCodec) {
|
|||
av_close_input_file(FormatContext);
|
||||
}
|
||||
|
||||
FFLAVFVideo::FFLAVFVideo(const char *SourceFile, int Track, FFIndex *Index,
|
||||
FFLAVFVideo::FFLAVFVideo(const char *SourceFile, int Track, FFMS_Index *Index,
|
||||
const char *PP, int Threads, int SeekMode, char *ErrorMsg, unsigned MsgSize)
|
||||
: FFVideo(SourceFile, Index, ErrorMsg, MsgSize) {
|
||||
: FFMS_VideoSource(SourceFile, Index, ErrorMsg, MsgSize) {
|
||||
|
||||
FormatContext = NULL;
|
||||
AVCodec *Codec = NULL;
|
||||
|
@ -170,10 +170,9 @@ Done:
|
|||
return 0;
|
||||
}
|
||||
|
||||
FFAVFrame *FFLAVFVideo::GetFrame(int n, char *ErrorMsg, unsigned MsgSize) {
|
||||
// PPFrame always holds frame LastFrameNum even if no PP is applied
|
||||
FFMS_Frame *FFLAVFVideo::GetFrame(int n, char *ErrorMsg, unsigned MsgSize) {
|
||||
if (LastFrameNum == n)
|
||||
return OutputFrame(DecodeFrame, ErrorMsg, MsgSize);
|
||||
return &LocalFrame;
|
||||
|
||||
bool HasSeeked = false;
|
||||
int SeekOffset = 0;
|
||||
|
|
|
@ -33,8 +33,8 @@ void FFMatroskaAudio::Free(bool CloseCodec) {
|
|||
}
|
||||
|
||||
FFMatroskaAudio::FFMatroskaAudio(const char *SourceFile, int Track,
|
||||
FFIndex *Index, char *ErrorMsg, unsigned MsgSize)
|
||||
: FFAudio(SourceFile, Index, ErrorMsg, MsgSize) {
|
||||
FFMS_Index *Index, char *ErrorMsg, unsigned MsgSize)
|
||||
: FFMS_AudioSource(SourceFile, Index, ErrorMsg, MsgSize) {
|
||||
CodecContext = NULL;
|
||||
AVCodec *Codec = NULL;
|
||||
TrackInfo *TI = NULL;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
|
||||
|
||||
FFMatroskaIndexer::FFMatroskaIndexer(const char *Filename, char *ErrorMsg, unsigned MsgSize) : FFIndexer(Filename, ErrorMsg, MsgSize) {
|
||||
FFMatroskaIndexer::FFMatroskaIndexer(const char *Filename, char *ErrorMsg, unsigned MsgSize) : FFMS_Indexer(Filename, ErrorMsg, MsgSize) {
|
||||
memset(Codec, 0, sizeof(Codec));
|
||||
SourceFile = Filename;
|
||||
char ErrorMessage[256];
|
||||
|
@ -55,17 +55,17 @@ FFMatroskaIndexer::~FFMatroskaIndexer() {
|
|||
fclose(MC.ST.fp);
|
||||
}
|
||||
|
||||
FFIndex *FFMatroskaIndexer::DoIndexing(char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_Index *FFMatroskaIndexer::DoIndexing(char *ErrorMsg, unsigned MsgSize) {
|
||||
char ErrorMessage[256];
|
||||
std::vector<SharedAudioContext> AudioContexts(mkv_GetNumTracks(MF), SharedAudioContext(true));
|
||||
std::vector<SharedVideoContext> VideoContexts(mkv_GetNumTracks(MF), SharedVideoContext(true));
|
||||
|
||||
std::auto_ptr<FFIndex> TrackIndices(new FFIndex(Filesize, Digest));
|
||||
TrackIndices->Decoder = 1;
|
||||
std::auto_ptr<FFMS_Index> TrackIndices(new FFMS_Index(Filesize, Digest));
|
||||
TrackIndices->Decoder = FFMS_SOURCE_MATROSKA;
|
||||
|
||||
for (unsigned int i = 0; i < mkv_GetNumTracks(MF); i++) {
|
||||
TrackInfo *TI = mkv_GetTrackInfo(MF, i);
|
||||
TrackIndices->push_back(FFTrack(mkv_TruncFloat(mkv_GetTrackInfo(MF, i)->TimecodeScale), 1000000, HaaliTrackTypeToFFTrackType(mkv_GetTrackInfo(MF, i)->Type)));
|
||||
TrackIndices->push_back(FFMS_Track(mkv_TruncFloat(mkv_GetTrackInfo(MF, i)->TimecodeScale), 1000000, HaaliTrackTypeToFFTrackType(mkv_GetTrackInfo(MF, i)->Type)));
|
||||
|
||||
if (HaaliTrackTypeToFFTrackType(TI->Type) == FFMS_TYPE_VIDEO && Codec[i] && (VideoContexts[i].Parser = av_parser_init(Codec[i]->id))) {
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "ffvideosource.h"
|
||||
|
||||
|
||||
|
||||
void FFMatroskaVideo::Free(bool CloseCodec) {
|
||||
if (CS)
|
||||
cs_Destroy(CS);
|
||||
|
@ -33,9 +35,9 @@ void FFMatroskaVideo::Free(bool CloseCodec) {
|
|||
}
|
||||
|
||||
FFMatroskaVideo::FFMatroskaVideo(const char *SourceFile, int Track,
|
||||
FFIndex *Index, const char *PP,
|
||||
FFMS_Index *Index, const char *PP,
|
||||
int Threads, char *ErrorMsg, unsigned MsgSize)
|
||||
: FFVideo(SourceFile, Index, ErrorMsg, MsgSize) {
|
||||
: FFMS_VideoSource(SourceFile, Index, ErrorMsg, MsgSize) {
|
||||
|
||||
AVCodec *Codec = NULL;
|
||||
CodecContext = NULL;
|
||||
|
@ -195,10 +197,9 @@ Done:
|
|||
return 0;
|
||||
}
|
||||
|
||||
FFAVFrame *FFMatroskaVideo::GetFrame(int n, char *ErrorMsg, unsigned MsgSize) {
|
||||
// PPFrame always holds frame LastFrameNum even if no PP is applied
|
||||
FFMS_Frame *FFMatroskaVideo::GetFrame(int n, char *ErrorMsg, unsigned MsgSize) {
|
||||
if (LastFrameNum == n)
|
||||
return OutputFrame(DecodeFrame, ErrorMsg, MsgSize);
|
||||
return &LocalFrame;
|
||||
|
||||
bool HasSeeked = false;
|
||||
|
||||
|
|
|
@ -27,15 +27,16 @@
|
|||
|
||||
|
||||
|
||||
static bool FFmpegInited = false;
|
||||
static bool FFmpegInited = false;
|
||||
bool HasHaaliMPEG = false;
|
||||
bool HasHaaliOGG = false;
|
||||
int CPUFeatures = 0;
|
||||
|
||||
#ifdef FFMS_WIN_DEBUG
|
||||
|
||||
extern "C" int av_log_level;
|
||||
|
||||
void av_log_windebug_callback(void* ptr, int level, const char* fmt, va_list vl)
|
||||
{
|
||||
void av_log_windebug_callback(void* ptr, int level, const char* fmt, va_list vl) {
|
||||
static int print_prefix=1;
|
||||
static int count;
|
||||
static char line[1024], prev[1024];
|
||||
|
@ -75,6 +76,13 @@ FFMS_API(void) FFMS_Init(int CPUFeatures) {
|
|||
av_log_set_level(AV_LOG_QUIET);
|
||||
#endif
|
||||
::CPUFeatures = CPUFeatures;
|
||||
#ifdef HAALISOURCE
|
||||
CComPtr<IMMContainer> pMMC;
|
||||
HasHaaliMPEG = !FAILED(pMMC.CoCreateInstance(HAALI_MPEG_PARSER));
|
||||
pMMC = NULL;
|
||||
HasHaaliOGG = !FAILED(pMMC.CoCreateInstance(HAALI_OGG_PARSER));
|
||||
pMMC = NULL;
|
||||
#endif
|
||||
FFmpegInited = true;
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +95,7 @@ FFMS_API(void) FFMS_SetLogLevel(int Level) {
|
|||
av_log_set_level(Level);
|
||||
}
|
||||
|
||||
FFMS_API(FFVideo *) FFMS_CreateVideoSource(const char *SourceFile, int Track, FFIndex *Index, const char *PP, int Threads, int SeekMode, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_API(FFMS_VideoSource *) FFMS_CreateVideoSource(const char *SourceFile, int Track, FFMS_Index *Index, const char *PP, int Threads, int SeekMode, char *ErrorMsg, unsigned MsgSize) {
|
||||
if (Track < 0 || Track >= static_cast<int>(Index->size())) {
|
||||
snprintf(ErrorMsg, MsgSize, "Out of bounds track index selected");
|
||||
return NULL;
|
||||
|
@ -100,11 +108,21 @@ FFMS_API(FFVideo *) FFMS_CreateVideoSource(const char *SourceFile, int Track, FF
|
|||
|
||||
try {
|
||||
switch (Index->Decoder) {
|
||||
case 0: return new FFLAVFVideo(SourceFile, Track, Index, PP, Threads, SeekMode, ErrorMsg, MsgSize);
|
||||
case 1: return new FFMatroskaVideo(SourceFile, Track, Index, PP, Threads, ErrorMsg, MsgSize);
|
||||
case FFMS_SOURCE_LAVF:
|
||||
return new FFLAVFVideo(SourceFile, Track, Index, PP, Threads, SeekMode, ErrorMsg, MsgSize);
|
||||
case FFMS_SOURCE_MATROSKA:
|
||||
return new FFMatroskaVideo(SourceFile, Track, Index, PP, Threads, ErrorMsg, MsgSize);
|
||||
#ifdef HAALISOURCE
|
||||
case 2: return new FFHaaliVideo(SourceFile, Track, Index, PP, Threads, 0, ErrorMsg, MsgSize);
|
||||
case 3: return new FFHaaliVideo(SourceFile, Track, Index, PP, Threads, 1, ErrorMsg, MsgSize);
|
||||
case FFMS_SOURCE_HAALIMPEG:
|
||||
if (HasHaaliMPEG)
|
||||
return new FFHaaliVideo(SourceFile, Track, Index, PP, Threads, 0, ErrorMsg, MsgSize);
|
||||
snprintf(ErrorMsg, MsgSize, "Haali MPEG/TS source unavailable");
|
||||
return NULL;
|
||||
case FFMS_SOURCE_HAALIOGG:
|
||||
if (HasHaaliOGG)
|
||||
return new FFHaaliVideo(SourceFile, Track, Index, PP, Threads, 1, ErrorMsg, MsgSize);
|
||||
snprintf(ErrorMsg, MsgSize, "Haali OGG/OGM source unavailable");
|
||||
return NULL;
|
||||
#endif
|
||||
default:
|
||||
snprintf(ErrorMsg, MsgSize, "Unsupported format");
|
||||
|
@ -115,7 +133,7 @@ FFMS_API(FFVideo *) FFMS_CreateVideoSource(const char *SourceFile, int Track, FF
|
|||
}
|
||||
}
|
||||
|
||||
FFMS_API(FFAudio *) FFMS_CreateAudioSource(const char *SourceFile, int Track, FFIndex *Index, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_API(FFMS_AudioSource *) FFMS_CreateAudioSource(const char *SourceFile, int Track, FFMS_Index *Index, char *ErrorMsg, unsigned MsgSize) {
|
||||
if (Track < 0 || Track >= static_cast<int>(Index->size())) {
|
||||
snprintf(ErrorMsg, MsgSize, "Out of bounds track index selected");
|
||||
return NULL;
|
||||
|
@ -128,11 +146,21 @@ FFMS_API(FFAudio *) FFMS_CreateAudioSource(const char *SourceFile, int Track, FF
|
|||
|
||||
try {
|
||||
switch (Index->Decoder) {
|
||||
case 0: return new FFLAVFAudio(SourceFile, Track, Index, ErrorMsg, MsgSize);
|
||||
case 1: return new FFMatroskaAudio(SourceFile, Track, Index, ErrorMsg, MsgSize);
|
||||
case FFMS_SOURCE_LAVF:
|
||||
return new FFLAVFAudio(SourceFile, Track, Index, ErrorMsg, MsgSize);
|
||||
case FFMS_SOURCE_MATROSKA:
|
||||
return new FFMatroskaAudio(SourceFile, Track, Index, ErrorMsg, MsgSize);
|
||||
#ifdef HAALISOURCE
|
||||
case 2: return new FFHaaliAudio(SourceFile, Track, Index, 0, ErrorMsg, MsgSize);
|
||||
case 3: return new FFHaaliAudio(SourceFile, Track, Index, 1, ErrorMsg, MsgSize);
|
||||
case FFMS_SOURCE_HAALIMPEG:
|
||||
if (HasHaaliMPEG)
|
||||
return new FFHaaliAudio(SourceFile, Track, Index, 0, ErrorMsg, MsgSize);
|
||||
snprintf(ErrorMsg, MsgSize, "Haali MPEG/TS source unavailable");
|
||||
return NULL;
|
||||
case FFMS_SOURCE_HAALIOGG:
|
||||
if (HasHaaliOGG)
|
||||
return new FFHaaliAudio(SourceFile, Track, Index, 1, ErrorMsg, MsgSize);
|
||||
snprintf(ErrorMsg, MsgSize, "Haali OGG/OGM source unavailable");
|
||||
return NULL;
|
||||
#endif
|
||||
default:
|
||||
snprintf(ErrorMsg, MsgSize, "Unsupported format");
|
||||
|
@ -143,47 +171,47 @@ FFMS_API(FFAudio *) FFMS_CreateAudioSource(const char *SourceFile, int Track, FF
|
|||
}
|
||||
}
|
||||
|
||||
FFMS_API(void) FFMS_DestroyVideoSource(FFVideo *V) {
|
||||
FFMS_API(void) FFMS_DestroyVideoSource(FFMS_VideoSource *V) {
|
||||
delete V;
|
||||
}
|
||||
|
||||
FFMS_API(void) FFMS_DestroyAudioSource(FFAudio *A) {
|
||||
FFMS_API(void) FFMS_DestroyAudioSource(FFMS_AudioSource *A) {
|
||||
delete A;
|
||||
}
|
||||
|
||||
FFMS_API(const FFVideoProperties *) FFMS_GetVideoProperties(FFVideo *V) {
|
||||
return &V->GetFFVideoProperties();
|
||||
FFMS_API(const FFMS_VideoProperties *) FFMS_GetVideoProperties(FFMS_VideoSource *V) {
|
||||
return &V->GetVideoProperties();
|
||||
}
|
||||
|
||||
FFMS_API(const FFAudioProperties *) FFMS_GetAudioProperties(FFAudio *A) {
|
||||
return &A->GetFFAudioProperties();
|
||||
FFMS_API(const FFMS_AudioProperties *) FFMS_GetAudioProperties(FFMS_AudioSource *A) {
|
||||
return &A->GetAudioProperties();
|
||||
}
|
||||
|
||||
FFMS_API(const FFAVFrame *) FFMS_GetFrame(FFVideo *V, int n, char *ErrorMsg, unsigned MsgSize) {
|
||||
return (FFAVFrame *)V->GetFrame(n, ErrorMsg, MsgSize);
|
||||
FFMS_API(const FFMS_Frame *) FFMS_GetFrame(FFMS_VideoSource *V, int n, char *ErrorMsg, unsigned MsgSize) {
|
||||
return (FFMS_Frame *)V->GetFrame(n, ErrorMsg, MsgSize);
|
||||
}
|
||||
|
||||
FFMS_API(const FFAVFrame *) FFMS_GetFrameByTime(FFVideo *V, double Time, char *ErrorMsg, unsigned MsgSize) {
|
||||
return (FFAVFrame *)V->GetFrameByTime(Time, ErrorMsg, MsgSize);
|
||||
FFMS_API(const FFMS_Frame *) FFMS_GetFrameByTime(FFMS_VideoSource *V, double Time, char *ErrorMsg, unsigned MsgSize) {
|
||||
return (FFMS_Frame *)V->GetFrameByTime(Time, ErrorMsg, MsgSize);
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_GetAudio(FFAudio *A, void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_API(int) FFMS_GetAudio(FFMS_AudioSource *A, void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize) {
|
||||
return A->GetAudio(Buf, Start, Count, ErrorMsg, MsgSize);
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_SetOutputFormatV(FFVideo *V, int64_t TargetFormats, int Width, int Height, int Resizer, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_API(int) FFMS_SetOutputFormatV(FFMS_VideoSource *V, int64_t TargetFormats, int Width, int Height, int Resizer, char *ErrorMsg, unsigned MsgSize) {
|
||||
return V->SetOutputFormat(TargetFormats, Width, Height, Resizer, ErrorMsg, MsgSize);
|
||||
}
|
||||
|
||||
FFMS_API(void) FFMS_ResetOutputFormatV(FFVideo *V) {
|
||||
FFMS_API(void) FFMS_ResetOutputFormatV(FFMS_VideoSource *V) {
|
||||
V->ResetOutputFormat();
|
||||
}
|
||||
|
||||
FFMS_API(void) FFMS_DestroyIndex(FFIndex *Index) {
|
||||
FFMS_API(void) FFMS_DestroyIndex(FFMS_Index *Index) {
|
||||
delete Index;
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_GetFirstTrackOfType(FFIndex *Index, int TrackType, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_API(int) FFMS_GetFirstTrackOfType(FFMS_Index *Index, int TrackType, char *ErrorMsg, unsigned MsgSize) {
|
||||
for (int i = 0; i < static_cast<int>(Index->size()); i++)
|
||||
if ((*Index)[i].TT == TrackType)
|
||||
return i;
|
||||
|
@ -191,7 +219,7 @@ FFMS_API(int) FFMS_GetFirstTrackOfType(FFIndex *Index, int TrackType, char *Erro
|
|||
return -1;
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_GetFirstIndexedTrackOfType(FFIndex *Index, int TrackType, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_API(int) FFMS_GetFirstIndexedTrackOfType(FFMS_Index *Index, int TrackType, char *ErrorMsg, unsigned MsgSize) {
|
||||
for (int i = 0; i < static_cast<int>(Index->size()); i++)
|
||||
if ((*Index)[i].TT == TrackType && (*Index)[i].size() > 0)
|
||||
return i;
|
||||
|
@ -199,56 +227,56 @@ FFMS_API(int) FFMS_GetFirstIndexedTrackOfType(FFIndex *Index, int TrackType, cha
|
|||
return -1;
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_GetNumTracks(FFIndex *Index) {
|
||||
FFMS_API(int) FFMS_GetNumTracks(FFMS_Index *Index) {
|
||||
return Index->size();
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_GetNumTracksI(FFIndexer *Indexer) {
|
||||
FFMS_API(int) FFMS_GetNumTracksI(FFMS_Indexer *Indexer) {
|
||||
return Indexer->GetNumberOfTracks();
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_GetTrackType(FFTrack *T) {
|
||||
FFMS_API(int) FFMS_GetTrackType(FFMS_Track *T) {
|
||||
return T->TT;
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_GetTrackTypeI(FFIndexer *Indexer, int Track) {
|
||||
FFMS_API(int) FFMS_GetTrackTypeI(FFMS_Indexer *Indexer, int Track) {
|
||||
return Indexer->GetTrackType(Track);
|
||||
}
|
||||
|
||||
FFMS_API(const char *) FFMS_GetCodecNameI(FFIndexer *Indexer, int Track) {
|
||||
FFMS_API(const char *) FFMS_GetCodecNameI(FFMS_Indexer *Indexer, int Track) {
|
||||
return Indexer->GetTrackCodec(Track);
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_GetNumFrames(FFTrack *T) {
|
||||
FFMS_API(int) FFMS_GetNumFrames(FFMS_Track *T) {
|
||||
return T->size();
|
||||
}
|
||||
|
||||
FFMS_API(const FFFrameInfo *) FFMS_GetFrameInfo(FFTrack *T, int Frame) {
|
||||
return reinterpret_cast<FFFrameInfo *>(&(*T)[Frame]);
|
||||
FFMS_API(const FFMS_FrameInfo *) FFMS_GetFrameInfo(FFMS_Track *T, int Frame) {
|
||||
return reinterpret_cast<FFMS_FrameInfo *>(&(*T)[Frame]);
|
||||
}
|
||||
|
||||
FFMS_API(FFTrack *) FFMS_GetTrackFromIndex(FFIndex *Index, int Track) {
|
||||
FFMS_API(FFMS_Track *) FFMS_GetTrackFromIndex(FFMS_Index *Index, int Track) {
|
||||
return &(*Index)[Track];
|
||||
}
|
||||
|
||||
FFMS_API(FFTrack *) FFMS_GetTrackFromVideo(FFVideo *V) {
|
||||
FFMS_API(FFMS_Track *) FFMS_GetTrackFromVideo(FFMS_VideoSource *V) {
|
||||
return V->GetFFTrack();
|
||||
}
|
||||
|
||||
FFMS_API(FFTrack *) FFMS_GetTrackFromAudio(FFAudio *A) {
|
||||
FFMS_API(FFMS_Track *) FFMS_GetTrackFromAudio(FFMS_AudioSource *A) {
|
||||
return A->GetFFTrack();
|
||||
}
|
||||
|
||||
FFMS_API(const FFTrackTimeBase *) FFMS_GetTimeBase(FFTrack *T) {
|
||||
FFMS_API(const FFMS_TrackTimeBase *) FFMS_GetTimeBase(FFMS_Track *T) {
|
||||
return &T->TB;
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_WriteTimecodes(FFTrack *T, const char *TimecodeFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_API(int) FFMS_WriteTimecodes(FFMS_Track *T, const char *TimecodeFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
return T->WriteTimecodes(TimecodeFile, ErrorMsg, MsgSize);
|
||||
}
|
||||
|
||||
FFMS_API(FFIndex *) FFMS_MakeIndex(const char *SourceFile, int IndexMask, int DumpMask, TAudioNameCallback ANC, void *ANCPrivate, bool IgnoreDecodeErrors, TIndexCallback IC, void *ICPrivate, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFIndexer *Indexer = FFMS_CreateIndexer(SourceFile, ErrorMsg, MsgSize);
|
||||
FFMS_API(FFMS_Index *) FFMS_MakeIndex(const char *SourceFile, int IndexMask, int DumpMask, TAudioNameCallback ANC, void *ANCPrivate, bool IgnoreDecodeErrors, TIndexCallback IC, void *ICPrivate, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_Indexer *Indexer = FFMS_CreateIndexer(SourceFile, ErrorMsg, MsgSize);
|
||||
if (!Indexer)
|
||||
return NULL;
|
||||
return FFMS_DoIndexing(Indexer, IndexMask, DumpMask, ANC, ANCPrivate, IgnoreDecodeErrors, IC, ICPrivate, ErrorMsg, MsgSize);
|
||||
|
@ -270,7 +298,7 @@ static void ReplaceString(std::string &s, std::string from, std::string to) {
|
|||
s.replace(idx, from.length(), to);
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_DefaultAudioFilename(const char *SourceFile, int Track, const FFAudioProperties *AP, char *FileName, int FNSize, void *Private) {
|
||||
FFMS_API(int) FFMS_DefaultAudioFilename(const char *SourceFile, int Track, const FFMS_AudioProperties *AP, char *FileName, int FNSize, void *Private) {
|
||||
std::string s = static_cast<char *>(Private);
|
||||
|
||||
ReplaceString(s, "%sourcefile%", SourceFile);
|
||||
|
@ -289,31 +317,31 @@ FFMS_API(int) FFMS_DefaultAudioFilename(const char *SourceFile, int Track, const
|
|||
}
|
||||
}
|
||||
|
||||
FFMS_API(FFIndexer *) FFMS_CreateIndexer(const char *SourceFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_API(FFMS_Indexer *) FFMS_CreateIndexer(const char *SourceFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
try {
|
||||
return FFIndexer::CreateFFIndexer(SourceFile, ErrorMsg, MsgSize);
|
||||
return FFMS_Indexer::CreateIndexer(SourceFile, ErrorMsg, MsgSize);
|
||||
} catch (...) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
FFMS_API(FFIndex *) FFMS_DoIndexing(FFIndexer *Indexer, int IndexMask, int DumpMask, TAudioNameCallback ANC, void *ANCPrivate, bool IgnoreDecodeErrors, TIndexCallback IC, void *ICPrivate, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_API(FFMS_Index *) FFMS_DoIndexing(FFMS_Indexer *Indexer, int IndexMask, int DumpMask, TAudioNameCallback ANC, void *ANCPrivate, bool IgnoreDecodeErrors, TIndexCallback IC, void *ICPrivate, char *ErrorMsg, unsigned MsgSize) {
|
||||
Indexer->SetIndexMask(IndexMask | DumpMask);
|
||||
Indexer->SetDumpMask(DumpMask);
|
||||
Indexer->SetIgnoreDecodeErrors(IgnoreDecodeErrors);
|
||||
Indexer->SetProgressCallback(IC, ICPrivate);
|
||||
Indexer->SetAudioNameCallback(ANC, ANCPrivate);
|
||||
FFIndex *Index = Indexer->DoIndexing(ErrorMsg, MsgSize);
|
||||
FFMS_Index *Index = Indexer->DoIndexing(ErrorMsg, MsgSize);
|
||||
delete Indexer;
|
||||
return Index;
|
||||
}
|
||||
|
||||
FFMS_API(void) FFMS_CancelIndexing(FFIndexer *Indexer) {
|
||||
FFMS_API(void) FFMS_CancelIndexing(FFMS_Indexer *Indexer) {
|
||||
delete Indexer;
|
||||
}
|
||||
|
||||
FFMS_API(FFIndex *) FFMS_ReadIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFIndex *Index = new FFIndex();
|
||||
FFMS_API(FFMS_Index *) FFMS_ReadIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_Index *Index = new FFMS_Index();
|
||||
if (Index->ReadIndex(IndexFile, ErrorMsg, MsgSize)) {
|
||||
delete Index;
|
||||
return NULL;
|
||||
|
@ -322,14 +350,33 @@ FFMS_API(FFIndex *) FFMS_ReadIndex(const char *IndexFile, char *ErrorMsg, unsign
|
|||
}
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_IndexBelongsToFile(FFIndex *Index, const char *SourceFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_API(int) FFMS_IndexBelongsToFile(FFMS_Index *Index, const char *SourceFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
return Index->CompareFileSignature(SourceFile, ErrorMsg, MsgSize);
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_WriteIndex(const char *IndexFile, FFIndex *Index, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_API(int) FFMS_WriteIndex(const char *IndexFile, FFMS_Index *Index, char *ErrorMsg, unsigned MsgSize) {
|
||||
return Index->WriteIndex(IndexFile, ErrorMsg, MsgSize);
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_GetPixFmt(const char *Name) {
|
||||
return avcodec_get_pix_fmt(Name);
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_GetPresentSources() {
|
||||
int Sources = FFMS_SOURCE_LAVF | FFMS_SOURCE_MATROSKA;
|
||||
#ifdef HAALISOURCE
|
||||
Sources |= FFMS_SOURCE_HAALIMPEG | FFMS_SOURCE_HAALIOGG;
|
||||
#endif
|
||||
return Sources;
|
||||
}
|
||||
|
||||
FFMS_API(int) FFMS_GetEnabledSources() {
|
||||
if (!FFmpegInited)
|
||||
return 0;
|
||||
int Sources = FFMS_SOURCE_LAVF | FFMS_SOURCE_MATROSKA;
|
||||
if (HasHaaliMPEG)
|
||||
Sources |= FFMS_SOURCE_HAALIMPEG;
|
||||
if (HasHaaliOGG)
|
||||
Sources |= FFMS_SOURCE_HAALIOGG;
|
||||
return Sources;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "ffvideosource.h"
|
||||
|
||||
int FFVideo::InitPP(const char *PP, char *ErrorMsg, unsigned MsgSize) {
|
||||
int FFMS_VideoSource::InitPP(const char *PP, char *ErrorMsg, unsigned MsgSize) {
|
||||
if (PP == NULL || !strcmp(PP, ""))
|
||||
return 0;
|
||||
|
||||
|
@ -33,7 +33,7 @@ int FFVideo::InitPP(const char *PP, char *ErrorMsg, unsigned MsgSize) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int FFVideo::ReAdjustPP(PixelFormat VPixelFormat, int Width, int Height, char *ErrorMsg, unsigned MsgSize) {
|
||||
int FFMS_VideoSource::ReAdjustPP(PixelFormat VPixelFormat, int Width, int Height, char *ErrorMsg, unsigned MsgSize) {
|
||||
if (!PPMode)
|
||||
return 0;
|
||||
|
||||
|
@ -59,14 +59,14 @@ int FFVideo::ReAdjustPP(PixelFormat VPixelFormat, int Width, int Height, char *E
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void CopyAVPictureFields(AVPicture &Picture, FFAVFrame &Dst) {
|
||||
static void CopyAVPictureFields(AVPicture &Picture, FFMS_Frame &Dst) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Dst.Data[i] = Picture.data[i];
|
||||
Dst.Linesize[i] = Picture.linesize[i];
|
||||
}
|
||||
}
|
||||
|
||||
FFAVFrame *FFVideo::OutputFrame(AVFrame *Frame, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_Frame *FFMS_VideoSource::OutputFrame(AVFrame *Frame, char *ErrorMsg, unsigned MsgSize) {
|
||||
if (LastFrameWidth != CodecContext->width || LastFrameHeight != CodecContext->height || LastFramePixelFormat != CodecContext->pix_fmt) {
|
||||
if (ReAdjustPP(CodecContext->pix_fmt, CodecContext->width, CodecContext->height, ErrorMsg, MsgSize))
|
||||
return NULL;
|
||||
|
@ -115,7 +115,7 @@ FFAVFrame *FFVideo::OutputFrame(AVFrame *Frame, char *ErrorMsg, unsigned MsgSize
|
|||
return &LocalFrame;
|
||||
}
|
||||
|
||||
FFVideo::FFVideo(const char *SourceFile, FFIndex *Index, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_VideoSource::FFMS_VideoSource(const char *SourceFile, FFMS_Index *Index, char *ErrorMsg, unsigned MsgSize) {
|
||||
if (Index->CompareFileSignature(SourceFile, ErrorMsg, MsgSize))
|
||||
throw ErrorMsg;
|
||||
|
||||
|
@ -140,7 +140,7 @@ FFVideo::FFVideo(const char *SourceFile, FFIndex *Index, char *ErrorMsg, unsigne
|
|||
avpicture_alloc(&SWSFrame, PIX_FMT_GRAY8, 16, 16);
|
||||
}
|
||||
|
||||
FFVideo::~FFVideo() {
|
||||
FFMS_VideoSource::~FFMS_VideoSource() {
|
||||
if (PPMode)
|
||||
pp_free_mode(PPMode);
|
||||
|
||||
|
@ -155,12 +155,12 @@ FFVideo::~FFVideo() {
|
|||
av_freep(&DecodeFrame);
|
||||
}
|
||||
|
||||
FFAVFrame *FFVideo::GetFrameByTime(double Time, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_Frame *FFMS_VideoSource::GetFrameByTime(double Time, char *ErrorMsg, unsigned MsgSize) {
|
||||
int Frame = Frames.ClosestFrameFromDTS(static_cast<int64_t>((Time * 1000 * Frames.TB.Den) / Frames.TB.Num));
|
||||
return GetFrame(Frame, ErrorMsg, MsgSize);
|
||||
}
|
||||
|
||||
int FFVideo::SetOutputFormat(int64_t TargetFormats, int Width, int Height, int Resizer, char *ErrorMsg, unsigned MsgSize) {
|
||||
int FFMS_VideoSource::SetOutputFormat(int64_t TargetFormats, int Width, int Height, int Resizer, char *ErrorMsg, unsigned MsgSize) {
|
||||
this->TargetWidth = Width;
|
||||
this->TargetHeight = Height;
|
||||
this->TargetPixelFormats = TargetFormats;
|
||||
|
@ -168,7 +168,7 @@ int FFVideo::SetOutputFormat(int64_t TargetFormats, int Width, int Height, int R
|
|||
return ReAdjustOutputFormat(TargetFormats, Width, Height, Resizer, ErrorMsg, MsgSize);
|
||||
}
|
||||
|
||||
int FFVideo::ReAdjustOutputFormat(int64_t TargetFormats, int Width, int Height, int Resizer, char *ErrorMsg, unsigned MsgSize) {
|
||||
int FFMS_VideoSource::ReAdjustOutputFormat(int64_t TargetFormats, int Width, int Height, int Resizer, char *ErrorMsg, unsigned MsgSize) {
|
||||
if (SWS) {
|
||||
sws_freeContext(SWS);
|
||||
SWS = NULL;
|
||||
|
@ -203,7 +203,7 @@ int FFVideo::ReAdjustOutputFormat(int64_t TargetFormats, int Width, int Height,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void FFVideo::ResetOutputFormat() {
|
||||
void FFMS_VideoSource::ResetOutputFormat() {
|
||||
if (SWS) {
|
||||
sws_freeContext(SWS);
|
||||
SWS = NULL;
|
||||
|
|
|
@ -45,7 +45,7 @@ extern "C" {
|
|||
# include "guids.h"
|
||||
#endif
|
||||
|
||||
class FFVideo {
|
||||
class FFMS_VideoSource {
|
||||
private:
|
||||
pp_context_t *PPContext;
|
||||
pp_mode_t *PPMode;
|
||||
|
@ -60,31 +60,31 @@ private:
|
|||
AVPicture PPFrame;
|
||||
AVPicture SWSFrame;
|
||||
protected:
|
||||
FFVideoProperties VP;
|
||||
FFAVFrame LocalFrame;
|
||||
FFMS_VideoProperties VP;
|
||||
FFMS_Frame LocalFrame;
|
||||
AVFrame *DecodeFrame;
|
||||
int LastFrameNum;
|
||||
FFTrack Frames;
|
||||
FFMS_Track Frames;
|
||||
int VideoTrack;
|
||||
int CurrentFrame;
|
||||
AVCodecContext *CodecContext;
|
||||
|
||||
FFVideo(const char *SourceFile, FFIndex *Index, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_VideoSource(const char *SourceFile, FFMS_Index *Index, char *ErrorMsg, unsigned MsgSize);
|
||||
int InitPP(const char *PP, char *ErrorMsg, unsigned MsgSize);
|
||||
int ReAdjustPP(PixelFormat VPixelFormat, int Width, int Height, char *ErrorMsg, unsigned MsgSize);
|
||||
FFAVFrame *OutputFrame(AVFrame *Frame, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_Frame *OutputFrame(AVFrame *Frame, char *ErrorMsg, unsigned MsgSize);
|
||||
public:
|
||||
virtual ~FFVideo();
|
||||
const FFVideoProperties& GetFFVideoProperties() { return VP; }
|
||||
FFTrack *GetFFTrack() { return &Frames; }
|
||||
virtual FFAVFrame *GetFrame(int n, char *ErrorMsg, unsigned MsgSize) = 0;
|
||||
FFAVFrame *GetFrameByTime(double Time, char *ErrorMsg, unsigned MsgSize);
|
||||
virtual ~FFMS_VideoSource();
|
||||
const FFMS_VideoProperties& GetVideoProperties() { return VP; }
|
||||
FFMS_Track *GetFFTrack() { return &Frames; }
|
||||
virtual FFMS_Frame *GetFrame(int n, char *ErrorMsg, unsigned MsgSize) = 0;
|
||||
FFMS_Frame *GetFrameByTime(double Time, char *ErrorMsg, unsigned MsgSize);
|
||||
int SetOutputFormat(int64_t TargetFormats, int Width, int Height, int Resizer, char *ErrorMsg, unsigned MsgSize);
|
||||
int ReAdjustOutputFormat(int64_t TargetFormats, int Width, int Height, int Resizer, char *ErrorMsg, unsigned MsgSize);
|
||||
void ResetOutputFormat();
|
||||
};
|
||||
|
||||
class FFLAVFVideo : public FFVideo {
|
||||
class FFLAVFVideo : public FFMS_VideoSource {
|
||||
private:
|
||||
AVFormatContext *FormatContext;
|
||||
int SeekMode;
|
||||
|
@ -92,12 +92,12 @@ private:
|
|||
void Free(bool CloseCodec);
|
||||
int DecodeNextFrame(int64_t *DTS, char *ErrorMsg, unsigned MsgSize);
|
||||
public:
|
||||
FFLAVFVideo(const char *SourceFile, int Track, FFIndex *Index, const char *PP, int Threads, int SeekMode, char *ErrorMsg, unsigned MsgSize);
|
||||
FFLAVFVideo(const char *SourceFile, int Track, FFMS_Index *Index, const char *PP, int Threads, int SeekMode, char *ErrorMsg, unsigned MsgSize);
|
||||
~FFLAVFVideo();
|
||||
FFAVFrame *GetFrame(int n, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_Frame *GetFrame(int n, char *ErrorMsg, unsigned MsgSize);
|
||||
};
|
||||
|
||||
class FFMatroskaVideo : public FFVideo {
|
||||
class FFMatroskaVideo : public FFMS_VideoSource {
|
||||
private:
|
||||
MatroskaFile *MF;
|
||||
MatroskaReaderContext MC;
|
||||
|
@ -107,14 +107,14 @@ private:
|
|||
void Free(bool CloseCodec);
|
||||
int DecodeNextFrame(int64_t *AFirstStartTime, char *ErrorMsg, unsigned MsgSize);
|
||||
public:
|
||||
FFMatroskaVideo(const char *SourceFile, int Track, FFIndex *Index, const char *PP, int Threads, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMatroskaVideo(const char *SourceFile, int Track, FFMS_Index *Index, const char *PP, int Threads, char *ErrorMsg, unsigned MsgSize);
|
||||
~FFMatroskaVideo();
|
||||
FFAVFrame *GetFrame(int n, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_Frame *GetFrame(int n, char *ErrorMsg, unsigned MsgSize);
|
||||
};
|
||||
|
||||
#ifdef HAALISOURCE
|
||||
|
||||
class FFHaaliVideo : public FFVideo {
|
||||
class FFHaaliVideo : public FFMS_VideoSource {
|
||||
private:
|
||||
CComPtr<IMMContainer> pMMC;
|
||||
std::vector<uint8_t> CodecPrivate;
|
||||
|
@ -123,9 +123,9 @@ private:
|
|||
void Free(bool CloseCodec);
|
||||
int DecodeNextFrame(int64_t *AFirstStartTime, char *ErrorMsg, unsigned MsgSize);
|
||||
public:
|
||||
FFHaaliVideo(const char *SourceFile, int Track, FFIndex *Index, const char *PP, int Threads, int SourceMode, char *ErrorMsg, unsigned MsgSize);
|
||||
FFHaaliVideo(const char *SourceFile, int Track, FFMS_Index *Index, const char *PP, int Threads, int SourceMode, char *ErrorMsg, unsigned MsgSize);
|
||||
~FFHaaliVideo();
|
||||
FFAVFrame *GetFrame(int n, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_Frame *GetFrame(int n, char *ErrorMsg, unsigned MsgSize);
|
||||
};
|
||||
|
||||
#endif // HAALISOURCE
|
||||
|
|
|
@ -116,10 +116,10 @@ DEFINE_GUID(MEDIASUBTYPE_WMV3,
|
|||
0x33564d57, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
|
||||
|
||||
// FIXME: move somewhere else?
|
||||
DEFINE_GUID(HAALI_TS_Parser,
|
||||
DEFINE_GUID(HAALI_MPEG_PARSER,
|
||||
0xB841F346, 0x4835, 0x4de8, 0xAA, 0x5E, 0x2E, 0x7C, 0xD2, 0xD4, 0xC4, 0x35);
|
||||
|
||||
DEFINE_GUID(HAALI_OGM_Parser,
|
||||
DEFINE_GUID(HAALI_OGG_PARSER,
|
||||
0xDB43B405, 0x43AA, 0x4F01, 0x82, 0xD8, 0xD8, 0x4D, 0x47, 0xE6, 0x01, 0x9C);
|
||||
|
||||
//DB43B405-43AA-4F01-82D8-D84D47E6019C
|
||||
|
|
|
@ -30,6 +30,9 @@ extern "C" {
|
|||
|
||||
|
||||
|
||||
extern bool HasHaaliMPEG;
|
||||
extern bool HasHaaliOGG;
|
||||
|
||||
struct IndexHeader {
|
||||
uint32_t Id;
|
||||
uint32_t Version;
|
||||
|
@ -102,7 +105,7 @@ TFrameInfo TFrameInfo::AudioFrameInfo(int64_t DTS, int64_t SampleStart, bool Key
|
|||
return TFrameInfo(DTS, SampleStart, 0, KeyFrame, FilePos, FrameSize);
|
||||
}
|
||||
|
||||
int FFTrack::WriteTimecodes(const char *TimecodeFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
int FFMS_Track::WriteTimecodes(const char *TimecodeFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
ffms_fstream Timecodes(TimecodeFile, std::ios::out | std::ios::trunc);
|
||||
|
||||
if (!Timecodes.is_open()) {
|
||||
|
@ -118,14 +121,14 @@ int FFTrack::WriteTimecodes(const char *TimecodeFile, char *ErrorMsg, unsigned M
|
|||
return 0;
|
||||
}
|
||||
|
||||
int FFTrack::FrameFromDTS(int64_t DTS) {
|
||||
int FFMS_Track::FrameFromDTS(int64_t DTS) {
|
||||
for (int i = 0; i < static_cast<int>(size()); i++)
|
||||
if (at(i).DTS == DTS)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int FFTrack::ClosestFrameFromDTS(int64_t DTS) {
|
||||
int FFMS_Track::ClosestFrameFromDTS(int64_t DTS) {
|
||||
int Frame = 0;
|
||||
int64_t BestDiff = 0xFFFFFFFFFFFFFFLL; // big number
|
||||
for (int i = 0; i < static_cast<int>(size()); i++) {
|
||||
|
@ -139,7 +142,7 @@ int FFTrack::ClosestFrameFromDTS(int64_t DTS) {
|
|||
return Frame;
|
||||
}
|
||||
|
||||
int FFTrack::FindClosestVideoKeyFrame(int Frame) {
|
||||
int FFMS_Track::FindClosestVideoKeyFrame(int Frame) {
|
||||
Frame = FFMIN(FFMAX(Frame, 0), static_cast<int>(size()) - 1);
|
||||
for (int i = Frame; i > 0; i--)
|
||||
if (at(i).KeyFrame)
|
||||
|
@ -147,7 +150,7 @@ int FFTrack::FindClosestVideoKeyFrame(int Frame) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int FFTrack::FindClosestAudioKeyFrame(int64_t Sample) {
|
||||
int FFMS_Track::FindClosestAudioKeyFrame(int64_t Sample) {
|
||||
for (size_t i = 0; i < size(); i++) {
|
||||
if (at(i).SampleStart == Sample && at(i).KeyFrame)
|
||||
return i;
|
||||
|
@ -157,19 +160,19 @@ int FFTrack::FindClosestAudioKeyFrame(int64_t Sample) {
|
|||
return size() - 1;
|
||||
}
|
||||
|
||||
FFTrack::FFTrack() {
|
||||
FFMS_Track::FFMS_Track() {
|
||||
this->TT = FFMS_TYPE_UNKNOWN;
|
||||
this->TB.Num = 0;
|
||||
this->TB.Den = 0;
|
||||
}
|
||||
|
||||
FFTrack::FFTrack(int64_t Num, int64_t Den, FFMS_TrackType TT) {
|
||||
FFMS_Track::FFMS_Track(int64_t Num, int64_t Den, FFMS_TrackType TT) {
|
||||
this->TT = TT;
|
||||
this->TB.Num = Num;
|
||||
this->TB.Den = Den;
|
||||
}
|
||||
|
||||
int FFIndex::CalculateFileSignature(const char *Filename, int64_t *Filesize, uint8_t Digest[20], char *ErrorMsg, unsigned MsgSize) {
|
||||
int FFMS_Index::CalculateFileSignature(const char *Filename, int64_t *Filesize, uint8_t Digest[20], char *ErrorMsg, unsigned MsgSize) {
|
||||
// use cstdio because Microsoft's implementation of std::fstream doesn't support files >4GB.
|
||||
// please kill me now.
|
||||
FILE *SFile = ffms_fopen(Filename,"rb");
|
||||
|
@ -179,7 +182,7 @@ int FFIndex::CalculateFileSignature(const char *Filename, int64_t *Filesize, uin
|
|||
return 1;
|
||||
}
|
||||
|
||||
const int BlockSize = 2*1024*1024;
|
||||
const int BlockSize = 1024*1024;
|
||||
std::vector<uint8_t> FileBuffer(BlockSize);
|
||||
std::vector<uint8_t> ctxmem(av_sha1_size);
|
||||
AVSHA1 *ctx = (AVSHA1 *)&ctxmem[0];
|
||||
|
@ -224,12 +227,12 @@ static bool DTSComparison(TFrameInfo FI1, TFrameInfo FI2) {
|
|||
return FI1.DTS < FI2.DTS;
|
||||
}
|
||||
|
||||
void FFIndex::Sort() {
|
||||
for (FFIndex::iterator Cur=begin(); Cur!=end(); Cur++)
|
||||
void FFMS_Index::Sort() {
|
||||
for (FFMS_Index::iterator Cur=begin(); Cur!=end(); Cur++)
|
||||
std::sort(Cur->begin(), Cur->end(), DTSComparison);
|
||||
}
|
||||
|
||||
int FFIndex::CompareFileSignature(const char *Filename, char *ErrorMsg, unsigned MsgSize) {
|
||||
int FFMS_Index::CompareFileSignature(const char *Filename, char *ErrorMsg, unsigned MsgSize) {
|
||||
int64_t CFilesize;
|
||||
uint8_t CDigest[20];
|
||||
CalculateFileSignature(Filename, &CFilesize, CDigest, ErrorMsg, MsgSize);
|
||||
|
@ -242,7 +245,7 @@ int FFIndex::CompareFileSignature(const char *Filename, char *ErrorMsg, unsigned
|
|||
return 0;
|
||||
}
|
||||
|
||||
int FFIndex::WriteIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
int FFMS_Index::WriteIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
ffms_fstream IndexStream(IndexFile, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||
|
||||
if (!IndexStream.is_open()) {
|
||||
|
@ -276,14 +279,14 @@ int FFIndex::WriteIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize)
|
|||
int64_t Frames = at(i).size();
|
||||
IndexStream.write(reinterpret_cast<char *>(&Frames), sizeof(Frames));
|
||||
|
||||
for (FFTrack::iterator Cur=at(i).begin(); Cur!=at(i).end(); Cur++)
|
||||
for (FFMS_Track::iterator Cur=at(i).begin(); Cur!=at(i).end(); Cur++)
|
||||
IndexStream.write(reinterpret_cast<char *>(&*Cur), sizeof(TFrameInfo));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FFIndex::ReadIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
int FFMS_Index::ReadIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize) {
|
||||
ffms_fstream Index(IndexFile, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!Index.is_open()) {
|
||||
|
@ -311,6 +314,11 @@ int FFIndex::ReadIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize)
|
|||
return 4;
|
||||
}
|
||||
|
||||
if (!(IH.Decoder & FFMS_GetEnabledSources())) {
|
||||
snprintf(ErrorMsg, MsgSize, "The source which this index was created with is not available");
|
||||
return 5;
|
||||
}
|
||||
|
||||
Decoder = IH.Decoder;
|
||||
Filesize = IH.FileSize;
|
||||
memcpy(Digest, IH.FileSignature, sizeof(Digest));
|
||||
|
@ -327,7 +335,7 @@ int FFIndex::ReadIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize)
|
|||
Index.read(reinterpret_cast<char *>(&Den), sizeof(Den));
|
||||
int64_t Frames;
|
||||
Index.read(reinterpret_cast<char *>(&Frames), sizeof(Frames));
|
||||
push_back(FFTrack(Num, Den, static_cast<FFMS_TrackType>(TT)));
|
||||
push_back(FFMS_Track(Num, Den, static_cast<FFMS_TrackType>(TT)));
|
||||
|
||||
TFrameInfo FI = TFrameInfo::VideoFrameInfo(0, 0, false);
|
||||
for (size_t j = 0; j < Frames; j++) {
|
||||
|
@ -338,44 +346,44 @@ int FFIndex::ReadIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize)
|
|||
|
||||
} catch (...) {
|
||||
snprintf(ErrorMsg, MsgSize, "Unknown error while reading index information in '%s'", IndexFile);
|
||||
return 5;
|
||||
return 6;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FFIndex::FFIndex() {
|
||||
FFMS_Index::FFMS_Index() {
|
||||
// this comment documents nothing
|
||||
}
|
||||
|
||||
FFIndex::FFIndex(int64_t Filesize, uint8_t Digest[20]) {
|
||||
FFMS_Index::FFMS_Index(int64_t Filesize, uint8_t Digest[20]) {
|
||||
this->Filesize = Filesize;
|
||||
memcpy(this->Digest, Digest, sizeof(this->Digest));
|
||||
}
|
||||
|
||||
void FFIndexer::SetIndexMask(int IndexMask) {
|
||||
void FFMS_Indexer::SetIndexMask(int IndexMask) {
|
||||
this->IndexMask = IndexMask;
|
||||
}
|
||||
|
||||
void FFIndexer::SetDumpMask(int DumpMask) {
|
||||
void FFMS_Indexer::SetDumpMask(int DumpMask) {
|
||||
this->DumpMask = DumpMask;
|
||||
}
|
||||
|
||||
void FFIndexer::SetIgnoreDecodeErrors(bool IgnoreDecodeErrors) {
|
||||
void FFMS_Indexer::SetIgnoreDecodeErrors(bool IgnoreDecodeErrors) {
|
||||
this->IgnoreDecodeErrors = IgnoreDecodeErrors;
|
||||
}
|
||||
|
||||
void FFIndexer::SetProgressCallback(TIndexCallback IC, void *ICPrivate) {
|
||||
void FFMS_Indexer::SetProgressCallback(TIndexCallback IC, void *ICPrivate) {
|
||||
this->IC = IC;
|
||||
this->ICPrivate = ICPrivate;
|
||||
}
|
||||
|
||||
void FFIndexer::SetAudioNameCallback(TAudioNameCallback ANC, void *ANCPrivate) {
|
||||
void FFMS_Indexer::SetAudioNameCallback(TAudioNameCallback ANC, void *ANCPrivate) {
|
||||
this->ANC = ANC;
|
||||
this->ANCPrivate = ANCPrivate;
|
||||
}
|
||||
|
||||
FFIndexer *FFIndexer::CreateFFIndexer(const char *Filename, char *ErrorMsg, unsigned MsgSize) {
|
||||
FFMS_Indexer *FFMS_Indexer::CreateIndexer(const char *Filename, char *ErrorMsg, unsigned MsgSize) {
|
||||
AVFormatContext *FormatContext = NULL;
|
||||
|
||||
if (av_open_input_file(&FormatContext, Filename, NULL, 0, NULL) != 0) {
|
||||
|
@ -391,12 +399,12 @@ FFIndexer *FFIndexer::CreateFFIndexer(const char *Filename, char *ErrorMsg, unsi
|
|||
|
||||
#ifdef HAALISOURCE
|
||||
// Do haali ts indexing instead?
|
||||
if (!strcmp(FormatContext->iformat->name, "mpeg") || !strcmp(FormatContext->iformat->name, "mpegts")) {
|
||||
if (HasHaaliMPEG && !strcmp(FormatContext->iformat->name, "mpeg") || !strcmp(FormatContext->iformat->name, "mpegts")) {
|
||||
av_close_input_file(FormatContext);
|
||||
return new FFHaaliIndexer(Filename, 0, ErrorMsg, MsgSize);
|
||||
}
|
||||
|
||||
if (!strcmp(FormatContext->iformat->name, "ogg")) {
|
||||
if (HasHaaliOGG && !strcmp(FormatContext->iformat->name, "ogg")) {
|
||||
av_close_input_file(FormatContext);
|
||||
return new FFHaaliIndexer(Filename, 1, ErrorMsg, MsgSize);
|
||||
}
|
||||
|
@ -405,20 +413,20 @@ FFIndexer *FFIndexer::CreateFFIndexer(const char *Filename, char *ErrorMsg, unsi
|
|||
return new FFLAVFIndexer(Filename, FormatContext, ErrorMsg, MsgSize);
|
||||
}
|
||||
|
||||
FFIndexer::FFIndexer(const char *Filename, char *ErrorMsg, unsigned MsgSize) : DecodingBuffer(AVCODEC_MAX_AUDIO_FRAME_SIZE * 5) {
|
||||
if (FFIndex::CalculateFileSignature(Filename, &Filesize, Digest, ErrorMsg, MsgSize))
|
||||
FFMS_Indexer::FFMS_Indexer(const char *Filename, char *ErrorMsg, unsigned MsgSize) : DecodingBuffer(AVCODEC_MAX_AUDIO_FRAME_SIZE * 5) {
|
||||
if (FFMS_Index::CalculateFileSignature(Filename, &Filesize, Digest, ErrorMsg, MsgSize))
|
||||
throw ErrorMsg;
|
||||
}
|
||||
|
||||
FFIndexer::~FFIndexer() {
|
||||
FFMS_Indexer::~FFMS_Indexer() {
|
||||
|
||||
}
|
||||
|
||||
bool FFIndexer::WriteAudio(SharedAudioContext &AudioContext, FFIndex *Index, int Track, int DBSize, char *ErrorMsg, unsigned MsgSize) {
|
||||
bool FFMS_Indexer::WriteAudio(SharedAudioContext &AudioContext, FFMS_Index *Index, int Track, int DBSize, char *ErrorMsg, unsigned MsgSize) {
|
||||
// Delay writer creation until after an audio frame has been decoded. This ensures that all parameters are known when writing the headers.
|
||||
if (DBSize > 0) {
|
||||
if (!AudioContext.W64Writer) {
|
||||
FFAudioProperties AP;
|
||||
FFMS_AudioProperties AP;
|
||||
FillAP(AP, AudioContext.CodecContext, (*Index)[Track]);
|
||||
int FNSize = (*ANC)(SourceFile, Track, &AP, NULL, 0, ANCPrivate);
|
||||
std::vector<char> WName(FNSize);
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
# include "guids.h"
|
||||
#endif
|
||||
|
||||
#define INDEXVERSION 28
|
||||
#define INDEXVERSION 29
|
||||
#define INDEXID 0x53920873
|
||||
|
||||
class SharedVideoContext {
|
||||
|
@ -78,10 +78,10 @@ private:
|
|||
TFrameInfo(int64_t DTS, int64_t SampleStart, int RepeatPict, bool KeyFrame, int64_t FilePos, unsigned int FrameSize);
|
||||
};
|
||||
|
||||
class FFTrack : public std::vector<TFrameInfo> {
|
||||
class FFMS_Track : public std::vector<TFrameInfo> {
|
||||
public:
|
||||
FFMS_TrackType TT;
|
||||
FFTrackTimeBase TB;
|
||||
FFMS_TrackTimeBase TB;
|
||||
|
||||
int FindClosestVideoKeyFrame(int Frame);
|
||||
int FindClosestAudioKeyFrame(int64_t Sample);
|
||||
|
@ -89,11 +89,11 @@ public:
|
|||
int ClosestFrameFromDTS(int64_t DTS);
|
||||
int WriteTimecodes(const char *TimecodeFile, char *ErrorMsg, unsigned MsgSize);
|
||||
|
||||
FFTrack();
|
||||
FFTrack(int64_t Num, int64_t Den, FFMS_TrackType TT);
|
||||
FFMS_Track();
|
||||
FFMS_Track(int64_t Num, int64_t Den, FFMS_TrackType TT);
|
||||
};
|
||||
|
||||
class FFIndex : public std::vector<FFTrack> {
|
||||
class FFMS_Index : public std::vector<FFMS_Track> {
|
||||
public:
|
||||
static int CalculateFileSignature(const char *Filename, int64_t *Filesize, uint8_t Digest[20], char *ErrorMsg, unsigned MsgSize);
|
||||
|
||||
|
@ -106,11 +106,11 @@ public:
|
|||
int WriteIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize);
|
||||
int ReadIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize);
|
||||
|
||||
FFIndex();
|
||||
FFIndex(int64_t Filesize, uint8_t Digest[20]);
|
||||
FFMS_Index();
|
||||
FFMS_Index(int64_t Filesize, uint8_t Digest[20]);
|
||||
};
|
||||
|
||||
class FFIndexer {
|
||||
class FFMS_Indexer {
|
||||
protected:
|
||||
int IndexMask;
|
||||
int DumpMask;
|
||||
|
@ -125,35 +125,35 @@ protected:
|
|||
int64_t Filesize;
|
||||
uint8_t Digest[20];
|
||||
|
||||
bool WriteAudio(SharedAudioContext &AudioContext, FFIndex *Index, int Track, int DBSize, char *ErrorMsg, unsigned MsgSize);
|
||||
bool WriteAudio(SharedAudioContext &AudioContext, FFMS_Index *Index, int Track, int DBSize, char *ErrorMsg, unsigned MsgSize);
|
||||
public:
|
||||
static FFIndexer *CreateFFIndexer(const char *Filename, char *ErrorMsg, unsigned MsgSize);
|
||||
FFIndexer(const char *Filename, char *ErrorMsg, unsigned MsgSize);
|
||||
virtual ~FFIndexer();
|
||||
static FFMS_Indexer *CreateIndexer(const char *Filename, char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_Indexer(const char *Filename, char *ErrorMsg, unsigned MsgSize);
|
||||
virtual ~FFMS_Indexer();
|
||||
void SetIndexMask(int IndexMask);
|
||||
void SetDumpMask(int DumpMask);
|
||||
void SetIgnoreDecodeErrors(bool IgnoreDecodeErrors);
|
||||
void SetProgressCallback(TIndexCallback IC, void *ICPrivate);
|
||||
void SetAudioNameCallback(TAudioNameCallback ANC, void *ANCPrivate);
|
||||
virtual FFIndex *DoIndexing(char *ErrorMsg, unsigned MsgSize) = 0;
|
||||
virtual FFMS_Index *DoIndexing(char *ErrorMsg, unsigned MsgSize) = 0;
|
||||
virtual int GetNumberOfTracks() = 0;
|
||||
virtual FFMS_TrackType GetTrackType(int Track) = 0;
|
||||
virtual const char *GetTrackCodec(int Track) = 0;
|
||||
};
|
||||
|
||||
class FFLAVFIndexer : public FFIndexer {
|
||||
class FFLAVFIndexer : public FFMS_Indexer {
|
||||
private:
|
||||
AVFormatContext *FormatContext;
|
||||
public:
|
||||
FFLAVFIndexer(const char *Filename, AVFormatContext *FormatContext, char *ErrorMsg, unsigned MsgSize);
|
||||
~FFLAVFIndexer();
|
||||
FFIndex *DoIndexing(char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_Index *DoIndexing(char *ErrorMsg, unsigned MsgSize);
|
||||
int GetNumberOfTracks();
|
||||
FFMS_TrackType GetTrackType(int Track);
|
||||
const char *GetTrackCodec(int Track);
|
||||
};
|
||||
|
||||
class FFMatroskaIndexer : public FFIndexer {
|
||||
class FFMatroskaIndexer : public FFMS_Indexer {
|
||||
private:
|
||||
MatroskaFile *MF;
|
||||
MatroskaReaderContext MC;
|
||||
|
@ -161,7 +161,7 @@ private:
|
|||
public:
|
||||
FFMatroskaIndexer(const char *Filename, char *ErrorMsg, unsigned MsgSize);
|
||||
~FFMatroskaIndexer();
|
||||
FFIndex *DoIndexing(char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_Index *DoIndexing(char *ErrorMsg, unsigned MsgSize);
|
||||
int GetNumberOfTracks();
|
||||
FFMS_TrackType GetTrackType(int Track);
|
||||
const char *GetTrackCodec(int Track);
|
||||
|
@ -169,7 +169,7 @@ public:
|
|||
|
||||
#ifdef HAALISOURCE
|
||||
|
||||
class FFHaaliIndexer : public FFIndexer {
|
||||
class FFHaaliIndexer : public FFMS_Indexer {
|
||||
private:
|
||||
int SourceMode;
|
||||
CComPtr<IMMContainer> pMMC;
|
||||
|
@ -182,7 +182,7 @@ private:
|
|||
int64_t Duration;
|
||||
public:
|
||||
FFHaaliIndexer(const char *Filename, int SourceMode, char *ErrorMsg, unsigned MsgSize);
|
||||
FFIndex *DoIndexing(char *ErrorMsg, unsigned MsgSize);
|
||||
FFMS_Index *DoIndexing(char *ErrorMsg, unsigned MsgSize);
|
||||
int GetNumberOfTracks();
|
||||
FFMS_TrackType GetTrackType(int Track);
|
||||
const char *GetTrackCodec(int Track);
|
||||
|
|
|
@ -161,7 +161,7 @@ void InitNullPacket(AVPacket *pkt) {
|
|||
pkt->size = 0;
|
||||
}
|
||||
|
||||
void FillAP(FFAudioProperties &AP, AVCodecContext *CTX, FFTrack &Frames) {
|
||||
void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames) {
|
||||
AP.SampleFormat = static_cast<FFMS_SampleFormat>(CTX->sample_fmt);
|
||||
AP.BitsPerSample = av_get_bits_per_sample_format(CTX->sample_fmt);
|
||||
if (CTX->sample_fmt == SAMPLE_FMT_S32)
|
||||
|
|
|
@ -85,7 +85,7 @@ FFMS_TrackType HaaliTrackTypeToFFTrackType(int TT);
|
|||
int ReadFrame(uint64_t FilePos, unsigned int &FrameSize, CompressedStream *CS, MatroskaReaderContext &Context, char *ErrorMsg, unsigned MsgSize);
|
||||
bool AudioFMTIsFloat(SampleFormat FMT);
|
||||
void InitNullPacket(AVPacket *pkt);
|
||||
void FillAP(FFAudioProperties &AP, AVCodecContext *CTX, FFTrack &Frames);
|
||||
void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames);
|
||||
#ifdef HAALISOURCE
|
||||
unsigned vtSize(VARIANT &vt);
|
||||
void vtCopy(VARIANT& vt,void *dest);
|
||||
|
|
Loading…
Reference in New Issue