Backed out 3 changesets (bug 1270016) for various media test failures/unexpected-passes a=backout

Backed out changeset 9178e6e14a5a (bug 1270016)
Backed out changeset 8359b182bb99 (bug 1270016)
Backed out changeset 8a0f3231b43e (bug 1270016)
This commit is contained in:
Wes Kocher 2016-08-22 10:07:57 -07:00
Родитель 24cb21d4f6
Коммит 9c3d37e549
34 изменённых файлов: 68 добавлений и 3655 удалений

Просмотреть файл

@ -80,11 +80,6 @@ AudioSampleToFloat(int16_t aValue)
{
return aValue/32768.0f;
}
inline float
AudioSampleToFloat(int32_t aValue)
{
return aValue/(float)(1U<<31);
}
template <typename T> T FloatToAudioSample(float aValue);

Просмотреть файл

@ -21,10 +21,8 @@ FFmpegAudioDecoder<LIBAV_VER>::FFmpegAudioDecoder(FFmpegLibWrapper* aLib,
{
MOZ_COUNT_CTOR(FFmpegAudioDecoder);
// Use a new MediaByteBuffer as the object will be modified during initialization.
if (aConfig.mCodecSpecificConfig && aConfig.mCodecSpecificConfig->Length()) {
mExtraData = new MediaByteBuffer;
mExtraData->AppendElements(*aConfig.mCodecSpecificConfig);
}
mExtraData = new MediaByteBuffer;
mExtraData->AppendElements(*aConfig.mCodecSpecificConfig);
}
RefPtr<MediaDataDecoder::InitPromise>
@ -93,25 +91,6 @@ CopyAndPackAudio(AVFrame* aFrame, uint32_t aNumChannels, uint32_t aNumAFrames)
*tmp++ = AudioSampleToFloat(data[channel][frame]);
}
}
} else if (aFrame->format == AV_SAMPLE_FMT_S32) {
// Audio data already packed. Need to convert from S16 to 32 bits Float
AudioDataValue* tmp = audio.get();
int32_t* data = reinterpret_cast<int32_t**>(aFrame->data)[0];
for (uint32_t frame = 0; frame < aNumAFrames; frame++) {
for (uint32_t channel = 0; channel < aNumChannels; channel++) {
*tmp++ = AudioSampleToFloat(*data++);
}
}
} else if (aFrame->format == AV_SAMPLE_FMT_S32P) {
// Planar audio data. Convert it from S32 to 32 bits float
// and pack it into something we can understand.
AudioDataValue* tmp = audio.get();
int32_t** data = reinterpret_cast<int32_t**>(aFrame->data);
for (uint32_t frame = 0; frame < aNumAFrames; frame++) {
for (uint32_t channel = 0; channel < aNumChannels; channel++) {
*tmp++ = AudioSampleToFloat(data[channel][frame]);
}
}
}
return audio;
@ -144,16 +123,6 @@ FFmpegAudioDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample)
return DecodeResult::DECODE_ERROR;
}
if (mFrame->format != AV_SAMPLE_FMT_FLT &&
mFrame->format != AV_SAMPLE_FMT_FLTP &&
mFrame->format != AV_SAMPLE_FMT_S16 &&
mFrame->format != AV_SAMPLE_FMT_S16P &&
mFrame->format != AV_SAMPLE_FMT_S32 &&
mFrame->format != AV_SAMPLE_FMT_S32P) {
NS_WARNING("FFmpeg audio decoder outputs unsupported audio format.");
return DecodeResult::DECODE_ERROR;
}
if (decoded) {
uint32_t numChannels = mCodecContext->channels;
AudioConfig::ChannelLayout layout(numChannels);
@ -207,9 +176,9 @@ FFmpegAudioDecoder<LIBAV_VER>::GetCodecId(const nsACString& aMimeType)
{
if (aMimeType.EqualsLiteral("audio/mpeg")) {
return AV_CODEC_ID_MP3;
} else if (aMimeType.EqualsLiteral("audio/flac")) {
return AV_CODEC_ID_FLAC;
} else if (aMimeType.EqualsLiteral("audio/mp4a-latm")) {
}
if (aMimeType.EqualsLiteral("audio/mp4a-latm")) {
return AV_CODEC_ID_AAC;
}

Просмотреть файл

@ -86,6 +86,15 @@ FFmpegDataDecoder<LIBAV_VER>::InitDecoder()
return NS_ERROR_FAILURE;
}
if (mCodecContext->codec_type == AVMEDIA_TYPE_AUDIO &&
mCodecContext->sample_fmt != AV_SAMPLE_FMT_FLT &&
mCodecContext->sample_fmt != AV_SAMPLE_FMT_FLTP &&
mCodecContext->sample_fmt != AV_SAMPLE_FMT_S16 &&
mCodecContext->sample_fmt != AV_SAMPLE_FMT_S16P) {
NS_WARNING("FFmpeg audio decoder outputs unsupported audio format.");
return NS_ERROR_FAILURE;
}
FFMPEG_LOG("FFmpeg init successful.");
return NS_OK;
}

Просмотреть файл

@ -45,24 +45,35 @@ public:
already_AddRefed<MediaDataDecoder>
CreateAudioDecoder(const CreateDecoderParams& aParams) override
{
#ifdef USING_MOZFFVPX
return nullptr;
#else
RefPtr<MediaDataDecoder> decoder =
new FFmpegAudioDecoder<V>(mLib,
aParams.mTaskQueue,
aParams.mCallback,
aParams.AudioConfig());
return decoder.forget();
#endif
}
bool SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const override
{
AVCodecID videoCodec = FFmpegVideoDecoder<V>::GetCodecId(aMimeType);
#ifdef USING_MOZFFVPX
if (videoCodec == AV_CODEC_ID_NONE) {
return false;
}
return !!FFmpegDataDecoder<V>::FindAVCodec(mLib, videoCodec);
#else
AVCodecID audioCodec = FFmpegAudioDecoder<V>::GetCodecId(aMimeType);
if (audioCodec == AV_CODEC_ID_NONE && videoCodec == AV_CODEC_ID_NONE) {
return false;
}
AVCodecID codec = audioCodec != AV_CODEC_ID_NONE ? audioCodec : videoCodec;
return !!FFmpegDataDecoder<V>::FindAVCodec(mLib, codec);
#endif
}
ConversionRequired

Просмотреть файл

