FFmpegSource 1.16 + minor fix
Originally committed to SVN as r2151.
This commit is contained in:
parent
b7af0a06d5
commit
d6e76cee4f
13 changed files with 114 additions and 310 deletions
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2007 Fredrik Mellbin
|
||||
// Copyright (c) 2007-2008 Fredrik Mellbin
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2007 Fredrik Mellbin
|
||||
// Copyright (c) 2007-2008 Fredrik Mellbin
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -29,7 +29,7 @@ int FFBase::FrameFromDTS(int64_t ADTS) {
|
|||
|
||||
int FFBase::ClosestFrameFromDTS(int64_t ADTS) {
|
||||
int Frame = 0;
|
||||
int64_t BestDiff = 0xFFFFFFFFFFFFFFLL;
|
||||
int64_t BestDiff = 0xFFFFFFFFFFFFFFLL; // big number
|
||||
for (int i = 0; i < (int)Frames.size(); i++) {
|
||||
int64_t CurrentDiff = FFABS(Frames[i].DTS - ADTS);
|
||||
if (CurrentDiff < BestDiff) {
|
||||
|
@ -113,83 +113,6 @@ bool FFBase::SaveTimecodesToFile(const char *ATimecodeFile, int64_t ScaleD, int6
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef FLAC_CACHE
|
||||
static FLAC__StreamDecoderReadStatus FLACStreamDecoderReadCallback(const FLAC__StreamDecoder *ADecoder, FLAC__byte ABuffer[], size_t *ABytes, FFBase *AOwner) {
|
||||
if(*ABytes > 0) {
|
||||
*ABytes = fread(ABuffer, sizeof(FLAC__byte), *ABytes, AOwner->FCFile);
|
||||
if(ferror(AOwner->FCFile))
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
|
||||
else if(*ABytes == 0)
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
||||
else
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
||||
} else {
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
|
||||
}
|
||||
}
|
||||
|
||||
static FLAC__StreamDecoderSeekStatus FLACStreamDecoderSeekCallback(const FLAC__StreamDecoder *ADecoder, FLAC__uint64 AAbsoluteByteOffset, FFBase *AOwner) {
|
||||
if(_fseeki64(AOwner->FCFile, AAbsoluteByteOffset, SEEK_SET) < 0)
|
||||
return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
|
||||
else
|
||||
return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
|
||||
}
|
||||
|
||||
static FLAC__StreamDecoderTellStatus FLACStreamDecoderTellCallback(const FLAC__StreamDecoder *ADecoder, FLAC__uint64 *AAbsoluteByteOffset, FFBase *AOwner) {
|
||||
__int64 Pos;
|
||||
if ((Pos = _ftelli64(AOwner->FCFile)) < 0) {
|
||||
return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
|
||||
} else {
|
||||
*AAbsoluteByteOffset = (FLAC__uint64)Pos;
|
||||
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static FLAC__StreamDecoderLengthStatus FLACStreamDecoderLengthCallback(const FLAC__StreamDecoder *ADecoder, FLAC__uint64 *AStreamLength, FFBase *AOwner) {
|
||||
__int64 OriginalPos;
|
||||
__int64 Length;
|
||||
if ((OriginalPos = _ftelli64(AOwner->FCFile)) < 0)
|
||||
return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
|
||||
_fseeki64(AOwner->FCFile, 0, SEEK_END);
|
||||
if ((Length = _ftelli64(AOwner->FCFile)) < 0)
|
||||
return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
|
||||
_fseeki64(AOwner->FCFile, OriginalPos, SEEK_SET);
|
||||
*AStreamLength = Length;
|
||||
return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
|
||||
}
|
||||
|
||||
static FLAC__bool FLACStreamDecoderEofCallback(const FLAC__StreamDecoder *ADecoder, FFBase *AOwner) {
|
||||
return feof(AOwner->FCFile) ? true : false;
|
||||
}
|
||||
|
||||
static FLAC__StreamDecoderWriteStatus FLACStreamDecoderWriteCallback(const FLAC__StreamDecoder *ADecoder, const FLAC__Frame *AFrame, const FLAC__int32 *const ABuffer[], FFBase *AOwner) {
|
||||
unsigned Blocksize = AFrame->header.blocksize;
|
||||
const VideoInfo VI = AOwner->GetVideoInfo();
|
||||
int16_t *Buffer = (int16_t *)AOwner->FCBuffer;
|
||||
|
||||
int j = 0;
|
||||
while (AOwner->FCCount > 0 && Blocksize > 0) {
|
||||
for (int i = 0; i < VI.nchannels; i++)
|
||||
*Buffer++ = ABuffer[i][j];
|
||||
j++;
|
||||
AOwner->FCCount--;
|
||||
Blocksize--;
|
||||
}
|
||||
|
||||
AOwner->FCBuffer = Buffer;
|
||||
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static void FLACStreamDecoderMetadataCallback(const FLAC__StreamDecoder *ADecoder, const FLAC__StreamMetadata *AMetadata, FFBase *AOwner) {
|
||||
AOwner->FCError = (AMetadata->data.stream_info.total_samples <= 0);
|
||||
}
|
||||
|
||||
static void FLACStreamDecoderErrorCallback(const FLAC__StreamDecoder *ADecoder, FLAC__StreamDecoderErrorStatus AStatus, FFBase *AOwner) {
|
||||
AOwner->FCError = true;
|
||||
}
|
||||
#endif // FLAC_CACHE
|
||||
|
||||
bool FFBase::OpenAudioCache(const char *AAudioCacheFile, const char *ASource, int AAudioTrack, IScriptEnvironment *Env) {
|
||||
char DefaultCacheFilename[1024];
|
||||
sprintf(DefaultCacheFilename, "%s.ffa%dcache", ASource, AAudioTrack);
|
||||
|
@ -197,7 +120,7 @@ bool FFBase::OpenAudioCache(const char *AAudioCacheFile, const char *ASource, in
|
|||
AAudioCacheFile = DefaultCacheFilename;
|
||||
|
||||
// Is an empty file?
|
||||
FCFile = fopen(AAudioCacheFile, "rb");
|
||||
FILE *FCFile = fopen(AAudioCacheFile, "rb");
|
||||
int64_t CacheSize;
|
||||
if (FCFile) {
|
||||
_fseeki64(FCFile, 0, SEEK_END);
|
||||
|
@ -212,29 +135,6 @@ bool FFBase::OpenAudioCache(const char *AAudioCacheFile, const char *ASource, in
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef FLAC_CACHE
|
||||
// is FLAC?
|
||||
FLACAudioCache = FLAC__stream_decoder_new();
|
||||
if (FLAC__stream_decoder_init_stream(FLACAudioCache,
|
||||
&(FLAC__StreamDecoderReadCallback)FLACStreamDecoderReadCallback,
|
||||
&(FLAC__StreamDecoderSeekCallback)FLACStreamDecoderSeekCallback,
|
||||
&(FLAC__StreamDecoderTellCallback)FLACStreamDecoderTellCallback,
|
||||
&(FLAC__StreamDecoderLengthCallback)FLACStreamDecoderLengthCallback,
|
||||
&(FLAC__StreamDecoderEofCallback)FLACStreamDecoderEofCallback,
|
||||
&(FLAC__StreamDecoderWriteCallback)FLACStreamDecoderWriteCallback,
|
||||
&(FLAC__StreamDecoderMetadataCallback)FLACStreamDecoderMetadataCallback, &(FLAC__StreamDecoderErrorCallback)FLACStreamDecoderErrorCallback, this) == FLAC__STREAM_DECODER_INIT_STATUS_OK) {
|
||||
FCError = true;
|
||||
FLAC__stream_decoder_process_until_end_of_metadata(FLACAudioCache);
|
||||
if (!FCError) {
|
||||
VI.num_audio_samples = FLAC__stream_decoder_get_total_samples(FLACAudioCache);
|
||||
AudioCacheType = acFLAC;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
FLAC__stream_decoder_delete(FLACAudioCache);
|
||||
FLACAudioCache = NULL;
|
||||
#endif // FLAC_CACHE
|
||||
|
||||
// Raw audio
|
||||
VI.num_audio_samples = VI.AudioSamplesFromBytes(CacheSize);
|
||||
AudioCacheType = acRaw;
|
||||
|
@ -243,64 +143,6 @@ bool FFBase::OpenAudioCache(const char *AAudioCacheFile, const char *ASource, in
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef FLAC_CACHE
|
||||
static FLAC__StreamEncoderWriteStatus FLACStreamEncoderWriteCallback(const FLAC__StreamEncoder *ASncoder, const FLAC__byte ABuffer[], size_t ABytes, unsigned ABamples, unsigned ACurrentFrame, FFBase *AOwner) {
|
||||
fwrite(ABuffer, sizeof(FLAC__byte), ABytes, AOwner->FCFile);
|
||||
if(ferror(AOwner->FCFile))
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
else
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
|
||||
}
|
||||
|
||||
static FLAC__StreamEncoderSeekStatus FLACStreamEncoderSeekCallback(const FLAC__StreamEncoder *AEncoder, FLAC__uint64 AAbsoluteByteOffset, FFBase *AOwner) {
|
||||
if(_fseeki64(AOwner->FCFile, AAbsoluteByteOffset, SEEK_SET) < 0)
|
||||
return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;
|
||||
else
|
||||
return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
|
||||
}
|
||||
|
||||
static FLAC__StreamEncoderTellStatus FLACStreamEncoderTellCallback(const FLAC__StreamEncoder *AEncoder, FLAC__uint64 *AAbsoluteByteOffset, FFBase *AOwner) {
|
||||
__int64 Pos;
|
||||
if((Pos = _ftelli64(AOwner->FCFile)) < 0) {
|
||||
return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR;
|
||||
} else {
|
||||
*AAbsoluteByteOffset = (FLAC__uint64)Pos;
|
||||
return FLAC__STREAM_ENCODER_TELL_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
FLAC__StreamEncoder *FFBase::NewFLACCacheWriter(const char *AAudioCacheFile, const char *ASource, int AAudioTrack, int ACompression, IScriptEnvironment *Env) {
|
||||
char DefaultCacheFilename[1024];
|
||||
sprintf(DefaultCacheFilename, "%s.ffa%dcache", ASource, AAudioTrack);
|
||||
if (!strcmp(AAudioCacheFile, ""))
|
||||
AAudioCacheFile = DefaultCacheFilename;
|
||||
|
||||
FCFile = fopen(AAudioCacheFile, "wb");
|
||||
if (!FCFile)
|
||||
Env->ThrowError("FFmpegSource: Failed to open '%s' for writing", AAudioCacheFile);
|
||||
FLAC__StreamEncoder *FSE;
|
||||
FSE = FLAC__stream_encoder_new();
|
||||
FLAC__stream_encoder_set_channels(FSE, VI.nchannels);
|
||||
FLAC__stream_encoder_set_bits_per_sample(FSE, VI.BytesPerChannelSample() * 8);
|
||||
FLAC__stream_encoder_set_sample_rate(FSE, VI.audio_samples_per_second);
|
||||
FLAC__stream_encoder_set_compression_level(FSE, ACompression);
|
||||
if (FLAC__stream_encoder_init_stream(FSE, &(FLAC__StreamEncoderWriteCallback)FLACStreamEncoderWriteCallback,
|
||||
&(FLAC__StreamEncoderSeekCallback)FLACStreamEncoderSeekCallback,
|
||||
&(FLAC__StreamEncoderTellCallback)FLACStreamEncoderTellCallback, NULL, this)
|
||||
!= FLAC__STREAM_ENCODER_INIT_STATUS_OK)
|
||||
Env->ThrowError("FFmpegSource: Failed to initialize the FLAC encoder for '%s'", AAudioCacheFile);
|
||||
|
||||
return FSE;
|
||||
}
|
||||
|
||||
void FFBase::CloseFLACCacheWriter(FLAC__StreamEncoder *AFSE) {
|
||||
FLAC__stream_encoder_finish(AFSE);
|
||||
FLAC__stream_encoder_delete(AFSE);
|
||||
fclose(FCFile);
|
||||
FCFile = NULL;
|
||||
}
|
||||
#endif // FLAC_CACHE
|
||||
|
||||
FILE *FFBase::NewRawCacheWriter(const char *AAudioCacheFile, const char *ASource, int AAudioTrack, IScriptEnvironment *Env) {
|
||||
char DefaultCacheFilename[1024];
|
||||
sprintf(DefaultCacheFilename, "%s.ffa%dcache", ASource, AAudioTrack);
|
||||
|
@ -325,7 +167,7 @@ void FFBase::InitPP(int AWidth, int AHeight, const char *APPString, int AQuality
|
|||
Env->ThrowError("FFmpegSource: Quality is out of range");
|
||||
|
||||
// Unsafe?
|
||||
PPMode = pp_get_mode_by_name_and_quality((char *)APPString, AQuality);
|
||||
PPMode = pp_get_mode_by_name_and_quality(APPString, AQuality);
|
||||
if (!PPMode)
|
||||
Env->ThrowError("FFmpegSource: Invalid postprocesing settings");
|
||||
|
||||
|
@ -379,7 +221,7 @@ PVideoFrame FFBase::OutputFrame(AVFrame *AFrame, IScriptEnvironment *Env) {
|
|||
AVPicture *SrcPicture = (AVPicture *)AFrame;
|
||||
|
||||
if (PPContext) {
|
||||
pp_postprocess(AFrame->data, AFrame->linesize, PPPicture.data, PPPicture.linesize, VI.width, VI.height, AFrame->qscale_table, AFrame->qstride, PPMode, PPContext, AFrame->pict_type | (AFrame->qscale_type ? PP_PICT_TYPE_QP2 : 0));
|
||||
pp_postprocess(const_cast<const uint8_t **>(AFrame->data), AFrame->linesize, PPPicture.data, PPPicture.linesize, VI.width, VI.height, AFrame->qscale_table, AFrame->qstride, PPMode, PPContext, AFrame->pict_type | (AFrame->qscale_type ? PP_PICT_TYPE_QP2 : 0));
|
||||
SrcPicture = &PPPicture;
|
||||
}
|
||||
|
||||
|
@ -416,15 +258,7 @@ PVideoFrame FFBase::OutputFrame(AVFrame *AFrame, IScriptEnvironment *Env) {
|
|||
void FFBase::GetAudio(void* Buf, __int64 Start, __int64 Count, IScriptEnvironment* Env) {
|
||||
if (AudioCacheType == acRaw) {
|
||||
_fseeki64(RawAudioCache, VI.BytesFromAudioSamples(Start), SEEK_SET);
|
||||
fread(Buf, 1, (size_t)VI.BytesFromAudioSamples(Count), RawAudioCache);
|
||||
#ifdef FLAC_CACHE
|
||||
} else if (AudioCacheType == acFLAC) {
|
||||
FCCount = Count;
|
||||
FCBuffer = Buf;
|
||||
FLAC__stream_decoder_seek_absolute(FLACAudioCache, Start);
|
||||
while (FCCount > 0)
|
||||
FLAC__stream_decoder_process_single(FLACAudioCache);
|
||||
#endif // FLAC_CACHE
|
||||
fread(Buf, 1, static_cast<size_t>(VI.BytesFromAudioSamples(Count)), RawAudioCache);
|
||||
} else {
|
||||
Env->ThrowError("FFmpegSource: Audio requested but none available");
|
||||
}
|
||||
|
@ -433,18 +267,12 @@ void FFBase::GetAudio(void* Buf, __int64 Start, __int64 Count, IScriptEnvironmen
|
|||
FFBase::FFBase() {
|
||||
memset(&VI, 0, sizeof(VI));
|
||||
AudioCacheType = acNone;
|
||||
FCError = false;
|
||||
RawAudioCache = NULL;
|
||||
PPContext = NULL;
|
||||
PPMode = NULL;
|
||||
SWS = NULL;
|
||||
LastFrameNum = -1;
|
||||
DecodingBuffer = new uint8_t[AVCODEC_MAX_AUDIO_FRAME_SIZE];
|
||||
#ifdef FLAC_CACHE
|
||||
FLACAudioCache = NULL;
|
||||
FLACBuffer = new FLAC__int32[AVCODEC_MAX_AUDIO_FRAME_SIZE];
|
||||
#endif // FLAC_CACHE
|
||||
FCFile = NULL;
|
||||
ConvertToFormat = PIX_FMT_NONE;
|
||||
memset(&PPPicture, 0, sizeof(PPPicture));
|
||||
DecodeFrame = avcodec_alloc_frame();
|
||||
|
@ -454,15 +282,6 @@ FFBase::~FFBase() {
|
|||
delete [] DecodingBuffer;
|
||||
if (RawAudioCache)
|
||||
fclose(RawAudioCache);
|
||||
#ifdef FLAC_CACHE
|
||||
delete [] FLACBuffer;
|
||||
if (FLACAudioCache) {
|
||||
FLAC__stream_decoder_finish(FLACAudioCache);
|
||||
FLAC__stream_decoder_delete(FLACAudioCache);
|
||||
}
|
||||
#endif // FLAC_CACHE
|
||||
if (FCFile)
|
||||
fclose(FCFile);
|
||||
if (SWS)
|
||||
sws_freeContext(SWS);
|
||||
if (PPMode)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2007 Fredrik Mellbin
|
||||
// Copyright (c) 2007-2008 Fredrik Mellbin
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2007 Fredrik Mellbin
|
||||
// Copyright (c) 2007-2008 Fredrik Mellbin
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -45,8 +45,8 @@ int FFMatroskaSource::GetTrackIndex(int Index, unsigned char ATrackType, IScript
|
|||
}
|
||||
|
||||
FFMatroskaSource::FFMatroskaSource(const char *ASource, int AVideoTrack, int AAudioTrack, const char *ATimecodes,
|
||||
bool AVCache, const char *AVideoCache, const char *AAudioCache, int AACCompression, const char *APPString,
|
||||
int AQuality, IScriptEnvironment* Env, FrameInfoVector *AFrames) {
|
||||
bool AVCache, const char *AVideoCache, const char *AAudioCache, const char *APPString,
|
||||
int AQuality, int AThreads, IScriptEnvironment* Env, FrameInfoVector *AFrames) {
|
||||
|
||||
AFrames = &Frames;
|
||||
CurrentFrame = 0;
|
||||
|
@ -105,6 +105,7 @@ FFMatroskaSource::FFMatroskaSource(const char *ASource, int AVideoTrack, int AAu
|
|||
VideoCodecContext = avcodec_alloc_context();
|
||||
VideoCodecContext->extradata = (uint8_t *)VideoTI->CodecPrivate;
|
||||
VideoCodecContext->extradata_size = VideoTI->CodecPrivateSize;
|
||||
VideoCodecContext->thread_count = AThreads;
|
||||
|
||||
VideoCodec = avcodec_find_decoder(MatroskaToFFCodecID(VideoTI));
|
||||
if (VideoCodec == NULL)
|
||||
|
@ -184,11 +185,11 @@ FFMatroskaSource::FFMatroskaSource(const char *ASource, int AVideoTrack, int AAu
|
|||
VI.audio_samples_per_second = AudioCodecContext->sample_rate;
|
||||
|
||||
switch (AudioCodecContext->sample_fmt) {
|
||||
case SAMPLE_FMT_U8: VI.sample_type = SAMPLE_INT8; AACCompression = -1; break;
|
||||
case SAMPLE_FMT_U8: VI.sample_type = SAMPLE_INT8; break;
|
||||
case SAMPLE_FMT_S16: VI.sample_type = SAMPLE_INT16; break;
|
||||
case SAMPLE_FMT_S24: VI.sample_type = SAMPLE_INT24; AACCompression = -1; break;
|
||||
case SAMPLE_FMT_S32: VI.sample_type = SAMPLE_INT32; AACCompression = -1; break;
|
||||
case SAMPLE_FMT_FLT: VI.sample_type = SAMPLE_FLOAT; AACCompression = -1; break;
|
||||
case SAMPLE_FMT_S24: VI.sample_type = SAMPLE_INT24; break;
|
||||
case SAMPLE_FMT_S32: VI.sample_type = SAMPLE_INT32; break;
|
||||
case SAMPLE_FMT_FLT: VI.sample_type = SAMPLE_FLOAT; break;
|
||||
default:
|
||||
Env->ThrowError("FFmpegSource: Unsupported/unknown sample format");
|
||||
}
|
||||
|
@ -202,20 +203,11 @@ FFMatroskaSource::FFMatroskaSource(const char *ASource, int AVideoTrack, int AAu
|
|||
|
||||
// Needs to be indexed?
|
||||
if (!ACacheIsValid || !VCacheIsValid) {
|
||||
#ifdef FLAC_CACHE
|
||||
FLAC__StreamEncoder *FSE = NULL;
|
||||
#endif // FLAC_CACHE
|
||||
FILE *RawCache = NULL;
|
||||
if (!ACacheIsValid)
|
||||
if (AACCompression >= 0)
|
||||
AudioCacheType = acFLAC;
|
||||
else
|
||||
AudioCacheType = acRaw;
|
||||
AudioCacheType = acRaw;
|
||||
|
||||
switch (AudioCacheType) {
|
||||
#ifdef FLAC_CACHE
|
||||
case acFLAC: FSE = NewFLACCacheWriter(AAudioCache, ASource, AudioTrack, AACCompression, Env); break;
|
||||
#endif // FLAC_CACHE
|
||||
case acRaw: RawCache = NewRawCacheWriter(AAudioCache, ASource, AudioTrack, Env); break;
|
||||
}
|
||||
|
||||
|
@ -244,21 +236,12 @@ FFMatroskaSource::FFMatroskaSource(const char *ASource, int AVideoTrack, int AAu
|
|||
|
||||
if (AudioCacheType == acRaw) {
|
||||
fwrite(DecodingBuffer, 1, TempOutputBufSize, RawCache);
|
||||
#ifdef FLAC_CACHE
|
||||
} else if (AudioCacheType == acFLAC) {
|
||||
for (int i = 0; i < DecodedSamples * VI.nchannels; i++)
|
||||
FLACBuffer[i] = ((int16_t *)DecodingBuffer)[i];
|
||||
FLAC__stream_encoder_process_interleaved(FSE, FLACBuffer, DecodedSamples);
|
||||
#endif // FLAC_CACHE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ACacheIsValid) {
|
||||
switch (AudioCacheType) {
|
||||
#ifdef FLAC_CACHE
|
||||
case acFLAC: CloseFLACCacheWriter(FSE); break;
|
||||
#endif // FLAC_CACHE
|
||||
case acRaw: CloseRawCacheWriter(RawCache); break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2007 Fredrik Mellbin
|
||||
// Copyright (c) 2007-2008 Fredrik Mellbin
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2007 Fredrik Mellbin
|
||||
// Copyright (c) 2007-2008 Fredrik Mellbin
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -45,8 +45,8 @@ int FFmpegSource::GetTrackIndex(int Index, CodecType ATrackType, IScriptEnvironm
|
|||
|
||||
|
||||
FFmpegSource::FFmpegSource(const char *ASource, int AVideoTrack, int AAudioTrack, const char *ATimecodes,
|
||||
bool AVCache, const char *AVideoCache, const char *AAudioCache, int AACCompression, const char *APPString,
|
||||
int AQuality, int ASeekMode, IScriptEnvironment *Env, FrameInfoVector *AFrames) {
|
||||
bool AVCache, const char *AVideoCache, const char *AAudioCache, const char *APPString,
|
||||
int AQuality, int AThreads, int ASeekMode, IScriptEnvironment *Env, FrameInfoVector *AFrames) {
|
||||
|
||||
AFrames = &Frames;
|
||||
CurrentFrame = 0;
|
||||
|
@ -79,6 +79,7 @@ FFmpegSource::FFmpegSource(const char *ASource, int AVideoTrack, int AAudioTrack
|
|||
VCacheIsValid = LoadFrameInfoFromFile(AVideoCache, ASource, VideoTrack);
|
||||
|
||||
VideoCodecContext = FormatContext->streams[VideoTrack]->codec;
|
||||
VideoCodecContext->thread_count = AThreads;
|
||||
|
||||
VideoCodec = avcodec_find_decoder(VideoCodecContext->codec_id);
|
||||
if (VideoCodec == NULL)
|
||||
|
@ -124,11 +125,11 @@ FFmpegSource::FFmpegSource(const char *ASource, int AVideoTrack, int AAudioTrack
|
|||
Env->ThrowError("FFmpegSource: Could not open audio codec");
|
||||
|
||||
switch (AudioCodecContext->sample_fmt) {
|
||||
case SAMPLE_FMT_U8: VI.sample_type = SAMPLE_INT8; AACCompression = -1; break;
|
||||
case SAMPLE_FMT_U8: VI.sample_type = SAMPLE_INT8; break;
|
||||
case SAMPLE_FMT_S16: VI.sample_type = SAMPLE_INT16; break;
|
||||
case SAMPLE_FMT_S24: VI.sample_type = SAMPLE_INT24; AACCompression = -1; break;
|
||||
case SAMPLE_FMT_S32: VI.sample_type = SAMPLE_INT32; AACCompression = -1; break;
|
||||
case SAMPLE_FMT_FLT: VI.sample_type = SAMPLE_FLOAT; AACCompression = -1; break;
|
||||
case SAMPLE_FMT_S24: VI.sample_type = SAMPLE_INT24; break;
|
||||
case SAMPLE_FMT_S32: VI.sample_type = SAMPLE_INT32; break;
|
||||
case SAMPLE_FMT_FLT: VI.sample_type = SAMPLE_FLOAT; break;
|
||||
default:
|
||||
Env->ThrowError("FFmpegSource: Unsupported/unknown sample format");
|
||||
}
|
||||
|
@ -144,20 +145,11 @@ FFmpegSource::FFmpegSource(const char *ASource, int AVideoTrack, int AAudioTrack
|
|||
|
||||
// Needs to be indexed?
|
||||
if (!ACacheIsValid || !VCacheIsValid) {
|
||||
#ifdef FLAC_CACHE
|
||||
FLAC__StreamEncoder *FSE = NULL;
|
||||
#endif // FLAC_CACHE
|
||||
FILE *RawCache = NULL;
|
||||
if (!ACacheIsValid)
|
||||
if (AACCompression >= 0)
|
||||
AudioCacheType = acFLAC;
|
||||
else
|
||||
AudioCacheType = acRaw;
|
||||
AudioCacheType = acRaw;
|
||||
|
||||
switch (AudioCacheType) {
|
||||
#ifdef FLAC_CACHE
|
||||
case acFLAC: FSE = NewFLACCacheWriter(AAudioCache, ASource, AudioTrack, AACCompression, Env); break;
|
||||
#endif // FLAC_CACHE
|
||||
case acRaw: RawCache = NewRawCacheWriter(AAudioCache, ASource, AudioTrack, Env); break;
|
||||
}
|
||||
|
||||
|
@ -184,12 +176,6 @@ FFmpegSource::FFmpegSource(const char *ASource, int AVideoTrack, int AAudioTrack
|
|||
|
||||
if (AudioCacheType == acRaw) {
|
||||
fwrite(DecodingBuffer, 1, TempOutputBufSize, RawCache);
|
||||
#ifdef FLAC_CACHE
|
||||
} else if (AudioCacheType == acFLAC) {
|
||||
for (int i = 0; i < DecodedSamples * VI.nchannels; i++)
|
||||
FLACBuffer[i] = ((int16_t *)DecodingBuffer)[i];
|
||||
FLAC__stream_encoder_process_interleaved(FSE, FLACBuffer, DecodedSamples);
|
||||
#endif // FLAC_CACHE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,9 +185,6 @@ FFmpegSource::FFmpegSource(const char *ASource, int AVideoTrack, int AAudioTrack
|
|||
|
||||
if (!ACacheIsValid) {
|
||||
switch (AudioCacheType) {
|
||||
#ifdef FLAC_CACHE
|
||||
case acFLAC: CloseFLACCacheWriter(FSE); break;
|
||||
#endif // FLAC_CACHE
|
||||
case acRaw: CloseRawCacheWriter(RawCache); break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2007 Fredrik Mellbin
|
||||
// Copyright (c) 2007-2008 Fredrik Mellbin
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -21,10 +21,6 @@
|
|||
#ifndef FFMPEGSOURCE_H
|
||||
#define FFMPEGSOURCE_H
|
||||
|
||||
#ifndef NO_FLAC_CACHE
|
||||
//#define FLAC_CACHE
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
@ -35,16 +31,11 @@
|
|||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
|
||||
#ifdef FLAC_CACHE
|
||||
#include <stream_decoder.h>
|
||||
#include <stream_encoder.h>
|
||||
#endif // FLAC_CACHE
|
||||
|
||||
extern "C" {
|
||||
#include <ffmpeg\avformat.h>
|
||||
#include <ffmpeg\avcodec.h>
|
||||
#include <ffmpeg\swscale.h>
|
||||
#include <postproc\postprocess.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libswscale/swscale.h>
|
||||
#include <libpostproc/postprocess.h>
|
||||
|
||||
#include "stdiostream.h"
|
||||
}
|
||||
|
@ -52,7 +43,7 @@ extern "C" {
|
|||
#include "MatroskaParser.h"
|
||||
#include "avisynth.h"
|
||||
|
||||
enum AudioCacheFormat {acNone, acRaw, acFLAC};
|
||||
enum AudioCacheFormat {acNone, acRaw};
|
||||
|
||||
struct FrameInfo {
|
||||
int64_t DTS;
|
||||
|
@ -111,11 +102,6 @@ protected:
|
|||
int LastFrameNum;
|
||||
uint8_t *DecodingBuffer;
|
||||
|
||||
#ifdef FLAC_CACHE
|
||||
FLAC__StreamDecoder *FLACAudioCache;
|
||||
FLAC__int32 *FLACBuffer;
|
||||
#endif // FLAC_CACHE
|
||||
|
||||
FrameInfoVector Frames;
|
||||
|
||||
int FindClosestKeyFrame(int AFrame);
|
||||
|
@ -126,10 +112,6 @@ protected:
|
|||
bool SaveTimecodesToFile(const char *ATimecodeFile, int64_t ScaleD, int64_t ScaleN);
|
||||
|
||||
bool OpenAudioCache(const char *AAudioCacheFile, const char *ASource, int AAudioTrack, IScriptEnvironment *Env);
|
||||
#ifdef FLAC_CACHE
|
||||
FLAC__StreamEncoder *FFBase::NewFLACCacheWriter(const char *AAudioCacheFile, const char *ASource, int AAudioTrack, int ACompression, IScriptEnvironment *Env);
|
||||
void FFBase::CloseFLACCacheWriter(FLAC__StreamEncoder *AFSE);
|
||||
#endif // FLAC_CACHE
|
||||
FILE *FFBase::NewRawCacheWriter(const char *AAudioCacheFile, const char *ASource, int AAudioTrack, IScriptEnvironment *Env);
|
||||
void FFBase::CloseRawCacheWriter(FILE *ARawCache);
|
||||
|
||||
|
@ -137,11 +119,6 @@ protected:
|
|||
void SetOutputFormat(int ACurrentFormat, IScriptEnvironment *Env);
|
||||
PVideoFrame OutputFrame(AVFrame *AFrame, IScriptEnvironment *Env);
|
||||
public:
|
||||
// FLAC decoder variables, have to be public
|
||||
FILE *FCFile;
|
||||
__int64 FCCount;
|
||||
void *FCBuffer;
|
||||
bool FCError;
|
||||
|
||||
FFBase();
|
||||
~FFBase();
|
||||
|
@ -164,7 +141,7 @@ private:
|
|||
int GetTrackIndex(int Index, CodecType ATrackType, IScriptEnvironment *Env);
|
||||
int DecodeNextFrame(AVFrame *Frame, int64_t *DTS);
|
||||
public:
|
||||
FFmpegSource(const char *ASource, int AVideoTrack, int AAudioTrack, const char *ATimecodes, bool AVCache, const char *AVideoCache, const char *AAudioCache, int AACCompression, const char *APPString, int AQuality, int ASeekMode, IScriptEnvironment *Env, FrameInfoVector *AFrames);
|
||||
FFmpegSource(const char *ASource, int AVideoTrack, int AAudioTrack, const char *ATimecodes, bool AVCache, const char *AVideoCache, const char *AAudioCache, const char *APPString, int AQuality, int AThreads, int ASeekMode, IScriptEnvironment *Env, FrameInfoVector *AFrames);
|
||||
~FFmpegSource();
|
||||
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment *Env);
|
||||
};
|
||||
|
@ -185,7 +162,7 @@ private:
|
|||
int DecodeNextFrame(AVFrame *AFrame, int64_t *AFirstStartTime, IScriptEnvironment* Env);
|
||||
int GetTrackIndex(int Index, unsigned char ATrackType, IScriptEnvironment *Env);
|
||||
public:
|
||||
FFMatroskaSource(const char *ASource, int AVideoTrack, int AAudioTrack, const char *ATimecodes, bool AVCache, const char *AVideoCache, const char *AAudioCache, int AACCompression, const char *APPString, int AQuality, IScriptEnvironment *Env, FrameInfoVector *AFrames);
|
||||
FFMatroskaSource(const char *ASource, int AVideoTrack, int AAudioTrack, const char *ATimecodes, bool AVCache, const char *AVideoCache, const char *AAudioCache, const char *APPString, int AQuality, int AThreads, IScriptEnvironment *Env, FrameInfoVector *AFrames);
|
||||
~FFMatroskaSource();
|
||||
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment *Env);
|
||||
};
|
||||
|
|
|
@ -28,7 +28,7 @@ Loads video files without sucking
|
|||
|
||||
<h2>Usage</h2>
|
||||
<p>
|
||||
<b>FFmpegSource(string source, int vtrack = -1, int atrack = -2, string timecodes, bool vcache = true, string vcachefile, string acachefile, int accompression = -1, string pp, int ppquality = 6, int seekmode = 1)</b><br />
|
||||
<b>FFmpegSource(string source, int vtrack = -1, int atrack = -2, string timecodes, bool vcache = true, string vcachefile, string acachefile, string pp, int ppquality = 6, int threads = 1, int seekmode = 1)</b><br />
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -45,7 +45,7 @@ Experimental, may or may not be accurate enough for real usage.
|
|||
|
||||
<p>
|
||||
<b>FFPP(clip, string pp, int ppquality = 6)</b><br />
|
||||
Separate postprocessing which also seems to include a few simple deinterlacers
|
||||
Separate postprocessing which also seems to include a few simple deinterlacers
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -79,14 +79,9 @@ Separate postprocessing which also seems to include a few simple deinterlacers
|
|||
Specifies the file to store the demuxed audio stream in. Only used by FFAudioSource if the stream isn't matroska. If nothing is specified (source).ffasd(tracknumber)cache is used.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>accompression:</b>
|
||||
Audio cache compression, -1 means raw audio and 0-8 uses FLAC with that compression level.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>pp:</b>
|
||||
See the table below for a full description, an empty string means no processing. It is recommended to avoid the autoq option since it's currently unknown what effect it will have on the processing.
|
||||
See the table below for a full description, an empty string means no processing. It is recommended to avoid the autoq option since it's currently unknown what effect it will have on the processing.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -94,6 +89,11 @@ Separate postprocessing which also seems to include a few simple deinterlacers
|
|||
The quality to use for the specified postprocessing. Valid values are 0-6 where 0 usually means that no actual processing is done.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>threads:</b>
|
||||
Sets the number of decoder threads used, ignored if the used decoder doesn't implement it.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>seekmode:</b>
|
||||
Force how seeking is handled, has no effect on matroska files which always use the equivalent of seekmode=1<br />
|
||||
|
@ -154,16 +154,32 @@ tn:64:128:256
|
|||
|
||||
<p><b>FFmpeg svn</b> from http://ffmpeg.mplayerhq.hu/</p>
|
||||
|
||||
<p><b>FLAC (optional)</b> from http://flac.sourceforge.net/ (static library seems to be broken)</p>
|
||||
|
||||
<p><b>Required FFmpeg Configuration:</b>
|
||||
./configure --enable-shared --disable-static --enable-memalign-hack --enable-gpl --enable-swscaler</p>
|
||||
./configure --enable-memalign-hack --enable-gpl --enable-swscale --enable-postproc
|
||||
|
||||
<p><b>Suggested Additional Options:</b>
|
||||
--disable-encoders --disable-muxers --enable-small</p>
|
||||
--enable-w32threads --disable-encoders --disable-muxers --enable-small --enable-libfaad --disable-debug</p>
|
||||
<p>
|
||||
Note that --enable-w32threads is required for multithreaded decoding to work.
|
||||
</p>
|
||||
|
||||
<h2>Changes</h2>
|
||||
<ul>
|
||||
<li>1.17<ul>
|
||||
<li>Updated FFmpeg to rev X</li>
|
||||
</ul></li>
|
||||
|
||||
<li>1.16<ul>
|
||||
<li>Added many new and missing matroska codec ids</li>
|
||||
<li>Added threads argument to set the number of decoding threads used</li>
|
||||
<li>Completely removed FLAC cache</li>
|
||||
<li>Updated FFmpeg to rev 12382</li>
|
||||
</ul></li>
|
||||
|
||||
<li>1.15<ul>
|
||||
<li>Updated FFmpeg to rev 11518</li>
|
||||
</ul></li>
|
||||
|
||||
<li>1.14<ul>
|
||||
<li>If the output colorspace is YV12 or YUY2 the width and height may be automatically cropped by one pixel to make it an even number</li>
|
||||
<li>FLAC cache is disabled because the static FLAC lib doesn't want to link</li>
|
||||
|
@ -172,8 +188,6 @@ tn:64:128:256
|
|||
<li>Updated FFmpeg to rev 11413</li>
|
||||
</ul></li>
|
||||
|
||||
<h2>Changes</h2>
|
||||
<ul>
|
||||
<li>1.13<ul>
|
||||
<li>Now always sorts the output timecodes so native avc in mkv won't have out of order values</li>
|
||||
<li>Fixed the missing '# timecode format v2' line in saved timecode files</li>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2007 Fredrik Mellbin
|
||||
// Copyright (c) 2007-2008 Fredrik Mellbin
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -75,7 +75,7 @@ PVideoFrame FFPP::GetFrame(int n, IScriptEnvironment* Env) {
|
|||
PVideoFrame Dst = Env->NewVideoFrame(vi);
|
||||
|
||||
if (vi.IsYV12()) {
|
||||
uint8_t *SrcData[3] = {(uint8_t *)Src->GetReadPtr(PLANAR_Y), (uint8_t *)Src->GetReadPtr(PLANAR_U), (uint8_t *)Src->GetReadPtr(PLANAR_V)};
|
||||
const uint8_t *SrcData[3] = {(uint8_t *)Src->GetReadPtr(PLANAR_Y), (uint8_t *)Src->GetReadPtr(PLANAR_U), (uint8_t *)Src->GetReadPtr(PLANAR_V)};
|
||||
int SrcStride[3] = {Src->GetPitch(PLANAR_Y), Src->GetPitch(PLANAR_U), Src->GetPitch(PLANAR_V)};
|
||||
uint8_t *DstData[3] = {Dst->GetWritePtr(PLANAR_Y), Dst->GetWritePtr(PLANAR_U), Dst->GetWritePtr(PLANAR_V)};
|
||||
int DstStride[3] = {Dst->GetPitch(PLANAR_Y), Dst->GetPitch(PLANAR_U), Dst->GetPitch(PLANAR_V)};
|
||||
|
@ -86,7 +86,7 @@ PVideoFrame FFPP::GetFrame(int n, IScriptEnvironment* Env) {
|
|||
int SrcStride[1] = {Src->GetPitch()};
|
||||
sws_scale(SWSTo422P, SrcData, SrcStride, 0, vi.height, InputPicture.data, InputPicture.linesize);
|
||||
|
||||
pp_postprocess(InputPicture.data, InputPicture.linesize, OutputPicture.data, OutputPicture.linesize, vi.width, vi.height, NULL, 0, PPMode, PPContext, 0);
|
||||
pp_postprocess(const_cast<const uint8_t **>(InputPicture.data), InputPicture.linesize, OutputPicture.data, OutputPicture.linesize, vi.width, vi.height, NULL, 0, PPMode, PPContext, 0);
|
||||
|
||||
uint8_t *DstData[1] = {Dst->GetWritePtr()};
|
||||
int DstStride[1] = {Dst->GetPitch()};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2007 Fredrik Mellbin
|
||||
// Copyright (c) 2007-2008 Fredrik Mellbin
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -64,9 +64,9 @@ AVSValue __cdecl CreateFFmpegSource(AVSValue Args, void* UserData, IScriptEnviro
|
|||
bool VCache = Args[4].AsBool(true);
|
||||
const char *VCacheFile = Args[5].AsString("");
|
||||
const char *ACacheFile = Args[6].AsString("");
|
||||
int ACCompression = Args[7].AsInt(-1);
|
||||
const char *PPString = Args[8].AsString("");
|
||||
int PPQuality = Args[9].AsInt(PP_QUALITY_MAX);
|
||||
const char *PPString = Args[7].AsString("");
|
||||
int PPQuality = Args[8].AsInt(PP_QUALITY_MAX);
|
||||
int Threads = Args[9].AsInt(1);
|
||||
int SeekMode = Args[10].AsInt(1);
|
||||
|
||||
if (VTrack <= -2 && ATrack <= -2)
|
||||
|
@ -75,13 +75,8 @@ AVSValue __cdecl CreateFFmpegSource(AVSValue Args, void* UserData, IScriptEnviro
|
|||
if (SeekMode < -1 || SeekMode > 3)
|
||||
Env->ThrowError("FFmpegSource: Invalid seekmode selected");
|
||||
|
||||
#ifdef FLAC_CACHE
|
||||
if (ACCompression < -1 || ACCompression > 8)
|
||||
#else
|
||||
if (ACCompression != -1)
|
||||
#endif // FLAC_CACHE
|
||||
Env->ThrowError("FFmpegSource: Invalid audio cache compression selected");
|
||||
|
||||
if (Threads < 1)
|
||||
Env->ThrowError("FFmpegSource: Invalid thread count");
|
||||
|
||||
AVFormatContext *FormatContext;
|
||||
|
||||
|
@ -93,12 +88,12 @@ AVSValue __cdecl CreateFFmpegSource(AVSValue Args, void* UserData, IScriptEnviro
|
|||
FrameInfoVector Frames;
|
||||
|
||||
if (IsMatroska) {
|
||||
return new FFMatroskaSource(Source, VTrack, ATrack, Timecodes, VCache, VCacheFile, ACacheFile, ACCompression, PPString, PPQuality, Env, &Frames);
|
||||
return new FFMatroskaSource(Source, VTrack, ATrack, Timecodes, VCache, VCacheFile, ACacheFile, PPString, PPQuality, Threads, Env, &Frames);
|
||||
} else {
|
||||
// Do a separate indexing pass, enjoy the constructor sideeffects
|
||||
if (SeekMode == -1)
|
||||
delete new FFmpegSource(Source, VTrack, ATrack, Timecodes, VCache, VCacheFile, ACacheFile, ACCompression, PPString, PPQuality, -2, Env, &Frames);
|
||||
return new FFmpegSource(Source, VTrack, ATrack, Timecodes, VCache, VCacheFile, ACacheFile, ACCompression, PPString, PPQuality, SeekMode, Env, &Frames);
|
||||
delete new FFmpegSource(Source, VTrack, ATrack, Timecodes, VCache, VCacheFile, ACacheFile, PPString, PPQuality, Threads, -2, Env, &Frames);
|
||||
return new FFmpegSource(Source, VTrack, ATrack, Timecodes, VCache, VCacheFile, ACacheFile, PPString, PPQuality, Threads, SeekMode, Env, &Frames);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +133,7 @@ AVSValue __cdecl CreateFFPP(AVSValue Args, void* UserData, IScriptEnvironment* E
|
|||
}
|
||||
|
||||
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* Env) {
|
||||
Env->AddFunction("FFmpegSource", "[source]s[vtrack]i[atrack]i[timecodes]s[vcache]b[vcachefile]s[acachefile]s[accompression]i[pp]s[ppquality]i[seekmode]i", CreateFFmpegSource, 0);
|
||||
Env->AddFunction("FFmpegSource", "[source]s[vtrack]i[atrack]i[timecodes]s[vcache]b[vcachefile]s[acachefile]s[pp]s[ppquality]i[threads]i[seekmode]i", CreateFFmpegSource, 0);
|
||||
Env->AddFunction("FFAudioSource", "[source]s[atrack]i[acachefile]s[ademuxedfile]s", CreateFFAudioSource, 0);
|
||||
Env->AddFunction("FFPP", "c[pp]s[ppquality]i", CreateFFPP, 0);
|
||||
return "FFmpegSource";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2007 Fredrik Mellbin
|
||||
// Copyright (c) 2007-2008 Fredrik Mellbin
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -135,9 +135,9 @@ CodecID MatroskaToFFCodecID(TrackInfo *TI) {
|
|||
case MAKEFOURCC('M', 'S', 'Z', 'H'):
|
||||
return CODEC_ID_MSZH;
|
||||
case MAKEFOURCC('Z', 'L', 'I', 'B'):
|
||||
return CODEC_ID_FLV1;
|
||||
case MAKEFOURCC('F', 'L', 'V', '1'):
|
||||
return CODEC_ID_ZLIB;
|
||||
case MAKEFOURCC('F', 'L', 'V', '1'):
|
||||
return CODEC_ID_FLV1;
|
||||
/*
|
||||
case MAKEFOURCC('P', 'N', 'G', '1'):
|
||||
return CODEC_ID_COREPNG;
|
||||
|
@ -199,18 +199,33 @@ CodecID MatroskaToFFCodecID(TrackInfo *TI) {
|
|||
default:
|
||||
return CODEC_ID_NONE;
|
||||
}
|
||||
|
||||
} else if (!strcmp(Codec, "V_MPEG4/ISO/AVC"))
|
||||
return CODEC_ID_H264;
|
||||
else if (!strcmp(Codec, "V_MPEG4/ISO/AP"))
|
||||
return CODEC_ID_MPEG4;
|
||||
else if (!strcmp(Codec, "V_MPEG4/ISO/ASP"))
|
||||
return CODEC_ID_MPEG4;
|
||||
else if (!strcmp(Codec, "V_MPEG4/ISO/SP"))
|
||||
return CODEC_ID_MPEG4;
|
||||
else if (!strcmp(Codec, "V_MPEG4/MS/V3"))
|
||||
return CODEC_ID_MSMPEG4V3;
|
||||
else if (!strcmp(Codec, "V_MPEG2"))
|
||||
return CODEC_ID_MPEG2VIDEO;
|
||||
else if (!strcmp(Codec, "V_MPEG1"))
|
||||
return CODEC_ID_MPEG2VIDEO; // still not a typo
|
||||
else if (!strcmp(Codec, "V_VC1"))
|
||||
return CODEC_ID_VC1;
|
||||
else if (!strcmp(Codec, "V_SNOW"))
|
||||
return CODEC_ID_SNOW;
|
||||
else if (!strcmp(Codec, "V_THEORA"))
|
||||
return CODEC_ID_THEORA;
|
||||
else if (!strcmp(Codec, "V_UNCOMPRESSED"))
|
||||
return CODEC_ID_NONE; // bleh
|
||||
else if (!strcmp(Codec, "V_QUICKTIME"))
|
||||
return CODEC_ID_SVQ3;
|
||||
else if (!strcmp(Codec, "V_CIPC"))
|
||||
return CODEC_ID_NONE; // don't know, don't care
|
||||
else if (!strncmp(Codec, "V_REAL/RV", 9)) {
|
||||
switch (Codec[9]) {
|
||||
case '1':
|
||||
|
@ -227,6 +242,8 @@ CodecID MatroskaToFFCodecID(TrackInfo *TI) {
|
|||
/* Audio Codecs */
|
||||
} else if (!strcmp(Codec, "A_AC3"))
|
||||
return CODEC_ID_AC3;
|
||||
else if (!strcmp(Codec, "A_EAC3"))
|
||||
return CODEC_ID_AC3;
|
||||
else if (!strcmp(Codec, "A_MPEG/L3"))
|
||||
return CODEC_ID_MP3;
|
||||
else if (!strcmp(Codec, "A_MPEG/L2"))
|
||||
|
@ -243,8 +260,20 @@ CodecID MatroskaToFFCodecID(TrackInfo *TI) {
|
|||
case 32: return CODEC_ID_PCM_S32LE;
|
||||
default: return CODEC_ID_NONE;
|
||||
}
|
||||
} else if (!strcmp(Codec, "A_PCM/INT/BIG")) {
|
||||
switch (TI->AV.Audio.BitDepth) {
|
||||
case 8: return CODEC_ID_PCM_S8;
|
||||
case 16: return CODEC_ID_PCM_S16BE;
|
||||
case 24: return CODEC_ID_PCM_S24BE;
|
||||
case 32: return CODEC_ID_PCM_S32BE;
|
||||
default: return CODEC_ID_NONE;
|
||||
}
|
||||
} else if (!strcmp(Codec, "A_PCM/FLOAT/IEEE"))
|
||||
return CODEC_ID_NONE; // no float codec id?
|
||||
else if (!strcmp(Codec, "A_FLAC"))
|
||||
return CODEC_ID_FLAC;
|
||||
else if (!strcmp(Codec, "A_MPC"))
|
||||
return CODEC_ID_MUSEPACK8;
|
||||
else if (!strcmp(Codec, "A_TTA1"))
|
||||
return CODEC_ID_TTA;
|
||||
else if (!strcmp(Codec, "A_WAVPACK4"))
|
||||
|
@ -263,6 +292,10 @@ CodecID MatroskaToFFCodecID(TrackInfo *TI) {
|
|||
return CODEC_ID_ATRAC3;
|
||||
else if (!strncmp(Codec, "A_AAC", 5))
|
||||
return CODEC_ID_AAC;
|
||||
else if (!strcmp(Codec, "A_SPEEX"))
|
||||
return CODEC_ID_SPEEX;
|
||||
else if (!strcmp(Codec, "A_QUICKTIME"))
|
||||
return CODEC_ID_NONE; // no
|
||||
else if (!strcmp(Codec, "A_MS/ACM")) {
|
||||
// nothing useful here anyway?
|
||||
//#include "Mmreg.h"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2007 Fredrik Mellbin
|
||||
// Copyright (c) 2007-2008 Fredrik Mellbin
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2007 Fredrik Mellbin
|
||||
// Copyright (c) 2007-2008 Fredrik Mellbin
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
Loading…
Reference in a new issue