@ -26,7 +26,6 @@ extern "C" {
#define AV_CODEC_ID_MP3 CODEC_ID_MP3
#define AV_CODEC_ID_VP8 CODEC_ID_VP8
#define AV_CODEC_ID_NONE CODEC_ID_NONE
#define AV_CODEC_ID_FLAC CODEC_ID_FLAC
typedef CodecID AVCodecID;
#endif

Просмотреть файл

@ -10,7 +10,6 @@ EXPORTS += [
]
UNIFIED_SOURCES += [
'../FFmpegAudioDecoder.cpp',
'../FFmpegDataDecoder.cpp',
'../FFmpegDecoderModule.cpp',
'../FFmpegVideoDecoder.cpp',

Просмотреть файл

@ -576,11 +576,11 @@
#define CONFIG_FAANDCT 0
#define CONFIG_FAANIDCT 0
#define CONFIG_FDCTDSP 0
#define CONFIG_FLACDSP 1
#define CONFIG_FLACDSP 0
#define CONFIG_FMTCONVERT 0
#define CONFIG_FRAME_THREAD_ENCODER 0
#define CONFIG_G722DSP 0
#define CONFIG_GOLOMB 1
#define CONFIG_GOLOMB 0
#define CONFIG_GPLV3 0
#define CONFIG_H263DSP 0
#define CONFIG_H264CHROMA 0
@ -922,7 +922,7 @@
#define CONFIG_EAC3_DECODER 0
#define CONFIG_EVRC_DECODER 0
#define CONFIG_FFWAVESYNTH_DECODER 0
#define CONFIG_FLAC_DECODER 1
#define CONFIG_FLAC_DECODER 0
#define CONFIG_G723_1_DECODER 0
#define CONFIG_G729_DECODER 0
#define CONFIG_GSM_DECODER 0
@ -2104,7 +2104,7 @@
#define CONFIG_DVBSUB_PARSER 0
#define CONFIG_DVDSUB_PARSER 0
#define CONFIG_DVD_NAV_PARSER 0
#define CONFIG_FLAC_PARSER 1
#define CONFIG_FLAC_PARSER 0
#define CONFIG_G729_PARSER 0
#define CONFIG_GSM_PARSER 0
#define CONFIG_H261_PARSER 0

Просмотреть файл

@ -561,11 +561,11 @@
%define CONFIG_FAANDCT 0
%define CONFIG_FAANIDCT 0
%define CONFIG_FDCTDSP 0
%define CONFIG_FLACDSP 1
%define CONFIG_FLACDSP 0
%define CONFIG_FMTCONVERT 0
%define CONFIG_FRAME_THREAD_ENCODER 0
%define CONFIG_G722DSP 0
%define CONFIG_GOLOMB 1
%define CONFIG_GOLOMB 0
%define CONFIG_GPLV3 0
%define CONFIG_H263DSP 0
%define CONFIG_H264CHROMA 0
@ -907,7 +907,7 @@
%define CONFIG_EAC3_DECODER 0
%define CONFIG_EVRC_DECODER 0
%define CONFIG_FFWAVESYNTH_DECODER 0
%define CONFIG_FLAC_DECODER 1
%define CONFIG_FLAC_DECODER 0
%define CONFIG_G723_1_DECODER 0
%define CONFIG_G729_DECODER 0
%define CONFIG_GSM_DECODER 0
@ -2089,7 +2089,7 @@
%define CONFIG_DVBSUB_PARSER 0
%define CONFIG_DVDSUB_PARSER 0
%define CONFIG_DVD_NAV_PARSER 0
%define CONFIG_FLAC_PARSER 1
%define CONFIG_FLAC_PARSER 0
%define CONFIG_G729_PARSER 0
%define CONFIG_GSM_PARSER 0
%define CONFIG_H261_PARSER 0

Просмотреть файл

@ -576,11 +576,11 @@
#define CONFIG_FAANDCT 0
#define CONFIG_FAANIDCT 0
#define CONFIG_FDCTDSP 0
#define CONFIG_FLACDSP 1
#define CONFIG_FLACDSP 0
#define CONFIG_FMTCONVERT 0
#define CONFIG_FRAME_THREAD_ENCODER 0
#define CONFIG_G722DSP 0
#define CONFIG_GOLOMB 1
#define CONFIG_GOLOMB 0
#define CONFIG_GPLV3 0
#define CONFIG_H263DSP 0
#define CONFIG_H264CHROMA 0
@ -922,7 +922,7 @@
#define CONFIG_EAC3_DECODER 0
#define CONFIG_EVRC_DECODER 0
#define CONFIG_FFWAVESYNTH_DECODER 0
#define CONFIG_FLAC_DECODER 1
#define CONFIG_FLAC_DECODER 0
#define CONFIG_G723_1_DECODER 0
#define CONFIG_G729_DECODER 0
#define CONFIG_GSM_DECODER 0
@ -2104,7 +2104,7 @@
#define CONFIG_DVBSUB_PARSER 0
#define CONFIG_DVDSUB_PARSER 0
#define CONFIG_DVD_NAV_PARSER 0
#define CONFIG_FLAC_PARSER 1
#define CONFIG_FLAC_PARSER 0
#define CONFIG_G729_PARSER 0
#define CONFIG_GSM_PARSER 0
#define CONFIG_H261_PARSER 0

Просмотреть файл

@ -575,11 +575,11 @@
#define CONFIG_FAANDCT 0
#define CONFIG_FAANIDCT 0
#define CONFIG_FDCTDSP 0
#define CONFIG_FLACDSP 1
#define CONFIG_FLACDSP 0
#define CONFIG_FMTCONVERT 0
#define CONFIG_FRAME_THREAD_ENCODER 0
#define CONFIG_G722DSP 0
#define CONFIG_GOLOMB 1
#define CONFIG_GOLOMB 0
#define CONFIG_GPLV3 0
#define CONFIG_H263DSP 0
#define CONFIG_H264CHROMA 0
@ -921,7 +921,7 @@
#define CONFIG_EAC3_DECODER 0
#define CONFIG_EVRC_DECODER 0
#define CONFIG_FFWAVESYNTH_DECODER 0
#define CONFIG_FLAC_DECODER 1
#define CONFIG_FLAC_DECODER 0
#define CONFIG_G723_1_DECODER 0
#define CONFIG_G729_DECODER 0
#define CONFIG_GSM_DECODER 0
@ -2103,7 +2103,7 @@
#define CONFIG_DVBSUB_PARSER 0
#define CONFIG_DVDSUB_PARSER 0
#define CONFIG_DVD_NAV_PARSER 0
#define CONFIG_FLAC_PARSER 1
#define CONFIG_FLAC_PARSER 0
#define CONFIG_G729_PARSER 0
#define CONFIG_GSM_PARSER 0
#define CONFIG_H261_PARSER 0

Просмотреть файл

@ -561,11 +561,11 @@
%define CONFIG_FAANDCT 0
%define CONFIG_FAANIDCT 0
%define CONFIG_FDCTDSP 0
%define CONFIG_FLACDSP 1
%define CONFIG_FLACDSP 0
%define CONFIG_FMTCONVERT 0
%define CONFIG_FRAME_THREAD_ENCODER 0
%define CONFIG_G722DSP 0
%define CONFIG_GOLOMB 1
%define CONFIG_GOLOMB 0
%define CONFIG_GPLV3 0
%define CONFIG_H263DSP 0
%define CONFIG_H264CHROMA 0
@ -907,7 +907,7 @@
%define CONFIG_EAC3_DECODER 0
%define CONFIG_EVRC_DECODER 0
%define CONFIG_FFWAVESYNTH_DECODER 0
%define CONFIG_FLAC_DECODER 1
%define CONFIG_FLAC_DECODER 0
%define CONFIG_G723_1_DECODER 0
%define CONFIG_G729_DECODER 0
%define CONFIG_GSM_DECODER 0
@ -2089,7 +2089,7 @@
%define CONFIG_DVBSUB_PARSER 0
%define CONFIG_DVDSUB_PARSER 0
%define CONFIG_DVD_NAV_PARSER 0
%define CONFIG_FLAC_PARSER 1
%define CONFIG_FLAC_PARSER 0
%define CONFIG_G729_PARSER 0
%define CONFIG_GSM_PARSER 0
%define CONFIG_H261_PARSER 0

Просмотреть файл

@ -576,11 +576,11 @@
#define CONFIG_FAANDCT 0
#define CONFIG_FAANIDCT 0
#define CONFIG_FDCTDSP 0
#define CONFIG_FLACDSP 1
#define CONFIG_FLACDSP 0
#define CONFIG_FMTCONVERT 0
#define CONFIG_FRAME_THREAD_ENCODER 0
#define CONFIG_G722DSP 0
#define CONFIG_GOLOMB 1
#define CONFIG_GOLOMB 0
#define CONFIG_GPLV3 0
#define CONFIG_H263DSP 0
#define CONFIG_H264CHROMA 0
@ -922,7 +922,7 @@
#define CONFIG_EAC3_DECODER 0
#define CONFIG_EVRC_DECODER 0
#define CONFIG_FFWAVESYNTH_DECODER 0
#define CONFIG_FLAC_DECODER 1
#define CONFIG_FLAC_DECODER 0
#define CONFIG_G723_1_DECODER 0
#define CONFIG_G729_DECODER 0
#define CONFIG_GSM_DECODER 0
@ -2104,7 +2104,7 @@
#define CONFIG_DVBSUB_PARSER 0
#define CONFIG_DVDSUB_PARSER 0
#define CONFIG_DVD_NAV_PARSER 0
#define CONFIG_FLAC_PARSER 1
#define CONFIG_FLAC_PARSER 0
#define CONFIG_G729_PARSER 0
#define CONFIG_GSM_PARSER 0
#define CONFIG_H261_PARSER 0

Просмотреть файл

@ -561,11 +561,11 @@
%define CONFIG_FAANDCT 0
%define CONFIG_FAANIDCT 0
%define CONFIG_FDCTDSP 0
%define CONFIG_FLACDSP 1
%define CONFIG_FLACDSP 0
%define CONFIG_FMTCONVERT 0
%define CONFIG_FRAME_THREAD_ENCODER 0
%define CONFIG_G722DSP 0
%define CONFIG_GOLOMB 1
%define CONFIG_GOLOMB 0
%define CONFIG_GPLV3 0
%define CONFIG_H263DSP 0
%define CONFIG_H264CHROMA 0
@ -907,7 +907,7 @@
%define CONFIG_EAC3_DECODER 0
%define CONFIG_EVRC_DECODER 0
%define CONFIG_FFWAVESYNTH_DECODER 0
%define CONFIG_FLAC_DECODER 1
%define CONFIG_FLAC_DECODER 0
%define CONFIG_G723_1_DECODER 0
%define CONFIG_G729_DECODER 0
%define CONFIG_GSM_DECODER 0
@ -2089,7 +2089,7 @@
%define CONFIG_DVBSUB_PARSER 0
%define CONFIG_DVDSUB_PARSER 0
%define CONFIG_DVD_NAV_PARSER 0
%define CONFIG_FLAC_PARSER 1
%define CONFIG_FLAC_PARSER 0
%define CONFIG_G729_PARSER 0
%define CONFIG_GSM_PARSER 0
%define CONFIG_H261_PARSER 0

Просмотреть файл

@ -576,11 +576,11 @@
#define CONFIG_FAANDCT 0
#define CONFIG_FAANIDCT 0
#define CONFIG_FDCTDSP 0
#define CONFIG_FLACDSP 1
#define CONFIG_FLACDSP 0
#define CONFIG_FMTCONVERT 0
#define CONFIG_FRAME_THREAD_ENCODER 0
#define CONFIG_G722DSP 0
#define CONFIG_GOLOMB 1
#define CONFIG_GOLOMB 0
#define CONFIG_GPLV3 0
#define CONFIG_H263DSP 0
#define CONFIG_H264CHROMA 0
@ -922,7 +922,7 @@
#define CONFIG_EAC3_DECODER 0
#define CONFIG_EVRC_DECODER 0
#define CONFIG_FFWAVESYNTH_DECODER 0
#define CONFIG_FLAC_DECODER 1
#define CONFIG_FLAC_DECODER 0
#define CONFIG_G723_1_DECODER 0
#define CONFIG_G729_DECODER 0
#define CONFIG_GSM_DECODER 0
@ -2104,7 +2104,7 @@
#define CONFIG_DVBSUB_PARSER 0
#define CONFIG_DVDSUB_PARSER 0
#define CONFIG_DVD_NAV_PARSER 0
#define CONFIG_FLAC_PARSER 1
#define CONFIG_FLAC_PARSER 0
#define CONFIG_G729_PARSER 0
#define CONFIG_GSM_PARSER 0
#define CONFIG_H261_PARSER 0

Просмотреть файл

@ -561,11 +561,11 @@
%define CONFIG_FAANDCT 0
%define CONFIG_FAANIDCT 0
%define CONFIG_FDCTDSP 0
%define CONFIG_FLACDSP 1
%define CONFIG_FLACDSP 0
%define CONFIG_FMTCONVERT 0
%define CONFIG_FRAME_THREAD_ENCODER 0
%define CONFIG_G722DSP 0
%define CONFIG_GOLOMB 1
%define CONFIG_GOLOMB 0
%define CONFIG_GPLV3 0
%define CONFIG_H263DSP 0
%define CONFIG_H264CHROMA 0
@ -907,7 +907,7 @@
%define CONFIG_EAC3_DECODER 0
%define CONFIG_EVRC_DECODER 0
%define CONFIG_FFWAVESYNTH_DECODER 0
%define CONFIG_FLAC_DECODER 1
%define CONFIG_FLAC_DECODER 0
%define CONFIG_G723_1_DECODER 0
%define CONFIG_G729_DECODER 0
%define CONFIG_GSM_DECODER 0
@ -2089,7 +2089,7 @@
%define CONFIG_DVBSUB_PARSER 0
%define CONFIG_DVDSUB_PARSER 0
%define CONFIG_DVD_NAV_PARSER 0
%define CONFIG_FLAC_PARSER 1
%define CONFIG_FLAC_PARSER 0
%define CONFIG_G729_PARSER 0
%define CONFIG_GSM_PARSER 0
%define CONFIG_H261_PARSER 0

Просмотреть файл

@ -576,11 +576,11 @@
#define CONFIG_FAANDCT 0
#define CONFIG_FAANIDCT 0
#define CONFIG_FDCTDSP 0
#define CONFIG_FLACDSP 1
#define CONFIG_FLACDSP 0
#define CONFIG_FMTCONVERT 0
#define CONFIG_FRAME_THREAD_ENCODER 0
#define CONFIG_G722DSP 0
#define CONFIG_GOLOMB 1
#define CONFIG_GOLOMB 0
#define CONFIG_GPLV3 0
#define CONFIG_H263DSP 0
#define CONFIG_H264CHROMA 0
@ -922,7 +922,7 @@
#define CONFIG_EAC3_DECODER 0
#define CONFIG_EVRC_DECODER 0
#define CONFIG_FFWAVESYNTH_DECODER 0
#define CONFIG_FLAC_DECODER 1
#define CONFIG_FLAC_DECODER 0
#define CONFIG_G723_1_DECODER 0
#define CONFIG_G729_DECODER 0
#define CONFIG_GSM_DECODER 0
@ -2104,7 +2104,7 @@
#define CONFIG_DVBSUB_PARSER 0
#define CONFIG_DVDSUB_PARSER 0
#define CONFIG_DVD_NAV_PARSER 0
#define CONFIG_FLAC_PARSER 1
#define CONFIG_FLAC_PARSER 0
#define CONFIG_G729_PARSER 0
#define CONFIG_GSM_PARSER 0
#define CONFIG_H261_PARSER 0

Просмотреть файл

@ -10,7 +10,6 @@ typedef struct H264PredContext H264PredContext;
typedef struct VideoDSPContext VideoDSPContext;
typedef struct VP8DSPContext VP8DSPContext;
typedef struct VP9DSPContext VP9DSPContext;
typedef struct FLACDSPContext FLACDSPContext;
AVHWAccel ff_h263_vaapi_hwaccel;
AVHWAccel ff_h263_vdpau_hwaccel;
@ -401,6 +400,7 @@ AVCodec ff_eac3_decoder;
AVCodec ff_evrc_decoder;
AVCodec ff_ffwavesynth_decoder;
AVCodec ff_flac_encoder;
AVCodec ff_flac_decoder;
AVCodec ff_g723_1_encoder;
AVCodec ff_g723_1_decoder;
AVCodec ff_g729_decoder;
@ -729,6 +729,7 @@ AVCodecParser ff_dvaudio_parser;
AVCodecParser ff_dvbsub_parser;
AVCodecParser ff_dvdsub_parser;
AVCodecParser ff_dvd_nav_parser;
AVCodecParser ff_flac_parser;
AVCodecParser ff_g729_parser;
AVCodecParser ff_gsm_parser;
AVCodecParser ff_h261_parser;
@ -784,13 +785,7 @@ void ff_vp78dsp_init_ppc(VP8DSPContext *c) {}
void ff_vp8dsp_init_arm(VP8DSPContext *c) {}
void ff_vp8dsp_init_mips(VP8DSPContext *c) {}
void ff_vp9dsp_init_mips(VP9DSPContext *dsp, int bpp) {}
void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps) {}
#if !defined(HAVE_64BIT_BUILD)
void ff_flac_decorrelate_indep8_16_sse2(uint8_t **out, int32_t **in, int channels, int len, int shift) {}
void ff_flac_decorrelate_indep8_32_avx(uint8_t **out, int32_t **in, int channels, int len, int shift) {}
void ff_flac_decorrelate_indep8_16_avx(uint8_t **out, int32_t **in, int channels, int len, int shift) {}
void ff_flac_decorrelate_indep8_32_sse2(uint8_t **out, int32_t **in, int channels, int len, int shift) {}
#endif
void av_bitstream_filter_close(AVBitStreamFilterContext *bsf) {}
int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
AVCodecContext *avctx, const char *args,

Просмотреть файл

@ -1,237 +0,0 @@
/*
* FLAC common code
* Copyright (c) 2009 Justin Ruggles
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/channel_layout.h"
#include "libavutil/crc.h"
#include "libavutil/log.h"
#include "bytestream.h"
#include "get_bits.h"
#include "flac.h"
#include "flacdata.h"
static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
static const uint64_t flac_channel_layouts[8] = {
AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_SURROUND,
AV_CH_LAYOUT_QUAD,
AV_CH_LAYOUT_5POINT0,
AV_CH_LAYOUT_5POINT1,
AV_CH_LAYOUT_6POINT1,
AV_CH_LAYOUT_7POINT1
};
static int64_t get_utf8(GetBitContext *gb)
{
int64_t val;
GET_UTF8(val, get_bits(gb, 8), return -1;)
return val;
}
int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
FLACFrameInfo *fi, int log_level_offset)
{
int bs_code, sr_code, bps_code;
/* frame sync code */
if ((get_bits(gb, 15) & 0x7FFF) != 0x7FFC) {
av_log(avctx, AV_LOG_ERROR + log_level_offset, "invalid sync code\n");
return AVERROR_INVALIDDATA;
}
/* variable block size stream code */
fi->is_var_size = get_bits1(gb);
/* block size and sample rate codes */
bs_code = get_bits(gb, 4);
sr_code = get_bits(gb, 4);
/* channels and decorrelation */
fi->ch_mode = get_bits(gb, 4);
if (fi->ch_mode < FLAC_MAX_CHANNELS) {
fi->channels = fi->ch_mode + 1;
fi->ch_mode = FLAC_CHMODE_INDEPENDENT;
} else if (fi->ch_mode < FLAC_MAX_CHANNELS + FLAC_CHMODE_MID_SIDE) {
fi->channels = 2;
fi->ch_mode -= FLAC_MAX_CHANNELS - 1;
} else {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"invalid channel mode: %d\n", fi->ch_mode);
return AVERROR_INVALIDDATA;
}
/* bits per sample */
bps_code = get_bits(gb, 3);
if (bps_code == 3 || bps_code == 7) {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"invalid sample size code (%d)\n",
bps_code);
return AVERROR_INVALIDDATA;
}
fi->bps = sample_size_table[bps_code];
/* reserved bit */
if (get_bits1(gb)) {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"broken stream, invalid padding\n");
return AVERROR_INVALIDDATA;
}
/* sample or frame count */
fi->frame_or_sample_num = get_utf8(gb);
if (fi->frame_or_sample_num < 0) {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"sample/frame number invalid; utf8 fscked\n");
return AVERROR_INVALIDDATA;
}
/* blocksize */
if (bs_code == 0) {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"reserved blocksize code: 0\n");
return AVERROR_INVALIDDATA;
} else if (bs_code == 6) {
fi->blocksize = get_bits(gb, 8) + 1;
} else if (bs_code == 7) {
fi->blocksize = get_bits(gb, 16) + 1;
} else {
fi->blocksize = ff_flac_blocksize_table[bs_code];
}
/* sample rate */
if (sr_code < 12) {
fi->samplerate = ff_flac_sample_rate_table[sr_code];
} else if (sr_code == 12) {
fi->samplerate = get_bits(gb, 8) * 1000;
} else if (sr_code == 13) {
fi->samplerate = get_bits(gb, 16);
} else if (sr_code == 14) {
fi->samplerate = get_bits(gb, 16) * 10;
} else {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"illegal sample rate code %d\n",
sr_code);
return AVERROR_INVALIDDATA;
}
/* header CRC-8 check */
skip_bits(gb, 8);
if (av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, gb->buffer,
get_bits_count(gb)/8)) {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"header crc mismatch\n");
return AVERROR_INVALIDDATA;
}
return 0;
}
int ff_flac_get_max_frame_size(int blocksize, int ch, int bps)
{
/* Technically, there is no limit to FLAC frame size, but an encoder
should not write a frame that is larger than if verbatim encoding mode
were to be used. */
int count;
count = 16; /* frame header */
count += ch * ((7+bps+7)/8); /* subframe headers */
if (ch == 2) {
/* for stereo, need to account for using decorrelation */
count += (( 2*bps+1) * blocksize + 7) / 8;
} else {
count += ( ch*bps * blocksize + 7) / 8;
}
count += 2; /* frame footer */
return count;
}
int ff_flac_is_extradata_valid(AVCodecContext *avctx,
enum FLACExtradataFormat *format,
uint8_t **streaminfo_start)
{
if (!avctx->extradata || avctx->extradata_size < FLAC_STREAMINFO_SIZE) {
av_log(avctx, AV_LOG_ERROR, "extradata NULL or too small.\n");
return 0;
}
if (AV_RL32(avctx->extradata) != MKTAG('f','L','a','C')) {
/* extradata contains STREAMINFO only */
if (avctx->extradata_size != FLAC_STREAMINFO_SIZE) {
av_log(avctx, AV_LOG_WARNING, "extradata contains %d bytes too many.\n",
FLAC_STREAMINFO_SIZE-avctx->extradata_size);
}
*format = FLAC_EXTRADATA_FORMAT_STREAMINFO;
*streaminfo_start = avctx->extradata;
} else {
if (avctx->extradata_size < 8+FLAC_STREAMINFO_SIZE) {
av_log(avctx, AV_LOG_ERROR, "extradata too small.\n");
return 0;
}
*format = FLAC_EXTRADATA_FORMAT_FULL_HEADER;
*streaminfo_start = &avctx->extradata[8];
}
return 1;
}
void ff_flac_set_channel_layout(AVCodecContext *avctx)
{
if (avctx->channels <= FF_ARRAY_ELEMS(flac_channel_layouts))
avctx->channel_layout = flac_channel_layouts[avctx->channels - 1];
else
avctx->channel_layout = 0;
}
void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
const uint8_t *buffer)
{
GetBitContext gb;
init_get_bits(&gb, buffer, FLAC_STREAMINFO_SIZE*8);
skip_bits(&gb, 16); /* skip min blocksize */
s->max_blocksize = get_bits(&gb, 16);
if (s->max_blocksize < FLAC_MIN_BLOCKSIZE) {
av_log(avctx, AV_LOG_WARNING, "invalid max blocksize: %d\n",
s->max_blocksize);
s->max_blocksize = 16;
}
skip_bits(&gb, 24); /* skip min frame size */
s->max_framesize = get_bits_long(&gb, 24);
s->samplerate = get_bits_long(&gb, 20);
s->channels = get_bits(&gb, 3) + 1;
s->bps = get_bits(&gb, 5) + 1;
avctx->channels = s->channels;
avctx->sample_rate = s->samplerate;
avctx->bits_per_raw_sample = s->bps;
if (!avctx->channel_layout ||
av_get_channel_layout_nb_channels(avctx->channel_layout) != avctx->channels)
ff_flac_set_channel_layout(avctx);
s->samples = get_bits64(&gb, 36);
skip_bits_long(&gb, 64); /* md5 sum */
skip_bits_long(&gb, 64); /* md5 sum */
}

Просмотреть файл

@ -1,153 +0,0 @@
/*
* FLAC (Free Lossless Audio Codec) decoder/demuxer common functions
* Copyright (c) 2008 Justin Ruggles
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* FLAC (Free Lossless Audio Codec) decoder/demuxer common functions
*/
#ifndef AVCODEC_FLAC_H
#define AVCODEC_FLAC_H
#include "avcodec.h"
#include "bytestream.h"
#include "get_bits.h"
#define FLAC_STREAMINFO_SIZE 34
#define FLAC_MAX_CHANNELS 8
#define FLAC_MIN_BLOCKSIZE 16
#define FLAC_MAX_BLOCKSIZE 65535
#define FLAC_MIN_FRAME_SIZE 11
enum {
FLAC_CHMODE_INDEPENDENT = 0,
FLAC_CHMODE_LEFT_SIDE = 1,
FLAC_CHMODE_RIGHT_SIDE = 2,
FLAC_CHMODE_MID_SIDE = 3,
};
enum {
FLAC_METADATA_TYPE_STREAMINFO = 0,
FLAC_METADATA_TYPE_PADDING,
FLAC_METADATA_TYPE_APPLICATION,
FLAC_METADATA_TYPE_SEEKTABLE,
FLAC_METADATA_TYPE_VORBIS_COMMENT,
FLAC_METADATA_TYPE_CUESHEET,
FLAC_METADATA_TYPE_PICTURE,
FLAC_METADATA_TYPE_INVALID = 127
};
enum FLACExtradataFormat {
FLAC_EXTRADATA_FORMAT_STREAMINFO = 0,
FLAC_EXTRADATA_FORMAT_FULL_HEADER = 1
};
#define FLACCOMMONINFO \
int samplerate; /**< sample rate */\
int channels; /**< number of channels */\
int bps; /**< bits-per-sample */\
/**
* Data needed from the Streaminfo header for use by the raw FLAC demuxer
* and/or the FLAC decoder.
*/
#define FLACSTREAMINFO \
FLACCOMMONINFO \
int max_blocksize; /**< maximum block size, in samples */\
int max_framesize; /**< maximum frame size, in bytes */\
int64_t samples; /**< total number of samples */\
typedef struct FLACStreaminfo {
FLACSTREAMINFO
} FLACStreaminfo;
typedef struct FLACFrameInfo {
FLACCOMMONINFO
int blocksize; /**< block size of the frame */
int ch_mode; /**< channel decorrelation mode */
int64_t frame_or_sample_num; /**< frame number or sample number */
int is_var_size; /**< specifies if the stream uses variable
block sizes or a fixed block size;
also determines the meaning of
frame_or_sample_num */
} FLACFrameInfo;
/**
* Parse the Streaminfo metadata block
* @param[out] avctx codec context to set basic stream parameters
* @param[out] s where parsed information is stored
* @param[in] buffer pointer to start of 34-byte streaminfo data
*/
void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
const uint8_t *buffer);
/**
* Validate the FLAC extradata.
* @param[in] avctx codec context containing the extradata.
* @param[out] format extradata format.
* @param[out] streaminfo_start pointer to start of 34-byte STREAMINFO data.
* @return 1 if valid, 0 if not valid.
*/
int ff_flac_is_extradata_valid(AVCodecContext *avctx,
enum FLACExtradataFormat *format,
uint8_t **streaminfo_start);
/**
* Calculate an estimate for the maximum frame size based on verbatim mode.
* @param blocksize block size, in samples
* @param ch number of channels
* @param bps bits-per-sample
*/
int ff_flac_get_max_frame_size(int blocksize, int ch, int bps);
/**
* Validate and decode a frame header.
* @param avctx AVCodecContext to use as av_log() context
* @param gb GetBitContext from which to read frame header
* @param[out] fi frame information
* @param log_level_offset log level offset. can be used to silence error messages.
* @return non-zero on error, 0 if ok
*/
int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
FLACFrameInfo *fi, int log_level_offset);
void ff_flac_set_channel_layout(AVCodecContext *avctx);
/**
* Parse the metadata block parameters from the header.
* @param[in] block_header header data, at least 4 bytes
* @param[out] last indicator for last metadata block
* @param[out] type metadata block type
* @param[out] size metadata block size
*/
static av_always_inline void flac_parse_block_header(const uint8_t *block_header,
int *last, int *type, int *size)
{
int tmp = bytestream_get_byte(&block_header);
if (last)
*last = tmp & 0x80;
if (type)
*type = tmp & 0x7F;
if (size)
*size = bytestream_get_be24(&block_header);
}
#endif /* AVCODEC_FLAC_H */

Просмотреть файл

@ -1,755 +0,0 @@
/*
* FLAC parser
* Copyright (c) 2010 Michael Chinen
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* FLAC parser
*
* The FLAC parser buffers input until FLAC_MIN_HEADERS has been found.
* Each time it finds and verifies a CRC-8 header it sees which of the
* FLAC_MAX_SEQUENTIAL_HEADERS that came before it have a valid CRC-16 footer
* that ends at the newly found header.
* Headers are scored by FLAC_HEADER_BASE_SCORE plus the max of its crc-verified
* children, penalized by changes in sample rate, frame number, etc.
* The parser returns the frame with the highest score.
**/
#include "libavutil/attributes.h"
#include "libavutil/crc.h"
#include "libavutil/fifo.h"
#include "bytestream.h"
#include "parser.h"
#include "flac.h"
/** maximum number of adjacent headers that compare CRCs against each other */
#define FLAC_MAX_SEQUENTIAL_HEADERS 4
/** minimum number of headers buffered and checked before returning frames */
#define FLAC_MIN_HEADERS 10
/** estimate for average size of a FLAC frame */
#define FLAC_AVG_FRAME_SIZE 8192
/** scoring settings for score_header */
#define FLAC_HEADER_BASE_SCORE 10
#define FLAC_HEADER_CHANGED_PENALTY 7
#define FLAC_HEADER_CRC_FAIL_PENALTY 50
#define FLAC_HEADER_NOT_PENALIZED_YET 100000
#define FLAC_HEADER_NOT_SCORED_YET -100000
/** largest possible size of flac header */
#define MAX_FRAME_HEADER_SIZE 16
typedef struct FLACHeaderMarker {
int offset; /**< byte offset from start of FLACParseContext->buffer */
int *link_penalty; /**< pointer to array of local scores between this header
and the one at a distance equal array position */
int max_score; /**< maximum score found after checking each child that
has a valid CRC */
FLACFrameInfo fi; /**< decoded frame header info */
struct FLACHeaderMarker *next; /**< next CRC-8 verified header that
immediately follows this one in
the bytestream */
struct FLACHeaderMarker *best_child; /**< following frame header with
which this frame has the best
score with */
} FLACHeaderMarker;
typedef struct FLACParseContext {
AVCodecParserContext *pc; /**< parent context */
AVCodecContext *avctx; /**< codec context pointer for logging */
FLACHeaderMarker *headers; /**< linked-list that starts at the first
CRC-8 verified header within buffer */
FLACHeaderMarker *best_header; /**< highest scoring header within buffer */
int nb_headers_found; /**< number of headers found in the last
flac_parse() call */
int nb_headers_buffered; /**< number of headers that are buffered */
int best_header_valid; /**< flag set when the parser returns junk;
if set return best_header next time */
AVFifoBuffer *fifo_buf; /**< buffer to store all data until headers
can be verified */
int end_padded; /**< specifies if fifo_buf's end is padded */
uint8_t *wrap_buf; /**< general fifo read buffer when wrapped */
int wrap_buf_allocated_size; /**< actual allocated size of the buffer */
FLACFrameInfo last_fi; /**< last decoded frame header info */
int last_fi_valid; /**< set if last_fi is valid */
} FLACParseContext;
static int frame_header_is_valid(AVCodecContext *avctx, const uint8_t *buf,
FLACFrameInfo *fi)
{
GetBitContext gb;
init_get_bits(&gb, buf, MAX_FRAME_HEADER_SIZE * 8);
return !ff_flac_decode_frame_header(avctx, &gb, fi, 127);
}
/**
* Non-destructive fast fifo pointer fetching
* Returns a pointer from the specified offset.
* If possible the pointer points within the fifo buffer.
* Otherwise (if it would cause a wrap around,) a pointer to a user-specified
* buffer is used.
* The pointer can be NULL. In any case it will be reallocated to hold the size.
* If the returned pointer will be used after subsequent calls to flac_fifo_read_wrap
* then the subsequent calls should pass in a different wrap_buf so as to not
* overwrite the contents of the previous wrap_buf.
* This function is based on av_fifo_generic_read, which is why there is a comment
* about a memory barrier for SMP.
*/
static uint8_t* flac_fifo_read_wrap(FLACParseContext *fpc, int offset, int len,
uint8_t** wrap_buf, int* allocated_size)
{
AVFifoBuffer *f = fpc->fifo_buf;
uint8_t *start = f->rptr + offset;
uint8_t *tmp_buf;
if (start >= f->end)
start -= f->end - f->buffer;
if (f->end - start >= len)
return start;
tmp_buf = av_fast_realloc(*wrap_buf, allocated_size, len);
if (!tmp_buf) {
av_log(fpc->avctx, AV_LOG_ERROR,
"couldn't reallocate wrap buffer of size %d", len);
return NULL;
}
*wrap_buf = tmp_buf;
do {
int seg_len = FFMIN(f->end - start, len);
memcpy(tmp_buf, start, seg_len);
tmp_buf = (uint8_t*)tmp_buf + seg_len;
// memory barrier needed for SMP here in theory
start += seg_len - (f->end - f->buffer);
len -= seg_len;
} while (len > 0);
return *wrap_buf;
}
/**
* Return a pointer in the fifo buffer where the offset starts at until
* the wrap point or end of request.
* len will contain the valid length of the returned buffer.
* A second call to flac_fifo_read (with new offset and len) should be called
* to get the post-wrap buf if the returned len is less than the requested.
**/
static uint8_t* flac_fifo_read(FLACParseContext *fpc, int offset, int *len)
{
AVFifoBuffer *f = fpc->fifo_buf;
uint8_t *start = f->rptr + offset;
if (start >= f->end)
start -= f->end - f->buffer;
*len = FFMIN(*len, f->end - start);
return start;
}
static int find_headers_search_validate(FLACParseContext *fpc, int offset)
{
FLACFrameInfo fi;
uint8_t *header_buf;
int size = 0;
header_buf = flac_fifo_read_wrap(fpc, offset,
MAX_FRAME_HEADER_SIZE,
&fpc->wrap_buf,
&fpc->wrap_buf_allocated_size);
if (frame_header_is_valid(fpc->avctx, header_buf, &fi)) {
FLACHeaderMarker **end_handle = &fpc->headers;
int i;
size = 0;
while (*end_handle) {
end_handle = &(*end_handle)->next;
size++;
}
*end_handle = av_mallocz(sizeof(**end_handle));
if (!*end_handle) {
av_log(fpc->avctx, AV_LOG_ERROR,
"couldn't allocate FLACHeaderMarker\n");
return AVERROR(ENOMEM);
}
(*end_handle)->fi = fi;
(*end_handle)->offset = offset;
(*end_handle)->link_penalty = av_malloc(sizeof(int) *
FLAC_MAX_SEQUENTIAL_HEADERS);
if (!(*end_handle)->link_penalty) {
av_freep(end_handle);
av_log(fpc->avctx, AV_LOG_ERROR,
"couldn't allocate link_penalty\n");
return AVERROR(ENOMEM);
}
for (i = 0; i < FLAC_MAX_SEQUENTIAL_HEADERS; i++)
(*end_handle)->link_penalty[i] = FLAC_HEADER_NOT_PENALIZED_YET;
fpc->nb_headers_found++;
size++;
}
return size;
}
static int find_headers_search(FLACParseContext *fpc, uint8_t *buf, int buf_size,
int search_start)
{
int size = 0, mod_offset = (buf_size - 1) % 4, i, j;
uint32_t x;
for (i = 0; i < mod_offset; i++) {
if ((AV_RB16(buf + i) & 0xFFFE) == 0xFFF8)
size = find_headers_search_validate(fpc, search_start + i);
}
for (; i < buf_size - 1; i += 4) {
x = AV_RB32(buf + i);
if (((x & ~(x + 0x01010101)) & 0x80808080)) {
for (j = 0; j < 4; j++) {
if ((AV_RB16(buf + i + j) & 0xFFFE) == 0xFFF8)
size = find_headers_search_validate(fpc, search_start + i + j);
}
}
}
return size;
}
static int find_new_headers(FLACParseContext *fpc, int search_start)
{
FLACHeaderMarker *end;
int search_end, size = 0, read_len, temp;
uint8_t *buf;
fpc->nb_headers_found = 0;
/* Search for a new header of at most 16 bytes. */
search_end = av_fifo_size(fpc->fifo_buf) - (MAX_FRAME_HEADER_SIZE - 1);
read_len = search_end - search_start + 1;
buf = flac_fifo_read(fpc, search_start, &read_len);
size = find_headers_search(fpc, buf, read_len, search_start);
search_start += read_len - 1;
/* If fifo end was hit do the wrap around. */
if (search_start != search_end) {
uint8_t wrap[2];
wrap[0] = buf[read_len - 1];
read_len = search_end - search_start + 1;
/* search_start + 1 is the post-wrap offset in the fifo. */
buf = flac_fifo_read(fpc, search_start + 1, &read_len);
wrap[1] = buf[0];
if ((AV_RB16(wrap) & 0xFFFE) == 0xFFF8) {
temp = find_headers_search_validate(fpc, search_start);
size = FFMAX(size, temp);
}
search_start++;
/* Continue to do the last half of the wrap. */
temp = find_headers_search(fpc, buf, read_len, search_start);
size = FFMAX(size, temp);
search_start += read_len - 1;
}
/* Return the size even if no new headers were found. */
if (!size && fpc->headers)
for (end = fpc->headers; end; end = end->next)
size++;
return size;
}
static int check_header_fi_mismatch(FLACParseContext *fpc,
FLACFrameInfo *header_fi,
FLACFrameInfo *child_fi,
int log_level_offset)
{
int deduction = 0;
if (child_fi->samplerate != header_fi->samplerate) {
deduction += FLAC_HEADER_CHANGED_PENALTY;
av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
"sample rate change detected in adjacent frames\n");
}
if (child_fi->bps != header_fi->bps) {
deduction += FLAC_HEADER_CHANGED_PENALTY;
av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
"bits per sample change detected in adjacent frames\n");
}
if (child_fi->is_var_size != header_fi->is_var_size) {
/* Changing blocking strategy not allowed per the spec */
deduction += FLAC_HEADER_BASE_SCORE;
av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
"blocking strategy change detected in adjacent frames\n");
}
if (child_fi->channels != header_fi->channels) {
deduction += FLAC_HEADER_CHANGED_PENALTY;
av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
"number of channels change detected in adjacent frames\n");
}
return deduction;
}
static int check_header_mismatch(FLACParseContext *fpc,
FLACHeaderMarker *header,
FLACHeaderMarker *child,
int log_level_offset)
{
FLACFrameInfo *header_fi = &header->fi, *child_fi = &child->fi;
int deduction, deduction_expected = 0, i;
deduction = check_header_fi_mismatch(fpc, header_fi, child_fi,
log_level_offset);
/* Check sample and frame numbers. */
if ((child_fi->frame_or_sample_num - header_fi->frame_or_sample_num
!= header_fi->blocksize) &&
(child_fi->frame_or_sample_num
!= header_fi->frame_or_sample_num + 1)) {
FLACHeaderMarker *curr;
int expected_frame_num, expected_sample_num;
/* If there are frames in the middle we expect this deduction,
as they are probably valid and this one follows it */
expected_frame_num = expected_sample_num = header_fi->frame_or_sample_num;
curr = header;
while (curr != child) {
/* Ignore frames that failed all crc checks */
for (i = 0; i < FLAC_MAX_SEQUENTIAL_HEADERS; i++) {
if (curr->link_penalty[i] < FLAC_HEADER_CRC_FAIL_PENALTY) {
expected_frame_num++;
expected_sample_num += curr->fi.blocksize;
break;
}
}
curr = curr->next;
}
if (expected_frame_num == child_fi->frame_or_sample_num ||
expected_sample_num == child_fi->frame_or_sample_num)
deduction_expected = deduction ? 0 : 1;
deduction += FLAC_HEADER_CHANGED_PENALTY;
av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
"sample/frame number mismatch in adjacent frames\n");
}
/* If we have suspicious headers, check the CRC between them */
if (deduction && !deduction_expected) {
FLACHeaderMarker *curr;
int read_len;
uint8_t *buf;
uint32_t crc = 1;
int inverted_test = 0;
/* Since CRC is expensive only do it if we haven't yet.
This assumes a CRC penalty is greater than all other check penalties */
curr = header->next;
for (i = 0; i < FLAC_MAX_SEQUENTIAL_HEADERS && curr != child; i++)
curr = curr->next;
if (header->link_penalty[i] < FLAC_HEADER_CRC_FAIL_PENALTY ||
header->link_penalty[i] == FLAC_HEADER_NOT_PENALIZED_YET) {
FLACHeaderMarker *start, *end;
/* Although overlapping chains are scored, the crc should never
have to be computed twice for a single byte. */
start = header;
end = child;
if (i > 0 &&
header->link_penalty[i - 1] >= FLAC_HEADER_CRC_FAIL_PENALTY) {
while (start->next != child)
start = start->next;
inverted_test = 1;
} else if (i > 0 &&
header->next->link_penalty[i-1] >=
FLAC_HEADER_CRC_FAIL_PENALTY ) {
end = header->next;
inverted_test = 1;
}
read_len = end->offset - start->offset;
buf = flac_fifo_read(fpc, start->offset, &read_len);
crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf, read_len);
read_len = (end->offset - start->offset) - read_len;
if (read_len) {
buf = flac_fifo_read(fpc, end->offset - read_len, &read_len);
crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI), crc, buf, read_len);
}
}
if (!crc ^ !inverted_test) {
deduction += FLAC_HEADER_CRC_FAIL_PENALTY;
av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
"crc check failed from offset %i (frame %"PRId64") to %i (frame %"PRId64")\n",
header->offset, header_fi->frame_or_sample_num,
child->offset, child_fi->frame_or_sample_num);
}
}
return deduction;
}
/**
* Score a header.
*
* Give FLAC_HEADER_BASE_SCORE points to a frame for existing.
* If it has children, (subsequent frames of which the preceding CRC footer
* validates against this one,) then take the maximum score of the children,
* with a penalty of FLAC_HEADER_CHANGED_PENALTY applied for each change to
* bps, sample rate, channels, but not decorrelation mode, or blocksize,
* because it can change often.
**/
static int score_header(FLACParseContext *fpc, FLACHeaderMarker *header)
{
FLACHeaderMarker *child;
int dist = 0;
int child_score;
int base_score = FLAC_HEADER_BASE_SCORE;
if (header->max_score != FLAC_HEADER_NOT_SCORED_YET)
return header->max_score;
/* Modify the base score with changes from the last output header */
if (fpc->last_fi_valid) {
/* Silence the log since this will be repeated if selected */
base_score -= check_header_fi_mismatch(fpc, &fpc->last_fi, &header->fi,
AV_LOG_DEBUG);
}
header->max_score = base_score;
/* Check and compute the children's scores. */
child = header->next;
for (dist = 0; dist < FLAC_MAX_SEQUENTIAL_HEADERS && child; dist++) {
/* Look at the child's frame header info and penalize suspicious
changes between the headers. */
if (header->link_penalty[dist] == FLAC_HEADER_NOT_PENALIZED_YET) {
header->link_penalty[dist] = check_header_mismatch(fpc, header,
child, AV_LOG_DEBUG);
}
child_score = score_header(fpc, child) - header->link_penalty[dist];
if (FLAC_HEADER_BASE_SCORE + child_score > header->max_score) {
/* Keep the child because the frame scoring is dynamic. */
header->best_child = child;
header->max_score = base_score + child_score;
}
child = child->next;
}
return header->max_score;
}
static void score_sequences(FLACParseContext *fpc)
{
FLACHeaderMarker *curr;
int best_score = 0;//FLAC_HEADER_NOT_SCORED_YET;
/* First pass to clear all old scores. */
for (curr = fpc->headers; curr; curr = curr->next)
curr->max_score = FLAC_HEADER_NOT_SCORED_YET;
/* Do a second pass to score them all. */
for (curr = fpc->headers; curr; curr = curr->next) {
if (score_header(fpc, curr) > best_score) {
fpc->best_header = curr;
best_score = curr->max_score;
}
}
}
static int get_best_header(FLACParseContext* fpc, const uint8_t **poutbuf,
int *poutbuf_size)
{
FLACHeaderMarker *header = fpc->best_header;
FLACHeaderMarker *child = header->best_child;
if (!child) {
*poutbuf_size = av_fifo_size(fpc->fifo_buf) - header->offset;
} else {
*poutbuf_size = child->offset - header->offset;
/* If the child has suspicious changes, log them */
check_header_mismatch(fpc, header, child, 0);
}
if (header->fi.channels != fpc->avctx->channels ||
!fpc->avctx->channel_layout) {
fpc->avctx->channels = header->fi.channels;
ff_flac_set_channel_layout(fpc->avctx);
}
fpc->avctx->sample_rate = header->fi.samplerate;
fpc->pc->duration = header->fi.blocksize;
*poutbuf = flac_fifo_read_wrap(fpc, header->offset, *poutbuf_size,
&fpc->wrap_buf,
&fpc->wrap_buf_allocated_size);
if (fpc->pc->flags & PARSER_FLAG_USE_CODEC_TS){
if (header->fi.is_var_size)
fpc->pc->pts = header->fi.frame_or_sample_num;
else if (header->best_child)
fpc->pc->pts = header->fi.frame_or_sample_num * header->fi.blocksize;
}
fpc->best_header_valid = 0;
fpc->last_fi_valid = 1;
fpc->last_fi = header->fi;
/* Return the negative overread index so the client can compute pos.
This should be the amount overread to the beginning of the child */
if (child)
return child->offset - av_fifo_size(fpc->fifo_buf);
return 0;
}
static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
FLACParseContext *fpc = s->priv_data;
FLACHeaderMarker *curr;
int nb_headers;
const uint8_t *read_end = buf;
const uint8_t *read_start = buf;
if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
FLACFrameInfo fi;
if (frame_header_is_valid(avctx, buf, &fi)) {
s->duration = fi.blocksize;
if (!avctx->sample_rate)
avctx->sample_rate = fi.samplerate;
if (fpc->pc->flags & PARSER_FLAG_USE_CODEC_TS){
fpc->pc->pts = fi.frame_or_sample_num;
if (!fi.is_var_size)
fpc->pc->pts *= fi.blocksize;
}
}
*poutbuf = buf;
*poutbuf_size = buf_size;
return buf_size;
}
fpc->avctx = avctx;
if (fpc->best_header_valid)
return get_best_header(fpc, poutbuf, poutbuf_size);
/* If a best_header was found last call remove it with the buffer data. */
if (fpc->best_header && fpc->best_header->best_child) {
FLACHeaderMarker *temp;
FLACHeaderMarker *best_child = fpc->best_header->best_child;
/* Remove headers in list until the end of the best_header. */
for (curr = fpc->headers; curr != best_child; curr = temp) {
if (curr != fpc->best_header) {
av_log(avctx, AV_LOG_DEBUG,
"dropping low score %i frame header from offset %i to %i\n",
curr->max_score, curr->offset, curr->next->offset);
}
temp = curr->next;
av_freep(&curr->link_penalty);
av_free(curr);
fpc->nb_headers_buffered--;
}
/* Release returned data from ring buffer. */
av_fifo_drain(fpc->fifo_buf, best_child->offset);
/* Fix the offset for the headers remaining to match the new buffer. */
for (curr = best_child->next; curr; curr = curr->next)
curr->offset -= best_child->offset;
fpc->nb_headers_buffered--;
best_child->offset = 0;
fpc->headers = best_child;
if (fpc->nb_headers_buffered >= FLAC_MIN_HEADERS) {
fpc->best_header = best_child;
return get_best_header(fpc, poutbuf, poutbuf_size);
}
fpc->best_header = NULL;
} else if (fpc->best_header) {
/* No end frame no need to delete the buffer; probably eof */
FLACHeaderMarker *temp;
for (curr = fpc->headers; curr != fpc->best_header; curr = temp) {
temp = curr->next;
av_freep(&curr->link_penalty);
av_free(curr);
}
fpc->headers = fpc->best_header->next;
av_freep(&fpc->best_header->link_penalty);
av_freep(&fpc->best_header);
}
/* Find and score new headers. */
/* buf_size is to zero when padding, so check for this since we do */
/* not want to try to read more input once we have found the end. */
/* Note that as (non-modified) parameters, buf can be non-NULL, */
/* while buf_size is 0. */
while ((buf && buf_size && read_end < buf + buf_size &&
fpc->nb_headers_buffered < FLAC_MIN_HEADERS)
|| ((!buf || !buf_size) && !fpc->end_padded)) {
int start_offset;
/* Pad the end once if EOF, to check the final region for headers. */
if (!buf || !buf_size) {
fpc->end_padded = 1;
buf_size = MAX_FRAME_HEADER_SIZE;
read_end = read_start + MAX_FRAME_HEADER_SIZE;
} else {
/* The maximum read size is the upper-bound of what the parser
needs to have the required number of frames buffered */
int nb_desired = FLAC_MIN_HEADERS - fpc->nb_headers_buffered + 1;
read_end = read_end + FFMIN(buf + buf_size - read_end,
nb_desired * FLAC_AVG_FRAME_SIZE);
}
if (!av_fifo_space(fpc->fifo_buf) &&
av_fifo_size(fpc->fifo_buf) / FLAC_AVG_FRAME_SIZE >
fpc->nb_headers_buffered * 20) {
/* There is less than one valid flac header buffered for 20 headers
* buffered. Therefore the fifo is most likely filled with invalid
* data and the input is not a flac file. */
goto handle_error;
}
/* Fill the buffer. */
if ( av_fifo_space(fpc->fifo_buf) < read_end - read_start
&& av_fifo_realloc2(fpc->fifo_buf, (read_end - read_start) + 2*av_fifo_size(fpc->fifo_buf)) < 0) {
av_log(avctx, AV_LOG_ERROR,
"couldn't reallocate buffer of size %"PTRDIFF_SPECIFIER"\n",
(read_end - read_start) + av_fifo_size(fpc->fifo_buf));
goto handle_error;
}
if (buf && buf_size) {
av_fifo_generic_write(fpc->fifo_buf, (void*) read_start,
read_end - read_start, NULL);
} else {
int8_t pad[MAX_FRAME_HEADER_SIZE] = { 0 };
av_fifo_generic_write(fpc->fifo_buf, (void*) pad, sizeof(pad), NULL);
}
/* Tag headers and update sequences. */
start_offset = av_fifo_size(fpc->fifo_buf) -
((read_end - read_start) + (MAX_FRAME_HEADER_SIZE - 1));
start_offset = FFMAX(0, start_offset);
nb_headers = find_new_headers(fpc, start_offset);
if (nb_headers < 0) {
av_log(avctx, AV_LOG_ERROR,
"find_new_headers couldn't allocate FLAC header\n");
goto handle_error;
}
fpc->nb_headers_buffered = nb_headers;
/* Wait till FLAC_MIN_HEADERS to output a valid frame. */
if (!fpc->end_padded && fpc->nb_headers_buffered < FLAC_MIN_HEADERS) {
if (buf && read_end < buf + buf_size) {
read_start = read_end;
continue;
} else {
goto handle_error;
}
}
/* If headers found, update the scores since we have longer chains. */
if (fpc->end_padded || fpc->nb_headers_found)
score_sequences(fpc);
/* restore the state pre-padding */
if (fpc->end_padded) {
int warp = fpc->fifo_buf->wptr - fpc->fifo_buf->buffer < MAX_FRAME_HEADER_SIZE;
/* HACK: drain the tail of the fifo */
fpc->fifo_buf->wptr -= MAX_FRAME_HEADER_SIZE;
fpc->fifo_buf->wndx -= MAX_FRAME_HEADER_SIZE;
if (warp) {
fpc->fifo_buf->wptr += fpc->fifo_buf->end -
fpc->fifo_buf->buffer;
}
buf_size = 0;
read_start = read_end = NULL;
}
}
for (curr = fpc->headers; curr; curr = curr->next) {
if (curr->max_score > 0 &&
(!fpc->best_header || curr->max_score > fpc->best_header->max_score)) {
fpc->best_header = curr;
}
}
if (fpc->best_header) {
fpc->best_header_valid = 1;
if (fpc->best_header->offset > 0) {
/* Output a junk frame. */
av_log(avctx, AV_LOG_DEBUG, "Junk frame till offset %i\n",
fpc->best_header->offset);
/* Set duration to 0. It is unknown or invalid in a junk frame. */
s->duration = 0;
*poutbuf_size = fpc->best_header->offset;
*poutbuf = flac_fifo_read_wrap(fpc, 0, *poutbuf_size,
&fpc->wrap_buf,
&fpc->wrap_buf_allocated_size);
return buf_size ? (read_end - buf) : (fpc->best_header->offset -
av_fifo_size(fpc->fifo_buf));
}
if (!buf_size)
return get_best_header(fpc, poutbuf, poutbuf_size);
}
handle_error:
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size ? read_end - buf : 0;
}
static av_cold int flac_parse_init(AVCodecParserContext *c)
{
FLACParseContext *fpc = c->priv_data;
fpc->pc = c;
/* There will generally be FLAC_MIN_HEADERS buffered in the fifo before
it drains. This is allocated early to avoid slow reallocation. */
fpc->fifo_buf = av_fifo_alloc_array(FLAC_MIN_HEADERS + 3, FLAC_AVG_FRAME_SIZE);
if (!fpc->fifo_buf) {
av_log(fpc->avctx, AV_LOG_ERROR,
"couldn't allocate fifo_buf\n");
return AVERROR(ENOMEM);
}
return 0;
}
static void flac_parse_close(AVCodecParserContext *c)
{
FLACParseContext *fpc = c->priv_data;
FLACHeaderMarker *curr = fpc->headers, *temp;
while (curr) {
temp = curr->next;
av_freep(&curr->link_penalty);
av_free(curr);
curr = temp;
}
av_fifo_freep(&fpc->fifo_buf);
av_freep(&fpc->wrap_buf);
}
AVCodecParser ff_flac_parser = {
.codec_ids = { AV_CODEC_ID_FLAC },
.priv_data_size = sizeof(FLACParseContext),
.parser_init = flac_parse_init,
.parser_parse = flac_parse,
.parser_close = flac_parse_close,
};

Просмотреть файл

@ -1,33 +0,0 @@
/*
* FLAC data
* Copyright (c) 2003 Alex Beregszaszi
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "internal.h"
const int ff_flac_sample_rate_table[16] =
{ 0,
88200, 176400, 192000,
8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
0, 0, 0, 0 };
const int32_t ff_flac_blocksize_table[16] = {
0, 192, 576<<0, 576<<1, 576<<2, 576<<3, 0, 0,
256<<0, 256<<1, 256<<2, 256<<3, 256<<4, 256<<5, 256<<6, 256<<7
};

Просмотреть файл

@ -1,31 +0,0 @@
/*
* FLAC data header
* Copyright (c) 2003 Alex Beregszaszi
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_FLACDATA_H
#define AVCODEC_FLACDATA_H
#include "internal.h"
extern const int ff_flac_sample_rate_table[16];
extern const int32_t ff_flac_blocksize_table[16];
#endif /* AVCODEC_FLACDATA_H */

Просмотреть файл

@ -1,677 +0,0 @@
/*
* FLAC (Free Lossless Audio Codec) decoder
* Copyright (c) 2003 Alex Beregszaszi
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* FLAC (Free Lossless Audio Codec) decoder
* @author Alex Beregszaszi
* @see http://flac.sourceforge.net/
*
* This decoder can be used in 1 of 2 ways: Either raw FLAC data can be fed
* through, starting from the initial 'fLaC' signature; or by passing the
* 34-byte streaminfo structure through avctx->extradata[_size] followed
* by data starting with the 0xFFF8 marker.
*/
#include <limits.h>
#include "libavutil/avassert.h"
#include "libavutil/crc.h"
#include "libavutil/opt.h"
#include "avcodec.h"
#include "internal.h"
#include "get_bits.h"
#include "bytestream.h"
#include "golomb.h"
#include "flac.h"
#include "flacdata.h"
#include "flacdsp.h"
#include "thread.h"
#include "unary.h"
typedef struct FLACContext {
AVClass *class;
struct FLACStreaminfo flac_stream_info;
AVCodecContext *avctx; ///< parent AVCodecContext
GetBitContext gb; ///< GetBitContext initialized to start at the current frame
int blocksize; ///< number of samples in the current frame
int sample_shift; ///< shift required to make output samples 16-bit or 32-bit
int ch_mode; ///< channel decorrelation type in the current frame
int got_streaminfo; ///< indicates if the STREAMINFO has been read
int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples
uint8_t *decoded_buffer;
unsigned int decoded_buffer_size;
int buggy_lpc; ///< use workaround for old lavc encoded files
FLACDSPContext dsp;
} FLACContext;
static int allocate_buffers(FLACContext *s);
static void flac_set_bps(FLACContext *s)
{
enum AVSampleFormat req = s->avctx->request_sample_fmt;
int need32 = s->flac_stream_info.bps > 16;
int want32 = av_get_bytes_per_sample(req) > 2;
int planar = av_sample_fmt_is_planar(req);
if (need32 || want32) {
if (planar)
s->avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
else
s->avctx->sample_fmt = AV_SAMPLE_FMT_S32;
s->sample_shift = 32 - s->flac_stream_info.bps;
} else {
if (planar)
s->avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
else
s->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
s->sample_shift = 16 - s->flac_stream_info.bps;
}
}
static av_cold int flac_decode_init(AVCodecContext *avctx)
{
enum FLACExtradataFormat format;
uint8_t *streaminfo;
int ret;
FLACContext *s = avctx->priv_data;
s->avctx = avctx;
/* for now, the raw FLAC header is allowed to be passed to the decoder as
frame data instead of extradata. */
if (!avctx->extradata)
return 0;
if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))
return AVERROR_INVALIDDATA;
/* initialize based on the demuxer-supplied streamdata header */
ff_flac_parse_streaminfo(avctx, &s->flac_stream_info, streaminfo);
ret = allocate_buffers(s);
if (ret < 0)
return ret;
flac_set_bps(s);
ff_flacdsp_init(&s->dsp, avctx->sample_fmt,
s->flac_stream_info.channels, s->flac_stream_info.bps);
s->got_streaminfo = 1;
return 0;
}
static void dump_headers(AVCodecContext *avctx, FLACStreaminfo *s)
{
av_log(avctx, AV_LOG_DEBUG, " Max Blocksize: %d\n", s->max_blocksize);
av_log(avctx, AV_LOG_DEBUG, " Max Framesize: %d\n", s->max_framesize);
av_log(avctx, AV_LOG_DEBUG, " Samplerate: %d\n", s->samplerate);
av_log(avctx, AV_LOG_DEBUG, " Channels: %d\n", s->channels);
av_log(avctx, AV_LOG_DEBUG, " Bits: %d\n", s->bps);
}
static int allocate_buffers(FLACContext *s)
{
int buf_size;
int ret;
av_assert0(s->flac_stream_info.max_blocksize);
buf_size = av_samples_get_buffer_size(NULL, s->flac_stream_info.channels,
s->flac_stream_info.max_blocksize,
AV_SAMPLE_FMT_S32P, 0);
if (buf_size < 0)
return buf_size;
av_fast_malloc(&s->decoded_buffer, &s->decoded_buffer_size, buf_size);
if (!s->decoded_buffer)
return AVERROR(ENOMEM);
ret = av_samples_fill_arrays((uint8_t **)s->decoded, NULL,
s->decoded_buffer,
s->flac_stream_info.channels,
s->flac_stream_info.max_blocksize,
AV_SAMPLE_FMT_S32P, 0);
return ret < 0 ? ret : 0;
}
/**
* Parse the STREAMINFO from an inline header.
* @param s the flac decoding context
* @param buf input buffer, starting with the "fLaC" marker
* @param buf_size buffer size
* @return non-zero if metadata is invalid
*/
static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size)
{
int metadata_type, metadata_size, ret;
if (buf_size < FLAC_STREAMINFO_SIZE+8) {
/* need more data */
return 0;
}
flac_parse_block_header(&buf[4], NULL, &metadata_type, &metadata_size);
if (metadata_type != FLAC_METADATA_TYPE_STREAMINFO ||
metadata_size != FLAC_STREAMINFO_SIZE) {
return AVERROR_INVALIDDATA;
}
ff_flac_parse_streaminfo(s->avctx, &s->flac_stream_info, &buf[8]);
ret = allocate_buffers(s);
if (ret < 0)
return ret;
flac_set_bps(s);
ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt,
s->flac_stream_info.channels, s->flac_stream_info.bps);
s->got_streaminfo = 1;
return 0;
}
/**
* Determine the size of an inline header.
* @param buf input buffer, starting with the "fLaC" marker
* @param buf_size buffer size
* @return number of bytes in the header, or 0 if more data is needed
*/
static int get_metadata_size(const uint8_t *buf, int buf_size)
{
int metadata_last, metadata_size;
const uint8_t *buf_end = buf + buf_size;
buf += 4;
do {
if (buf_end - buf < 4)
return 0;
flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size);
buf += 4;
if (buf_end - buf < metadata_size) {
/* need more data in order to read the complete header */
return 0;
}
buf += metadata_size;
} while (!metadata_last);
return buf_size - (buf_end - buf);
}
static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order)
{
int i, tmp, partition, method_type, rice_order;
int rice_bits, rice_esc;
int samples;
method_type = get_bits(&s->gb, 2);
if (method_type > 1) {
av_log(s->avctx, AV_LOG_ERROR, "illegal residual coding method %d\n",
method_type);
return AVERROR_INVALIDDATA;
}
rice_order = get_bits(&s->gb, 4);
samples= s->blocksize >> rice_order;
if (samples << rice_order != s->blocksize) {
av_log(s->avctx, AV_LOG_ERROR, "invalid rice order: %i blocksize %i\n",
rice_order, s->blocksize);
return AVERROR_INVALIDDATA;
}
if (pred_order > samples) {
av_log(s->avctx, AV_LOG_ERROR, "invalid predictor order: %i > %i\n",
pred_order, samples);
return AVERROR_INVALIDDATA;
}
rice_bits = 4 + method_type;
rice_esc = (1 << rice_bits) - 1;
decoded += pred_order;
i= pred_order;
for (partition = 0; partition < (1 << rice_order); partition++) {
tmp = get_bits(&s->gb, rice_bits);
if (tmp == rice_esc) {
tmp = get_bits(&s->gb, 5);
for (; i < samples; i++)
*decoded++ = get_sbits_long(&s->gb, tmp);
} else {
for (; i < samples; i++) {
*decoded++ = get_sr_golomb_flac(&s->gb, tmp, INT_MAX, 0);
}
}
i= 0;
}
return 0;
}
static int decode_subframe_fixed(FLACContext *s, int32_t *decoded,
int pred_order, int bps)
{
const int blocksize = s->blocksize;
int av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d), i;
int ret;
/* warm up samples */
for (i = 0; i < pred_order; i++) {
decoded[i] = get_sbits_long(&s->gb, bps);
}
if ((ret = decode_residuals(s, decoded, pred_order)) < 0)
return ret;
if (pred_order > 0)
a = decoded[pred_order-1];
if (pred_order > 1)
b = a - decoded[pred_order-2];
if (pred_order > 2)
c = b - decoded[pred_order-2] + decoded[pred_order-3];
if (pred_order > 3)
d = c - decoded[pred_order-2] + 2*decoded[pred_order-3] - decoded[pred_order-4];
switch (pred_order) {
case 0:
break;
case 1:
for (i = pred_order; i < blocksize; i++)
decoded[i] = a += decoded[i];
break;
case 2:
for (i = pred_order; i < blocksize; i++)
decoded[i] = a += b += decoded[i];
break;
case 3:
for (i = pred_order; i < blocksize; i++)
decoded[i] = a += b += c += decoded[i];
break;
case 4:
for (i = pred_order; i < blocksize; i++)
decoded[i] = a += b += c += d += decoded[i];
break;
default:
av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order);
return AVERROR_INVALIDDATA;
}
return 0;
}
static void lpc_analyze_remodulate(int32_t *decoded, const int coeffs[32],
int order, int qlevel, int len, int bps)
{
int i, j;
int ebps = 1 << (bps-1);
unsigned sigma = 0;
for (i = order; i < len; i++)
sigma |= decoded[i] + ebps;
if (sigma < 2*ebps)
return;
for (i = len - 1; i >= order; i--) {
int64_t p = 0;
for (j = 0; j < order; j++)
p += coeffs[j] * (int64_t)decoded[i-order+j];
decoded[i] -= p >> qlevel;
}
for (i = order; i < len; i++, decoded++) {
int32_t p = 0;
for (j = 0; j < order; j++)
p += coeffs[j] * (uint32_t)decoded[j];
decoded[j] += p >> qlevel;
}
}
static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order,
int bps)
{
int i, ret;
int coeff_prec, qlevel;
int coeffs[32];
/* warm up samples */
for (i = 0; i < pred_order; i++) {
decoded[i] = get_sbits_long(&s->gb, bps);
}
coeff_prec = get_bits(&s->gb, 4) + 1;
if (coeff_prec == 16) {
av_log(s->avctx, AV_LOG_ERROR, "invalid coeff precision\n");
return AVERROR_INVALIDDATA;
}
qlevel = get_sbits(&s->gb, 5);
if (qlevel < 0) {
av_log(s->avctx, AV_LOG_ERROR, "qlevel %d not supported, maybe buggy stream\n",
qlevel);
return AVERROR_INVALIDDATA;
}
for (i = 0; i < pred_order; i++) {
coeffs[pred_order - i - 1] = get_sbits(&s->gb, coeff_prec);
}
if ((ret = decode_residuals(s, decoded, pred_order)) < 0)
return ret;
if ( ( s->buggy_lpc && s->flac_stream_info.bps <= 16)
|| ( !s->buggy_lpc && bps <= 16
&& bps + coeff_prec + av_log2(pred_order) <= 32)) {
s->dsp.lpc16(decoded, coeffs, pred_order, qlevel, s->blocksize);
} else {
s->dsp.lpc32(decoded, coeffs, pred_order, qlevel, s->blocksize);
if (s->flac_stream_info.bps <= 16)
lpc_analyze_remodulate(decoded, coeffs, pred_order, qlevel, s->blocksize, bps);
}
return 0;
}
static inline int decode_subframe(FLACContext *s, int channel)
{
int32_t *decoded = s->decoded[channel];
int type, wasted = 0;
int bps = s->flac_stream_info.bps;
int i, tmp, ret;
if (channel == 0) {
if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE)
bps++;
} else {
if (s->ch_mode == FLAC_CHMODE_LEFT_SIDE || s->ch_mode == FLAC_CHMODE_MID_SIDE)
bps++;
}
if (get_bits1(&s->gb)) {
av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n");
return AVERROR_INVALIDDATA;
}
type = get_bits(&s->gb, 6);
if (get_bits1(&s->gb)) {
int left = get_bits_left(&s->gb);
if ( left <= 0 ||
(left < bps && !show_bits_long(&s->gb, left)) ||
!show_bits_long(&s->gb, bps)) {
av_log(s->avctx, AV_LOG_ERROR,
"Invalid number of wasted bits > available bits (%d) - left=%d\n",
bps, left);
return AVERROR_INVALIDDATA;
}
wasted = 1 + get_unary(&s->gb, 1, get_bits_left(&s->gb));
bps -= wasted;
}
if (bps > 32) {
avpriv_report_missing_feature(s->avctx, "Decorrelated bit depth > 32");
return AVERROR_PATCHWELCOME;
}
//FIXME use av_log2 for types
if (type == 0) {
tmp = get_sbits_long(&s->gb, bps);
for (i = 0; i < s->blocksize; i++)
decoded[i] = tmp;
} else if (type == 1) {
for (i = 0; i < s->blocksize; i++)
decoded[i] = get_sbits_long(&s->gb, bps);
} else if ((type >= 8) && (type <= 12)) {
if ((ret = decode_subframe_fixed(s, decoded, type & ~0x8, bps)) < 0)
return ret;
} else if (type >= 32) {
if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0)
return ret;
} else {
av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n");
return AVERROR_INVALIDDATA;
}
if (wasted) {
int i;
for (i = 0; i < s->blocksize; i++)
decoded[i] <<= wasted;
}
return 0;
}
static int decode_frame(FLACContext *s)
{
int i, ret;
GetBitContext *gb = &s->gb;
FLACFrameInfo fi;
if ((ret = ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) < 0) {
av_log(s->avctx, AV_LOG_ERROR, "invalid frame header\n");
return ret;
}
if ( s->flac_stream_info.channels
&& fi.channels != s->flac_stream_info.channels
&& s->got_streaminfo) {
s->flac_stream_info.channels = s->avctx->channels = fi.channels;
ff_flac_set_channel_layout(s->avctx);
ret = allocate_buffers(s);
if (ret < 0)
return ret;
}
s->flac_stream_info.channels = s->avctx->channels = fi.channels;
if (!s->avctx->channel_layout)
ff_flac_set_channel_layout(s->avctx);
s->ch_mode = fi.ch_mode;
if (!s->flac_stream_info.bps && !fi.bps) {
av_log(s->avctx, AV_LOG_ERROR, "bps not found in STREAMINFO or frame header\n");
return AVERROR_INVALIDDATA;
}
if (!fi.bps) {
fi.bps = s->flac_stream_info.bps;
} else if (s->flac_stream_info.bps && fi.bps != s->flac_stream_info.bps) {
av_log(s->avctx, AV_LOG_ERROR, "switching bps mid-stream is not "
"supported\n");
return AVERROR_INVALIDDATA;
}
if (!s->flac_stream_info.bps) {
s->flac_stream_info.bps = s->avctx->bits_per_raw_sample = fi.bps;
flac_set_bps(s);
}
if (!s->flac_stream_info.max_blocksize)
s->flac_stream_info.max_blocksize = FLAC_MAX_BLOCKSIZE;
if (fi.blocksize > s->flac_stream_info.max_blocksize) {
av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", fi.blocksize,
s->flac_stream_info.max_blocksize);
return AVERROR_INVALIDDATA;
}
s->blocksize = fi.blocksize;
if (!s->flac_stream_info.samplerate && !fi.samplerate) {
av_log(s->avctx, AV_LOG_ERROR, "sample rate not found in STREAMINFO"
" or frame header\n");
return AVERROR_INVALIDDATA;
}
if (fi.samplerate == 0)
fi.samplerate = s->flac_stream_info.samplerate;
s->flac_stream_info.samplerate = s->avctx->sample_rate = fi.samplerate;
if (!s->got_streaminfo) {
ret = allocate_buffers(s);
if (ret < 0)
return ret;
s->got_streaminfo = 1;
dump_headers(s->avctx, &s->flac_stream_info);
}
ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt,
s->flac_stream_info.channels, s->flac_stream_info.bps);
// dump_headers(s->avctx, &s->flac_stream_info);
/* subframes */
for (i = 0; i < s->flac_stream_info.channels; i++) {
if ((ret = decode_subframe(s, i)) < 0)
return ret;
}
align_get_bits(gb);
/* frame footer */
skip_bits(gb, 16); /* data crc */
return 0;
}
static int flac_decode_frame(AVCodecContext *avctx, void *data,
int *got_frame_ptr, AVPacket *avpkt)
{
AVFrame *frame = data;
ThreadFrame tframe = { .f = data };
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
FLACContext *s = avctx->priv_data;
int bytes_read = 0;
int ret;
*got_frame_ptr = 0;
if (s->flac_stream_info.max_framesize == 0) {
s->flac_stream_info.max_framesize =
ff_flac_get_max_frame_size(s->flac_stream_info.max_blocksize ? s->flac_stream_info.max_blocksize : FLAC_MAX_BLOCKSIZE,
FLAC_MAX_CHANNELS, 32);
}
if (buf_size > 5 && !memcmp(buf, "\177FLAC", 5)) {
av_log(s->avctx, AV_LOG_DEBUG, "skipping flac header packet 1\n");
return buf_size;
}
if (buf_size > 0 && (*buf & 0x7F) == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
av_log(s->avctx, AV_LOG_DEBUG, "skipping vorbis comment\n");
return buf_size;
}
/* check that there is at least the smallest decodable amount of data.
this amount corresponds to the smallest valid FLAC frame possible.
FF F8 69 02 00 00 9A 00 00 34 46 */
if (buf_size < FLAC_MIN_FRAME_SIZE)
return buf_size;
/* check for inline header */
if (AV_RB32(buf) == MKBETAG('f','L','a','C')) {
if (!s->got_streaminfo && (ret = parse_streaminfo(s, buf, buf_size))) {
av_log(s->avctx, AV_LOG_ERROR, "invalid header\n");
return ret;
}
return get_metadata_size(buf, buf_size);
}
/* decode frame */
if ((ret = init_get_bits8(&s->gb, buf, buf_size)) < 0)
return ret;
if ((ret = decode_frame(s)) < 0) {
av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n");
return ret;
}
bytes_read = get_bits_count(&s->gb)/8;
if ((s->avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) &&
av_crc(av_crc_get_table(AV_CRC_16_ANSI),
0, buf, bytes_read)) {
av_log(s->avctx, AV_LOG_ERROR, "CRC error at PTS %"PRId64"\n", avpkt->pts);
if (s->avctx->err_recognition & AV_EF_EXPLODE)
return AVERROR_INVALIDDATA;
}
/* get output buffer */
frame->nb_samples = s->blocksize;
if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
return ret;
s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded,
s->flac_stream_info.channels,
s->blocksize, s->sample_shift);
if (bytes_read > buf_size) {
av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size);
return AVERROR_INVALIDDATA;
}
if (bytes_read < buf_size) {
av_log(s->avctx, AV_LOG_DEBUG, "underread: %d orig size: %d\n",
buf_size - bytes_read, buf_size);
}
*got_frame_ptr = 1;
return bytes_read;
}
#if HAVE_THREADS
static int init_thread_copy(AVCodecContext *avctx)
{
FLACContext *s = avctx->priv_data;
s->decoded_buffer = NULL;
s->decoded_buffer_size = 0;
s->avctx = avctx;
if (s->flac_stream_info.max_blocksize)
return allocate_buffers(s);
return 0;
}
#endif
static av_cold int flac_decode_close(AVCodecContext *avctx)
{
FLACContext *s = avctx->priv_data;
av_freep(&s->decoded_buffer);
return 0;
}
static const AVOption options[] = {
{ "use_buggy_lpc", "emulate old buggy lavc behavior", offsetof(FLACContext, buggy_lpc), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM },
{ NULL },
};
static const AVClass flac_decoder_class = {
"FLAC decoder",
av_default_item_name,
options,
LIBAVUTIL_VERSION_INT,
};
AVCodec ff_flac_decoder = {
.name = "flac",
.long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
.type = AVMEDIA_TYPE_AUDIO,
.id = AV_CODEC_ID_FLAC,
.priv_data_size = sizeof(FLACContext),
.init = flac_decode_init,
.close = flac_decode_close,
.decode = flac_decode_frame,
.init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_S32,
AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_NONE },
.priv_class = &flac_decoder_class,
};

Просмотреть файл

@ -1,130 +0,0 @@
/*
* Copyright (c) 2012 Mans Rullgard <mans@mansr.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/attributes.h"
#include "libavutil/samplefmt.h"
#include "flacdsp.h"
#include "config.h"
#define SAMPLE_SIZE 16
#define PLANAR 0
#include "flacdsp_template.c"
#include "flacdsp_lpc_template.c"
#undef PLANAR
#define PLANAR 1
#include "flacdsp_template.c"
#undef SAMPLE_SIZE
#undef PLANAR
#define SAMPLE_SIZE 32
#define PLANAR 0
#include "flacdsp_template.c"
#include "flacdsp_lpc_template.c"
#undef PLANAR
#define PLANAR 1
#include "flacdsp_template.c"
static void flac_lpc_16_c(int32_t *decoded, const int coeffs[32],
int pred_order, int qlevel, int len)
{
int i, j;
for (i = pred_order; i < len - 1; i += 2, decoded += 2) {
int c = coeffs[0];
int d = decoded[0];
int s0 = 0, s1 = 0;
for (j = 1; j < pred_order; j++) {
s0 += c*d;
d = decoded[j];
s1 += c*d;
c = coeffs[j];
}
s0 += c*d;
d = decoded[j] += s0 >> qlevel;
s1 += c*d;
decoded[j + 1] += s1 >> qlevel;
}
if (i < len) {
int sum = 0;
for (j = 0; j < pred_order; j++)
sum += coeffs[j] * decoded[j];
decoded[j] += sum >> qlevel;
}
}
static void flac_lpc_32_c(int32_t *decoded, const int coeffs[32],
int pred_order, int qlevel, int len)
{
int i, j;
for (i = pred_order; i < len; i++, decoded++) {
int64_t sum = 0;
for (j = 0; j < pred_order; j++)
sum += (int64_t)coeffs[j] * decoded[j];
decoded[j] += sum >> qlevel;
}
}
av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int channels,
int bps)
{
c->lpc16 = flac_lpc_16_c;
c->lpc32 = flac_lpc_32_c;
c->lpc16_encode = flac_lpc_encode_c_16;
c->lpc32_encode = flac_lpc_encode_c_32;
switch (fmt) {
case AV_SAMPLE_FMT_S32:
c->decorrelate[0] = flac_decorrelate_indep_c_32;
c->decorrelate[1] = flac_decorrelate_ls_c_32;
c->decorrelate[2] = flac_decorrelate_rs_c_32;
c->decorrelate[3] = flac_decorrelate_ms_c_32;
break;
case AV_SAMPLE_FMT_S32P:
c->decorrelate[0] = flac_decorrelate_indep_c_32p;
c->decorrelate[1] = flac_decorrelate_ls_c_32p;
c->decorrelate[2] = flac_decorrelate_rs_c_32p;
c->decorrelate[3] = flac_decorrelate_ms_c_32p;
break;
case AV_SAMPLE_FMT_S16:
c->decorrelate[0] = flac_decorrelate_indep_c_16;
c->decorrelate[1] = flac_decorrelate_ls_c_16;
c->decorrelate[2] = flac_decorrelate_rs_c_16;
c->decorrelate[3] = flac_decorrelate_ms_c_16;
break;
case AV_SAMPLE_FMT_S16P:
c->decorrelate[0] = flac_decorrelate_indep_c_16p;
c->decorrelate[1] = flac_decorrelate_ls_c_16p;
c->decorrelate[2] = flac_decorrelate_rs_c_16p;
c->decorrelate[3] = flac_decorrelate_ms_c_16p;
break;
}
if (ARCH_ARM)
ff_flacdsp_init_arm(c, fmt, channels, bps);
if (ARCH_X86)
ff_flacdsp_init_x86(c, fmt, channels, bps);
}

Просмотреть файл

@ -1,42 +0,0 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_FLACDSP_H
#define AVCODEC_FLACDSP_H
#include <stdint.h>
#include "libavutil/samplefmt.h"
typedef struct FLACDSPContext {
void (*decorrelate[4])(uint8_t **out, int32_t **in, int channels,
int len, int shift);
void (*lpc16)(int32_t *samples, const int coeffs[32], int order,
int qlevel, int len);
void (*lpc32)(int32_t *samples, const int coeffs[32], int order,
int qlevel, int len);
void (*lpc16_encode)(int32_t *res, const int32_t *smp, int len, int order,
const int32_t coefs[32], int shift);
void (*lpc32_encode)(int32_t *res, const int32_t *smp, int len, int order,
const int32_t coefs[32], int shift);
} FLACDSPContext;
void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps);
void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps);
void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps);
#endif /* AVCODEC_FLACDSP_H */

Просмотреть файл

@ -1,159 +0,0 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include "libavutil/avutil.h"
#include "mathops.h"
#undef FUNC
#undef sum_type
#undef MUL
#undef CLIP
#undef FSUF
#define FUNC(n) AV_JOIN(n ## _, SAMPLE_SIZE)
#if SAMPLE_SIZE == 32
# define sum_type int64_t
# define MUL(a, b) MUL64(a, b)
# define CLIP(x) av_clipl_int32(x)
#else
# define sum_type int32_t
# define MUL(a, b) ((a) * (b))
# define CLIP(x) (x)
#endif
#define LPC1(x) { \
int c = coefs[(x)-1]; \
p0 += MUL(c, s); \
s = smp[i-(x)+1]; \
p1 += MUL(c, s); \
}
static av_always_inline void FUNC(lpc_encode_unrolled)(int32_t *res,
const int32_t *smp, int len, int order,
const int32_t *coefs, int shift, int big)
{
int i;
for (i = order; i < len; i += 2) {
int s = smp[i-order];
sum_type p0 = 0, p1 = 0;
if (big) {
switch (order) {
case 32: LPC1(32)
case 31: LPC1(31)
case 30: LPC1(30)
case 29: LPC1(29)
case 28: LPC1(28)
case 27: LPC1(27)
case 26: LPC1(26)
case 25: LPC1(25)
case 24: LPC1(24)
case 23: LPC1(23)
case 22: LPC1(22)
case 21: LPC1(21)
case 20: LPC1(20)
case 19: LPC1(19)
case 18: LPC1(18)
case 17: LPC1(17)
case 16: LPC1(16)
case 15: LPC1(15)
case 14: LPC1(14)
case 13: LPC1(13)
case 12: LPC1(12)
case 11: LPC1(11)
case 10: LPC1(10)
case 9: LPC1( 9)
LPC1( 8)
LPC1( 7)
LPC1( 6)
LPC1( 5)
LPC1( 4)
LPC1( 3)
LPC1( 2)
LPC1( 1)
}
} else {
switch (order) {
case 8: LPC1( 8)
case 7: LPC1( 7)
case 6: LPC1( 6)
case 5: LPC1( 5)
case 4: LPC1( 4)
case 3: LPC1( 3)
case 2: LPC1( 2)
case 1: LPC1( 1)
}
}
res[i ] = smp[i ] - CLIP(p0 >> shift);
res[i+1] = smp[i+1] - CLIP(p1 >> shift);
}
}
static void FUNC(flac_lpc_encode_c)(int32_t *res, const int32_t *smp, int len,
int order, const int32_t *coefs, int shift)
{
int i;
for (i = 0; i < order; i++)
res[i] = smp[i];
#if CONFIG_SMALL
for (i = order; i < len; i += 2) {
int j;
int s = smp[i];
sum_type p0 = 0, p1 = 0;
for (j = 0; j < order; j++) {
int c = coefs[j];
p1 += MUL(c, s);
s = smp[i-j-1];
p0 += MUL(c, s);
}
res[i ] = smp[i ] - CLIP(p0 >> shift);
res[i+1] = smp[i+1] - CLIP(p1 >> shift);
}
#else
switch (order) {
case 1: FUNC(lpc_encode_unrolled)(res, smp, len, 1, coefs, shift, 0); break;
case 2: FUNC(lpc_encode_unrolled)(res, smp, len, 2, coefs, shift, 0); break;
case 3: FUNC(lpc_encode_unrolled)(res, smp, len, 3, coefs, shift, 0); break;
case 4: FUNC(lpc_encode_unrolled)(res, smp, len, 4, coefs, shift, 0); break;
case 5: FUNC(lpc_encode_unrolled)(res, smp, len, 5, coefs, shift, 0); break;
case 6: FUNC(lpc_encode_unrolled)(res, smp, len, 6, coefs, shift, 0); break;
case 7: FUNC(lpc_encode_unrolled)(res, smp, len, 7, coefs, shift, 0); break;
case 8: FUNC(lpc_encode_unrolled)(res, smp, len, 8, coefs, shift, 0); break;
default: FUNC(lpc_encode_unrolled)(res, smp, len, order, coefs, shift, 1); break;
}
#endif
}
/* Comment for clarity/de-obfuscation.
*
* for (int i = order; i < len; i++) {
* int32_t p = 0;
* for (int j = 0; j < order; j++) {
* int c = coefs[j];
* int s = smp[(i-1)-j];
* p += c*s;
* }
* res[i] = smp[i] - (p >> shift);
* }
*
* The CONFIG_SMALL code above simplifies to this, in the case of SAMPLE_SIZE
* not being equal to 32 (at the present time that means for 16-bit audio). The
* code above does 2 samples per iteration. Commit bfdd5bc (made all the way
* back in 2007) says that way is faster.
*/

Просмотреть файл

@ -1,103 +0,0 @@
/*
* Copyright (c) 2012 Mans Rullgard <mans@mansr.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include "libavutil/avutil.h"
#undef FUNC
#undef FSUF
#undef sample
#undef sample_type
#undef OUT
#undef S
#if SAMPLE_SIZE == 32
# define sample_type int32_t
#else
# define sample_type int16_t
#endif
#if PLANAR
# define FSUF AV_JOIN(SAMPLE_SIZE, p)
# define sample sample_type *
# define OUT(n) n
# define S(s, c, i) (s[c][i])
#else
# define FSUF SAMPLE_SIZE
# define sample sample_type
# define OUT(n) n[0]
# define S(s, c, i) (*s++)
#endif
#define FUNC(n) AV_JOIN(n ## _, FSUF)
static void FUNC(flac_decorrelate_indep_c)(uint8_t **out, int32_t **in,
int channels, int len, int shift)
{
sample *samples = (sample *) OUT(out);
int i, j;
for (j = 0; j < len; j++)
for (i = 0; i < channels; i++)
S(samples, i, j) = in[i][j] << shift;
}
static void FUNC(flac_decorrelate_ls_c)(uint8_t **out, int32_t **in,
int channels, int len, int shift)
{
sample *samples = (sample *) OUT(out);
int i;
for (i = 0; i < len; i++) {
int a = in[0][i];
int b = in[1][i];
S(samples, 0, i) = a << shift;
S(samples, 1, i) = (a - b) << shift;
}
}
static void FUNC(flac_decorrelate_rs_c)(uint8_t **out, int32_t **in,
int channels, int len, int shift)
{
sample *samples = (sample *) OUT(out);
int i;
for (i = 0; i < len; i++) {
int a = in[0][i];
int b = in[1][i];
S(samples, 0, i) = (a + b) << shift;
S(samples, 1, i) = b << shift;
}
}
static void FUNC(flac_decorrelate_ms_c)(uint8_t **out, int32_t **in,
int channels, int len, int shift)
{
sample *samples = (sample *) OUT(out);
int i;
for (i = 0; i < len; i++) {
int a = in[0][i];
int b = in[1][i];
a -= b >> 1;
S(samples, 0, i) = (a + b) << shift;
S(samples, 1, i) = a << shift;
}
}

Просмотреть файл

@ -1,173 +0,0 @@
/*
* exp golomb vlc stuff
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* @brief
* exp golomb vlc stuff
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#include "libavutil/common.h"
const uint8_t ff_golomb_vlc_len[512]={
19,17,15,15,13,13,13,13,11,11,11,11,11,11,11,11,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
};
const uint8_t ff_ue_golomb_vlc_code[512]={
32,32,32,32,32,32,32,32,31,32,32,32,32,32,32,32,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
const int8_t ff_se_golomb_vlc_code[512]={
17, 17, 17, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 17, 8, -8, 9, -9, 10,-10, 11,-11, 12,-12, 13,-13, 14,-14, 15,-15,
4, 4, 4, 4, -4, -4, -4, -4, 5, 5, 5, 5, -5, -5, -5, -5, 6, 6, 6, 6, -6, -6, -6, -6, 7, 7, 7, 7, -7, -7, -7, -7,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const uint8_t ff_ue_golomb_len[256]={
1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,
};
const uint8_t ff_interleaved_golomb_vlc_len[256]={
9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5,
9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5,
9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
};
const uint8_t ff_interleaved_ue_golomb_vlc_code[256]={
15,16,7, 7, 17,18,8, 8, 3, 3, 3, 3, 3, 3, 3, 3,
19,20,9, 9, 21,22,10,10,4, 4, 4, 4, 4, 4, 4, 4,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
23,24,11,11,25,26,12,12,5, 5, 5, 5, 5, 5, 5, 5,
27,28,13,13,29,30,14,14,6, 6, 6, 6, 6, 6, 6, 6,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const int8_t ff_interleaved_se_golomb_vlc_code[256]={
8, -8, 4, 4, 9, -9, -4, -4, 2, 2, 2, 2, 2, 2, 2, 2,
10,-10, 5, 5, 11,-11, -5, -5, -2, -2, -2, -2, -2, -2, -2, -2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
12,-12, 6, 6, 13,-13, -6, -6, 3, 3, 3, 3, 3, 3, 3, 3,
14,-14, 7, 7, 15,-15, -7, -7, -3, -3, -3, -3, -3, -3, -3, -3,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]={
0, 1, 0, 0, 2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 5, 2, 2, 6, 7, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8, 9, 4, 4, 10,11,5, 5, 2, 2, 2, 2, 2, 2, 2, 2,
12,13,6, 6, 14,15,7, 7, 3, 3, 3, 3, 3, 3, 3, 3,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};

Просмотреть файл

@ -1,579 +0,0 @@
/*
* exp golomb vlc stuff
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2004 Alex Beregszaszi
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* @brief
* exp golomb vlc stuff
* @author Michael Niedermayer <michaelni@gmx.at> and Alex Beregszaszi
*/
#ifndef AVCODEC_GOLOMB_H
#define AVCODEC_GOLOMB_H
#include <stdint.h>
#include "get_bits.h"
#include "put_bits.h"
#define INVALID_VLC 0x80000000
extern const uint8_t ff_golomb_vlc_len[512];
extern const uint8_t ff_ue_golomb_vlc_code[512];
extern const int8_t ff_se_golomb_vlc_code[512];
extern const uint8_t ff_ue_golomb_len[256];
extern const uint8_t ff_interleaved_golomb_vlc_len[256];
extern const uint8_t ff_interleaved_ue_golomb_vlc_code[256];
extern const int8_t ff_interleaved_se_golomb_vlc_code[256];
extern const uint8_t ff_interleaved_dirac_golomb_vlc_code[256];
/**
* Read an unsigned Exp-Golomb code in the range 0 to 8190.
*/
static inline int get_ue_golomb(GetBitContext *gb)
{
unsigned int buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
if (buf >= (1 << 27)) {
buf >>= 32 - 9;
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_ue_golomb_vlc_code[buf];
} else {
int log = 2 * av_log2(buf) - 31;
LAST_SKIP_BITS(re, gb, 32 - log);
CLOSE_READER(re, gb);
if (log < 7) {
av_log(NULL, AV_LOG_ERROR, "Invalid UE golomb code\n");
return AVERROR_INVALIDDATA;
}
buf >>= log;
buf--;
return buf;
}
}
/**
* Read an unsigned Exp-Golomb code in the range 0 to UINT32_MAX-1.
*/
static inline unsigned get_ue_golomb_long(GetBitContext *gb)
{
unsigned buf, log;
buf = show_bits_long(gb, 32);
log = 31 - av_log2(buf);
skip_bits_long(gb, log);
return get_bits_long(gb, log + 1) - 1;
}
/**
* read unsigned exp golomb code, constraint to a max of 31.
* the return value is undefined if the stored value exceeds 31.
*/
static inline int get_ue_golomb_31(GetBitContext *gb)
{
unsigned int buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
buf >>= 32 - 9;
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_ue_golomb_vlc_code[buf];
}
static inline unsigned get_interleaved_ue_golomb(GetBitContext *gb)
{
uint32_t buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
if (buf & 0xAA800000) {
buf >>= 32 - 8;
LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_interleaved_ue_golomb_vlc_code[buf];
} else {
unsigned ret = 1;
do {
buf >>= 32 - 8;
LAST_SKIP_BITS(re, gb,
FFMIN(ff_interleaved_golomb_vlc_len[buf], 8));
if (ff_interleaved_golomb_vlc_len[buf] != 9) {
ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1;
ret |= ff_interleaved_dirac_golomb_vlc_code[buf];
break;
}
ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf];
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
} while (ret<0x8000000U && BITS_AVAILABLE(re, gb));
CLOSE_READER(re, gb);
return ret - 1;
}
}
/**
* read unsigned truncated exp golomb code.
*/
static inline int get_te0_golomb(GetBitContext *gb, int range)
{
av_assert2(range >= 1);
if (range == 1)
return 0;
else if (range == 2)
return get_bits1(gb) ^ 1;
else
return get_ue_golomb(gb);
}
/**
* read unsigned truncated exp golomb code.
*/
static inline int get_te_golomb(GetBitContext *gb, int range)
{
av_assert2(range >= 1);
if (range == 2)
return get_bits1(gb) ^ 1;
else
return get_ue_golomb(gb);
}
/**
* read signed exp golomb code.
*/
static inline int get_se_golomb(GetBitContext *gb)
{
unsigned int buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
if (buf >= (1 << 27)) {
buf >>= 32 - 9;
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_se_golomb_vlc_code[buf];
} else {
int log = av_log2(buf), sign;
LAST_SKIP_BITS(re, gb, 31 - log);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
buf >>= log;
LAST_SKIP_BITS(re, gb, 32 - log);
CLOSE_READER(re, gb);
sign = -(buf & 1);
buf = ((buf >> 1) ^ sign) - sign;
return buf;
}
}
static inline int get_se_golomb_long(GetBitContext *gb)
{
unsigned int buf = get_ue_golomb_long(gb);
int sign = (buf & 1) - 1;
return ((buf >> 1) ^ sign) + 1;
}
static inline int get_interleaved_se_golomb(GetBitContext *gb)
{
unsigned int buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
if (buf & 0xAA800000) {
buf >>= 32 - 8;
LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_interleaved_se_golomb_vlc_code[buf];
} else {
int log;
LAST_SKIP_BITS(re, gb, 8);
UPDATE_CACHE(re, gb);
buf |= 1 | (GET_CACHE(re, gb) >> 8);
if ((buf & 0xAAAAAAAA) == 0)
return INVALID_VLC;
for (log = 31; (buf & 0x80000000) == 0; log--)
buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30);
LAST_SKIP_BITS(re, gb, 63 - 2 * log - 8);
CLOSE_READER(re, gb);
return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1;
}
}
static inline int dirac_get_se_golomb(GetBitContext *gb)
{
uint32_t ret = get_interleaved_ue_golomb(gb);
if (ret) {
int sign = -get_bits1(gb);
ret = (ret ^ sign) - sign;
}
return ret;
}
/**
* read unsigned golomb rice code (ffv1).
*/
static inline int get_ur_golomb(GetBitContext *gb, int k, int limit,
int esc_len)
{
unsigned int buf;
int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
log = av_log2(buf);
if (log > 31 - limit) {
buf >>= log - k;
buf += (30U - log) << k;
LAST_SKIP_BITS(re, gb, 32 + k - log);
CLOSE_READER(re, gb);
return buf;
} else {
LAST_SKIP_BITS(re, gb, limit);
UPDATE_CACHE(re, gb);
buf = SHOW_UBITS(re, gb, esc_len);
LAST_SKIP_BITS(re, gb, esc_len);
CLOSE_READER(re, gb);
return buf + limit - 1;
}
}
/**
* read unsigned golomb rice code (jpegls).
*/
static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit,
int esc_len)
{
unsigned int buf;
int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
log = av_log2(buf);
if (log - k >= 32 - MIN_CACHE_BITS + (MIN_CACHE_BITS == 32) &&
32 - log < limit) {
buf >>= log - k;
buf += (30U - log) << k;
LAST_SKIP_BITS(re, gb, 32 + k - log);
CLOSE_READER(re, gb);
return buf;
} else {
int i;
for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) {
if (gb->size_in_bits <= re_index)
return -1;
LAST_SKIP_BITS(re, gb, 1);
UPDATE_CACHE(re, gb);
}
SKIP_BITS(re, gb, 1);
if (i < limit - 1) {
if (k) {
if (k > MIN_CACHE_BITS - 1) {
buf = SHOW_UBITS(re, gb, 16) << (k-16);
LAST_SKIP_BITS(re, gb, 16);
UPDATE_CACHE(re, gb);
buf |= SHOW_UBITS(re, gb, k-16);
LAST_SKIP_BITS(re, gb, k-16);
} else {
buf = SHOW_UBITS(re, gb, k);
LAST_SKIP_BITS(re, gb, k);
}
} else {
buf = 0;
}
CLOSE_READER(re, gb);
return buf + (i << k);
} else if (i == limit - 1) {
buf = SHOW_UBITS(re, gb, esc_len);
LAST_SKIP_BITS(re, gb, esc_len);
CLOSE_READER(re, gb);
return buf + 1;
} else
return -1;
}
}
/**
* read signed golomb rice code (ffv1).
*/
static inline int get_sr_golomb(GetBitContext *gb, int k, int limit,
int esc_len)
{
unsigned v = get_ur_golomb(gb, k, limit, esc_len);
return (v >> 1) ^ -(v & 1);
}
/**
* read signed golomb rice code (flac).
*/
static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit,
int esc_len)
{
unsigned v = get_ur_golomb_jpegls(gb, k, limit, esc_len);
return (v >> 1) ^ -(v & 1);
}
/**
* read unsigned golomb rice code (shorten).
*/
static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k)
{
return get_ur_golomb_jpegls(gb, k, INT_MAX, 0);
}
/**
* read signed golomb rice code (shorten).
*/
static inline int get_sr_golomb_shorten(GetBitContext *gb, int k)
{
int uvar = get_ur_golomb_jpegls(gb, k + 1, INT_MAX, 0);
return (uvar >> 1) ^ -(uvar & 1);
}
#ifdef TRACE
static inline int get_ue(GetBitContext *s, const char *file, const char *func,
int line)
{
int show = show_bits(s, 24);
int pos = get_bits_count(s);
int i = get_ue_golomb(s);
int len = get_bits_count(s) - pos;
int bits = show >> (24 - len);
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n",
bits, len, i, pos, file, func, line);
return i;
}
static inline int get_se(GetBitContext *s, const char *file, const char *func,
int line)
{
int show = show_bits(s, 24);
int pos = get_bits_count(s);
int i = get_se_golomb(s);
int len = get_bits_count(s) - pos;
int bits = show >> (24 - len);
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n",
bits, len, i, pos, file, func, line);
return i;
}
static inline int get_te(GetBitContext *s, int r, char *file, const char *func,
int line)
{
int show = show_bits(s, 24);
int pos = get_bits_count(s);
int i = get_te0_golomb(s, r);
int len = get_bits_count(s) - pos;
int bits = show >> (24 - len);
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n",
bits, len, i, pos, file, func, line);
return i;
}
#define get_ue_golomb(a) get_ue(a, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_se_golomb(a) get_se(a, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#endif /* TRACE */
/**
* write unsigned exp golomb code.
*/
static inline void set_ue_golomb(PutBitContext *pb, int i)
{
av_assert2(i >= 0);
if (i < 256)
put_bits(pb, ff_ue_golomb_len[i], i + 1);
else {
int e = av_log2(i + 1);
put_bits(pb, 2 * e + 1, i + 1);
}
}
/**
* write truncated unsigned exp golomb code.
*/
static inline void set_te_golomb(PutBitContext *pb, int i, int range)
{
av_assert2(range >= 1);
av_assert2(i <= range);
if (range == 2)
put_bits(pb, 1, i ^ 1);
else
set_ue_golomb(pb, i);
}
/**
* write signed exp golomb code. 16 bits at most.
*/
static inline void set_se_golomb(PutBitContext *pb, int i)
{
#if 0
if (i <= 0)
i = -2 * i;
else
i = 2 * i - 1;
#elif 1
i = 2 * i - 1;
if (i < 0)
i ^= -1; //FIXME check if gcc does the right thing
#else
i = 2 * i - 1;
i ^= (i >> 31);
#endif
set_ue_golomb(pb, i);
}
/**
* write unsigned golomb rice code (ffv1).
*/
static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit,
int esc_len)
{
int e;
av_assert2(i >= 0);
e = i >> k;
if (e < limit)
put_bits(pb, e + k + 1, (1 << k) + av_mod_uintp2(i, k));
else
put_bits(pb, limit + esc_len, i - limit + 1);
}
/**
* write unsigned golomb rice code (jpegls).
*/
static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k,
int limit, int esc_len)
{
int e;
av_assert2(i >= 0);
e = (i >> k) + 1;
if (e < limit) {
while (e > 31) {
put_bits(pb, 31, 0);
e -= 31;
}
put_bits(pb, e, 1);
if (k)
put_sbits(pb, k, i);
} else {
while (limit > 31) {
put_bits(pb, 31, 0);
limit -= 31;
}
put_bits(pb, limit, 1);
put_bits(pb, esc_len, i - 1);
}
}
/**
* write signed golomb rice code (ffv1).
*/
static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit,
int esc_len)
{
int v;
v = -2 * i - 1;
v ^= (v >> 31);
set_ur_golomb(pb, v, k, limit, esc_len);
}
/**
* write signed golomb rice code (flac).
*/
static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k,
int limit, int esc_len)
{
int v;
v = -2 * i - 1;
v ^= (v >> 31);
set_ur_golomb_jpegls(pb, v, k, limit, esc_len);
}
#endif /* AVCODEC_GOLOMB_H */

Просмотреть файл

@ -18,12 +18,6 @@ SOURCES += [
'bitstream.c',
'codec_desc.c',
'dummy_funcs.c',
'flac.c',
'flac_parser.c',
'flacdata.c',
'flacdec.c',
'flacdsp.c',
'golomb.c',
'h264pred.c',
'imgconvert.c',
'log2_tab.c',

Просмотреть файл

@ -1,56 +0,0 @@
/*
* copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_UNARY_H
#define AVCODEC_UNARY_H
#include "get_bits.h"
/**
* Get unary code of limited length
* @param gb GetBitContext
* @param[in] stop The bitstop value (unary code of 1's or 0's)
* @param[in] len Maximum length
* @return Unary length/index
*/
static inline int get_unary(GetBitContext *gb, int stop, int len)
{
int i;
for(i = 0; i < len && get_bits1(gb) != stop; i++);
return i;
}
/**
* Get unary code terminated by a 0 with a maximum length of 33
* @param gb GetBitContext
* @return Unary length/index
*/
static inline int get_unary_0_33(GetBitContext *gb)
{
return get_unary(gb, 0, 33);
}
static inline int get_unary_0_9(GetBitContext *gb)
{
return get_unary(gb, 0, 9);
}
#endif /* AVCODEC_UNARY_H */

Просмотреть файл

@ -1,313 +0,0 @@
;******************************************************************************
;* FLAC DSP SIMD optimizations
;*
;* Copyright (C) 2014 Loren Merritt
;* Copyright (C) 2014 James Almer
;*
;* This file is part of FFmpeg.
;*
;* FFmpeg is free software; you can redistribute it and/or
;* modify it under the terms of the GNU Lesser General Public
;* License as published by the Free Software Foundation; either
;* version 2.1 of the License, or (at your option) any later version.
;*
;* FFmpeg is distributed in the hope that it will be useful,
;* but WITHOUT ANY WARRANTY; without even the implied warranty of
;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;* Lesser General Public License for more details.
;*
;* You should have received a copy of the GNU Lesser General Public
;* License along with FFmpeg; if not, write to the Free Software
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
;******************************************************************************
%include "libavutil/x86/x86util.asm"
SECTION .text
%macro PMACSDQL 5
%if cpuflag(xop)
pmacsdql %1, %2, %3, %1
%else
pmuldq %2, %3
paddq %1, %2
%endif
%endmacro
%macro LPC_32 1
INIT_XMM %1
cglobal flac_lpc_32, 5,6,5, decoded, coeffs, pred_order, qlevel, len, j
sub lend, pred_orderd
jle .ret
lea decodedq, [decodedq+pred_orderq*4-8]
lea coeffsq, [coeffsq+pred_orderq*4]
neg pred_orderq
movd m4, qlevelm
ALIGN 16
.loop_sample:
movd m0, [decodedq+pred_orderq*4+8]
add decodedq, 8
movd m1, [coeffsq+pred_orderq*4]
pxor m2, m2
pxor m3, m3
lea jq, [pred_orderq+1]
test jq, jq
jz .end_order
.loop_order:
PMACSDQL m2, m0, m1, m2, m0
movd m0, [decodedq+jq*4]
PMACSDQL m3, m1, m0, m3, m1
movd m1, [coeffsq+jq*4]
inc jq
jl .loop_order
.end_order:
PMACSDQL m2, m0, m1, m2, m0
psrlq m2, m4
movd m0, [decodedq]
paddd m0, m2
movd [decodedq], m0
sub lend, 2
jl .ret
PMACSDQL m3, m1, m0, m3, m1
psrlq m3, m4
movd m1, [decodedq+4]
paddd m1, m3
movd [decodedq+4], m1
jg .loop_sample
.ret:
REP_RET
%endmacro
%if HAVE_XOP_EXTERNAL
LPC_32 xop
%endif
LPC_32 sse4
;----------------------------------------------------------------------------------
;void ff_flac_decorrelate_[lrm]s_16_sse2(uint8_t **out, int32_t **in, int channels,
; int len, int shift);
;----------------------------------------------------------------------------------
%macro FLAC_DECORRELATE_16 3-4
cglobal flac_decorrelate_%1_16, 2, 4, 4, out, in0, in1, len
%if ARCH_X86_32
mov lend, lenm
%endif
movd m3, r4m
shl lend, 2
mov in1q, [in0q + gprsize]
mov in0q, [in0q]
mov outq, [outq]
add in1q, lenq
add in0q, lenq
add outq, lenq
neg lenq
align 16
.loop:
mova m0, [in0q + lenq]
mova m1, [in1q + lenq]
%ifidn %1, ms
psrad m2, m1, 1
psubd m0, m2
%endif
%ifnidn %1, indep2
p%4d m2, m0, m1
%endif
packssdw m%2, m%2
packssdw m%3, m%3
punpcklwd m%2, m%3
psllw m%2, m3
mova [outq + lenq], m%2
add lenq, 16
jl .loop
REP_RET
%endmacro
INIT_XMM sse2
FLAC_DECORRELATE_16 ls, 0, 2, sub
FLAC_DECORRELATE_16 rs, 2, 1, add
FLAC_DECORRELATE_16 ms, 2, 0, add
;----------------------------------------------------------------------------------
;void ff_flac_decorrelate_[lrm]s_32_sse2(uint8_t **out, int32_t **in, int channels,
; int len, int shift);
;----------------------------------------------------------------------------------
%macro FLAC_DECORRELATE_32 5
cglobal flac_decorrelate_%1_32, 2, 4, 4, out, in0, in1, len
%if ARCH_X86_32
mov lend, lenm
%endif
movd m3, r4m
mov in1q, [in0q + gprsize]
mov in0q, [in0q]
mov outq, [outq]
sub in1q, in0q
align 16
.loop:
mova m0, [in0q]
mova m1, [in0q + in1q]
%ifidn %1, ms
psrad m2, m1, 1
psubd m0, m2
%endif
p%5d m2, m0, m1
pslld m%2, m3
pslld m%3, m3
SBUTTERFLY dq, %2, %3, %4
mova [outq ], m%2
mova [outq + mmsize], m%3
add in0q, mmsize
add outq, mmsize*2
sub lend, mmsize/4
jg .loop
REP_RET
%endmacro
INIT_XMM sse2
FLAC_DECORRELATE_32 ls, 0, 2, 1, sub
FLAC_DECORRELATE_32 rs, 2, 1, 0, add
FLAC_DECORRELATE_32 ms, 2, 0, 1, add
;-----------------------------------------------------------------------------------------
;void ff_flac_decorrelate_indep<ch>_<bps>_<opt>(uint8_t **out, int32_t **in, int channels,
; int len, int shift);
;-----------------------------------------------------------------------------------------
;%1 = bps
;%2 = channels
;%3 = last xmm reg used
;%4 = word/dword (shift instruction)
%macro FLAC_DECORRELATE_INDEP 4
%define REPCOUNT %2/(32/%1) ; 16bits = channels / 2; 32bits = channels
cglobal flac_decorrelate_indep%2_%1, 2, %2+2, %3+1, out, in0, in1, len, in2, in3, in4, in5, in6, in7
%if ARCH_X86_32
%if %2 == 6
DEFINE_ARGS out, in0, in1, in2, in3, in4, in5
%define lend dword r3m
%else
mov lend, lenm
%endif
%endif
movd m%3, r4m
%assign %%i 1
%rep %2-1
mov in %+ %%i %+ q, [in0q+%%i*gprsize]
%assign %%i %%i+1
%endrep
mov in0q, [in0q]
mov outq, [outq]
%assign %%i 1
%rep %2-1
sub in %+ %%i %+ q, in0q
%assign %%i %%i+1
%endrep
align 16
.loop:
mova m0, [in0q]
%assign %%i 1
%rep REPCOUNT-1
mova m %+ %%i, [in0q + in %+ %%i %+ q]
%assign %%i %%i+1
%endrep
%if %1 == 32
%if %2 == 8
TRANSPOSE8x4D 0, 1, 2, 3, 4, 5, 6, 7, 8
%elif %2 == 6
SBUTTERFLY dq, 0, 1, 6
SBUTTERFLY dq, 2, 3, 6
SBUTTERFLY dq, 4, 5, 6
punpcklqdq m6, m0, m2
punpckhqdq m2, m4
shufps m4, m0, 0xe4
punpcklqdq m0, m1, m3
punpckhqdq m3, m5
shufps m5, m1, 0xe4
SWAP 0,6,1,4,5,3
%elif %2 == 4
TRANSPOSE4x4D 0, 1, 2, 3, 4
%else ; %2 == 2
SBUTTERFLY dq, 0, 1, 2
%endif
%else ; %1 == 16
%if %2 == 8
packssdw m0, [in0q + in4q]
packssdw m1, [in0q + in5q]
packssdw m2, [in0q + in6q]
packssdw m3, [in0q + in7q]
TRANSPOSE2x4x4W 0, 1, 2, 3, 4
%elif %2 == 6
packssdw m0, [in0q + in3q]
packssdw m1, [in0q + in4q]
packssdw m2, [in0q + in5q]
pshufd m3, m0, q1032
punpcklwd m0, m1
punpckhwd m1, m2
punpcklwd m2, m3
shufps m3, m0, m2, q2020
shufps m0, m1, q2031
shufps m2, m1, q3131
shufps m1, m2, m3, q3120
shufps m3, m0, q0220
shufps m0, m2, q3113
SWAP 2, 0, 3
%else ; %2 == 4
packssdw m0, [in0q + in2q]
packssdw m1, [in0q + in3q]
SBUTTERFLY wd, 0, 1, 2
SBUTTERFLY dq, 0, 1, 2
%endif
%endif
%assign %%i 0
%rep REPCOUNT
psll%4 m %+ %%i, m%3
%assign %%i %%i+1
%endrep
%assign %%i 0
%rep REPCOUNT
mova [outq + %%i*mmsize], m %+ %%i
%assign %%i %%i+1
%endrep
add in0q, mmsize
add outq, mmsize*REPCOUNT
sub lend, mmsize/4
jg .loop
REP_RET
%endmacro
INIT_XMM sse2
FLAC_DECORRELATE_16 indep2, 0, 1 ; Reuse stereo 16bits macro
FLAC_DECORRELATE_INDEP 32, 2, 3, d
FLAC_DECORRELATE_INDEP 16, 4, 3, w
FLAC_DECORRELATE_INDEP 32, 4, 5, d
FLAC_DECORRELATE_INDEP 16, 6, 4, w
FLAC_DECORRELATE_INDEP 32, 6, 7, d
%if ARCH_X86_64
FLAC_DECORRELATE_INDEP 16, 8, 5, w
FLAC_DECORRELATE_INDEP 32, 8, 9, d
%endif
INIT_XMM avx
FLAC_DECORRELATE_INDEP 32, 4, 5, d
FLAC_DECORRELATE_INDEP 32, 6, 7, d
%if ARCH_X86_64
FLAC_DECORRELATE_INDEP 16, 8, 5, w
FLAC_DECORRELATE_INDEP 32, 8, 9, d
%endif

Просмотреть файл

@ -1,115 +0,0 @@
/*
* Copyright (c) 2014 James Almer
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavcodec/flacdsp.h"
#include "libavutil/x86/cpu.h"
#include "config.h"
void ff_flac_lpc_32_sse4(int32_t *samples, const int coeffs[32], int order,
int qlevel, int len);
void ff_flac_lpc_32_xop(int32_t *samples, const int coeffs[32], int order,
int qlevel, int len);
void ff_flac_enc_lpc_16_sse4(int32_t *, const int32_t *, int, int, const int32_t *,int);
#define DECORRELATE_FUNCS(fmt, opt) \
void ff_flac_decorrelate_ls_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
int len, int shift); \
void ff_flac_decorrelate_rs_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
int len, int shift); \
void ff_flac_decorrelate_ms_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
int len, int shift); \
void ff_flac_decorrelate_indep2_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
int len, int shift); \
void ff_flac_decorrelate_indep4_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
int len, int shift); \
void ff_flac_decorrelate_indep6_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
int len, int shift); \
void ff_flac_decorrelate_indep8_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
int len, int shift)
DECORRELATE_FUNCS(16, sse2);
DECORRELATE_FUNCS(16, avx);
DECORRELATE_FUNCS(32, sse2);
DECORRELATE_FUNCS(32, avx);
av_cold void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int channels,
int bps)
{
#if HAVE_YASM
int cpu_flags = av_get_cpu_flags();
#if CONFIG_FLAC_DECODER
if (EXTERNAL_SSE2(cpu_flags)) {
if (fmt == AV_SAMPLE_FMT_S16) {
if (channels == 2)
c->decorrelate[0] = ff_flac_decorrelate_indep2_16_sse2;
else if (channels == 4)
c->decorrelate[0] = ff_flac_decorrelate_indep4_16_sse2;
else if (channels == 6)
c->decorrelate[0] = ff_flac_decorrelate_indep6_16_sse2;
else if (ARCH_X86_64 && channels == 8)
c->decorrelate[0] = ff_flac_decorrelate_indep8_16_sse2;
c->decorrelate[1] = ff_flac_decorrelate_ls_16_sse2;
c->decorrelate[2] = ff_flac_decorrelate_rs_16_sse2;
c->decorrelate[3] = ff_flac_decorrelate_ms_16_sse2;
} else if (fmt == AV_SAMPLE_FMT_S32) {
if (channels == 2)
c->decorrelate[0] = ff_flac_decorrelate_indep2_32_sse2;
else if (channels == 4)
c->decorrelate[0] = ff_flac_decorrelate_indep4_32_sse2;
else if (channels == 6)
c->decorrelate[0] = ff_flac_decorrelate_indep6_32_sse2;
else if (ARCH_X86_64 && channels == 8)
c->decorrelate[0] = ff_flac_decorrelate_indep8_32_sse2;
c->decorrelate[1] = ff_flac_decorrelate_ls_32_sse2;
c->decorrelate[2] = ff_flac_decorrelate_rs_32_sse2;
c->decorrelate[3] = ff_flac_decorrelate_ms_32_sse2;
}
}
if (EXTERNAL_SSE4(cpu_flags)) {
c->lpc32 = ff_flac_lpc_32_sse4;
}
if (EXTERNAL_AVX(cpu_flags)) {
if (fmt == AV_SAMPLE_FMT_S16) {
if (ARCH_X86_64 && channels == 8)
c->decorrelate[0] = ff_flac_decorrelate_indep8_16_avx;
} else if (fmt == AV_SAMPLE_FMT_S32) {
if (channels == 4)
c->decorrelate[0] = ff_flac_decorrelate_indep4_32_avx;
else if (channels == 6)
c->decorrelate[0] = ff_flac_decorrelate_indep6_32_avx;
else if (ARCH_X86_64 && channels == 8)
c->decorrelate[0] = ff_flac_decorrelate_indep8_32_avx;
}
}
if (EXTERNAL_XOP(cpu_flags)) {
c->lpc32 = ff_flac_lpc_32_xop;
}
#endif
#if CONFIG_FLAC_ENCODER
if (EXTERNAL_SSE4(cpu_flags)) {
if (CONFIG_GPL)
c->lpc16_encode = ff_flac_enc_lpc_16_sse4;
}
#endif
#endif /* HAVE_YASM */
}

Просмотреть файл

@ -6,8 +6,6 @@
SOURCES += [
'constants.c',
'flacdsp.asm',
'flacdsp_init.c',
'h264_intrapred.asm',
'h264_intrapred_10bit.asm',
'h264_intrapred_init.c',