mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
Ultra-gross hackery, but works! Now, need to pare it down, heavily...
This commit is contained in:
parent
fb906481cc
commit
8fbc4a3379
@ -386,15 +386,20 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\ext\at3_standalone\at3_decoders.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\atomic.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\atrac.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\atrac3data.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\atrac3plus.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\atrac3plus_data.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\attributes.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\avcodec.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\avfft.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\avstring.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\avutil.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\bprint.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\bswap.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\buffer.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\buffer_internal.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\bytestream.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\channel_layout.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\common.h" />
|
||||
@ -402,20 +407,29 @@
|
||||
<ClInclude Include="..\ext\at3_standalone\config.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\dict.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\error.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\fft-internal.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\fft.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\float_dsp.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\frame.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\get_bits.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\internal.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\intfloat.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\intmath.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\intreadwrite.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\libm.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\log.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\macros.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\mathematics.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\mathops.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\mem.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\opt.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\options_table.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\pixdesc.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\pixfmt.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\rational.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\rdft.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\samplefmt.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\sinewin.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\util_internal.h" />
|
||||
<ClInclude Include="..\ext\at3_standalone\version.h" />
|
||||
<ClInclude Include="..\ext\basis_universal\basisu.h" />
|
||||
@ -617,14 +631,36 @@
|
||||
<ClInclude Include="x64Emitter.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\ext\at3_standalone\atomic.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\atrac.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\atrac3.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\atrac3plus.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\atrac3plusdec.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\atrac3plusdsp.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\avfft.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\avpacket.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\avstring.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\av_buffer.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\bitstream.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\bprint.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\channel_layout.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\codec_desc.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\dict.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\fft_template.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\float_dsp.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\frame.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\intmath.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\mathematics.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\mathops.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\mdct_template.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\mem.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\opt.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\options.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\rational.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\rdft.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\samplefmt.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\sinewin.c" />
|
||||
<ClCompile Include="..\ext\at3_standalone\utils.c" />
|
||||
<ClCompile Include="..\ext\basis_universal\basisu_transcoder.cpp" />
|
||||
<ClCompile Include="..\ext\libpng17\png.c">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
|
@ -623,6 +623,48 @@
|
||||
<ClInclude Include="..\ext\at3_standalone\pixdesc.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\mem.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\sinewin.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\attributes.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\opt.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\options_table.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\log.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\buffer_internal.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\atomic.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\intmath.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\bprint.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\avstring.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\fft-internal.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\rational.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\at3_standalone\rdft.h">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ABI.cpp" />
|
||||
@ -1107,6 +1149,72 @@
|
||||
<ClCompile Include="..\ext\at3_standalone\frame.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\samplefmt.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\mem.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\sinewin.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\options.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\channel_layout.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\av_buffer.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\dict.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\atomic.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\utils.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\atrac.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\avpacket.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\mathematics.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\opt.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\mdct_template.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\avstring.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\bprint.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\codec_desc.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\fft_template.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\rational.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\rdft.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\intmath.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\at3_standalone\bitstream.c">
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Crypto">
|
||||
|
@ -1,5 +1,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ext/at3_standalone/compat.h"
|
||||
#include "ext/at3_standalone/common.h"
|
||||
|
||||
/*
|
||||
void *av_malloc(size_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
@ -17,3 +22,71 @@ void av_freep(void **p) {
|
||||
free(pp);
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc)
|
||||
{
|
||||
void *val;
|
||||
|
||||
memcpy(&val, ptr, sizeof(val));
|
||||
if (min_size <= *size) {
|
||||
av_assert0(val || !min_size);
|
||||
return 0;
|
||||
}
|
||||
min_size = FFMAX(min_size + min_size / 16 + 32, min_size);
|
||||
av_freep(ptr);
|
||||
val = zero_realloc ? av_mallocz(min_size) : av_malloc(min_size);
|
||||
memcpy(ptr, &val, sizeof(val));
|
||||
if (!val)
|
||||
min_size = 0;
|
||||
*size = min_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int av_fast_malloc(void *ptr, unsigned int *size, size_t min_size) {
|
||||
return ff_fast_malloc(ptr, size, min_size, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
void av_log(void *avcl, int level, const char *fmt, ...) {
|
||||
|
||||
}
|
||||
|
||||
int av_get_cpu_flags(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ff_fft_init_aarch64(void) {}
|
||||
void ff_fft_init_x86(void) {}
|
||||
void ff_fft_init_arm(void) {}
|
||||
void ff_fft_init_mips(void) {}
|
||||
void ff_fft_init_ppc(void) {}
|
||||
|
||||
const uint8_t ff_reverse[256] = {
|
||||
0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
|
||||
0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
|
||||
0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
|
||||
0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
|
||||
0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
|
||||
0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
|
||||
0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
|
||||
0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
|
||||
0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
|
||||
0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
|
||||
0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
|
||||
0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
|
||||
0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
|
||||
0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
|
||||
0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
|
||||
0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF,
|
||||
};
|
||||
|
||||
const uint8_t ff_log2_tab[256] = {
|
||||
0,0,1,1,2,2,2,2,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,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,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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
|
||||
};
|
||||
|
@ -7,22 +7,68 @@ extern "C" {
|
||||
#include "ext/at3_standalone/avcodec.h"
|
||||
}
|
||||
|
||||
inline int16_t clamp16(float f) {
|
||||
if (f >= 1.0f)
|
||||
return 32767;
|
||||
else if (f <= -1.0f)
|
||||
return -32767;
|
||||
else
|
||||
return (int)(f * 32767);
|
||||
}
|
||||
|
||||
// Uses our standalone AT3/AT3+ decoder derived from FFMPEG
|
||||
class Atrac3Audio : public AudioDecoder {
|
||||
public:
|
||||
Atrac3Audio(PSPAudioType audioType) {
|
||||
ctx_ = avcodec_alloc_context3(&ff_atrac3p_decoder);
|
||||
atrac3p_decode_init(ctx_);
|
||||
// int retval = atrac3p_decode_init(ctx_);
|
||||
frame_ = av_frame_alloc();
|
||||
}
|
||||
~Atrac3Audio() {
|
||||
atrac3p_decode_close(ctx_);
|
||||
avcodec_close(ctx_);
|
||||
av_frame_free(&frame_);
|
||||
av_freep(&ctx_->extradata);
|
||||
av_freep(&ctx_->subtitle_header);
|
||||
av_freep(&ctx_);
|
||||
}
|
||||
|
||||
bool Decode(const uint8_t *inbuf, int inbytes, uint8_t *outbuf, int *outbytes) override {
|
||||
if (!codecOpen_) {
|
||||
ctx_->block_align = inbytes;
|
||||
ctx_->channels = 2;
|
||||
ctx_->channel_layout = ctx_->channels == 2 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
|
||||
ctx_->sample_rate = 44100;
|
||||
int retval = avcodec_open2(ctx_, &ff_atrac3p_decoder, nullptr);
|
||||
_dbg_assert_(retval >= 0);
|
||||
if (retval < 0) {
|
||||
return false;
|
||||
}
|
||||
codecOpen_ = true;
|
||||
}
|
||||
|
||||
int got_frame = 0;
|
||||
int samples = atrac3p_decode_frame(ctx_, frame_, &got_frame, inbuf, inbytes);
|
||||
int result = atrac3p_decode_frame(ctx_, frame_, &got_frame, inbuf, inbytes);
|
||||
if (result < 0) {
|
||||
*outbytes = 0;
|
||||
return false;
|
||||
}
|
||||
srcPos_ = result;
|
||||
outSamples_ = frame_->nb_samples;
|
||||
if (frame_->nb_samples > 0) {
|
||||
*outbytes = frame_->nb_samples * 2 * 2;
|
||||
|
||||
// Convert frame to outbuf.
|
||||
for (int channel = 0; channel < 2; channel++) {
|
||||
float **pointers = (float **)frame_->data;
|
||||
int16_t *output = (int16_t *)outbuf;
|
||||
for (int i = 0; i < frame_->nb_samples; i++) {
|
||||
output[i * 2] = clamp16(pointers[0][i]);
|
||||
output[i * 2 + 1] = clamp16(pointers[1][i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*outbytes = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -38,6 +84,18 @@ public:
|
||||
// Hmm. ignore for now.
|
||||
}
|
||||
|
||||
void SetExtraData(const uint8_t *data, int size, int wav_bytes_per_packet) {
|
||||
_dbg_assert_(ctx_);
|
||||
_dbg_assert_(!codecOpen_);
|
||||
ctx_->extradata = (uint8_t *)av_mallocz(size);
|
||||
ctx_->extradata_size = size;
|
||||
ctx_->block_align = wav_bytes_per_packet;
|
||||
codecOpen_ = false;
|
||||
if (data != nullptr) {
|
||||
memcpy(ctx_->extradata, data, size);
|
||||
}
|
||||
}
|
||||
|
||||
PSPAudioType GetAudioType() const override { return audioType_; }
|
||||
|
||||
private:
|
||||
@ -47,6 +105,8 @@ private:
|
||||
int outSamples_ = 0;
|
||||
int srcPos_ = 0;
|
||||
|
||||
bool codecOpen_ = false;
|
||||
|
||||
PSPAudioType audioType_;
|
||||
};
|
||||
|
||||
|
@ -231,7 +231,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>USE_FFMPEG;RC_CLIENT_SUPPORTS_RAINTEGRATION;_CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_32=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>RC_CLIENT_SUPPORTS_RAINTEGRATION;_CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_32=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
@ -271,7 +271,7 @@
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<PreprocessorDefinitions>USE_FFMPEG;RC_CLIENT_SUPPORTS_RAINTEGRATION;_CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_64=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>RC_CLIENT_SUPPORTS_RAINTEGRATION;_CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_64=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
@ -307,7 +307,7 @@
|
||||
<Midl />
|
||||
<ClCompile>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<PreprocessorDefinitions>USE_FFMPEG;_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_64=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_64=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
@ -343,7 +343,7 @@
|
||||
<Midl />
|
||||
<ClCompile>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<PreprocessorDefinitions>USE_FFMPEG;_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_32=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_32=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
@ -378,7 +378,7 @@
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<PreprocessorDefinitions>USE_FFMPEG;RC_CLIENT_SUPPORTS_RAINTEGRATION;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_32=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>RC_CLIENT_SUPPORTS_RAINTEGRATION;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_32=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
@ -428,7 +428,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
<PreprocessorDefinitions>USE_FFMPEG;RC_CLIENT_SUPPORTS_RAINTEGRATION;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_64=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>RC_CLIENT_SUPPORTS_RAINTEGRATION;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_64=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
@ -471,7 +471,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
<PreprocessorDefinitions>USE_FFMPEG;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_64=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_64=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
@ -513,7 +513,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
<PreprocessorDefinitions>USE_FFMPEG;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_32=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_32=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
|
127
ext/at3_standalone/atomic.c
Normal file
127
ext/at3_standalone/atomic.c
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Ronald S. Bultje <rsbultje@gmail.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 "config.h"
|
||||
#include "atomic.h"
|
||||
|
||||
#if !HAVE_ATOMICS_NATIVE
|
||||
|
||||
#if HAVE_PTHREADS
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
int avpriv_atomic_int_get(volatile int *ptr)
|
||||
{
|
||||
int res;
|
||||
|
||||
pthread_mutex_lock(&atomic_lock);
|
||||
res = *ptr;
|
||||
pthread_mutex_unlock(&atomic_lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void avpriv_atomic_int_set(volatile int *ptr, int val)
|
||||
{
|
||||
pthread_mutex_lock(&atomic_lock);
|
||||
*ptr = val;
|
||||
pthread_mutex_unlock(&atomic_lock);
|
||||
}
|
||||
|
||||
int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc)
|
||||
{
|
||||
int res;
|
||||
|
||||
pthread_mutex_lock(&atomic_lock);
|
||||
*ptr += inc;
|
||||
res = *ptr;
|
||||
pthread_mutex_unlock(&atomic_lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval)
|
||||
{
|
||||
void *ret;
|
||||
pthread_mutex_lock(&atomic_lock);
|
||||
ret = *ptr;
|
||||
if (ret == oldval)
|
||||
*ptr = newval;
|
||||
pthread_mutex_unlock(&atomic_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif !HAVE_THREADS
|
||||
|
||||
int avpriv_atomic_int_get(volatile int *ptr)
|
||||
{
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
void avpriv_atomic_int_set(volatile int *ptr, int val)
|
||||
{
|
||||
*ptr = val;
|
||||
}
|
||||
|
||||
int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc)
|
||||
{
|
||||
*ptr += inc;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval)
|
||||
{
|
||||
if (*ptr == oldval) {
|
||||
*ptr = newval;
|
||||
return oldval;
|
||||
}
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
#else /* HAVE_THREADS */
|
||||
|
||||
/* This should never trigger, unless a new threading implementation
|
||||
* without correct atomics dependencies in configure or a corresponding
|
||||
* atomics implementation is added. */
|
||||
#error "Threading is enabled, but there is no implementation of atomic operations available"
|
||||
|
||||
#endif /* HAVE_PTHREADS */
|
||||
|
||||
#endif /* !HAVE_ATOMICS_NATIVE */
|
||||
|
||||
#ifdef TEST
|
||||
#include "avassert.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
volatile int val = 1;
|
||||
int res;
|
||||
|
||||
res = avpriv_atomic_int_add_and_fetch(&val, 1);
|
||||
av_assert0(res == 2);
|
||||
avpriv_atomic_int_set(&val, 3);
|
||||
res = avpriv_atomic_int_get(&val);
|
||||
av_assert0(res == 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
79
ext/at3_standalone/atomic.h
Normal file
79
ext/at3_standalone/atomic.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Ronald S. Bultje <rsbultje@gmail.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
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_ATOMIC_H
|
||||
#define AVUTIL_ATOMIC_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_ATOMICS_NATIVE
|
||||
|
||||
#if HAVE_ATOMICS_GCC
|
||||
#include "atomic_gcc.h"
|
||||
#elif HAVE_ATOMICS_WIN32
|
||||
#include "atomic_win32.h"
|
||||
#elif HAVE_ATOMICS_SUNCC
|
||||
#include "atomic_suncc.h"
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
* Load the current value stored in an atomic integer.
|
||||
*
|
||||
* @param ptr atomic integer
|
||||
* @return the current value of the atomic integer
|
||||
* @note This acts as a memory barrier.
|
||||
*/
|
||||
int avpriv_atomic_int_get(volatile int *ptr);
|
||||
|
||||
/**
|
||||
* Store a new value in an atomic integer.
|
||||
*
|
||||
* @param ptr atomic integer
|
||||
* @param val the value to store in the atomic integer
|
||||
* @note This acts as a memory barrier.
|
||||
*/
|
||||
void avpriv_atomic_int_set(volatile int *ptr, int val);
|
||||
|
||||
/**
|
||||
* Add a value to an atomic integer.
|
||||
*
|
||||
* @param ptr atomic integer
|
||||
* @param inc the value to add to the atomic integer (may be negative)
|
||||
* @return the new value of the atomic integer.
|
||||
* @note This does NOT act as a memory barrier. This is primarily
|
||||
* intended for reference counting.
|
||||
*/
|
||||
int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc);
|
||||
|
||||
/**
|
||||
* Atomic pointer compare and swap.
|
||||
*
|
||||
* @param ptr pointer to the pointer to operate on
|
||||
* @param oldval do the swap if the current value of *ptr equals to oldval
|
||||
* @param newval value to replace *ptr with
|
||||
* @return the value of *ptr before comparison
|
||||
*/
|
||||
void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval);
|
||||
|
||||
#endif /* HAVE_ATOMICS_NATIVE */
|
||||
|
||||
#endif /* AVUTIL_ATOMIC_H */
|
165
ext/at3_standalone/atrac.c
Normal file
165
ext/at3_standalone/atrac.c
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* common functions for the ATRAC family of decoders
|
||||
*
|
||||
* Copyright (c) 2006-2013 Maxim Poliakovski
|
||||
* Copyright (c) 2006-2008 Benjamin Larsson
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "atrac.h"
|
||||
|
||||
float ff_atrac_sf_table[64];
|
||||
static float qmf_window[48];
|
||||
|
||||
static const float qmf_48tap_half[24] = {
|
||||
-0.00001461907, -0.00009205479,-0.000056157569,0.00030117269,
|
||||
0.0002422519, -0.00085293897,-0.0005205574, 0.0020340169,
|
||||
0.00078333891, -0.0042153862, -0.00075614988, 0.0078402944,
|
||||
-0.000061169922,-0.01344162, 0.0024626821, 0.021736089,
|
||||
-0.007801671, -0.034090221, 0.01880949, 0.054326009,
|
||||
-0.043596379, -0.099384367, 0.13207909, 0.46424159
|
||||
};
|
||||
|
||||
av_cold void ff_atrac_generate_tables(void)
|
||||
{
|
||||
int i;
|
||||
float s;
|
||||
|
||||
/* Generate scale factors */
|
||||
if (!ff_atrac_sf_table[63])
|
||||
for (i=0 ; i<64 ; i++)
|
||||
ff_atrac_sf_table[i] = pow(2.0, (i - 15) / 3.0);
|
||||
|
||||
/* Generate the QMF window. */
|
||||
if (!qmf_window[47])
|
||||
for (i=0 ; i<24; i++) {
|
||||
s = qmf_48tap_half[i] * 2.0;
|
||||
qmf_window[i] = qmf_window[47 - i] = s;
|
||||
}
|
||||
}
|
||||
|
||||
av_cold void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset,
|
||||
int loc_scale)
|
||||
{
|
||||
int i;
|
||||
|
||||
gctx->loc_scale = loc_scale;
|
||||
gctx->loc_size = 1 << loc_scale;
|
||||
gctx->id2exp_offset = id2exp_offset;
|
||||
|
||||
/* Generate gain level table. */
|
||||
for (i = 0; i < 16; i++)
|
||||
gctx->gain_tab1[i] = powf(2.0, id2exp_offset - i);
|
||||
|
||||
/* Generate gain interpolation table. */
|
||||
for (i = -15; i < 16; i++)
|
||||
gctx->gain_tab2[i + 15] = powf(2.0, -1.0f / gctx->loc_size * i);
|
||||
}
|
||||
|
||||
void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev,
|
||||
AtracGainInfo *gc_now, AtracGainInfo *gc_next,
|
||||
int num_samples, float *out)
|
||||
{
|
||||
float lev, gc_scale, gain_inc;
|
||||
int i, pos, lastpos;
|
||||
|
||||
gc_scale = gc_next->num_points ? gctx->gain_tab1[gc_next->lev_code[0]]
|
||||
: 1.0f;
|
||||
|
||||
if (!gc_now->num_points) {
|
||||
for (pos = 0; pos < num_samples; pos++)
|
||||
out[pos] = in[pos] * gc_scale + prev[pos];
|
||||
} else {
|
||||
pos = 0;
|
||||
|
||||
for (i = 0; i < gc_now->num_points; i++) {
|
||||
lastpos = gc_now->loc_code[i] << gctx->loc_scale;
|
||||
|
||||
lev = gctx->gain_tab1[gc_now->lev_code[i]];
|
||||
gain_inc = gctx->gain_tab2[(i + 1 < gc_now->num_points ? gc_now->lev_code[i + 1]
|
||||
: gctx->id2exp_offset) -
|
||||
gc_now->lev_code[i] + 15];
|
||||
|
||||
/* apply constant gain level and overlap */
|
||||
for (; pos < lastpos; pos++)
|
||||
out[pos] = (in[pos] * gc_scale + prev[pos]) * lev;
|
||||
|
||||
/* interpolate between two different gain levels */
|
||||
for (; pos < lastpos + gctx->loc_size; pos++) {
|
||||
out[pos] = (in[pos] * gc_scale + prev[pos]) * lev;
|
||||
lev *= gain_inc;
|
||||
}
|
||||
}
|
||||
|
||||
for (; pos < num_samples; pos++)
|
||||
out[pos] = in[pos] * gc_scale + prev[pos];
|
||||
}
|
||||
|
||||
/* copy the overlapping part into the delay buffer */
|
||||
memcpy(prev, &in[num_samples], num_samples * sizeof(float));
|
||||
}
|
||||
|
||||
void ff_atrac_iqmf(float *inlo, float *inhi, unsigned int nIn, float *pOut,
|
||||
float *delayBuf, float *temp)
|
||||
{
|
||||
int i, j;
|
||||
float *p1, *p3;
|
||||
|
||||
memcpy(temp, delayBuf, 46*sizeof(float));
|
||||
|
||||
p3 = temp + 46;
|
||||
|
||||
/* loop1 */
|
||||
for(i=0; i<nIn; i+=2){
|
||||
p3[2*i+0] = inlo[i ] + inhi[i ];
|
||||
p3[2*i+1] = inlo[i ] - inhi[i ];
|
||||
p3[2*i+2] = inlo[i+1] + inhi[i+1];
|
||||
p3[2*i+3] = inlo[i+1] - inhi[i+1];
|
||||
}
|
||||
|
||||
/* loop2 */
|
||||
p1 = temp;
|
||||
for (j = nIn; j != 0; j--) {
|
||||
float s1 = 0.0;
|
||||
float s2 = 0.0;
|
||||
|
||||
for (i = 0; i < 48; i += 2) {
|
||||
s1 += p1[i] * qmf_window[i];
|
||||
s2 += p1[i+1] * qmf_window[i+1];
|
||||
}
|
||||
|
||||
pOut[0] = s2;
|
||||
pOut[1] = s1;
|
||||
|
||||
p1 += 2;
|
||||
pOut += 2;
|
||||
}
|
||||
|
||||
/* Update the delay buffer. */
|
||||
memcpy(delayBuf, temp + nIn*2, 46*sizeof(float));
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#define av_cold
|
||||
#define DECLARE_ALIGNED(bits, type, name) type name
|
||||
#define LOCAL_ALIGNED(bits, type, name, subscript) type name subscript
|
||||
#define av_restrict
|
||||
#define av_always_inline __forceinline
|
||||
#define av_const
|
||||
#define av_alias
|
||||
#define av_unused
|
||||
#define av_pure
|
||||
#define av_warn_unused_result
|
||||
#define av_assert0(cond)
|
||||
#define av_assert1(cond)
|
||||
#define av_assert2(cond)
|
||||
#define attribute_deprecated
|
||||
#define av_printf_format(a,b)
|
||||
#define avpriv_report_missing_feature(...)
|
392
ext/at3_standalone/av_buffer.c
Normal file
392
ext/at3_standalone/av_buffer.c
Normal file
@ -0,0 +1,392 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#undef free
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "buffer_internal.h"
|
||||
#include "common.h"
|
||||
#include "mem.h"
|
||||
|
||||
AVBufferRef *av_buffer_create(uint8_t *data, int size,
|
||||
void (*free)(void *opaque, uint8_t *data),
|
||||
void *opaque, int flags)
|
||||
{
|
||||
AVBufferRef *ref = NULL;
|
||||
AVBuffer *buf = NULL;
|
||||
|
||||
buf = av_mallocz(sizeof(*buf));
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
buf->data = data;
|
||||
buf->size = size;
|
||||
buf->free = free ? free : av_buffer_default_free;
|
||||
buf->opaque = opaque;
|
||||
buf->refcount = 1;
|
||||
|
||||
if (flags & AV_BUFFER_FLAG_READONLY)
|
||||
buf->flags |= BUFFER_FLAG_READONLY;
|
||||
|
||||
ref = av_mallocz(sizeof(*ref));
|
||||
if (!ref) {
|
||||
av_freep(&buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ref->buffer = buf;
|
||||
ref->data = data;
|
||||
ref->size = size;
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
void av_buffer_default_free(void *opaque, uint8_t *data)
|
||||
{
|
||||
av_free(data);
|
||||
}
|
||||
|
||||
AVBufferRef *av_buffer_alloc(int size)
|
||||
{
|
||||
AVBufferRef *ret = NULL;
|
||||
uint8_t *data = NULL;
|
||||
|
||||
data = av_malloc(size);
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
ret = av_buffer_create(data, size, av_buffer_default_free, NULL, 0);
|
||||
if (!ret)
|
||||
av_freep(&data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVBufferRef *av_buffer_allocz(int size)
|
||||
{
|
||||
AVBufferRef *ret = av_buffer_alloc(size);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
memset(ret->data, 0, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVBufferRef *av_buffer_ref(AVBufferRef *buf)
|
||||
{
|
||||
AVBufferRef *ret = av_mallocz(sizeof(*ret));
|
||||
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
*ret = *buf;
|
||||
|
||||
avpriv_atomic_int_add_and_fetch(&buf->buffer->refcount, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void buffer_replace(AVBufferRef **dst, AVBufferRef **src)
|
||||
{
|
||||
AVBuffer *b;
|
||||
|
||||
b = (*dst)->buffer;
|
||||
|
||||
if (src) {
|
||||
**dst = **src;
|
||||
av_freep(src);
|
||||
} else
|
||||
av_freep(dst);
|
||||
|
||||
if (!avpriv_atomic_int_add_and_fetch(&b->refcount, -1)) {
|
||||
b->free(b->opaque, b->data);
|
||||
av_freep(&b);
|
||||
}
|
||||
}
|
||||
|
||||
void av_buffer_unref(AVBufferRef **buf)
|
||||
{
|
||||
if (!buf || !*buf)
|
||||
return;
|
||||
|
||||
buffer_replace(buf, NULL);
|
||||
}
|
||||
|
||||
int av_buffer_is_writable(const AVBufferRef *buf)
|
||||
{
|
||||
if (buf->buffer->flags & AV_BUFFER_FLAG_READONLY)
|
||||
return 0;
|
||||
|
||||
return avpriv_atomic_int_get(&buf->buffer->refcount) == 1;
|
||||
}
|
||||
|
||||
void *av_buffer_get_opaque(const AVBufferRef *buf)
|
||||
{
|
||||
return buf->buffer->opaque;
|
||||
}
|
||||
|
||||
int av_buffer_get_ref_count(const AVBufferRef *buf)
|
||||
{
|
||||
return buf->buffer->refcount;
|
||||
}
|
||||
|
||||
int av_buffer_make_writable(AVBufferRef **pbuf)
|
||||
{
|
||||
AVBufferRef *newbuf, *buf = *pbuf;
|
||||
|
||||
if (av_buffer_is_writable(buf))
|
||||
return 0;
|
||||
|
||||
newbuf = av_buffer_alloc(buf->size);
|
||||
if (!newbuf)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
memcpy(newbuf->data, buf->data, buf->size);
|
||||
|
||||
buffer_replace(pbuf, &newbuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int av_buffer_realloc(AVBufferRef **pbuf, int size)
|
||||
{
|
||||
AVBufferRef *buf = *pbuf;
|
||||
uint8_t *tmp;
|
||||
|
||||
if (!buf) {
|
||||
/* allocate a new buffer with av_realloc(), so it will be reallocatable
|
||||
* later */
|
||||
uint8_t *data = av_realloc(NULL, size);
|
||||
if (!data)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
buf = av_buffer_create(data, size, av_buffer_default_free, NULL, 0);
|
||||
if (!buf) {
|
||||
av_freep(&data);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
buf->buffer->flags |= BUFFER_FLAG_REALLOCATABLE;
|
||||
*pbuf = buf;
|
||||
|
||||
return 0;
|
||||
} else if (buf->size == size)
|
||||
return 0;
|
||||
|
||||
if (!(buf->buffer->flags & BUFFER_FLAG_REALLOCATABLE) ||
|
||||
!av_buffer_is_writable(buf)) {
|
||||
/* cannot realloc, allocate a new reallocable buffer and copy data */
|
||||
AVBufferRef *newb = NULL;
|
||||
|
||||
av_buffer_realloc(&newb, size);
|
||||
if (!newb)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
memcpy(newb->data, buf->data, FFMIN(size, buf->size));
|
||||
|
||||
buffer_replace(pbuf, &newb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = av_realloc(buf->buffer->data, size);
|
||||
if (!tmp)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
buf->buffer->data = buf->data = tmp;
|
||||
buf->buffer->size = buf->size = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size))
|
||||
{
|
||||
AVBufferPool *pool = av_mallocz(sizeof(*pool));
|
||||
if (!pool)
|
||||
return NULL;
|
||||
|
||||
pool->size = size;
|
||||
pool->alloc = alloc ? alloc : av_buffer_alloc;
|
||||
|
||||
avpriv_atomic_int_set(&pool->refcount, 1);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function gets called when the pool has been uninited and
|
||||
* all the buffers returned to it.
|
||||
*/
|
||||
static void buffer_pool_free(AVBufferPool *pool)
|
||||
{
|
||||
while (pool->pool) {
|
||||
BufferPoolEntry *buf = pool->pool;
|
||||
pool->pool = buf->next;
|
||||
|
||||
buf->free(buf->opaque, buf->data);
|
||||
av_freep(&buf);
|
||||
}
|
||||
av_freep(&pool);
|
||||
}
|
||||
|
||||
void av_buffer_pool_uninit(AVBufferPool **ppool)
|
||||
{
|
||||
AVBufferPool *pool;
|
||||
|
||||
if (!ppool || !*ppool)
|
||||
return;
|
||||
pool = *ppool;
|
||||
*ppool = NULL;
|
||||
|
||||
if (!avpriv_atomic_int_add_and_fetch(&pool->refcount, -1))
|
||||
buffer_pool_free(pool);
|
||||
}
|
||||
|
||||
#if USE_ATOMICS
|
||||
/* remove the whole buffer list from the pool and return it */
|
||||
static BufferPoolEntry *get_pool(AVBufferPool *pool)
|
||||
{
|
||||
BufferPoolEntry *cur = *(void * volatile *)&pool->pool, *last = NULL;
|
||||
|
||||
while (cur != last) {
|
||||
last = cur;
|
||||
cur = avpriv_atomic_ptr_cas((void * volatile *)&pool->pool, last, NULL);
|
||||
if (!cur)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
static void add_to_pool(BufferPoolEntry *buf)
|
||||
{
|
||||
AVBufferPool *pool;
|
||||
BufferPoolEntry *cur, *end = buf;
|
||||
|
||||
if (!buf)
|
||||
return;
|
||||
pool = buf->pool;
|
||||
|
||||
while (end->next)
|
||||
end = end->next;
|
||||
|
||||
while (avpriv_atomic_ptr_cas((void * volatile *)&pool->pool, NULL, buf)) {
|
||||
/* pool is not empty, retrieve it and append it to our list */
|
||||
cur = get_pool(pool);
|
||||
end->next = cur;
|
||||
while (end->next)
|
||||
end = end->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void pool_release_buffer(void *opaque, uint8_t *data)
|
||||
{
|
||||
BufferPoolEntry *buf = opaque;
|
||||
AVBufferPool *pool = buf->pool;
|
||||
|
||||
#if USE_ATOMICS
|
||||
add_to_pool(buf);
|
||||
#else
|
||||
buf->next = pool->pool;
|
||||
pool->pool = buf;
|
||||
#endif
|
||||
|
||||
if (!avpriv_atomic_int_add_and_fetch(&pool->refcount, -1))
|
||||
buffer_pool_free(pool);
|
||||
}
|
||||
|
||||
/* allocate a new buffer and override its free() callback so that
|
||||
* it is returned to the pool on free */
|
||||
static AVBufferRef *pool_alloc_buffer(AVBufferPool *pool)
|
||||
{
|
||||
BufferPoolEntry *buf;
|
||||
AVBufferRef *ret;
|
||||
|
||||
ret = pool->alloc(pool->size);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
buf = av_mallocz(sizeof(*buf));
|
||||
if (!buf) {
|
||||
av_buffer_unref(&ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf->data = ret->buffer->data;
|
||||
buf->opaque = ret->buffer->opaque;
|
||||
buf->free = ret->buffer->free;
|
||||
buf->pool = pool;
|
||||
|
||||
ret->buffer->opaque = buf;
|
||||
ret->buffer->free = pool_release_buffer;
|
||||
|
||||
#if USE_ATOMICS
|
||||
avpriv_atomic_int_add_and_fetch(&pool->refcount, 1);
|
||||
avpriv_atomic_int_add_and_fetch(&pool->nb_allocated, 1);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVBufferRef *av_buffer_pool_get(AVBufferPool *pool)
|
||||
{
|
||||
AVBufferRef *ret;
|
||||
BufferPoolEntry *buf;
|
||||
|
||||
#if USE_ATOMICS
|
||||
/* check whether the pool is empty */
|
||||
buf = get_pool(pool);
|
||||
if (!buf && pool->refcount <= pool->nb_allocated) {
|
||||
av_log(NULL, AV_LOG_DEBUG, "Pool race dectected, spining to avoid overallocation and eventual OOM\n");
|
||||
while (!buf && avpriv_atomic_int_get(&pool->refcount) <= avpriv_atomic_int_get(&pool->nb_allocated))
|
||||
buf = get_pool(pool);
|
||||
}
|
||||
|
||||
if (!buf)
|
||||
return pool_alloc_buffer(pool);
|
||||
|
||||
/* keep the first entry, return the rest of the list to the pool */
|
||||
add_to_pool(buf->next);
|
||||
buf->next = NULL;
|
||||
|
||||
ret = av_buffer_create(buf->data, pool->size, pool_release_buffer,
|
||||
buf, 0);
|
||||
if (!ret) {
|
||||
add_to_pool(buf);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
buf = pool->pool;
|
||||
if (buf) {
|
||||
ret = av_buffer_create(buf->data, pool->size, pool_release_buffer,
|
||||
buf, 0);
|
||||
if (ret) {
|
||||
pool->pool = buf->next;
|
||||
buf->next = NULL;
|
||||
}
|
||||
} else {
|
||||
ret = pool_alloc_buffer(pool);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret)
|
||||
avpriv_atomic_int_add_and_fetch(&pool->refcount, 1);
|
||||
|
||||
return ret;
|
||||
}
|
@ -28,15 +28,15 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
/*
|
||||
#include "attributes.h"
|
||||
#include "buffer.h"
|
||||
#include "channel_layout.h"
|
||||
#include "log.h"
|
||||
/*
|
||||
#include "libavutil/samplefmt.h"
|
||||
#include "libavutil/attributes.h"
|
||||
#include "libavutil/avutil.h"
|
||||
#include "libavutil/buffer.h"
|
||||
#include "libavutil/cpu.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/log.h"
|
||||
#include "libavutil/pixfmt.h"
|
||||
*/
|
||||
#include "frame.h"
|
||||
@ -1451,7 +1451,7 @@ typedef struct AVPacket {
|
||||
* stored.
|
||||
* May be NULL, then the packet data is not reference-counted.
|
||||
*/
|
||||
// AVBufferRef *buf;
|
||||
AVBufferRef *buf;
|
||||
/**
|
||||
* Presentation timestamp in AVStream->time_base units; the time at which
|
||||
* the decompressed packet will be presented to the user.
|
||||
@ -1538,7 +1538,7 @@ typedef struct AVCodecContext {
|
||||
* information on struct for av_log
|
||||
* - set by avcodec_alloc_context3
|
||||
*/
|
||||
// const AVClass *av_class;
|
||||
const AVClass *av_class;
|
||||
int log_level_offset;
|
||||
|
||||
enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
|
||||
|
642
ext/at3_standalone/avpacket.c
Normal file
642
ext/at3_standalone/avpacket.c
Normal file
@ -0,0 +1,642 @@
|
||||
/*
|
||||
* AVPacket functions for libavcodec
|
||||
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
|
||||
*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "internal.h"
|
||||
#include "mathematics.h"
|
||||
#include "mem.h"
|
||||
#include "avcodec.h"
|
||||
#include "bytestream.h"
|
||||
#include "internal.h"
|
||||
|
||||
void av_init_packet(AVPacket *pkt)
|
||||
{
|
||||
pkt->pts = AV_NOPTS_VALUE;
|
||||
pkt->dts = AV_NOPTS_VALUE;
|
||||
pkt->pos = -1;
|
||||
pkt->duration = 0;
|
||||
#if FF_API_CONVERGENCE_DURATION
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
pkt->convergence_duration = 0;
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
pkt->flags = 0;
|
||||
pkt->stream_index = 0;
|
||||
pkt->buf = NULL;
|
||||
pkt->side_data = NULL;
|
||||
pkt->side_data_elems = 0;
|
||||
}
|
||||
|
||||
AVPacket *av_packet_alloc(void)
|
||||
{
|
||||
AVPacket *pkt = av_mallocz(sizeof(AVPacket));
|
||||
if (!pkt)
|
||||
return pkt;
|
||||
|
||||
av_packet_unref(pkt);
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
void av_packet_free(AVPacket **pkt)
|
||||
{
|
||||
if (!pkt || !*pkt)
|
||||
return;
|
||||
|
||||
av_packet_unref(*pkt);
|
||||
av_freep(pkt);
|
||||
}
|
||||
|
||||
static int packet_alloc(AVBufferRef **buf, int size)
|
||||
{
|
||||
int ret;
|
||||
if (size < 0 || size >= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
ret = av_buffer_realloc(buf, size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
memset((*buf)->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int av_new_packet(AVPacket *pkt, int size)
|
||||
{
|
||||
AVBufferRef *buf = NULL;
|
||||
int ret = packet_alloc(&buf, size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
av_init_packet(pkt);
|
||||
pkt->buf = buf;
|
||||
pkt->data = buf->data;
|
||||
pkt->size = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void av_shrink_packet(AVPacket *pkt, int size)
|
||||
{
|
||||
if (pkt->size <= size)
|
||||
return;
|
||||
pkt->size = size;
|
||||
memset(pkt->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
}
|
||||
|
||||
int av_grow_packet(AVPacket *pkt, int grow_by)
|
||||
{
|
||||
int new_size;
|
||||
av_assert0((unsigned)pkt->size <= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!pkt->size)
|
||||
return av_new_packet(pkt, grow_by);
|
||||
if ((unsigned)grow_by >
|
||||
INT_MAX - (pkt->size + AV_INPUT_BUFFER_PADDING_SIZE))
|
||||
return -1;
|
||||
|
||||
new_size = pkt->size + grow_by + AV_INPUT_BUFFER_PADDING_SIZE;
|
||||
if (pkt->buf) {
|
||||
int ret = av_buffer_realloc(&pkt->buf, new_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
pkt->buf = av_buffer_alloc(new_size);
|
||||
if (!pkt->buf)
|
||||
return AVERROR(ENOMEM);
|
||||
memcpy(pkt->buf->data, pkt->data, FFMIN(pkt->size, pkt->size + grow_by));
|
||||
}
|
||||
pkt->data = pkt->buf->data;
|
||||
pkt->size += grow_by;
|
||||
memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size)
|
||||
{
|
||||
if (size >= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
pkt->buf = av_buffer_create(data, size + AV_INPUT_BUFFER_PADDING_SIZE,
|
||||
av_buffer_default_free, NULL, 0);
|
||||
if (!pkt->buf)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
pkt->data = data;
|
||||
pkt->size = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if FF_API_AVPACKET_OLD_API
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
#define ALLOC_MALLOC(data, size) data = av_malloc(size)
|
||||
#define ALLOC_BUF(data, size) \
|
||||
do { \
|
||||
av_buffer_realloc(&pkt->buf, size); \
|
||||
data = pkt->buf ? pkt->buf->data : NULL; \
|
||||
} while (0)
|
||||
|
||||
#define DUP_DATA(dst, src, size, padding, ALLOC) \
|
||||
do { \
|
||||
void *data; \
|
||||
if (padding) { \
|
||||
if ((unsigned)(size) > \
|
||||
(unsigned)(size) + AV_INPUT_BUFFER_PADDING_SIZE) \
|
||||
goto failed_alloc; \
|
||||
ALLOC(data, size + AV_INPUT_BUFFER_PADDING_SIZE); \
|
||||
} else { \
|
||||
ALLOC(data, size); \
|
||||
} \
|
||||
if (!data) \
|
||||
goto failed_alloc; \
|
||||
memcpy(data, src, size); \
|
||||
if (padding) \
|
||||
memset((uint8_t *)data + size, 0, \
|
||||
AV_INPUT_BUFFER_PADDING_SIZE); \
|
||||
dst = data; \
|
||||
} while (0)
|
||||
|
||||
/* Makes duplicates of data, side_data, but does not copy any other fields */
|
||||
static int copy_packet_data(AVPacket *pkt, const AVPacket *src, int dup)
|
||||
{
|
||||
pkt->data = NULL;
|
||||
pkt->side_data = NULL;
|
||||
if (pkt->buf) {
|
||||
AVBufferRef *ref = av_buffer_ref(src->buf);
|
||||
if (!ref)
|
||||
return AVERROR(ENOMEM);
|
||||
pkt->buf = ref;
|
||||
pkt->data = ref->data;
|
||||
} else {
|
||||
DUP_DATA(pkt->data, src->data, pkt->size, 1, ALLOC_BUF);
|
||||
}
|
||||
if (pkt->side_data_elems && dup)
|
||||
pkt->side_data = src->side_data;
|
||||
if (pkt->side_data_elems && !dup) {
|
||||
return av_copy_packet_side_data(pkt, src);
|
||||
}
|
||||
return 0;
|
||||
|
||||
failed_alloc:
|
||||
av_packet_unref(pkt);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
int av_copy_packet_side_data(AVPacket *pkt, const AVPacket *src)
|
||||
{
|
||||
if (src->side_data_elems) {
|
||||
int i;
|
||||
DUP_DATA(pkt->side_data, src->side_data,
|
||||
src->side_data_elems * sizeof(*src->side_data), 0, ALLOC_MALLOC);
|
||||
if (src != pkt) {
|
||||
memset(pkt->side_data, 0,
|
||||
src->side_data_elems * sizeof(*src->side_data));
|
||||
}
|
||||
for (i = 0; i < src->side_data_elems; i++) {
|
||||
DUP_DATA(pkt->side_data[i].data, src->side_data[i].data,
|
||||
src->side_data[i].size, 1, ALLOC_MALLOC);
|
||||
pkt->side_data[i].size = src->side_data[i].size;
|
||||
pkt->side_data[i].type = src->side_data[i].type;
|
||||
}
|
||||
}
|
||||
pkt->side_data_elems = src->side_data_elems;
|
||||
return 0;
|
||||
|
||||
failed_alloc:
|
||||
av_packet_unref(pkt);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
||||
int av_dup_packet(AVPacket *pkt)
|
||||
{
|
||||
AVPacket tmp_pkt;
|
||||
|
||||
if (!pkt->buf && pkt->data) {
|
||||
tmp_pkt = *pkt;
|
||||
return copy_packet_data(pkt, &tmp_pkt, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int av_copy_packet(AVPacket *dst, const AVPacket *src)
|
||||
{
|
||||
*dst = *src;
|
||||
return copy_packet_data(dst, src, 0);
|
||||
}
|
||||
|
||||
void av_packet_free_side_data(AVPacket *pkt)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < pkt->side_data_elems; i++)
|
||||
av_freep(&pkt->side_data[i].data);
|
||||
av_freep(&pkt->side_data);
|
||||
pkt->side_data_elems = 0;
|
||||
}
|
||||
|
||||
#if FF_API_AVPACKET_OLD_API
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
void av_free_packet(AVPacket *pkt)
|
||||
{
|
||||
if (pkt) {
|
||||
if (pkt->buf)
|
||||
av_buffer_unref(&pkt->buf);
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
|
||||
av_packet_free_side_data(pkt);
|
||||
}
|
||||
}
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
||||
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
|
||||
uint8_t *data, size_t size)
|
||||
{
|
||||
int elems = pkt->side_data_elems;
|
||||
|
||||
if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data))
|
||||
return AVERROR(ERANGE);
|
||||
|
||||
pkt->side_data = av_realloc(pkt->side_data,
|
||||
(elems + 1) * sizeof(*pkt->side_data));
|
||||
if (!pkt->side_data)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
pkt->side_data[elems].data = data;
|
||||
pkt->side_data[elems].size = size;
|
||||
pkt->side_data[elems].type = type;
|
||||
pkt->side_data_elems++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
|
||||
int size)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *data;
|
||||
|
||||
if ((unsigned)size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
|
||||
return NULL;
|
||||
data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
ret = av_packet_add_side_data(pkt, type, data, size);
|
||||
if (ret < 0) {
|
||||
av_freep(&data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t *av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
|
||||
int *size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pkt->side_data_elems; i++) {
|
||||
if (pkt->side_data[i].type == type) {
|
||||
if (size)
|
||||
*size = pkt->side_data[i].size;
|
||||
return pkt->side_data[i].data;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *av_packet_side_data_name(enum AVPacketSideDataType type)
|
||||
{
|
||||
switch(type) {
|
||||
case AV_PKT_DATA_PALETTE: return "Palette";
|
||||
case AV_PKT_DATA_NEW_EXTRADATA: return "New Extradata";
|
||||
case AV_PKT_DATA_PARAM_CHANGE: return "Param Change";
|
||||
case AV_PKT_DATA_H263_MB_INFO: return "H263 MB Info";
|
||||
case AV_PKT_DATA_REPLAYGAIN: return "Replay Gain";
|
||||
case AV_PKT_DATA_DISPLAYMATRIX: return "Display Matrix";
|
||||
case AV_PKT_DATA_STEREO3D: return "Stereo 3D";
|
||||
case AV_PKT_DATA_AUDIO_SERVICE_TYPE: return "Audio Service Type";
|
||||
case AV_PKT_DATA_SKIP_SAMPLES: return "Skip Samples";
|
||||
case AV_PKT_DATA_JP_DUALMONO: return "JP Dual Mono";
|
||||
case AV_PKT_DATA_STRINGS_METADATA: return "Strings Metadata";
|
||||
case AV_PKT_DATA_SUBTITLE_POSITION: return "Subtitle Position";
|
||||
case AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL: return "Matroska BlockAdditional";
|
||||
case AV_PKT_DATA_WEBVTT_IDENTIFIER: return "WebVTT ID";
|
||||
case AV_PKT_DATA_WEBVTT_SETTINGS: return "WebVTT Settings";
|
||||
case AV_PKT_DATA_METADATA_UPDATE: return "Metadata Update";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL
|
||||
|
||||
int av_packet_merge_side_data(AVPacket *pkt){
|
||||
if(pkt->side_data_elems){
|
||||
AVBufferRef *buf;
|
||||
int i;
|
||||
uint8_t *p;
|
||||
uint64_t size= pkt->size + 8LL + AV_INPUT_BUFFER_PADDING_SIZE;
|
||||
AVPacket old= *pkt;
|
||||
for (i=0; i<old.side_data_elems; i++) {
|
||||
size += old.side_data[i].size + 5LL;
|
||||
}
|
||||
if (size > INT_MAX)
|
||||
return AVERROR(EINVAL);
|
||||
buf = av_buffer_alloc(size);
|
||||
if (!buf)
|
||||
return AVERROR(ENOMEM);
|
||||
pkt->buf = buf;
|
||||
pkt->data = p = buf->data;
|
||||
pkt->size = size - AV_INPUT_BUFFER_PADDING_SIZE;
|
||||
bytestream_put_buffer(&p, old.data, old.size);
|
||||
for (i=old.side_data_elems-1; i>=0; i--) {
|
||||
bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size);
|
||||
bytestream_put_be32(&p, old.side_data[i].size);
|
||||
*p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128);
|
||||
}
|
||||
bytestream_put_be64(&p, FF_MERGE_MARKER);
|
||||
av_assert0(p-pkt->data == pkt->size);
|
||||
memset(p, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
av_packet_unref(&old);
|
||||
pkt->side_data_elems = 0;
|
||||
pkt->side_data = NULL;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int av_packet_split_side_data(AVPacket *pkt){
|
||||
if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
|
||||
int i;
|
||||
unsigned int size;
|
||||
uint8_t *p;
|
||||
|
||||
p = pkt->data + pkt->size - 8 - 5;
|
||||
for (i=1; ; i++){
|
||||
size = AV_RB32(p);
|
||||
if (size>INT_MAX - 5 || p - pkt->data < size)
|
||||
return 0;
|
||||
if (p[4]&128)
|
||||
break;
|
||||
if (p - pkt->data < size + 5)
|
||||
return 0;
|
||||
p-= size+5;
|
||||
}
|
||||
|
||||
pkt->side_data = av_malloc_array(i, sizeof(*pkt->side_data));
|
||||
if (!pkt->side_data)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
p= pkt->data + pkt->size - 8 - 5;
|
||||
for (i=0; ; i++){
|
||||
size= AV_RB32(p);
|
||||
av_assert0(size<=INT_MAX - 5 && p - pkt->data >= size);
|
||||
pkt->side_data[i].data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
pkt->side_data[i].size = size;
|
||||
pkt->side_data[i].type = p[4]&127;
|
||||
if (!pkt->side_data[i].data)
|
||||
return AVERROR(ENOMEM);
|
||||
memcpy(pkt->side_data[i].data, p-size, size);
|
||||
pkt->size -= size + 5;
|
||||
if(p[4]&128)
|
||||
break;
|
||||
p-= size+5;
|
||||
}
|
||||
pkt->size -= 8;
|
||||
pkt->side_data_elems = i+1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size)
|
||||
{
|
||||
AVDictionaryEntry *t = NULL;
|
||||
uint8_t *data = NULL;
|
||||
*size = 0;
|
||||
|
||||
if (!dict)
|
||||
return NULL;
|
||||
|
||||
while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) {
|
||||
const size_t keylen = strlen(t->key);
|
||||
const size_t valuelen = strlen(t->value);
|
||||
const size_t new_size = *size + keylen + 1 + valuelen + 1;
|
||||
uint8_t *const new_data = av_realloc(data, new_size);
|
||||
|
||||
if (!new_data)
|
||||
goto fail;
|
||||
data = new_data;
|
||||
if (new_size > INT_MAX)
|
||||
goto fail;
|
||||
|
||||
memcpy(data + *size, t->key, keylen + 1);
|
||||
memcpy(data + *size + keylen + 1, t->value, valuelen + 1);
|
||||
|
||||
*size = new_size;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
fail:
|
||||
av_freep(&data);
|
||||
*size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict)
|
||||
{
|
||||
const uint8_t *end = data + size;
|
||||
int ret = 0;
|
||||
|
||||
if (!dict || !data || !size)
|
||||
return ret;
|
||||
if (size && end[-1])
|
||||
return AVERROR_INVALIDDATA;
|
||||
while (data < end) {
|
||||
const uint8_t *key = data;
|
||||
const uint8_t *val = data + strlen(key) + 1;
|
||||
|
||||
if (val >= end)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
ret = av_dict_set(dict, key, val, 0);
|
||||
if (ret < 0)
|
||||
break;
|
||||
data = val + strlen(val) + 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
|
||||
int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pkt->side_data_elems; i++) {
|
||||
if (pkt->side_data[i].type == type) {
|
||||
if (size > pkt->side_data[i].size)
|
||||
return AVERROR(ENOMEM);
|
||||
pkt->side_data[i].size = size;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return AVERROR(ENOENT);
|
||||
}
|
||||
|
||||
int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
dst->pts = src->pts;
|
||||
dst->dts = src->dts;
|
||||
dst->pos = src->pos;
|
||||
dst->duration = src->duration;
|
||||
#if FF_API_CONVERGENCE_DURATION
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
dst->convergence_duration = src->convergence_duration;
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
dst->flags = src->flags;
|
||||
dst->stream_index = src->stream_index;
|
||||
|
||||
for (i = 0; i < src->side_data_elems; i++) {
|
||||
enum AVPacketSideDataType type = src->side_data[i].type;
|
||||
int size = src->side_data[i].size;
|
||||
uint8_t *src_data = src->side_data[i].data;
|
||||
uint8_t *dst_data = av_packet_new_side_data(dst, type, size);
|
||||
|
||||
if (!dst_data) {
|
||||
av_packet_free_side_data(dst);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
memcpy(dst_data, src_data, size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void av_packet_unref(AVPacket *pkt)
|
||||
{
|
||||
av_packet_free_side_data(pkt);
|
||||
av_buffer_unref(&pkt->buf);
|
||||
av_init_packet(pkt);
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
}
|
||||
|
||||
int av_packet_ref(AVPacket *dst, const AVPacket *src)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = av_packet_copy_props(dst, src);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!src->buf) {
|
||||
ret = packet_alloc(&dst->buf, src->size);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
memcpy(dst->buf->data, src->data, src->size);
|
||||
} else {
|
||||
dst->buf = av_buffer_ref(src->buf);
|
||||
if (!dst->buf) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
dst->size = src->size;
|
||||
dst->data = dst->buf->data;
|
||||
return 0;
|
||||
fail:
|
||||
av_packet_free_side_data(dst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVPacket *av_packet_clone(AVPacket *src)
|
||||
{
|
||||
AVPacket *ret = av_packet_alloc();
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
if (av_packet_ref(ret, src))
|
||||
av_packet_free(&ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
|
||||
{
|
||||
*dst = *src;
|
||||
av_init_packet(src);
|
||||
}
|
||||
|
||||
void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb)
|
||||
{
|
||||
if (pkt->pts != AV_NOPTS_VALUE)
|
||||
pkt->pts = av_rescale_q(pkt->pts, src_tb, dst_tb);
|
||||
if (pkt->dts != AV_NOPTS_VALUE)
|
||||
pkt->dts = av_rescale_q(pkt->dts, src_tb, dst_tb);
|
||||
if (pkt->duration > 0)
|
||||
pkt->duration = av_rescale_q(pkt->duration, src_tb, dst_tb);
|
||||
#if FF_API_CONVERGENCE_DURATION
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
if (pkt->convergence_duration > 0)
|
||||
pkt->convergence_duration = av_rescale_q(pkt->convergence_duration, src_tb, dst_tb);
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
}
|
||||
|
||||
int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type)
|
||||
{
|
||||
uint8_t *side_data;
|
||||
int side_data_size;
|
||||
int i;
|
||||
|
||||
side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, &side_data_size);
|
||||
if (!side_data) {
|
||||
side_data_size = 4+4+8*error_count;
|
||||
side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
|
||||
side_data_size);
|
||||
}
|
||||
|
||||
if (!side_data || side_data_size < 4+4+8*error_count)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
AV_WL32(side_data , quality );
|
||||
side_data[4] = pict_type;
|
||||
side_data[5] = error_count;
|
||||
for (i = 0; i<error_count; i++)
|
||||
AV_WL64(side_data+8 + 8*i , error[i]);
|
||||
|
||||
return 0;
|
||||
}
|
500
ext/at3_standalone/avstring.c
Normal file
500
ext/at3_standalone/avstring.c
Normal file
@ -0,0 +1,500 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
|
||||
* Copyright (c) 2007 Mans Rullgard
|
||||
*
|
||||
* 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 <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "mem.h"
|
||||
#include "avstring.h"
|
||||
#include "bprint.h"
|
||||
|
||||
int av_strstart(const char *str, const char *pfx, const char **ptr)
|
||||
{
|
||||
while (*pfx && *pfx == *str) {
|
||||
pfx++;
|
||||
str++;
|
||||
}
|
||||
if (!*pfx && ptr)
|
||||
*ptr = str;
|
||||
return !*pfx;
|
||||
}
|
||||
|
||||
int av_stristart(const char *str, const char *pfx, const char **ptr)
|
||||
{
|
||||
while (*pfx && av_toupper((unsigned)*pfx) == av_toupper((unsigned)*str)) {
|
||||
pfx++;
|
||||
str++;
|
||||
}
|
||||
if (!*pfx && ptr)
|
||||
*ptr = str;
|
||||
return !*pfx;
|
||||
}
|
||||
|
||||
char *av_stristr(const char *s1, const char *s2)
|
||||
{
|
||||
if (!*s2)
|
||||
return (char*)(intptr_t)s1;
|
||||
|
||||
do
|
||||
if (av_stristart(s1, s2, NULL))
|
||||
return (char*)(intptr_t)s1;
|
||||
while (*s1++);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *av_strnstr(const char *haystack, const char *needle, size_t hay_length)
|
||||
{
|
||||
size_t needle_len = strlen(needle);
|
||||
if (!needle_len)
|
||||
return (char*)haystack;
|
||||
while (hay_length >= needle_len) {
|
||||
hay_length--;
|
||||
if (!memcmp(haystack, needle, needle_len))
|
||||
return (char*)haystack;
|
||||
haystack++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t av_strlcpy(char *dst, const char *src, size_t size)
|
||||
{
|
||||
size_t len = 0;
|
||||
while (++len < size && *src)
|
||||
*dst++ = *src++;
|
||||
if (len <= size)
|
||||
*dst = 0;
|
||||
return len + strlen(src) - 1;
|
||||
}
|
||||
|
||||
size_t av_strlcat(char *dst, const char *src, size_t size)
|
||||
{
|
||||
size_t len = strlen(dst);
|
||||
if (size <= len + 1)
|
||||
return len + strlen(src);
|
||||
return len + av_strlcpy(dst + len, src, size - len);
|
||||
}
|
||||
|
||||
size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...)
|
||||
{
|
||||
size_t len = strlen(dst);
|
||||
va_list vl;
|
||||
|
||||
va_start(vl, fmt);
|
||||
len += vsnprintf(dst + len, size > len ? size - len : 0, fmt, vl);
|
||||
va_end(vl);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
char *av_asprintf(const char *fmt, ...)
|
||||
{
|
||||
char *p = NULL;
|
||||
va_list va;
|
||||
int len;
|
||||
|
||||
va_start(va, fmt);
|
||||
len = vsnprintf(NULL, 0, fmt, va);
|
||||
va_end(va);
|
||||
if (len < 0)
|
||||
goto end;
|
||||
|
||||
p = av_malloc(len + 1);
|
||||
if (!p)
|
||||
goto end;
|
||||
|
||||
va_start(va, fmt);
|
||||
len = vsnprintf(p, len + 1, fmt, va);
|
||||
va_end(va);
|
||||
if (len < 0)
|
||||
av_freep(&p);
|
||||
|
||||
end:
|
||||
return p;
|
||||
}
|
||||
|
||||
char *av_d2str(double d)
|
||||
{
|
||||
char *str = av_malloc(16);
|
||||
if (str)
|
||||
snprintf(str, 16, "%f", d);
|
||||
return str;
|
||||
}
|
||||
|
||||
#define WHITESPACES " \n\t"
|
||||
|
||||
char *av_get_token(const char **buf, const char *term)
|
||||
{
|
||||
char *out = av_malloc(strlen(*buf) + 1);
|
||||
char *ret = out, *end = out;
|
||||
const char *p = *buf;
|
||||
if (!out)
|
||||
return NULL;
|
||||
p += strspn(p, WHITESPACES);
|
||||
|
||||
while (*p && !strspn(p, term)) {
|
||||
char c = *p++;
|
||||
if (c == '\\' && *p) {
|
||||
*out++ = *p++;
|
||||
end = out;
|
||||
} else if (c == '\'') {
|
||||
while (*p && *p != '\'')
|
||||
*out++ = *p++;
|
||||
if (*p) {
|
||||
p++;
|
||||
end = out;
|
||||
}
|
||||
} else {
|
||||
*out++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
*out-- = 0;
|
||||
while (out >= end && strspn(out, WHITESPACES));
|
||||
|
||||
*buf = p;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *av_strtok(char *s, const char *delim, char **saveptr)
|
||||
{
|
||||
char *tok;
|
||||
|
||||
if (!s && !(s = *saveptr))
|
||||
return NULL;
|
||||
|
||||
/* skip leading delimiters */
|
||||
s += strspn(s, delim);
|
||||
|
||||
/* s now points to the first non delimiter char, or to the end of the string */
|
||||
if (!*s) {
|
||||
*saveptr = NULL;
|
||||
return NULL;
|
||||
}
|
||||
tok = s++;
|
||||
|
||||
/* skip non delimiters */
|
||||
s += strcspn(s, delim);
|
||||
if (*s) {
|
||||
*s = 0;
|
||||
*saveptr = s+1;
|
||||
} else {
|
||||
*saveptr = NULL;
|
||||
}
|
||||
|
||||
return tok;
|
||||
}
|
||||
|
||||
int av_strcasecmp(const char *a, const char *b)
|
||||
{
|
||||
uint8_t c1, c2;
|
||||
do {
|
||||
c1 = av_tolower(*a++);
|
||||
c2 = av_tolower(*b++);
|
||||
} while (c1 && c1 == c2);
|
||||
return c1 - c2;
|
||||
}
|
||||
|
||||
int av_strncasecmp(const char *a, const char *b, size_t n)
|
||||
{
|
||||
const char *end = a + n;
|
||||
uint8_t c1, c2;
|
||||
do {
|
||||
c1 = av_tolower(*a++);
|
||||
c2 = av_tolower(*b++);
|
||||
} while (a < end && c1 && c1 == c2);
|
||||
return c1 - c2;
|
||||
}
|
||||
|
||||
const char *av_basename(const char *path)
|
||||
{
|
||||
char *p = strrchr(path, '/');
|
||||
|
||||
#if HAVE_DOS_PATHS
|
||||
char *q = strrchr(path, '\\');
|
||||
char *d = strchr(path, ':');
|
||||
|
||||
p = FFMAX3(p, q, d);
|
||||
#endif
|
||||
|
||||
if (!p)
|
||||
return path;
|
||||
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
const char *av_dirname(char *path)
|
||||
{
|
||||
char *p = strrchr(path, '/');
|
||||
|
||||
#if HAVE_DOS_PATHS
|
||||
char *q = strrchr(path, '\\');
|
||||
char *d = strchr(path, ':');
|
||||
|
||||
d = d ? d + 1 : d;
|
||||
|
||||
p = FFMAX3(p, q, d);
|
||||
#endif
|
||||
|
||||
if (!p)
|
||||
return ".";
|
||||
|
||||
*p = '\0';
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
char *av_append_path_component(const char *path, const char *component)
|
||||
{
|
||||
size_t p_len, c_len;
|
||||
char *fullpath;
|
||||
|
||||
if (!path)
|
||||
return av_strdup(component);
|
||||
if (!component)
|
||||
return av_strdup(path);
|
||||
|
||||
p_len = strlen(path);
|
||||
c_len = strlen(component);
|
||||
if (p_len > SIZE_MAX - c_len || p_len + c_len > SIZE_MAX - 2)
|
||||
return NULL;
|
||||
fullpath = av_malloc(p_len + c_len + 2);
|
||||
if (fullpath) {
|
||||
if (p_len) {
|
||||
av_strlcpy(fullpath, path, p_len + 1);
|
||||
if (c_len) {
|
||||
if (fullpath[p_len - 1] != '/' && component[0] != '/')
|
||||
fullpath[p_len++] = '/';
|
||||
else if (fullpath[p_len - 1] == '/' && component[0] == '/')
|
||||
p_len--;
|
||||
}
|
||||
}
|
||||
av_strlcpy(&fullpath[p_len], component, c_len + 1);
|
||||
fullpath[p_len + c_len] = 0;
|
||||
}
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
int av_escape(char **dst, const char *src, const char *special_chars,
|
||||
enum AVEscapeMode mode, int flags)
|
||||
{
|
||||
AVBPrint dstbuf;
|
||||
|
||||
av_bprint_init(&dstbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
|
||||
av_bprint_escape(&dstbuf, src, special_chars, mode, flags);
|
||||
|
||||
if (!av_bprint_is_complete(&dstbuf)) {
|
||||
av_bprint_finalize(&dstbuf, NULL);
|
||||
return AVERROR(ENOMEM);
|
||||
} else {
|
||||
av_bprint_finalize(&dstbuf, dst);
|
||||
return dstbuf.len;
|
||||
}
|
||||
}
|
||||
|
||||
int av_match_name(const char *name, const char *names)
|
||||
{
|
||||
const char *p;
|
||||
int len, namelen;
|
||||
|
||||
if (!name || !names)
|
||||
return 0;
|
||||
|
||||
namelen = strlen(name);
|
||||
while (*names) {
|
||||
int negate = '-' == *names;
|
||||
p = strchr(names, ',');
|
||||
if (!p)
|
||||
p = names + strlen(names);
|
||||
names += negate;
|
||||
len = FFMAX(p - names, namelen);
|
||||
if (!av_strncasecmp(name, names, len) || !strncmp("ALL", names, FFMAX(3, p - names)))
|
||||
return !negate;
|
||||
names = p + (*p == ',');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end,
|
||||
unsigned int flags)
|
||||
{
|
||||
const uint8_t *p = *bufp;
|
||||
uint32_t top;
|
||||
uint64_t code;
|
||||
int ret = 0, tail_len;
|
||||
uint32_t overlong_encoding_mins[6] = {
|
||||
0x00000000, 0x00000080, 0x00000800, 0x00010000, 0x00200000, 0x04000000,
|
||||
};
|
||||
|
||||
if (p >= buf_end)
|
||||
return 0;
|
||||
|
||||
code = *p++;
|
||||
|
||||
/* first sequence byte starts with 10, or is 1111-1110 or 1111-1111,
|
||||
which is not admitted */
|
||||
if ((code & 0xc0) == 0x80 || code >= 0xFE) {
|
||||
ret = AVERROR(EILSEQ);
|
||||
goto end;
|
||||
}
|
||||
top = (code & 128) >> 1;
|
||||
|
||||
tail_len = 0;
|
||||
while (code & top) {
|
||||
int tmp;
|
||||
tail_len++;
|
||||
if (p >= buf_end) {
|
||||
(*bufp) ++;
|
||||
return AVERROR(EILSEQ); /* incomplete sequence */
|
||||
}
|
||||
|
||||
/* we assume the byte to be in the form 10xx-xxxx */
|
||||
tmp = *p++ - 128; /* strip leading 1 */
|
||||
if (tmp>>6) {
|
||||
(*bufp) ++;
|
||||
return AVERROR(EILSEQ);
|
||||
}
|
||||
code = (code<<6) + tmp;
|
||||
top <<= 5;
|
||||
}
|
||||
code &= (top << 1) - 1;
|
||||
|
||||
/* check for overlong encodings */
|
||||
av_assert0(tail_len <= 5);
|
||||
if (code < overlong_encoding_mins[tail_len]) {
|
||||
ret = AVERROR(EILSEQ);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (code >= 1U<<31) {
|
||||
ret = AVERROR(EILSEQ); /* out-of-range value */
|
||||
goto end;
|
||||
}
|
||||
|
||||
*codep = code;
|
||||
|
||||
if (code > 0x10FFFF &&
|
||||
!(flags & AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES))
|
||||
ret = AVERROR(EILSEQ);
|
||||
if (code < 0x20 && code != 0x9 && code != 0xA && code != 0xD &&
|
||||
flags & AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES)
|
||||
ret = AVERROR(EILSEQ);
|
||||
if (code >= 0xD800 && code <= 0xDFFF &&
|
||||
!(flags & AV_UTF8_FLAG_ACCEPT_SURROGATES))
|
||||
ret = AVERROR(EILSEQ);
|
||||
if ((code == 0xFFFE || code == 0xFFFF) &&
|
||||
!(flags & AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS))
|
||||
ret = AVERROR(EILSEQ);
|
||||
|
||||
end:
|
||||
*bufp = p;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int av_match_list(const char *name, const char *list, char separator)
|
||||
{
|
||||
const char *p, *q;
|
||||
|
||||
for (p = name; p && *p; ) {
|
||||
for (q = list; q && *q; ) {
|
||||
int k;
|
||||
for (k = 0; p[k] == q[k] || (p[k]*q[k] == 0 && p[k]+q[k] == separator); k++)
|
||||
if (k && (!p[k] || p[k] == separator))
|
||||
return 1;
|
||||
q = strchr(q, separator);
|
||||
q += !!q;
|
||||
}
|
||||
p = strchr(p, separator);
|
||||
p += !!p;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
char *fullpath;
|
||||
static const char * const strings[] = {
|
||||
"''",
|
||||
"",
|
||||
":",
|
||||
"\\",
|
||||
"'",
|
||||
" '' :",
|
||||
" '' '' :",
|
||||
"foo '' :",
|
||||
"'foo'",
|
||||
"foo ",
|
||||
" ' foo ' ",
|
||||
"foo\\",
|
||||
"foo': blah:blah",
|
||||
"foo\\: blah:blah",
|
||||
"foo\'",
|
||||
"'foo : ' :blahblah",
|
||||
"\\ :blah",
|
||||
" foo",
|
||||
" foo ",
|
||||
" foo \\ ",
|
||||
"foo ':blah",
|
||||
" foo bar : blahblah",
|
||||
"\\f\\o\\o",
|
||||
"'foo : \\ \\ ' : blahblah",
|
||||
"'\\fo\\o:': blahblah",
|
||||
"\\'fo\\o\\:': foo ' :blahblah"
|
||||
};
|
||||
|
||||
printf("Testing av_get_token()\n");
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(strings); i++) {
|
||||
const char *p = strings[i];
|
||||
char *q;
|
||||
printf("|%s|", p);
|
||||
q = av_get_token(&p, ":");
|
||||
printf(" -> |%s|", q);
|
||||
printf(" + |%s|\n", p);
|
||||
av_free(q);
|
||||
}
|
||||
|
||||
printf("Testing av_append_path_component()\n");
|
||||
#define TEST_APPEND_PATH_COMPONENT(path, component, expected) \
|
||||
fullpath = av_append_path_component((path), (component)); \
|
||||
printf("%s = %s\n", fullpath ? fullpath : "(null)", expected); \
|
||||
av_free(fullpath);
|
||||
TEST_APPEND_PATH_COMPONENT(NULL, NULL, "(null)")
|
||||
TEST_APPEND_PATH_COMPONENT("path", NULL, "path");
|
||||
TEST_APPEND_PATH_COMPONENT(NULL, "comp", "comp");
|
||||
TEST_APPEND_PATH_COMPONENT("path", "comp", "path/comp");
|
||||
TEST_APPEND_PATH_COMPONENT("path/", "comp", "path/comp");
|
||||
TEST_APPEND_PATH_COMPONENT("path", "/comp", "path/comp");
|
||||
TEST_APPEND_PATH_COMPONENT("path/", "/comp", "path/comp");
|
||||
TEST_APPEND_PATH_COMPONENT("path/path2/", "/comp/comp2", "path/path2/comp/comp2");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
402
ext/at3_standalone/avstring.h
Normal file
402
ext/at3_standalone/avstring.h
Normal file
@ -0,0 +1,402 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Mans Rullgard
|
||||
*
|
||||
* 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 AVUTIL_AVSTRING_H
|
||||
#define AVUTIL_AVSTRING_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "attributes.h"
|
||||
|
||||
/**
|
||||
* @addtogroup lavu_string
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return non-zero if pfx is a prefix of str. If it is, *ptr is set to
|
||||
* the address of the first character in str after the prefix.
|
||||
*
|
||||
* @param str input string
|
||||
* @param pfx prefix to test
|
||||
* @param ptr updated if the prefix is matched inside str
|
||||
* @return non-zero if the prefix matches, zero otherwise
|
||||
*/
|
||||
int av_strstart(const char *str, const char *pfx, const char **ptr);
|
||||
|
||||
/**
|
||||
* Return non-zero if pfx is a prefix of str independent of case. If
|
||||
* it is, *ptr is set to the address of the first character in str
|
||||
* after the prefix.
|
||||
*
|
||||
* @param str input string
|
||||
* @param pfx prefix to test
|
||||
* @param ptr updated if the prefix is matched inside str
|
||||
* @return non-zero if the prefix matches, zero otherwise
|
||||
*/
|
||||
int av_stristart(const char *str, const char *pfx, const char **ptr);
|
||||
|
||||
/**
|
||||
* Locate the first case-independent occurrence in the string haystack
|
||||
* of the string needle. A zero-length string needle is considered to
|
||||
* match at the start of haystack.
|
||||
*
|
||||
* This function is a case-insensitive version of the standard strstr().
|
||||
*
|
||||
* @param haystack string to search in
|
||||
* @param needle string to search for
|
||||
* @return pointer to the located match within haystack
|
||||
* or a null pointer if no match
|
||||
*/
|
||||
char *av_stristr(const char *haystack, const char *needle);
|
||||
|
||||
/**
|
||||
* Locate the first occurrence of the string needle in the string haystack
|
||||
* where not more than hay_length characters are searched. A zero-length
|
||||
* string needle is considered to match at the start of haystack.
|
||||
*
|
||||
* This function is a length-limited version of the standard strstr().
|
||||
*
|
||||
* @param haystack string to search in
|
||||
* @param needle string to search for
|
||||
* @param hay_length length of string to search in
|
||||
* @return pointer to the located match within haystack
|
||||
* or a null pointer if no match
|
||||
*/
|
||||
char *av_strnstr(const char *haystack, const char *needle, size_t hay_length);
|
||||
|
||||
/**
|
||||
* Copy the string src to dst, but no more than size - 1 bytes, and
|
||||
* null-terminate dst.
|
||||
*
|
||||
* This function is the same as BSD strlcpy().
|
||||
*
|
||||
* @param dst destination buffer
|
||||
* @param src source string
|
||||
* @param size size of destination buffer
|
||||
* @return the length of src
|
||||
*
|
||||
* @warning since the return value is the length of src, src absolutely
|
||||
* _must_ be a properly 0-terminated string, otherwise this will read beyond
|
||||
* the end of the buffer and possibly crash.
|
||||
*/
|
||||
size_t av_strlcpy(char *dst, const char *src, size_t size);
|
||||
|
||||
/**
|
||||
* Append the string src to the string dst, but to a total length of
|
||||
* no more than size - 1 bytes, and null-terminate dst.
|
||||
*
|
||||
* This function is similar to BSD strlcat(), but differs when
|
||||
* size <= strlen(dst).
|
||||
*
|
||||
* @param dst destination buffer
|
||||
* @param src source string
|
||||
* @param size size of destination buffer
|
||||
* @return the total length of src and dst
|
||||
*
|
||||
* @warning since the return value use the length of src and dst, these
|
||||
* absolutely _must_ be a properly 0-terminated strings, otherwise this
|
||||
* will read beyond the end of the buffer and possibly crash.
|
||||
*/
|
||||
size_t av_strlcat(char *dst, const char *src, size_t size);
|
||||
|
||||
/**
|
||||
* Append output to a string, according to a format. Never write out of
|
||||
* the destination buffer, and always put a terminating 0 within
|
||||
* the buffer.
|
||||
* @param dst destination buffer (string to which the output is
|
||||
* appended)
|
||||
* @param size total size of the destination buffer
|
||||
* @param fmt printf-compatible format string, specifying how the
|
||||
* following parameters are used
|
||||
* @return the length of the string that would have been generated
|
||||
* if enough space had been available
|
||||
*/
|
||||
size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...) av_printf_format(3, 4);
|
||||
|
||||
/**
|
||||
* Get the count of continuous non zero chars starting from the beginning.
|
||||
*
|
||||
* @param len maximum number of characters to check in the string, that
|
||||
* is the maximum value which is returned by the function
|
||||
*/
|
||||
static inline size_t av_strnlen(const char *s, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < len && s[i]; i++)
|
||||
;
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print arguments following specified format into a large enough auto
|
||||
* allocated buffer. It is similar to GNU asprintf().
|
||||
* @param fmt printf-compatible format string, specifying how the
|
||||
* following parameters are used.
|
||||
* @return the allocated string
|
||||
* @note You have to free the string yourself with av_free().
|
||||
*/
|
||||
char *av_asprintf(const char *fmt, ...) av_printf_format(1, 2);
|
||||
|
||||
/**
|
||||
* Convert a number to a av_malloced string.
|
||||
*/
|
||||
char *av_d2str(double d);
|
||||
|
||||
/**
|
||||
* Unescape the given string until a non escaped terminating char,
|
||||
* and return the token corresponding to the unescaped string.
|
||||
*
|
||||
* The normal \ and ' escaping is supported. Leading and trailing
|
||||
* whitespaces are removed, unless they are escaped with '\' or are
|
||||
* enclosed between ''.
|
||||
*
|
||||
* @param buf the buffer to parse, buf will be updated to point to the
|
||||
* terminating char
|
||||
* @param term a 0-terminated list of terminating chars
|
||||
* @return the malloced unescaped string, which must be av_freed by
|
||||
* the user, NULL in case of allocation failure
|
||||
*/
|
||||
char *av_get_token(const char **buf, const char *term);
|
||||
|
||||
/**
|
||||
* Split the string into several tokens which can be accessed by
|
||||
* successive calls to av_strtok().
|
||||
*
|
||||
* A token is defined as a sequence of characters not belonging to the
|
||||
* set specified in delim.
|
||||
*
|
||||
* On the first call to av_strtok(), s should point to the string to
|
||||
* parse, and the value of saveptr is ignored. In subsequent calls, s
|
||||
* should be NULL, and saveptr should be unchanged since the previous
|
||||
* call.
|
||||
*
|
||||
* This function is similar to strtok_r() defined in POSIX.1.
|
||||
*
|
||||
* @param s the string to parse, may be NULL
|
||||
* @param delim 0-terminated list of token delimiters, must be non-NULL
|
||||
* @param saveptr user-provided pointer which points to stored
|
||||
* information necessary for av_strtok() to continue scanning the same
|
||||
* string. saveptr is updated to point to the next character after the
|
||||
* first delimiter found, or to NULL if the string was terminated
|
||||
* @return the found token, or NULL when no token is found
|
||||
*/
|
||||
char *av_strtok(char *s, const char *delim, char **saveptr);
|
||||
|
||||
/**
|
||||
* Locale-independent conversion of ASCII isdigit.
|
||||
*/
|
||||
static inline av_const int av_isdigit(int c)
|
||||
{
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
/**
|
||||
* Locale-independent conversion of ASCII isgraph.
|
||||
*/
|
||||
static inline av_const int av_isgraph(int c)
|
||||
{
|
||||
return c > 32 && c < 127;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locale-independent conversion of ASCII isspace.
|
||||
*/
|
||||
static inline av_const int av_isspace(int c)
|
||||
{
|
||||
return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' ||
|
||||
c == '\v';
|
||||
}
|
||||
|
||||
/**
|
||||
* Locale-independent conversion of ASCII characters to uppercase.
|
||||
*/
|
||||
static inline av_const int av_toupper(int c)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z')
|
||||
c ^= 0x20;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locale-independent conversion of ASCII characters to lowercase.
|
||||
*/
|
||||
static inline av_const int av_tolower(int c)
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
c ^= 0x20;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locale-independent conversion of ASCII isxdigit.
|
||||
*/
|
||||
static inline av_const int av_isxdigit(int c)
|
||||
{
|
||||
c = av_tolower(c);
|
||||
return av_isdigit(c) || (c >= 'a' && c <= 'f');
|
||||
}
|
||||
|
||||
/**
|
||||
* Locale-independent case-insensitive compare.
|
||||
* @note This means only ASCII-range characters are case-insensitive
|
||||
*/
|
||||
int av_strcasecmp(const char *a, const char *b);
|
||||
|
||||
/**
|
||||
* Locale-independent case-insensitive compare.
|
||||
* @note This means only ASCII-range characters are case-insensitive
|
||||
*/
|
||||
int av_strncasecmp(const char *a, const char *b, size_t n);
|
||||
|
||||
|
||||
/**
|
||||
* Thread safe basename.
|
||||
* @param path the path, on DOS both \ and / are considered separators.
|
||||
* @return pointer to the basename substring.
|
||||
*/
|
||||
const char *av_basename(const char *path);
|
||||
|
||||
/**
|
||||
* Thread safe dirname.
|
||||
* @param path the path, on DOS both \ and / are considered separators.
|
||||
* @return the path with the separator replaced by the string terminator or ".".
|
||||
* @note the function may change the input string.
|
||||
*/
|
||||
const char *av_dirname(char *path);
|
||||
|
||||
/**
|
||||
* Match instances of a name in a comma-separated list of names.
|
||||
* List entries are checked from the start to the end of the names list,
|
||||
* the first match ends further processing. If an entry prefixed with '-'
|
||||
* matches, then 0 is returned. The "ALL" list entry is considered to
|
||||
* match all names.
|
||||
*
|
||||
* @param name Name to look for.
|
||||
* @param names List of names.
|
||||
* @return 1 on match, 0 otherwise.
|
||||
*/
|
||||
int av_match_name(const char *name, const char *names);
|
||||
|
||||
/**
|
||||
* Append path component to the existing path.
|
||||
* Path separator '/' is placed between when needed.
|
||||
* Resulting string have to be freed with av_free().
|
||||
* @param path base path
|
||||
* @param component component to be appended
|
||||
* @return new path or NULL on error.
|
||||
*/
|
||||
char *av_append_path_component(const char *path, const char *component);
|
||||
|
||||
enum AVEscapeMode {
|
||||
AV_ESCAPE_MODE_AUTO, ///< Use auto-selected escaping mode.
|
||||
AV_ESCAPE_MODE_BACKSLASH, ///< Use backslash escaping.
|
||||
AV_ESCAPE_MODE_QUOTE, ///< Use single-quote escaping.
|
||||
};
|
||||
|
||||
/**
|
||||
* Consider spaces special and escape them even in the middle of the
|
||||
* string.
|
||||
*
|
||||
* This is equivalent to adding the whitespace characters to the special
|
||||
* characters lists, except it is guaranteed to use the exact same list
|
||||
* of whitespace characters as the rest of libavutil.
|
||||
*/
|
||||
#define AV_ESCAPE_FLAG_WHITESPACE (1 << 0)
|
||||
|
||||
/**
|
||||
* Escape only specified special characters.
|
||||
* Without this flag, escape also any characters that may be considered
|
||||
* special by av_get_token(), such as the single quote.
|
||||
*/
|
||||
#define AV_ESCAPE_FLAG_STRICT (1 << 1)
|
||||
|
||||
/**
|
||||
* Escape string in src, and put the escaped string in an allocated
|
||||
* string in *dst, which must be freed with av_free().
|
||||
*
|
||||
* @param dst pointer where an allocated string is put
|
||||
* @param src string to escape, must be non-NULL
|
||||
* @param special_chars string containing the special characters which
|
||||
* need to be escaped, can be NULL
|
||||
* @param mode escape mode to employ, see AV_ESCAPE_MODE_* macros.
|
||||
* Any unknown value for mode will be considered equivalent to
|
||||
* AV_ESCAPE_MODE_BACKSLASH, but this behaviour can change without
|
||||
* notice.
|
||||
* @param flags flags which control how to escape, see AV_ESCAPE_FLAG_ macros
|
||||
* @return the length of the allocated string, or a negative error code in case of error
|
||||
* @see av_bprint_escape()
|
||||
*/
|
||||
av_warn_unused_result
|
||||
int av_escape(char **dst, const char *src, const char *special_chars,
|
||||
enum AVEscapeMode mode, int flags);
|
||||
|
||||
#define AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES 1 ///< accept codepoints over 0x10FFFF
|
||||
#define AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS 2 ///< accept non-characters - 0xFFFE and 0xFFFF
|
||||
#define AV_UTF8_FLAG_ACCEPT_SURROGATES 4 ///< accept UTF-16 surrogates codes
|
||||
#define AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES 8 ///< exclude control codes not accepted by XML
|
||||
|
||||
#define AV_UTF8_FLAG_ACCEPT_ALL \
|
||||
AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES|AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS|AV_UTF8_FLAG_ACCEPT_SURROGATES
|
||||
|
||||
/**
|
||||
* Read and decode a single UTF-8 code point (character) from the
|
||||
* buffer in *buf, and update *buf to point to the next byte to
|
||||
* decode.
|
||||
*
|
||||
* In case of an invalid byte sequence, the pointer will be updated to
|
||||
* the next byte after the invalid sequence and the function will
|
||||
* return an error code.
|
||||
*
|
||||
* Depending on the specified flags, the function will also fail in
|
||||
* case the decoded code point does not belong to a valid range.
|
||||
*
|
||||
* @note For speed-relevant code a carefully implemented use of
|
||||
* GET_UTF8() may be preferred.
|
||||
*
|
||||
* @param codep pointer used to return the parsed code in case of success.
|
||||
* The value in *codep is set even in case the range check fails.
|
||||
* @param bufp pointer to the address the first byte of the sequence
|
||||
* to decode, updated by the function to point to the
|
||||
* byte next after the decoded sequence
|
||||
* @param buf_end pointer to the end of the buffer, points to the next
|
||||
* byte past the last in the buffer. This is used to
|
||||
* avoid buffer overreads (in case of an unfinished
|
||||
* UTF-8 sequence towards the end of the buffer).
|
||||
* @param flags a collection of AV_UTF8_FLAG_* flags
|
||||
* @return >= 0 in case a sequence was successfully read, a negative
|
||||
* value in case of invalid sequence
|
||||
*/
|
||||
av_warn_unused_result
|
||||
int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end,
|
||||
unsigned int flags);
|
||||
|
||||
/**
|
||||
* Check if a name is in a list.
|
||||
* @returns 0 if not found, or the 1 based index where it has been found in the
|
||||
* list.
|
||||
*/
|
||||
int av_match_list(const char *name, const char *list, char separator);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVUTIL_AVSTRING_H */
|
321
ext/at3_standalone/bitstream.c
Normal file
321
ext/at3_standalone/bitstream.c
Normal file
@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Common bit i/o utils
|
||||
* Copyright (c) 2000, 2001 Fabrice Bellard
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2010 Loren Merritt
|
||||
*
|
||||
* alternative bitstream reader & writer by 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
|
||||
* bitstream api.
|
||||
*/
|
||||
|
||||
#include "atomic.h"
|
||||
#include "qsort.h"
|
||||
#include "avcodec.h"
|
||||
#include "internal.h"
|
||||
#include "util_internal.h"
|
||||
#include "mathops.h"
|
||||
#include "get_bits.h"
|
||||
|
||||
const uint8_t ff_log2_run[41]={
|
||||
0, 0, 0, 0, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 3, 3, 3, 3,
|
||||
4, 4, 5, 5, 6, 6, 7, 7,
|
||||
8, 9,10,11,12,13,14,15,
|
||||
16,17,18,19,20,21,22,23,
|
||||
24,
|
||||
};
|
||||
|
||||
/* VLC decoding */
|
||||
|
||||
#define GET_DATA(v, table, i, wrap, size) \
|
||||
{ \
|
||||
const uint8_t *ptr = (const uint8_t *)table + i * wrap; \
|
||||
switch(size) { \
|
||||
case 1: \
|
||||
v = *(const uint8_t *)ptr; \
|
||||
break; \
|
||||
case 2: \
|
||||
v = *(const uint16_t *)ptr; \
|
||||
break; \
|
||||
default: \
|
||||
v = *(const uint32_t *)ptr; \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
static int alloc_table(VLC *vlc, int size, int use_static)
|
||||
{
|
||||
int index = vlc->table_size;
|
||||
|
||||
vlc->table_size += size;
|
||||
if (vlc->table_size > vlc->table_allocated) {
|
||||
if (use_static)
|
||||
abort(); // cannot do anything, init_vlc() is used with too little memory
|
||||
vlc->table_allocated += (1 << vlc->bits);
|
||||
vlc->table = av_realloc_f(vlc->table, vlc->table_allocated, sizeof(VLC_TYPE) * 2);
|
||||
if (!vlc->table) {
|
||||
vlc->table_allocated = 0;
|
||||
vlc->table_size = 0;
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
memset(vlc->table + vlc->table_allocated - (1 << vlc->bits), 0, sizeof(VLC_TYPE) * 2 << vlc->bits);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
static av_always_inline uint32_t bitswap_32(uint32_t x)
|
||||
{
|
||||
return (uint32_t)ff_reverse[ x & 0xFF] << 24 |
|
||||
(uint32_t)ff_reverse[(x >> 8) & 0xFF] << 16 |
|
||||
(uint32_t)ff_reverse[(x >> 16) & 0xFF] << 8 |
|
||||
(uint32_t)ff_reverse[ x >> 24];
|
||||
}
|
||||
|
||||
typedef struct VLCcode {
|
||||
uint8_t bits;
|
||||
uint16_t symbol;
|
||||
/** codeword, with the first bit-to-be-read in the msb
|
||||
* (even if intended for a little-endian bitstream reader) */
|
||||
uint32_t code;
|
||||
} VLCcode;
|
||||
|
||||
static int compare_vlcspec(const void *a, const void *b)
|
||||
{
|
||||
const VLCcode *sa = a, *sb = b;
|
||||
return (sa->code >> 1) - (sb->code >> 1);
|
||||
}
|
||||
/**
|
||||
* Build VLC decoding tables suitable for use with get_vlc().
|
||||
*
|
||||
* @param vlc the context to be initted
|
||||
*
|
||||
* @param table_nb_bits max length of vlc codes to store directly in this table
|
||||
* (Longer codes are delegated to subtables.)
|
||||
*
|
||||
* @param nb_codes number of elements in codes[]
|
||||
*
|
||||
* @param codes descriptions of the vlc codes
|
||||
* These must be ordered such that codes going into the same subtable are contiguous.
|
||||
* Sorting by VLCcode.code is sufficient, though not necessary.
|
||||
*/
|
||||
static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
|
||||
VLCcode *codes, int flags)
|
||||
{
|
||||
int table_size, table_index, index, code_prefix, symbol, subtable_bits;
|
||||
int i, j, k, n, nb, inc;
|
||||
uint32_t code;
|
||||
volatile VLC_TYPE (* volatile table)[2]; // the double volatile is needed to prevent a internal compiler error in gcc 4.2
|
||||
|
||||
table_size = 1 << table_nb_bits;
|
||||
if (table_nb_bits > 30)
|
||||
return -1;
|
||||
table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);
|
||||
ff_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size);
|
||||
if (table_index < 0)
|
||||
return table_index;
|
||||
table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index];
|
||||
|
||||
/* first pass: map codes and compute auxiliary table sizes */
|
||||
for (i = 0; i < nb_codes; i++) {
|
||||
n = codes[i].bits;
|
||||
code = codes[i].code;
|
||||
symbol = codes[i].symbol;
|
||||
ff_dlog(NULL, "i=%d n=%d code=0x%x\n", i, n, code);
|
||||
if (n <= table_nb_bits) {
|
||||
/* no need to add another table */
|
||||
j = code >> (32 - table_nb_bits);
|
||||
nb = 1 << (table_nb_bits - n);
|
||||
inc = 1;
|
||||
if (flags & INIT_VLC_LE) {
|
||||
j = bitswap_32(code);
|
||||
inc = 1 << n;
|
||||
}
|
||||
for (k = 0; k < nb; k++) {
|
||||
int bits = table[j][1];
|
||||
ff_dlog(NULL, "%4x: code=%d n=%d\n", j, i, n);
|
||||
if (bits != 0 && bits != n) {
|
||||
av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
table[j][1] = n; //bits
|
||||
table[j][0] = symbol;
|
||||
j += inc;
|
||||
}
|
||||
} else {
|
||||
/* fill auxiliary table recursively */
|
||||
n -= table_nb_bits;
|
||||
code_prefix = code >> (32 - table_nb_bits);
|
||||
subtable_bits = n;
|
||||
codes[i].bits = n;
|
||||
codes[i].code = code << table_nb_bits;
|
||||
for (k = i+1; k < nb_codes; k++) {
|
||||
n = codes[k].bits - table_nb_bits;
|
||||
if (n <= 0)
|
||||
break;
|
||||
code = codes[k].code;
|
||||
if (code >> (32 - table_nb_bits) != code_prefix)
|
||||
break;
|
||||
codes[k].bits = n;
|
||||
codes[k].code = code << table_nb_bits;
|
||||
subtable_bits = FFMAX(subtable_bits, n);
|
||||
}
|
||||
subtable_bits = FFMIN(subtable_bits, table_nb_bits);
|
||||
j = (flags & INIT_VLC_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) : code_prefix;
|
||||
table[j][1] = -subtable_bits;
|
||||
ff_dlog(NULL, "%4x: n=%d (subtable)\n",
|
||||
j, codes[i].bits + table_nb_bits);
|
||||
index = build_table(vlc, subtable_bits, k-i, codes+i, flags);
|
||||
if (index < 0)
|
||||
return index;
|
||||
/* note: realloc has been done, so reload tables */
|
||||
table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index];
|
||||
table[j][0] = index; //code
|
||||
i = k-1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < table_size; i++) {
|
||||
if (table[i][1] == 0) //bits
|
||||
table[i][0] = -1; //codes
|
||||
}
|
||||
|
||||
return table_index;
|
||||
}
|
||||
|
||||
|
||||
/* Build VLC decoding tables suitable for use with get_vlc().
|
||||
|
||||
'nb_bits' set the decoding table size (2^nb_bits) entries. The
|
||||
bigger it is, the faster is the decoding. But it should not be too
|
||||
big to save memory and L1 cache. '9' is a good compromise.
|
||||
|
||||
'nb_codes' : number of vlcs codes
|
||||
|
||||
'bits' : table which gives the size (in bits) of each vlc code.
|
||||
|
||||
'codes' : table which gives the bit pattern of of each vlc code.
|
||||
|
||||
'symbols' : table which gives the values to be returned from get_vlc().
|
||||
|
||||
'xxx_wrap' : give the number of bytes between each entry of the
|
||||
'bits' or 'codes' tables.
|
||||
|
||||
'xxx_size' : gives the number of bytes of each entry of the 'bits'
|
||||
or 'codes' tables.
|
||||
|
||||
'wrap' and 'size' make it possible to use any memory configuration and types
|
||||
(byte/word/long) to store the 'bits', 'codes', and 'symbols' tables.
|
||||
|
||||
'use_static' should be set to 1 for tables, which should be freed
|
||||
with av_free_static(), 0 if ff_free_vlc() will be used.
|
||||
*/
|
||||
int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
|
||||
const void *bits, int bits_wrap, int bits_size,
|
||||
const void *codes, int codes_wrap, int codes_size,
|
||||
const void *symbols, int symbols_wrap, int symbols_size,
|
||||
int flags)
|
||||
{
|
||||
VLCcode *buf;
|
||||
int i, j, ret;
|
||||
VLCcode localbuf[1500]; // the maximum currently needed is 1296 by rv34
|
||||
VLC localvlc, *vlc;
|
||||
|
||||
vlc = vlc_arg;
|
||||
vlc->bits = nb_bits;
|
||||
if (flags & INIT_VLC_USE_NEW_STATIC) {
|
||||
av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf));
|
||||
buf = localbuf;
|
||||
localvlc = *vlc_arg;
|
||||
vlc = &localvlc;
|
||||
vlc->table_size = 0;
|
||||
} else {
|
||||
vlc->table = NULL;
|
||||
vlc->table_allocated = 0;
|
||||
vlc->table_size = 0;
|
||||
|
||||
buf = av_malloc_array((nb_codes + 1), sizeof(VLCcode));
|
||||
if (!buf)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
|
||||
av_assert0(symbols_size <= 2 || !symbols);
|
||||
j = 0;
|
||||
#define COPY(condition)\
|
||||
for (i = 0; i < nb_codes; i++) { \
|
||||
GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size); \
|
||||
if (!(condition)) \
|
||||
continue; \
|
||||
if (buf[j].bits > 3*nb_bits || buf[j].bits>32) { \
|
||||
av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[j].bits);\
|
||||
if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
|
||||
av_free(buf); \
|
||||
return -1; \
|
||||
} \
|
||||
GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \
|
||||
if (buf[j].code >= (1LL<<buf[j].bits)) { \
|
||||
av_log(NULL, AV_LOG_ERROR, "Invalid code in init_vlc\n"); \
|
||||
if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
|
||||
av_free(buf); \
|
||||
return -1; \
|
||||
} \
|
||||
if (flags & INIT_VLC_LE) \
|
||||
buf[j].code = bitswap_32(buf[j].code); \
|
||||
else \
|
||||
buf[j].code <<= 32 - buf[j].bits; \
|
||||
if (symbols) \
|
||||
GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size) \
|
||||
else \
|
||||
buf[j].symbol = i; \
|
||||
j++; \
|
||||
}
|
||||
COPY(buf[j].bits > nb_bits);
|
||||
// qsort is the slowest part of init_vlc, and could probably be improved or avoided
|
||||
AV_QSORT(buf, j, struct VLCcode, compare_vlcspec);
|
||||
COPY(buf[j].bits && buf[j].bits <= nb_bits);
|
||||
nb_codes = j;
|
||||
|
||||
ret = build_table(vlc, nb_bits, nb_codes, buf, flags);
|
||||
|
||||
if (flags & INIT_VLC_USE_NEW_STATIC) {
|
||||
if(vlc->table_size != vlc->table_allocated)
|
||||
av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
|
||||
|
||||
av_assert0(ret >= 0);
|
||||
*vlc_arg = *vlc;
|
||||
} else {
|
||||
av_free(buf);
|
||||
if (ret < 0) {
|
||||
av_freep(&vlc->table);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ff_free_vlc(VLC *vlc)
|
||||
{
|
||||
av_freep(&vlc->table);
|
||||
}
|
379
ext/at3_standalone/bprint.c
Normal file
379
ext/at3_standalone/bprint.c
Normal file
@ -0,0 +1,379 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Nicolas George
|
||||
*
|
||||
* 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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "avstring.h"
|
||||
#include "bprint.h"
|
||||
#include "common.h"
|
||||
#include "error.h"
|
||||
#include "mem.h"
|
||||
|
||||
#define av_bprint_room(buf) ((buf)->size - FFMIN((buf)->len, (buf)->size))
|
||||
#define av_bprint_is_allocated(buf) ((buf)->str != (buf)->reserved_internal_buffer)
|
||||
|
||||
static int av_bprint_alloc(AVBPrint *buf, unsigned room)
|
||||
{
|
||||
char *old_str, *new_str;
|
||||
unsigned min_size, new_size;
|
||||
|
||||
if (buf->size == buf->size_max)
|
||||
return AVERROR(EIO);
|
||||
if (!av_bprint_is_complete(buf))
|
||||
return AVERROR_INVALIDDATA; /* it is already truncated anyway */
|
||||
min_size = buf->len + 1 + FFMIN(UINT_MAX - buf->len - 1, room);
|
||||
new_size = buf->size > buf->size_max / 2 ? buf->size_max : buf->size * 2;
|
||||
if (new_size < min_size)
|
||||
new_size = FFMIN(buf->size_max, min_size);
|
||||
old_str = av_bprint_is_allocated(buf) ? buf->str : NULL;
|
||||
new_str = av_realloc(old_str, new_size);
|
||||
if (!new_str)
|
||||
return AVERROR(ENOMEM);
|
||||
if (!old_str)
|
||||
memcpy(new_str, buf->str, buf->len + 1);
|
||||
buf->str = new_str;
|
||||
buf->size = new_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void av_bprint_grow(AVBPrint *buf, unsigned extra_len)
|
||||
{
|
||||
/* arbitrary margin to avoid small overflows */
|
||||
extra_len = FFMIN(extra_len, UINT_MAX - 5 - buf->len);
|
||||
buf->len += extra_len;
|
||||
if (buf->size)
|
||||
buf->str[FFMIN(buf->len, buf->size - 1)] = 0;
|
||||
}
|
||||
|
||||
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
|
||||
{
|
||||
unsigned size_auto = (char *)buf + sizeof(*buf) -
|
||||
buf->reserved_internal_buffer;
|
||||
|
||||
if (size_max == 1)
|
||||
size_max = size_auto;
|
||||
buf->str = buf->reserved_internal_buffer;
|
||||
buf->len = 0;
|
||||
buf->size = FFMIN(size_auto, size_max);
|
||||
buf->size_max = size_max;
|
||||
*buf->str = 0;
|
||||
if (size_init > buf->size)
|
||||
av_bprint_alloc(buf, size_init - 1);
|
||||
}
|
||||
|
||||
void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size)
|
||||
{
|
||||
buf->str = buffer;
|
||||
buf->len = 0;
|
||||
buf->size = size;
|
||||
buf->size_max = size;
|
||||
*buf->str = 0;
|
||||
}
|
||||
|
||||
void av_bprintf(AVBPrint *buf, const char *fmt, ...)
|
||||
{
|
||||
unsigned room;
|
||||
char *dst;
|
||||
va_list vl;
|
||||
int extra_len;
|
||||
|
||||
while (1) {
|
||||
room = av_bprint_room(buf);
|
||||
dst = room ? buf->str + buf->len : NULL;
|
||||
va_start(vl, fmt);
|
||||
extra_len = vsnprintf(dst, room, fmt, vl);
|
||||
va_end(vl);
|
||||
if (extra_len <= 0)
|
||||
return;
|
||||
if (extra_len < room)
|
||||
break;
|
||||
if (av_bprint_alloc(buf, extra_len))
|
||||
break;
|
||||
}
|
||||
av_bprint_grow(buf, extra_len);
|
||||
}
|
||||
|
||||
void av_vbprintf(AVBPrint *buf, const char *fmt, va_list vl_arg)
|
||||
{
|
||||
unsigned room;
|
||||
char *dst;
|
||||
int extra_len;
|
||||
va_list vl;
|
||||
|
||||
while (1) {
|
||||
room = av_bprint_room(buf);
|
||||
dst = room ? buf->str + buf->len : NULL;
|
||||
va_copy(vl, vl_arg);
|
||||
extra_len = vsnprintf(dst, room, fmt, vl);
|
||||
va_end(vl);
|
||||
if (extra_len <= 0)
|
||||
return;
|
||||
if (extra_len < room)
|
||||
break;
|
||||
if (av_bprint_alloc(buf, extra_len))
|
||||
break;
|
||||
}
|
||||
av_bprint_grow(buf, extra_len);
|
||||
}
|
||||
|
||||
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
|
||||
{
|
||||
unsigned room, real_n;
|
||||
|
||||
while (1) {
|
||||
room = av_bprint_room(buf);
|
||||
if (n < room)
|
||||
break;
|
||||
if (av_bprint_alloc(buf, n))
|
||||
break;
|
||||
}
|
||||
if (room) {
|
||||
real_n = FFMIN(n, room - 1);
|
||||
memset(buf->str + buf->len, c, real_n);
|
||||
}
|
||||
av_bprint_grow(buf, n);
|
||||
}
|
||||
|
||||
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
|
||||
{
|
||||
unsigned room, real_n;
|
||||
|
||||
while (1) {
|
||||
room = av_bprint_room(buf);
|
||||
if (size < room)
|
||||
break;
|
||||
if (av_bprint_alloc(buf, size))
|
||||
break;
|
||||
}
|
||||
if (room) {
|
||||
real_n = FFMIN(size, room - 1);
|
||||
memcpy(buf->str + buf->len, data, real_n);
|
||||
}
|
||||
av_bprint_grow(buf, size);
|
||||
}
|
||||
|
||||
void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm)
|
||||
{
|
||||
unsigned room;
|
||||
size_t l;
|
||||
|
||||
if (!*fmt)
|
||||
return;
|
||||
while (1) {
|
||||
room = av_bprint_room(buf);
|
||||
if (room && (l = strftime(buf->str + buf->len, room, fmt, tm)))
|
||||
break;
|
||||
/* strftime does not tell us how much room it would need: let us
|
||||
retry with twice as much until the buffer is large enough */
|
||||
room = !room ? strlen(fmt) + 1 :
|
||||
room <= INT_MAX / 2 ? room * 2 : INT_MAX;
|
||||
if (av_bprint_alloc(buf, room)) {
|
||||
/* impossible to grow, try to manage something useful anyway */
|
||||
room = av_bprint_room(buf);
|
||||
if (room < 1024) {
|
||||
/* if strftime fails because the buffer has (almost) reached
|
||||
its maximum size, let us try in a local buffer; 1k should
|
||||
be enough to format any real date+time string */
|
||||
char buf2[1024];
|
||||
if ((l = strftime(buf2, sizeof(buf2), fmt, tm))) {
|
||||
av_bprintf(buf, "%s", buf2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (room) {
|
||||
/* if anything else failed and the buffer is not already
|
||||
truncated, let us add a stock string and force truncation */
|
||||
static const char txt[] = "[truncated strftime output]";
|
||||
memset(buf->str + buf->len, '!', room);
|
||||
memcpy(buf->str + buf->len, txt, FFMIN(sizeof(txt) - 1, room));
|
||||
av_bprint_grow(buf, room); /* force truncation */
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
av_bprint_grow(buf, l);
|
||||
}
|
||||
|
||||
void av_bprint_get_buffer(AVBPrint *buf, unsigned size,
|
||||
unsigned char **mem, unsigned *actual_size)
|
||||
{
|
||||
if (size > av_bprint_room(buf))
|
||||
av_bprint_alloc(buf, size);
|
||||
*actual_size = av_bprint_room(buf);
|
||||
*mem = *actual_size ? buf->str + buf->len : NULL;
|
||||
}
|
||||
|
||||
void av_bprint_clear(AVBPrint *buf)
|
||||
{
|
||||
if (buf->len) {
|
||||
*buf->str = 0;
|
||||
buf->len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
|
||||
{
|
||||
unsigned real_size = FFMIN(buf->len + 1, buf->size);
|
||||
char *str;
|
||||
int ret = 0;
|
||||
|
||||
if (ret_str) {
|
||||
if (av_bprint_is_allocated(buf)) {
|
||||
str = av_realloc(buf->str, real_size);
|
||||
if (!str)
|
||||
str = buf->str;
|
||||
buf->str = NULL;
|
||||
} else {
|
||||
str = av_malloc(real_size);
|
||||
if (str)
|
||||
memcpy(str, buf->str, real_size);
|
||||
else
|
||||
ret = AVERROR(ENOMEM);
|
||||
}
|
||||
*ret_str = str;
|
||||
} else {
|
||||
if (av_bprint_is_allocated(buf))
|
||||
av_freep(&buf->str);
|
||||
}
|
||||
buf->size = real_size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define WHITESPACES " \n\t"
|
||||
|
||||
void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_chars,
|
||||
enum AVEscapeMode mode, int flags)
|
||||
{
|
||||
const char *src0 = src;
|
||||
|
||||
if (mode == AV_ESCAPE_MODE_AUTO)
|
||||
mode = AV_ESCAPE_MODE_BACKSLASH; /* TODO: implement a heuristic */
|
||||
|
||||
switch (mode) {
|
||||
case AV_ESCAPE_MODE_QUOTE:
|
||||
/* enclose the string between '' */
|
||||
av_bprint_chars(dstbuf, '\'', 1);
|
||||
for (; *src; src++) {
|
||||
if (*src == '\'')
|
||||
av_bprintf(dstbuf, "'\\''");
|
||||
else
|
||||
av_bprint_chars(dstbuf, *src, 1);
|
||||
}
|
||||
av_bprint_chars(dstbuf, '\'', 1);
|
||||
break;
|
||||
|
||||
/* case AV_ESCAPE_MODE_BACKSLASH or unknown mode */
|
||||
default:
|
||||
/* \-escape characters */
|
||||
for (; *src; src++) {
|
||||
int is_first_last = src == src0 || !*(src+1);
|
||||
int is_ws = !!strchr(WHITESPACES, *src);
|
||||
int is_strictly_special = special_chars && strchr(special_chars, *src);
|
||||
int is_special =
|
||||
is_strictly_special || strchr("'\\", *src) ||
|
||||
(is_ws && (flags & AV_ESCAPE_FLAG_WHITESPACE));
|
||||
|
||||
if (is_strictly_special ||
|
||||
(!(flags & AV_ESCAPE_FLAG_STRICT) &&
|
||||
(is_special || (is_ws && is_first_last))))
|
||||
av_bprint_chars(dstbuf, '\\', 1);
|
||||
av_bprint_chars(dstbuf, *src, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#undef printf
|
||||
|
||||
static void bprint_pascal(AVBPrint *b, unsigned size)
|
||||
{
|
||||
unsigned i, j;
|
||||
unsigned p[42];
|
||||
|
||||
av_assert0(size < FF_ARRAY_ELEMS(p));
|
||||
|
||||
p[0] = 1;
|
||||
av_bprintf(b, "%8d\n", 1);
|
||||
for (i = 1; i <= size; i++) {
|
||||
p[i] = 1;
|
||||
for (j = i - 1; j > 0; j--)
|
||||
p[j] = p[j] + p[j - 1];
|
||||
for (j = 0; j <= i; j++)
|
||||
av_bprintf(b, "%8d", p[j]);
|
||||
av_bprintf(b, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
AVBPrint b;
|
||||
char buf[256];
|
||||
struct tm testtime = { .tm_year = 100, .tm_mon = 11, .tm_mday = 20 };
|
||||
|
||||
av_bprint_init(&b, 0, -1);
|
||||
bprint_pascal(&b, 5);
|
||||
printf("Short text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
|
||||
printf("%s\n", b.str);
|
||||
av_bprint_finalize(&b, NULL);
|
||||
|
||||
av_bprint_init(&b, 0, -1);
|
||||
bprint_pascal(&b, 25);
|
||||
printf("Long text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
|
||||
av_bprint_finalize(&b, NULL);
|
||||
|
||||
av_bprint_init(&b, 0, 2048);
|
||||
bprint_pascal(&b, 25);
|
||||
printf("Long text in limited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
|
||||
av_bprint_finalize(&b, NULL);
|
||||
|
||||
av_bprint_init(&b, 0, 1);
|
||||
bprint_pascal(&b, 5);
|
||||
printf("Short text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
|
||||
|
||||
av_bprint_init(&b, 0, 1);
|
||||
bprint_pascal(&b, 25);
|
||||
printf("Long text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str)/8*8, b.len);
|
||||
/* Note that the size of the automatic buffer is arch-dependent. */
|
||||
|
||||
av_bprint_init(&b, 0, 0);
|
||||
bprint_pascal(&b, 25);
|
||||
printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
|
||||
|
||||
av_bprint_init_for_buffer(&b, buf, sizeof(buf));
|
||||
bprint_pascal(&b, 25);
|
||||
printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(buf), b.len);
|
||||
|
||||
av_bprint_init(&b, 0, -1);
|
||||
av_bprint_strftime(&b, "%Y-%m-%d", &testtime);
|
||||
printf("strftime full: %u/%u \"%s\"\n", (unsigned)strlen(buf), b.len, b.str);
|
||||
av_bprint_finalize(&b, NULL);
|
||||
|
||||
av_bprint_init(&b, 0, 8);
|
||||
av_bprint_strftime(&b, "%Y-%m-%d", &testtime);
|
||||
printf("strftime truncated: %u/%u \"%s\"\n", (unsigned)strlen(buf), b.len, b.str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
219
ext/at3_standalone/bprint.h
Normal file
219
ext/at3_standalone/bprint.h
Normal file
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Nicolas George
|
||||
*
|
||||
* 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 AVUTIL_BPRINT_H
|
||||
#define AVUTIL_BPRINT_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "avstring.h"
|
||||
|
||||
/**
|
||||
* Define a structure with extra padding to a fixed size
|
||||
* This helps ensuring binary compatibility with future versions.
|
||||
*/
|
||||
|
||||
#define FF_PAD_STRUCTURE(name, size, ...) \
|
||||
struct ff_pad_helper_##name { __VA_ARGS__ }; \
|
||||
typedef struct name { \
|
||||
__VA_ARGS__ \
|
||||
char reserved_padding[size - sizeof(struct ff_pad_helper_##name)]; \
|
||||
} name;
|
||||
|
||||
/**
|
||||
* Buffer to print data progressively
|
||||
*
|
||||
* The string buffer grows as necessary and is always 0-terminated.
|
||||
* The content of the string is never accessed, and thus is
|
||||
* encoding-agnostic and can even hold binary data.
|
||||
*
|
||||
* Small buffers are kept in the structure itself, and thus require no
|
||||
* memory allocation at all (unless the contents of the buffer is needed
|
||||
* after the structure goes out of scope). This is almost as lightweight as
|
||||
* declaring a local "char buf[512]".
|
||||
*
|
||||
* The length of the string can go beyond the allocated size: the buffer is
|
||||
* then truncated, but the functions still keep account of the actual total
|
||||
* length.
|
||||
*
|
||||
* In other words, buf->len can be greater than buf->size and records the
|
||||
* total length of what would have been to the buffer if there had been
|
||||
* enough memory.
|
||||
*
|
||||
* Append operations do not need to be tested for failure: if a memory
|
||||
* allocation fails, data stop being appended to the buffer, but the length
|
||||
* is still updated. This situation can be tested with
|
||||
* av_bprint_is_complete().
|
||||
*
|
||||
* The size_max field determines several possible behaviours:
|
||||
*
|
||||
* size_max = -1 (= UINT_MAX) or any large value will let the buffer be
|
||||
* reallocated as necessary, with an amortized linear cost.
|
||||
*
|
||||
* size_max = 0 prevents writing anything to the buffer: only the total
|
||||
* length is computed. The write operations can then possibly be repeated in
|
||||
* a buffer with exactly the necessary size
|
||||
* (using size_init = size_max = len + 1).
|
||||
*
|
||||
* size_max = 1 is automatically replaced by the exact size available in the
|
||||
* structure itself, thus ensuring no dynamic memory allocation. The
|
||||
* internal buffer is large enough to hold a reasonable paragraph of text,
|
||||
* such as the current paragraph.
|
||||
*/
|
||||
|
||||
FF_PAD_STRUCTURE(AVBPrint, 1024,
|
||||
char *str; /**< string so far */
|
||||
unsigned len; /**< length so far */
|
||||
unsigned size; /**< allocated memory */
|
||||
unsigned size_max; /**< maximum allocated memory */
|
||||
char reserved_internal_buffer[1];
|
||||
)
|
||||
|
||||
/**
|
||||
* Convenience macros for special values for av_bprint_init() size_max
|
||||
* parameter.
|
||||
*/
|
||||
#define AV_BPRINT_SIZE_UNLIMITED ((unsigned)-1)
|
||||
#define AV_BPRINT_SIZE_AUTOMATIC 1
|
||||
#define AV_BPRINT_SIZE_COUNT_ONLY 0
|
||||
|
||||
/**
|
||||
* Init a print buffer.
|
||||
*
|
||||
* @param buf buffer to init
|
||||
* @param size_init initial size (including the final 0)
|
||||
* @param size_max maximum size;
|
||||
* 0 means do not write anything, just count the length;
|
||||
* 1 is replaced by the maximum value for automatic storage;
|
||||
* any large value means that the internal buffer will be
|
||||
* reallocated as needed up to that limit; -1 is converted to
|
||||
* UINT_MAX, the largest limit possible.
|
||||
* Check also AV_BPRINT_SIZE_* macros.
|
||||
*/
|
||||
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max);
|
||||
|
||||
/**
|
||||
* Init a print buffer using a pre-existing buffer.
|
||||
*
|
||||
* The buffer will not be reallocated.
|
||||
*
|
||||
* @param buf buffer structure to init
|
||||
* @param buffer byte buffer to use for the string data
|
||||
* @param size size of buffer
|
||||
*/
|
||||
void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size);
|
||||
|
||||
/**
|
||||
* Append a formatted string to a print buffer.
|
||||
*/
|
||||
void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3);
|
||||
|
||||
/**
|
||||
* Append a formatted string to a print buffer.
|
||||
*/
|
||||
void av_vbprintf(AVBPrint *buf, const char *fmt, va_list vl_arg);
|
||||
|
||||
/**
|
||||
* Append char c n times to a print buffer.
|
||||
*/
|
||||
void av_bprint_chars(AVBPrint *buf, char c, unsigned n);
|
||||
|
||||
/**
|
||||
* Append data to a print buffer.
|
||||
*
|
||||
* param buf bprint buffer to use
|
||||
* param data pointer to data
|
||||
* param size size of data
|
||||
*/
|
||||
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size);
|
||||
|
||||
struct tm;
|
||||
/**
|
||||
* Append a formatted date and time to a print buffer.
|
||||
*
|
||||
* param buf bprint buffer to use
|
||||
* param fmt date and time format string, see strftime()
|
||||
* param tm broken-down time structure to translate
|
||||
*
|
||||
* @note due to poor design of the standard strftime function, it may
|
||||
* produce poor results if the format string expands to a very long text and
|
||||
* the bprint buffer is near the limit stated by the size_max option.
|
||||
*/
|
||||
void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm);
|
||||
|
||||
/**
|
||||
* Allocate bytes in the buffer for external use.
|
||||
*
|
||||
* @param[in] buf buffer structure
|
||||
* @param[in] size required size
|
||||
* @param[out] mem pointer to the memory area
|
||||
* @param[out] actual_size size of the memory area after allocation;
|
||||
* can be larger or smaller than size
|
||||
*/
|
||||
void av_bprint_get_buffer(AVBPrint *buf, unsigned size,
|
||||
unsigned char **mem, unsigned *actual_size);
|
||||
|
||||
/**
|
||||
* Reset the string to "" but keep internal allocated data.
|
||||
*/
|
||||
void av_bprint_clear(AVBPrint *buf);
|
||||
|
||||
/**
|
||||
* Test if the print buffer is complete (not truncated).
|
||||
*
|
||||
* It may have been truncated due to a memory allocation failure
|
||||
* or the size_max limit (compare size and size_max if necessary).
|
||||
*/
|
||||
static inline int av_bprint_is_complete(const AVBPrint *buf)
|
||||
{
|
||||
return buf->len < buf->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize a print buffer.
|
||||
*
|
||||
* The print buffer can no longer be used afterwards,
|
||||
* but the len and size fields are still valid.
|
||||
*
|
||||
* @arg[out] ret_str if not NULL, used to return a permanent copy of the
|
||||
* buffer contents, or NULL if memory allocation fails;
|
||||
* if NULL, the buffer is discarded and freed
|
||||
* @return 0 for success or error code (probably AVERROR(ENOMEM))
|
||||
*/
|
||||
int av_bprint_finalize(AVBPrint *buf, char **ret_str);
|
||||
|
||||
/**
|
||||
* Escape the content in src and append it to dstbuf.
|
||||
*
|
||||
* @param dstbuf already inited destination bprint buffer
|
||||
* @param src string containing the text to escape
|
||||
* @param special_chars string containing the special characters which
|
||||
* need to be escaped, can be NULL
|
||||
* @param mode escape mode to employ, see AV_ESCAPE_MODE_* macros.
|
||||
* Any unknown value for mode will be considered equivalent to
|
||||
* AV_ESCAPE_MODE_BACKSLASH, but this behaviour can change without
|
||||
* notice.
|
||||
* @param flags flags which control how to escape, see AV_ESCAPE_FLAG_* macros
|
||||
*/
|
||||
void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_chars,
|
||||
enum AVEscapeMode mode, int flags);
|
||||
|
||||
#endif /* AVUTIL_BPRINT_H */
|
94
ext/at3_standalone/buffer_internal.h
Normal file
94
ext/at3_standalone/buffer_internal.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 AVUTIL_BUFFER_INTERNAL_H
|
||||
#define AVUTIL_BUFFER_INTERNAL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "buffer.h"
|
||||
|
||||
/**
|
||||
* The buffer is always treated as read-only.
|
||||
*/
|
||||
#define BUFFER_FLAG_READONLY (1 << 0)
|
||||
/**
|
||||
* The buffer was av_realloc()ed, so it is reallocatable.
|
||||
*/
|
||||
#define BUFFER_FLAG_REALLOCATABLE (1 << 1)
|
||||
|
||||
struct AVBuffer {
|
||||
uint8_t *data; /**< data described by this buffer */
|
||||
int size; /**< size of data in bytes */
|
||||
|
||||
/**
|
||||
* number of existing AVBufferRef instances referring to this buffer
|
||||
*/
|
||||
volatile int refcount;
|
||||
|
||||
/**
|
||||
* a callback for freeing the data
|
||||
*/
|
||||
void (*free)(void *opaque, uint8_t *data);
|
||||
|
||||
/**
|
||||
* an opaque pointer, to be used by the freeing callback
|
||||
*/
|
||||
void *opaque;
|
||||
|
||||
/**
|
||||
* A combination of BUFFER_FLAG_*
|
||||
*/
|
||||
int flags;
|
||||
};
|
||||
|
||||
typedef struct BufferPoolEntry {
|
||||
uint8_t *data;
|
||||
|
||||
/*
|
||||
* Backups of the original opaque/free of the AVBuffer corresponding to
|
||||
* data. They will be used to free the buffer when the pool is freed.
|
||||
*/
|
||||
void *opaque;
|
||||
void (*free)(void *opaque, uint8_t *data);
|
||||
|
||||
AVBufferPool *pool;
|
||||
struct BufferPoolEntry *next;
|
||||
} BufferPoolEntry;
|
||||
|
||||
struct AVBufferPool {
|
||||
BufferPoolEntry *pool;
|
||||
|
||||
/*
|
||||
* This is used to track when the pool is to be freed.
|
||||
* The pointer to the pool itself held by the caller is considered to
|
||||
* be one reference. Each buffer requested by the caller increases refcount
|
||||
* by one, returning the buffer to the pool decreases it by one.
|
||||
* refcount reaches zero when the buffer has been uninited AND all the
|
||||
* buffers have been released, then it's safe to free the pool and all
|
||||
* the buffers in it.
|
||||
*/
|
||||
volatile int refcount;
|
||||
|
||||
volatile int nb_allocated;
|
||||
|
||||
int size;
|
||||
AVBufferRef* (*alloc)(int size);
|
||||
};
|
||||
|
||||
#endif /* AVUTIL_BUFFER_INTERNAL_H */
|
220
ext/at3_standalone/channel_layout.c
Normal file
220
ext/at3_standalone/channel_layout.c
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (c) 2006 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
|
||||
* audio channel layout utility functions
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "avutil.h"
|
||||
#include "channel_layout.h"
|
||||
#include "common.h"
|
||||
|
||||
struct channel_name {
|
||||
const char *name;
|
||||
const char *description;
|
||||
};
|
||||
|
||||
static const struct channel_name channel_names[] = {
|
||||
[0] = { "FL", "front left" },
|
||||
[1] = { "FR", "front right" },
|
||||
[2] = { "FC", "front center" },
|
||||
[3] = { "LFE", "low frequency" },
|
||||
[4] = { "BL", "back left" },
|
||||
[5] = { "BR", "back right" },
|
||||
[6] = { "FLC", "front left-of-center" },
|
||||
[7] = { "FRC", "front right-of-center" },
|
||||
[8] = { "BC", "back center" },
|
||||
[9] = { "SL", "side left" },
|
||||
[10] = { "SR", "side right" },
|
||||
[11] = { "TC", "top center" },
|
||||
[12] = { "TFL", "top front left" },
|
||||
[13] = { "TFC", "top front center" },
|
||||
[14] = { "TFR", "top front right" },
|
||||
[15] = { "TBL", "top back left" },
|
||||
[16] = { "TBC", "top back center" },
|
||||
[17] = { "TBR", "top back right" },
|
||||
[29] = { "DL", "downmix left" },
|
||||
[30] = { "DR", "downmix right" },
|
||||
[31] = { "WL", "wide left" },
|
||||
[32] = { "WR", "wide right" },
|
||||
[33] = { "SDL", "surround direct left" },
|
||||
[34] = { "SDR", "surround direct right" },
|
||||
[35] = { "LFE2", "low frequency 2" },
|
||||
};
|
||||
|
||||
static const char *get_channel_name(int channel_id)
|
||||
{
|
||||
if (channel_id < 0 || channel_id >= FF_ARRAY_ELEMS(channel_names))
|
||||
return NULL;
|
||||
return channel_names[channel_id].name;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
int nb_channels;
|
||||
uint64_t layout;
|
||||
} channel_layout_map[] = {
|
||||
{ "mono", 1, AV_CH_LAYOUT_MONO },
|
||||
{ "stereo", 2, AV_CH_LAYOUT_STEREO },
|
||||
{ "2.1", 3, AV_CH_LAYOUT_2POINT1 },
|
||||
{ "3.0", 3, AV_CH_LAYOUT_SURROUND },
|
||||
{ "3.0(back)", 3, AV_CH_LAYOUT_2_1 },
|
||||
{ "4.0", 4, AV_CH_LAYOUT_4POINT0 },
|
||||
{ "quad", 4, AV_CH_LAYOUT_QUAD },
|
||||
{ "quad(side)", 4, AV_CH_LAYOUT_2_2 },
|
||||
{ "3.1", 4, AV_CH_LAYOUT_3POINT1 },
|
||||
{ "5.0", 5, AV_CH_LAYOUT_5POINT0_BACK },
|
||||
{ "5.0(side)", 5, AV_CH_LAYOUT_5POINT0 },
|
||||
{ "4.1", 5, AV_CH_LAYOUT_4POINT1 },
|
||||
{ "5.1", 6, AV_CH_LAYOUT_5POINT1_BACK },
|
||||
{ "5.1(side)", 6, AV_CH_LAYOUT_5POINT1 },
|
||||
{ "6.0", 6, AV_CH_LAYOUT_6POINT0 },
|
||||
{ "6.0(front)", 6, AV_CH_LAYOUT_6POINT0_FRONT },
|
||||
{ "hexagonal", 6, AV_CH_LAYOUT_HEXAGONAL },
|
||||
{ "6.1", 7, AV_CH_LAYOUT_6POINT1 },
|
||||
{ "6.1(back)", 7, AV_CH_LAYOUT_6POINT1_BACK },
|
||||
{ "6.1(front)", 7, AV_CH_LAYOUT_6POINT1_FRONT },
|
||||
{ "7.0", 7, AV_CH_LAYOUT_7POINT0 },
|
||||
{ "7.0(front)", 7, AV_CH_LAYOUT_7POINT0_FRONT },
|
||||
{ "7.1", 8, AV_CH_LAYOUT_7POINT1 },
|
||||
{ "7.1(wide)", 8, AV_CH_LAYOUT_7POINT1_WIDE_BACK },
|
||||
{ "7.1(wide-side)", 8, AV_CH_LAYOUT_7POINT1_WIDE },
|
||||
{ "octagonal", 8, AV_CH_LAYOUT_OCTAGONAL },
|
||||
{ "hexadecagonal", 16, AV_CH_LAYOUT_HEXADECAGONAL },
|
||||
{ "downmix", 2, AV_CH_LAYOUT_STEREO_DOWNMIX, },
|
||||
};
|
||||
|
||||
static uint64_t get_channel_layout_single(const char *name, int name_len)
|
||||
{
|
||||
int i;
|
||||
char *end;
|
||||
int64_t layout;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) {
|
||||
if (strlen(channel_layout_map[i].name) == name_len &&
|
||||
!memcmp(channel_layout_map[i].name, name, name_len))
|
||||
return channel_layout_map[i].layout;
|
||||
}
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
|
||||
if (channel_names[i].name &&
|
||||
strlen(channel_names[i].name) == name_len &&
|
||||
!memcmp(channel_names[i].name, name, name_len))
|
||||
return (int64_t)1 << i;
|
||||
|
||||
errno = 0;
|
||||
i = strtol(name, &end, 10);
|
||||
|
||||
if (!errno && (end + 1 - name == name_len && *end == 'c'))
|
||||
return av_get_default_channel_layout(i);
|
||||
|
||||
errno = 0;
|
||||
layout = strtoll(name, &end, 0);
|
||||
if (!errno && end - name == name_len)
|
||||
return FFMAX(layout, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t av_get_channel_layout(const char *name)
|
||||
{
|
||||
const char *n, *e;
|
||||
const char *name_end = name + strlen(name);
|
||||
int64_t layout = 0, layout_single;
|
||||
|
||||
for (n = name; n < name_end; n = e + 1) {
|
||||
for (e = n; e < name_end && *e != '+' && *e != '|'; e++);
|
||||
layout_single = get_channel_layout_single(n, e - n);
|
||||
if (!layout_single)
|
||||
return 0;
|
||||
layout |= layout_single;
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
|
||||
{
|
||||
return av_popcount64(channel_layout);
|
||||
}
|
||||
|
||||
int64_t av_get_default_channel_layout(int nb_channels) {
|
||||
int i;
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
|
||||
if (nb_channels == channel_layout_map[i].nb_channels)
|
||||
return channel_layout_map[i].layout;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int av_get_channel_layout_channel_index(uint64_t channel_layout,
|
||||
uint64_t channel)
|
||||
{
|
||||
if (!(channel_layout & channel) ||
|
||||
av_get_channel_layout_nb_channels(channel) != 1)
|
||||
return AVERROR(EINVAL);
|
||||
channel_layout &= channel - 1;
|
||||
return av_get_channel_layout_nb_channels(channel_layout);
|
||||
}
|
||||
|
||||
const char *av_get_channel_name(uint64_t channel)
|
||||
{
|
||||
int i;
|
||||
if (av_get_channel_layout_nb_channels(channel) != 1)
|
||||
return NULL;
|
||||
for (i = 0; i < 64; i++)
|
||||
if ((1ULL<<i) & channel)
|
||||
return get_channel_name(i);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *av_get_channel_description(uint64_t channel)
|
||||
{
|
||||
int i;
|
||||
if (av_get_channel_layout_nb_channels(channel) != 1)
|
||||
return NULL;
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
|
||||
if ((1ULL<<i) & channel)
|
||||
return channel_names[i].description;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (av_get_channel_layout_nb_channels(channel_layout) <= index)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
if ((1ULL << i) & channel_layout && !index--)
|
||||
return 1ULL << i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int av_get_standard_channel_layout(unsigned index, uint64_t *layout,
|
||||
const char **name)
|
||||
{
|
||||
if (index >= FF_ARRAY_ELEMS(channel_layout_map))
|
||||
return AVERROR_EOF;
|
||||
if (layout) *layout = channel_layout_map[index].layout;
|
||||
if (name) *name = channel_layout_map[index].name;
|
||||
return 0;
|
||||
}
|
2933
ext/at3_standalone/codec_desc.c
Normal file
2933
ext/at3_standalone/codec_desc.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,22 +2,27 @@
|
||||
|
||||
// Compat hacks
|
||||
|
||||
#define av_cold
|
||||
#define DECLARE_ALIGNED(bits, type, name) type name
|
||||
#define LOCAL_ALIGNED(bits, type, name, subscript) type name subscript
|
||||
#define av_restrict
|
||||
#define av_always_inline __forceinline
|
||||
#define av_const
|
||||
#define av_alias
|
||||
#define av_unused
|
||||
#define av_pure
|
||||
#define av_warn_unused_result
|
||||
#define av_assert0(cond)
|
||||
#define av_assert1(cond)
|
||||
#define av_assert2(cond)
|
||||
#define av_log(...)
|
||||
#define attribute_deprecated
|
||||
#define av_printf_format(a,b)
|
||||
#define avpriv_report_missing_feature(...)
|
||||
#include "attributes.h"
|
||||
|
||||
#include "error.h"
|
||||
|
||||
#define CONFIG_MEMORY_POISONING 0
|
||||
#define CONFIG_HARDCODED_TABLES 0
|
||||
#define CONFIG_ME_CMP 0
|
||||
#define HWACCEL_CODEC_CAP_EXPERIMENTAL 0
|
||||
#define HAVE_THREADS 0
|
||||
#define CONFIG_FRAME_THREAD_ENCODER 0
|
||||
#define CONFIG_GRAY 0
|
||||
#define NULL_IF_CONFIG_SMALL(x) NULL
|
||||
#define ARCH_AARCH64 0
|
||||
#define ARCH_ARM 0
|
||||
#define ARCH_PPC 0
|
||||
#define ARCH_X86 0
|
||||
#define HAVE_MIPSFPU 0
|
||||
#define FF_API_AVPACKET_OLD_API 1
|
||||
#define FF_DISABLE_DEPRECATION_WARNINGS
|
||||
#define FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#define CONFIG_MDCT 1
|
||||
#define CONFIG_FFT 1
|
||||
|
||||
int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc);
|
||||
|
337
ext/at3_standalone/dict.c
Normal file
337
ext/at3_standalone/dict.c
Normal file
@ -0,0 +1,337 @@
|
||||
/*
|
||||
* copyright (c) 2009 Michael Niedermayer
|
||||
*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "avstring.h"
|
||||
#include "dict.h"
|
||||
#include "internal.h"
|
||||
#include "mem.h"
|
||||
|
||||
struct AVDictionary {
|
||||
int count;
|
||||
AVDictionaryEntry *elems;
|
||||
};
|
||||
|
||||
int av_dict_count(const AVDictionary *m)
|
||||
{
|
||||
return m ? m->count : 0;
|
||||
}
|
||||
|
||||
AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key,
|
||||
const AVDictionaryEntry *prev, int flags)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
if (!m)
|
||||
return NULL;
|
||||
|
||||
if (prev)
|
||||
i = prev - m->elems + 1;
|
||||
else
|
||||
i = 0;
|
||||
|
||||
for (; i < m->count; i++) {
|
||||
const char *s = m->elems[i].key;
|
||||
if (flags & AV_DICT_MATCH_CASE)
|
||||
for (j = 0; s[j] == key[j] && key[j]; j++)
|
||||
;
|
||||
else
|
||||
for (j = 0; av_toupper(s[j]) == av_toupper(key[j]) && key[j]; j++)
|
||||
;
|
||||
if (key[j])
|
||||
continue;
|
||||
if (s[j] && !(flags & AV_DICT_IGNORE_SUFFIX))
|
||||
continue;
|
||||
return &m->elems[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int av_dict_set(AVDictionary **pm, const char *key, const char *value,
|
||||
int flags)
|
||||
{
|
||||
AVDictionary *m = *pm;
|
||||
AVDictionaryEntry *tag = av_dict_get(m, key, NULL, flags);
|
||||
char *oldval = NULL, *copy_key = NULL, *copy_value = NULL;
|
||||
|
||||
if (flags & AV_DICT_DONT_STRDUP_KEY)
|
||||
copy_key = (void *)key;
|
||||
else
|
||||
copy_key = av_strdup(key);
|
||||
if (flags & AV_DICT_DONT_STRDUP_VAL)
|
||||
copy_value = (void *)value;
|
||||
else if (copy_key)
|
||||
copy_value = av_strdup(value);
|
||||
if (!m)
|
||||
m = *pm = av_mallocz(sizeof(*m));
|
||||
if (!m || (key && !copy_key) || (value && !copy_value))
|
||||
goto err_out;
|
||||
|
||||
if (tag) {
|
||||
if (flags & AV_DICT_DONT_OVERWRITE) {
|
||||
av_free(copy_key);
|
||||
av_free(copy_value);
|
||||
return 0;
|
||||
}
|
||||
if (flags & AV_DICT_APPEND)
|
||||
oldval = tag->value;
|
||||
else
|
||||
av_free(tag->value);
|
||||
av_free(tag->key);
|
||||
*tag = m->elems[--m->count];
|
||||
} else {
|
||||
AVDictionaryEntry *tmp = av_realloc(m->elems,
|
||||
(m->count + 1) * sizeof(*m->elems));
|
||||
if (!tmp)
|
||||
goto err_out;
|
||||
m->elems = tmp;
|
||||
}
|
||||
if (copy_value) {
|
||||
m->elems[m->count].key = copy_key;
|
||||
m->elems[m->count].value = copy_value;
|
||||
if (oldval && flags & AV_DICT_APPEND) {
|
||||
size_t len = strlen(oldval) + strlen(copy_value) + 1;
|
||||
char *newval = av_mallocz(len);
|
||||
if (!newval)
|
||||
goto err_out;
|
||||
av_strlcat(newval, oldval, len);
|
||||
av_freep(&oldval);
|
||||
av_strlcat(newval, copy_value, len);
|
||||
m->elems[m->count].value = newval;
|
||||
av_freep(©_value);
|
||||
}
|
||||
m->count++;
|
||||
} else {
|
||||
av_freep(©_key);
|
||||
}
|
||||
if (!m->count) {
|
||||
av_freep(&m->elems);
|
||||
av_freep(pm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
if (m && !m->count) {
|
||||
av_freep(&m->elems);
|
||||
av_freep(pm);
|
||||
}
|
||||
av_free(copy_key);
|
||||
av_free(copy_value);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value,
|
||||
int flags)
|
||||
{
|
||||
char valuestr[22];
|
||||
snprintf(valuestr, sizeof(valuestr), "%"PRId64, value);
|
||||
flags &= ~AV_DICT_DONT_STRDUP_VAL;
|
||||
return av_dict_set(pm, key, valuestr, flags);
|
||||
}
|
||||
|
||||
static int parse_key_value_pair(AVDictionary **pm, const char **buf,
|
||||
const char *key_val_sep, const char *pairs_sep,
|
||||
int flags)
|
||||
{
|
||||
char *key = av_get_token(buf, key_val_sep);
|
||||
char *val = NULL;
|
||||
int ret;
|
||||
|
||||
if (key && *key && strspn(*buf, key_val_sep)) {
|
||||
(*buf)++;
|
||||
val = av_get_token(buf, pairs_sep);
|
||||
}
|
||||
|
||||
if (key && *key && val && *val)
|
||||
ret = av_dict_set(pm, key, val, flags);
|
||||
else
|
||||
ret = AVERROR(EINVAL);
|
||||
|
||||
av_freep(&key);
|
||||
av_freep(&val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int av_dict_parse_string(AVDictionary **pm, const char *str,
|
||||
const char *key_val_sep, const char *pairs_sep,
|
||||
int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
/* ignore STRDUP flags */
|
||||
flags &= ~(AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
|
||||
|
||||
while (*str) {
|
||||
if ((ret = parse_key_value_pair(pm, &str, key_val_sep, pairs_sep, flags)) < 0)
|
||||
return ret;
|
||||
|
||||
if (*str)
|
||||
str++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void av_dict_free(AVDictionary **pm)
|
||||
{
|
||||
AVDictionary *m = *pm;
|
||||
|
||||
if (m) {
|
||||
while (m->count--) {
|
||||
av_freep(&m->elems[m->count].key);
|
||||
av_freep(&m->elems[m->count].value);
|
||||
}
|
||||
av_freep(&m->elems);
|
||||
}
|
||||
av_freep(pm);
|
||||
}
|
||||
|
||||
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
|
||||
{
|
||||
AVDictionaryEntry *t = NULL;
|
||||
|
||||
while ((t = av_dict_get(src, "", t, AV_DICT_IGNORE_SUFFIX))) {
|
||||
int ret = av_dict_set(dst, t->key, t->value, flags);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
static void print_dict(const AVDictionary *m)
|
||||
{
|
||||
AVDictionaryEntry *t = NULL;
|
||||
while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX)))
|
||||
printf("%s %s ", t->key, t->value);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void test_separators(const AVDictionary *m, const char pair, const char val)
|
||||
{
|
||||
AVDictionary *dict = NULL;
|
||||
char pairs[] = {pair , '\0'};
|
||||
char vals[] = {val, '\0'};
|
||||
|
||||
char *buffer = NULL;
|
||||
av_dict_copy(&dict, m, 0);
|
||||
print_dict(dict);
|
||||
av_dict_get_string(dict, &buffer, val, pair);
|
||||
printf("%s\n", buffer);
|
||||
av_dict_free(&dict);
|
||||
av_dict_parse_string(&dict, buffer, vals, pairs, 0);
|
||||
av_freep(&buffer);
|
||||
print_dict(dict);
|
||||
av_dict_free(&dict);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
AVDictionary *dict = NULL;
|
||||
AVDictionaryEntry *e;
|
||||
char *buffer = NULL;
|
||||
|
||||
printf("Testing av_dict_get_string() and av_dict_parse_string()\n");
|
||||
av_dict_get_string(dict, &buffer, '=', ',');
|
||||
printf("%s\n", buffer);
|
||||
av_freep(&buffer);
|
||||
av_dict_set(&dict, "aaa", "aaa", 0);
|
||||
av_dict_set(&dict, "b,b", "bbb", 0);
|
||||
av_dict_set(&dict, "c=c", "ccc", 0);
|
||||
av_dict_set(&dict, "ddd", "d,d", 0);
|
||||
av_dict_set(&dict, "eee", "e=e", 0);
|
||||
av_dict_set(&dict, "f,f", "f=f", 0);
|
||||
av_dict_set(&dict, "g=g", "g,g", 0);
|
||||
test_separators(dict, ',', '=');
|
||||
av_dict_free(&dict);
|
||||
av_dict_set(&dict, "aaa", "aaa", 0);
|
||||
av_dict_set(&dict, "bbb", "bbb", 0);
|
||||
av_dict_set(&dict, "ccc", "ccc", 0);
|
||||
av_dict_set(&dict, "\\,=\'\"", "\\,=\'\"", 0);
|
||||
test_separators(dict, '"', '=');
|
||||
test_separators(dict, '\'', '=');
|
||||
test_separators(dict, ',', '"');
|
||||
test_separators(dict, ',', '\'');
|
||||
test_separators(dict, '\'', '"');
|
||||
test_separators(dict, '"', '\'');
|
||||
av_dict_free(&dict);
|
||||
|
||||
printf("\nTesting av_dict_set()\n");
|
||||
av_dict_set(&dict, "a", "a", 0);
|
||||
av_dict_set(&dict, "b", av_strdup("b"), AV_DICT_DONT_STRDUP_VAL);
|
||||
av_dict_set(&dict, av_strdup("c"), "c", AV_DICT_DONT_STRDUP_KEY);
|
||||
av_dict_set(&dict, av_strdup("d"), av_strdup("d"), AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
|
||||
av_dict_set(&dict, "e", "e", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&dict, "e", "f", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&dict, "f", "f", 0);
|
||||
av_dict_set(&dict, "f", NULL, 0);
|
||||
av_dict_set(&dict, "ff", "f", 0);
|
||||
av_dict_set(&dict, "ff", "f", AV_DICT_APPEND);
|
||||
e = NULL;
|
||||
while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX)))
|
||||
printf("%s %s\n", e->key, e->value);
|
||||
av_dict_free(&dict);
|
||||
|
||||
av_dict_set(&dict, NULL, "a", 0);
|
||||
av_dict_set(&dict, NULL, "b", 0);
|
||||
av_dict_get(dict, NULL, NULL, 0);
|
||||
e = NULL;
|
||||
while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX)))
|
||||
printf("'%s' '%s'\n", e->key, e->value);
|
||||
av_dict_free(&dict);
|
||||
|
||||
|
||||
//valgrind sensible test
|
||||
printf("\nTesting av_dict_set_int()\n");
|
||||
av_dict_set_int(&dict, "1", 1, AV_DICT_DONT_STRDUP_VAL);
|
||||
av_dict_set_int(&dict, av_strdup("2"), 2, AV_DICT_DONT_STRDUP_KEY);
|
||||
av_dict_set_int(&dict, av_strdup("3"), 3, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
|
||||
av_dict_set_int(&dict, "4", 4, 0);
|
||||
av_dict_set_int(&dict, "5", 5, AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set_int(&dict, "5", 6, AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set_int(&dict, "12", 1, 0);
|
||||
av_dict_set_int(&dict, "12", 2, AV_DICT_APPEND);
|
||||
e = NULL;
|
||||
while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX)))
|
||||
printf("%s %s\n", e->key, e->value);
|
||||
av_dict_free(&dict);
|
||||
|
||||
//valgrind sensible test
|
||||
printf("\nTesting av_dict_set() with existing AVDictionaryEntry.key as key\n");
|
||||
av_dict_set(&dict, "key", "old", 0);
|
||||
e = av_dict_get(dict, "key", NULL, 0);
|
||||
av_dict_set(&dict, e->key, "new val OK", 0);
|
||||
e = av_dict_get(dict, "key", NULL, 0);
|
||||
printf("%s\n", e->value);
|
||||
av_dict_set(&dict, e->key, e->value, 0);
|
||||
e = av_dict_get(dict, "key", NULL, 0);
|
||||
printf("%s\n", e->value);
|
||||
av_dict_free(&dict);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
94
ext/at3_standalone/fft-internal.h
Normal file
94
ext/at3_standalone/fft-internal.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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_FFT_INTERNAL_H
|
||||
#define AVCODEC_FFT_INTERNAL_H
|
||||
|
||||
#if FFT_FLOAT
|
||||
|
||||
#define FIX15(v) (v)
|
||||
#define sqrthalf (float)M_SQRT1_2
|
||||
|
||||
#define BF(x, y, a, b) do { \
|
||||
x = a - b; \
|
||||
y = a + b; \
|
||||
} while (0)
|
||||
|
||||
#define CMUL(dre, dim, are, aim, bre, bim) do { \
|
||||
(dre) = (are) * (bre) - (aim) * (bim); \
|
||||
(dim) = (are) * (bim) + (aim) * (bre); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define SCALE_FLOAT(a, bits) lrint((a) * (double)(1 << (bits)))
|
||||
|
||||
#if FFT_FIXED_32
|
||||
|
||||
#define CMUL(dre, dim, are, aim, bre, bim) do { \
|
||||
int64_t accu; \
|
||||
(accu) = (int64_t)(bre) * (are); \
|
||||
(accu) -= (int64_t)(bim) * (aim); \
|
||||
(dre) = (int)(((accu) + 0x40000000) >> 31); \
|
||||
(accu) = (int64_t)(bre) * (aim); \
|
||||
(accu) += (int64_t)(bim) * (are); \
|
||||
(dim) = (int)(((accu) + 0x40000000) >> 31); \
|
||||
} while (0)
|
||||
|
||||
#define FIX15(a) av_clip(SCALE_FLOAT(a, 31), -2147483647, 2147483647)
|
||||
|
||||
#else /* FFT_FIXED_32 */
|
||||
|
||||
#include "fft.h"
|
||||
#include "mathops.h"
|
||||
|
||||
void ff_mdct_calcw_c(FFTContext *s, FFTDouble *output, const FFTSample *input);
|
||||
|
||||
#define FIX15(a) av_clip(SCALE_FLOAT(a, 15), -32767, 32767)
|
||||
|
||||
#define sqrthalf ((int16_t)((1<<15)*M_SQRT1_2))
|
||||
|
||||
#define BF(x, y, a, b) do { \
|
||||
x = (a - b) >> 1; \
|
||||
y = (a + b) >> 1; \
|
||||
} while (0)
|
||||
|
||||
#define CMULS(dre, dim, are, aim, bre, bim, sh) do { \
|
||||
(dre) = (MUL16(are, bre) - MUL16(aim, bim)) >> sh; \
|
||||
(dim) = (MUL16(are, bim) + MUL16(aim, bre)) >> sh; \
|
||||
} while (0)
|
||||
|
||||
#define CMUL(dre, dim, are, aim, bre, bim) \
|
||||
CMULS(dre, dim, are, aim, bre, bim, 15)
|
||||
|
||||
#define CMULL(dre, dim, are, aim, bre, bim) \
|
||||
CMULS(dre, dim, are, aim, bre, bim, 0)
|
||||
|
||||
#endif /* FFT_FIXED_32 */
|
||||
|
||||
#endif /* FFT_FLOAT */
|
||||
|
||||
#define ff_imdct_calc_c FFT_NAME(ff_imdct_calc_c)
|
||||
#define ff_imdct_half_c FFT_NAME(ff_imdct_half_c)
|
||||
#define ff_mdct_calc_c FFT_NAME(ff_mdct_calc_c)
|
||||
|
||||
void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input);
|
||||
void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input);
|
||||
void ff_mdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input);
|
||||
|
||||
#endif /* AVCODEC_FFT_INTERNAL_H */
|
531
ext/at3_standalone/fft_template.c
Normal file
531
ext/at3_standalone/fft_template.c
Normal file
@ -0,0 +1,531 @@
|
||||
/*
|
||||
* FFT/IFFT transforms
|
||||
* Copyright (c) 2008 Loren Merritt
|
||||
* Copyright (c) 2002 Fabrice Bellard
|
||||
* Partly based on libdjbfft by D. J. Bernstein
|
||||
*
|
||||
* 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
|
||||
* FFT/IFFT transforms.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mem.h"
|
||||
#include "mathematics.h"
|
||||
#include "fft.h"
|
||||
#include "fft-internal.h"
|
||||
|
||||
#if FFT_FIXED_32
|
||||
#include "fft_table.h"
|
||||
#else /* FFT_FIXED_32 */
|
||||
|
||||
/* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */
|
||||
#if !CONFIG_HARDCODED_TABLES
|
||||
COSTABLE(16);
|
||||
COSTABLE(32);
|
||||
COSTABLE(64);
|
||||
COSTABLE(128);
|
||||
COSTABLE(256);
|
||||
COSTABLE(512);
|
||||
COSTABLE(1024);
|
||||
COSTABLE(2048);
|
||||
COSTABLE(4096);
|
||||
COSTABLE(8192);
|
||||
COSTABLE(16384);
|
||||
COSTABLE(32768);
|
||||
COSTABLE(65536);
|
||||
#endif
|
||||
COSTABLE_CONST FFTSample * const FFT_NAME(ff_cos_tabs)[] = {
|
||||
NULL, NULL, NULL, NULL,
|
||||
FFT_NAME(ff_cos_16),
|
||||
FFT_NAME(ff_cos_32),
|
||||
FFT_NAME(ff_cos_64),
|
||||
FFT_NAME(ff_cos_128),
|
||||
FFT_NAME(ff_cos_256),
|
||||
FFT_NAME(ff_cos_512),
|
||||
FFT_NAME(ff_cos_1024),
|
||||
FFT_NAME(ff_cos_2048),
|
||||
FFT_NAME(ff_cos_4096),
|
||||
FFT_NAME(ff_cos_8192),
|
||||
FFT_NAME(ff_cos_16384),
|
||||
FFT_NAME(ff_cos_32768),
|
||||
FFT_NAME(ff_cos_65536),
|
||||
};
|
||||
|
||||
#endif /* FFT_FIXED_32 */
|
||||
|
||||
static void fft_permute_c(FFTContext *s, FFTComplex *z);
|
||||
static void fft_calc_c(FFTContext *s, FFTComplex *z);
|
||||
|
||||
static int split_radix_permutation(int i, int n, int inverse)
|
||||
{
|
||||
int m;
|
||||
if(n <= 2) return i&1;
|
||||
m = n >> 1;
|
||||
if(!(i&m)) return split_radix_permutation(i, m, inverse)*2;
|
||||
m >>= 1;
|
||||
if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1;
|
||||
else return split_radix_permutation(i, m, inverse)*4 - 1;
|
||||
}
|
||||
|
||||
av_cold void ff_init_ff_cos_tabs(int index)
|
||||
{
|
||||
#if (!CONFIG_HARDCODED_TABLES) && (!FFT_FIXED_32)
|
||||
int i;
|
||||
int m = 1<<index;
|
||||
double freq = 2*M_PI/m;
|
||||
FFTSample *tab = FFT_NAME(ff_cos_tabs)[index];
|
||||
for(i=0; i<=m/4; i++)
|
||||
tab[i] = FIX15(cos(i*freq));
|
||||
for(i=1; i<m/4; i++)
|
||||
tab[m/2-i] = tab[i];
|
||||
#endif
|
||||
}
|
||||
|
||||
static const int avx_tab[] = {
|
||||
0, 4, 1, 5, 8, 12, 9, 13, 2, 6, 3, 7, 10, 14, 11, 15
|
||||
};
|
||||
|
||||
static int is_second_half_of_fft32(int i, int n)
|
||||
{
|
||||
if (n <= 32)
|
||||
return i >= 16;
|
||||
else if (i < n/2)
|
||||
return is_second_half_of_fft32(i, n/2);
|
||||
else if (i < 3*n/4)
|
||||
return is_second_half_of_fft32(i - n/2, n/4);
|
||||
else
|
||||
return is_second_half_of_fft32(i - 3*n/4, n/4);
|
||||
}
|
||||
|
||||
static av_cold void fft_perm_avx(FFTContext *s)
|
||||
{
|
||||
int i;
|
||||
int n = 1 << s->nbits;
|
||||
|
||||
for (i = 0; i < n; i += 16) {
|
||||
int k;
|
||||
if (is_second_half_of_fft32(i, n)) {
|
||||
for (k = 0; k < 16; k++)
|
||||
s->revtab[-split_radix_permutation(i + k, n, s->inverse) & (n - 1)] =
|
||||
i + avx_tab[k];
|
||||
|
||||
} else {
|
||||
for (k = 0; k < 16; k++) {
|
||||
int j = i + k;
|
||||
j = (j & ~7) | ((j >> 1) & 3) | ((j << 2) & 4);
|
||||
s->revtab[-split_radix_permutation(i + k, n, s->inverse) & (n - 1)] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse)
|
||||
{
|
||||
int i, j, n;
|
||||
|
||||
if (nbits < 2 || nbits > 16)
|
||||
goto fail;
|
||||
s->nbits = nbits;
|
||||
n = 1 << nbits;
|
||||
|
||||
s->revtab = av_malloc(n * sizeof(uint16_t));
|
||||
if (!s->revtab)
|
||||
goto fail;
|
||||
s->tmp_buf = av_malloc(n * sizeof(FFTComplex));
|
||||
if (!s->tmp_buf)
|
||||
goto fail;
|
||||
s->inverse = inverse;
|
||||
s->fft_permutation = FF_FFT_PERM_DEFAULT;
|
||||
|
||||
s->fft_permute = fft_permute_c;
|
||||
s->fft_calc = fft_calc_c;
|
||||
#if CONFIG_MDCT
|
||||
s->imdct_calc = ff_imdct_calc_c;
|
||||
s->imdct_half = ff_imdct_half_c;
|
||||
s->mdct_calc = ff_mdct_calc_c;
|
||||
#endif
|
||||
|
||||
#if FFT_FIXED_32
|
||||
{
|
||||
int n=0;
|
||||
ff_fft_lut_init(ff_fft_offsets_lut, 0, 1 << 16, &n);
|
||||
}
|
||||
#else /* FFT_FIXED_32 */
|
||||
#if FFT_FLOAT
|
||||
if (ARCH_AARCH64) ff_fft_init_aarch64(s);
|
||||
if (ARCH_ARM) ff_fft_init_arm(s);
|
||||
if (ARCH_PPC) ff_fft_init_ppc(s);
|
||||
if (ARCH_X86) ff_fft_init_x86(s);
|
||||
if (CONFIG_MDCT) s->mdct_calcw = s->mdct_calc;
|
||||
if (HAVE_MIPSFPU) ff_fft_init_mips(s);
|
||||
#else
|
||||
if (CONFIG_MDCT) s->mdct_calcw = ff_mdct_calcw_c;
|
||||
if (ARCH_ARM) ff_fft_fixed_init_arm(s);
|
||||
#endif
|
||||
for(j=4; j<=nbits; j++) {
|
||||
ff_init_ff_cos_tabs(j);
|
||||
}
|
||||
#endif /* FFT_FIXED_32 */
|
||||
|
||||
|
||||
if (s->fft_permutation == FF_FFT_PERM_AVX) {
|
||||
fft_perm_avx(s);
|
||||
} else {
|
||||
for(i=0; i<n; i++) {
|
||||
j = i;
|
||||
if (s->fft_permutation == FF_FFT_PERM_SWAP_LSBS)
|
||||
j = (j&~3) | ((j>>1)&1) | ((j<<1)&2);
|
||||
int index = -split_radix_permutation(i, n, s->inverse) & (n - 1);
|
||||
s->revtab[index] = j;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
av_freep(&s->revtab);
|
||||
av_freep(&s->tmp_buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void fft_permute_c(FFTContext *s, FFTComplex *z)
|
||||
{
|
||||
int j, np;
|
||||
const uint16_t *revtab = s->revtab;
|
||||
np = 1 << s->nbits;
|
||||
/* TODO: handle split-radix permute in a more optimal way, probably in-place */
|
||||
for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j];
|
||||
memcpy(z, s->tmp_buf, np * sizeof(FFTComplex));
|
||||
}
|
||||
|
||||
av_cold void ff_fft_end(FFTContext *s)
|
||||
{
|
||||
av_freep(&s->revtab);
|
||||
av_freep(&s->tmp_buf);
|
||||
}
|
||||
|
||||
#if FFT_FIXED_32
|
||||
|
||||
static void fft_calc_c(FFTContext *s, FFTComplex *z) {
|
||||
|
||||
int nbits, i, n, num_transforms, offset, step;
|
||||
int n4, n2, n34;
|
||||
FFTSample tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
|
||||
FFTComplex *tmpz;
|
||||
const int fft_size = (1 << s->nbits);
|
||||
int64_t accu;
|
||||
|
||||
num_transforms = (0x2aab >> (16 - s->nbits)) | 1;
|
||||
|
||||
for (n=0; n<num_transforms; n++){
|
||||
offset = ff_fft_offsets_lut[n] << 2;
|
||||
tmpz = z + offset;
|
||||
|
||||
tmp1 = tmpz[0].re + tmpz[1].re;
|
||||
tmp5 = tmpz[2].re + tmpz[3].re;
|
||||
tmp2 = tmpz[0].im + tmpz[1].im;
|
||||
tmp6 = tmpz[2].im + tmpz[3].im;
|
||||
tmp3 = tmpz[0].re - tmpz[1].re;
|
||||
tmp8 = tmpz[2].im - tmpz[3].im;
|
||||
tmp4 = tmpz[0].im - tmpz[1].im;
|
||||
tmp7 = tmpz[2].re - tmpz[3].re;
|
||||
|
||||
tmpz[0].re = tmp1 + tmp5;
|
||||
tmpz[2].re = tmp1 - tmp5;
|
||||
tmpz[0].im = tmp2 + tmp6;
|
||||
tmpz[2].im = tmp2 - tmp6;
|
||||
tmpz[1].re = tmp3 + tmp8;
|
||||
tmpz[3].re = tmp3 - tmp8;
|
||||
tmpz[1].im = tmp4 - tmp7;
|
||||
tmpz[3].im = tmp4 + tmp7;
|
||||
}
|
||||
|
||||
if (fft_size < 8)
|
||||
return;
|
||||
|
||||
num_transforms = (num_transforms >> 1) | 1;
|
||||
|
||||
for (n=0; n<num_transforms; n++){
|
||||
offset = ff_fft_offsets_lut[n] << 3;
|
||||
tmpz = z + offset;
|
||||
|
||||
tmp1 = tmpz[4].re + tmpz[5].re;
|
||||
tmp3 = tmpz[6].re + tmpz[7].re;
|
||||
tmp2 = tmpz[4].im + tmpz[5].im;
|
||||
tmp4 = tmpz[6].im + tmpz[7].im;
|
||||
tmp5 = tmp1 + tmp3;
|
||||
tmp7 = tmp1 - tmp3;
|
||||
tmp6 = tmp2 + tmp4;
|
||||
tmp8 = tmp2 - tmp4;
|
||||
|
||||
tmp1 = tmpz[4].re - tmpz[5].re;
|
||||
tmp2 = tmpz[4].im - tmpz[5].im;
|
||||
tmp3 = tmpz[6].re - tmpz[7].re;
|
||||
tmp4 = tmpz[6].im - tmpz[7].im;
|
||||
|
||||
tmpz[4].re = tmpz[0].re - tmp5;
|
||||
tmpz[0].re = tmpz[0].re + tmp5;
|
||||
tmpz[4].im = tmpz[0].im - tmp6;
|
||||
tmpz[0].im = tmpz[0].im + tmp6;
|
||||
tmpz[6].re = tmpz[2].re - tmp8;
|
||||
tmpz[2].re = tmpz[2].re + tmp8;
|
||||
tmpz[6].im = tmpz[2].im + tmp7;
|
||||
tmpz[2].im = tmpz[2].im - tmp7;
|
||||
|
||||
accu = (int64_t)Q31(M_SQRT1_2)*(tmp1 + tmp2);
|
||||
tmp5 = (int32_t)((accu + 0x40000000) >> 31);
|
||||
accu = (int64_t)Q31(M_SQRT1_2)*(tmp3 - tmp4);
|
||||
tmp7 = (int32_t)((accu + 0x40000000) >> 31);
|
||||
accu = (int64_t)Q31(M_SQRT1_2)*(tmp2 - tmp1);
|
||||
tmp6 = (int32_t)((accu + 0x40000000) >> 31);
|
||||
accu = (int64_t)Q31(M_SQRT1_2)*(tmp3 + tmp4);
|
||||
tmp8 = (int32_t)((accu + 0x40000000) >> 31);
|
||||
tmp1 = tmp5 + tmp7;
|
||||
tmp3 = tmp5 - tmp7;
|
||||
tmp2 = tmp6 + tmp8;
|
||||
tmp4 = tmp6 - tmp8;
|
||||
|
||||
tmpz[5].re = tmpz[1].re - tmp1;
|
||||
tmpz[1].re = tmpz[1].re + tmp1;
|
||||
tmpz[5].im = tmpz[1].im - tmp2;
|
||||
tmpz[1].im = tmpz[1].im + tmp2;
|
||||
tmpz[7].re = tmpz[3].re - tmp4;
|
||||
tmpz[3].re = tmpz[3].re + tmp4;
|
||||
tmpz[7].im = tmpz[3].im + tmp3;
|
||||
tmpz[3].im = tmpz[3].im - tmp3;
|
||||
}
|
||||
|
||||
step = 1 << ((MAX_LOG2_NFFT-4) - 4);
|
||||
n4 = 4;
|
||||
|
||||
for (nbits=4; nbits<=s->nbits; nbits++){
|
||||
n2 = 2*n4;
|
||||
n34 = 3*n4;
|
||||
num_transforms = (num_transforms >> 1) | 1;
|
||||
|
||||
for (n=0; n<num_transforms; n++){
|
||||
const FFTSample *w_re_ptr = ff_w_tab_sr + step;
|
||||
const FFTSample *w_im_ptr = ff_w_tab_sr + MAX_FFT_SIZE/(4*16) - step;
|
||||
offset = ff_fft_offsets_lut[n] << nbits;
|
||||
tmpz = z + offset;
|
||||
|
||||
tmp5 = tmpz[ n2].re + tmpz[n34].re;
|
||||
tmp1 = tmpz[ n2].re - tmpz[n34].re;
|
||||
tmp6 = tmpz[ n2].im + tmpz[n34].im;
|
||||
tmp2 = tmpz[ n2].im - tmpz[n34].im;
|
||||
|
||||
tmpz[ n2].re = tmpz[ 0].re - tmp5;
|
||||
tmpz[ 0].re = tmpz[ 0].re + tmp5;
|
||||
tmpz[ n2].im = tmpz[ 0].im - tmp6;
|
||||
tmpz[ 0].im = tmpz[ 0].im + tmp6;
|
||||
tmpz[n34].re = tmpz[n4].re - tmp2;
|
||||
tmpz[ n4].re = tmpz[n4].re + tmp2;
|
||||
tmpz[n34].im = tmpz[n4].im + tmp1;
|
||||
tmpz[ n4].im = tmpz[n4].im - tmp1;
|
||||
|
||||
for (i=1; i<n4; i++){
|
||||
FFTSample w_re = w_re_ptr[0];
|
||||
FFTSample w_im = w_im_ptr[0];
|
||||
accu = (int64_t)w_re*tmpz[ n2+i].re;
|
||||
accu += (int64_t)w_im*tmpz[ n2+i].im;
|
||||
tmp1 = (int32_t)((accu + 0x40000000) >> 31);
|
||||
accu = (int64_t)w_re*tmpz[ n2+i].im;
|
||||
accu -= (int64_t)w_im*tmpz[ n2+i].re;
|
||||
tmp2 = (int32_t)((accu + 0x40000000) >> 31);
|
||||
accu = (int64_t)w_re*tmpz[n34+i].re;
|
||||
accu -= (int64_t)w_im*tmpz[n34+i].im;
|
||||
tmp3 = (int32_t)((accu + 0x40000000) >> 31);
|
||||
accu = (int64_t)w_re*tmpz[n34+i].im;
|
||||
accu += (int64_t)w_im*tmpz[n34+i].re;
|
||||
tmp4 = (int32_t)((accu + 0x40000000) >> 31);
|
||||
|
||||
tmp5 = tmp1 + tmp3;
|
||||
tmp1 = tmp1 - tmp3;
|
||||
tmp6 = tmp2 + tmp4;
|
||||
tmp2 = tmp2 - tmp4;
|
||||
|
||||
tmpz[ n2+i].re = tmpz[ i].re - tmp5;
|
||||
tmpz[ i].re = tmpz[ i].re + tmp5;
|
||||
tmpz[ n2+i].im = tmpz[ i].im - tmp6;
|
||||
tmpz[ i].im = tmpz[ i].im + tmp6;
|
||||
tmpz[n34+i].re = tmpz[n4+i].re - tmp2;
|
||||
tmpz[ n4+i].re = tmpz[n4+i].re + tmp2;
|
||||
tmpz[n34+i].im = tmpz[n4+i].im + tmp1;
|
||||
tmpz[ n4+i].im = tmpz[n4+i].im - tmp1;
|
||||
|
||||
w_re_ptr += step;
|
||||
w_im_ptr -= step;
|
||||
}
|
||||
}
|
||||
step >>= 1;
|
||||
n4 <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* FFT_FIXED_32 */
|
||||
|
||||
#define BUTTERFLIES(a0,a1,a2,a3) {\
|
||||
BF(t3, t5, t5, t1);\
|
||||
BF(a2.re, a0.re, a0.re, t5);\
|
||||
BF(a3.im, a1.im, a1.im, t3);\
|
||||
BF(t4, t6, t2, t6);\
|
||||
BF(a3.re, a1.re, a1.re, t4);\
|
||||
BF(a2.im, a0.im, a0.im, t6);\
|
||||
}
|
||||
|
||||
// force loading all the inputs before storing any.
|
||||
// this is slightly slower for small data, but avoids store->load aliasing
|
||||
// for addresses separated by large powers of 2.
|
||||
#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\
|
||||
FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\
|
||||
BF(t3, t5, t5, t1);\
|
||||
BF(a2.re, a0.re, r0, t5);\
|
||||
BF(a3.im, a1.im, i1, t3);\
|
||||
BF(t4, t6, t2, t6);\
|
||||
BF(a3.re, a1.re, r1, t4);\
|
||||
BF(a2.im, a0.im, i0, t6);\
|
||||
}
|
||||
|
||||
#define TRANSFORM(a0,a1,a2,a3,wre,wim) {\
|
||||
CMUL(t1, t2, a2.re, a2.im, wre, -wim);\
|
||||
CMUL(t5, t6, a3.re, a3.im, wre, wim);\
|
||||
BUTTERFLIES(a0,a1,a2,a3)\
|
||||
}
|
||||
|
||||
#define TRANSFORM_ZERO(a0,a1,a2,a3) {\
|
||||
t1 = a2.re;\
|
||||
t2 = a2.im;\
|
||||
t5 = a3.re;\
|
||||
t6 = a3.im;\
|
||||
BUTTERFLIES(a0,a1,a2,a3)\
|
||||
}
|
||||
|
||||
/* z[0...8n-1], w[1...2n-1] */
|
||||
#define PASS(name)\
|
||||
static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\
|
||||
{\
|
||||
FFTDouble t1, t2, t3, t4, t5, t6;\
|
||||
int o1 = 2*n;\
|
||||
int o2 = 4*n;\
|
||||
int o3 = 6*n;\
|
||||
const FFTSample *wim = wre+o1;\
|
||||
n--;\
|
||||
\
|
||||
TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\
|
||||
TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
|
||||
do {\
|
||||
z += 2;\
|
||||
wre += 2;\
|
||||
wim -= 2;\
|
||||
TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\
|
||||
TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
|
||||
} while(--n);\
|
||||
}
|
||||
|
||||
PASS(pass)
|
||||
#undef BUTTERFLIES
|
||||
#define BUTTERFLIES BUTTERFLIES_BIG
|
||||
PASS(pass_big)
|
||||
|
||||
#define DECL_FFT(n,n2,n4)\
|
||||
static void fft##n(FFTComplex *z)\
|
||||
{\
|
||||
fft##n2(z);\
|
||||
fft##n4(z+n4*2);\
|
||||
fft##n4(z+n4*3);\
|
||||
pass(z,FFT_NAME(ff_cos_##n),n4/2);\
|
||||
}
|
||||
|
||||
static void fft4(FFTComplex *z)
|
||||
{
|
||||
FFTDouble t1, t2, t3, t4, t5, t6, t7, t8;
|
||||
|
||||
BF(t3, t1, z[0].re, z[1].re);
|
||||
BF(t8, t6, z[3].re, z[2].re);
|
||||
BF(z[2].re, z[0].re, t1, t6);
|
||||
BF(t4, t2, z[0].im, z[1].im);
|
||||
BF(t7, t5, z[2].im, z[3].im);
|
||||
BF(z[3].im, z[1].im, t4, t8);
|
||||
BF(z[3].re, z[1].re, t3, t7);
|
||||
BF(z[2].im, z[0].im, t2, t5);
|
||||
}
|
||||
|
||||
static void fft8(FFTComplex *z)
|
||||
{
|
||||
FFTDouble t1, t2, t3, t4, t5, t6;
|
||||
|
||||
fft4(z);
|
||||
|
||||
BF(t1, z[5].re, z[4].re, -z[5].re);
|
||||
BF(t2, z[5].im, z[4].im, -z[5].im);
|
||||
BF(t5, z[7].re, z[6].re, -z[7].re);
|
||||
BF(t6, z[7].im, z[6].im, -z[7].im);
|
||||
|
||||
BUTTERFLIES(z[0],z[2],z[4],z[6]);
|
||||
TRANSFORM(z[1],z[3],z[5],z[7],sqrthalf,sqrthalf);
|
||||
}
|
||||
|
||||
#if !CONFIG_SMALL
|
||||
static void fft16(FFTComplex *z)
|
||||
{
|
||||
FFTDouble t1, t2, t3, t4, t5, t6;
|
||||
FFTSample cos_16_1 = FFT_NAME(ff_cos_16)[1];
|
||||
FFTSample cos_16_3 = FFT_NAME(ff_cos_16)[3];
|
||||
|
||||
fft8(z);
|
||||
fft4(z+8);
|
||||
fft4(z+12);
|
||||
|
||||
TRANSFORM_ZERO(z[0],z[4],z[8],z[12]);
|
||||
TRANSFORM(z[2],z[6],z[10],z[14],sqrthalf,sqrthalf);
|
||||
TRANSFORM(z[1],z[5],z[9],z[13],cos_16_1,cos_16_3);
|
||||
TRANSFORM(z[3],z[7],z[11],z[15],cos_16_3,cos_16_1);
|
||||
}
|
||||
#else
|
||||
DECL_FFT(16,8,4)
|
||||
#endif
|
||||
DECL_FFT(32,16,8)
|
||||
DECL_FFT(64,32,16)
|
||||
DECL_FFT(128,64,32)
|
||||
DECL_FFT(256,128,64)
|
||||
DECL_FFT(512,256,128)
|
||||
#if !CONFIG_SMALL
|
||||
#define pass pass_big
|
||||
#endif
|
||||
DECL_FFT(1024,512,256)
|
||||
DECL_FFT(2048,1024,512)
|
||||
DECL_FFT(4096,2048,1024)
|
||||
DECL_FFT(8192,4096,2048)
|
||||
DECL_FFT(16384,8192,4096)
|
||||
DECL_FFT(32768,16384,8192)
|
||||
DECL_FFT(65536,32768,16384)
|
||||
|
||||
static void (* const fft_dispatch[])(FFTComplex*) = {
|
||||
fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024,
|
||||
fft2048, fft4096, fft8192, fft16384, fft32768, fft65536,
|
||||
};
|
||||
|
||||
static void fft_calc_c(FFTContext *s, FFTComplex *z)
|
||||
{
|
||||
fft_dispatch[s->nbits-2](z);
|
||||
}
|
||||
#endif /* FFT_FIXED_32 */
|
@ -162,58 +162,6 @@ void av_frame_free(AVFrame **frame)
|
||||
av_freep(frame);
|
||||
}
|
||||
|
||||
static int get_video_buffer(AVFrame *frame, int align)
|
||||
{
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
|
||||
int ret, i;
|
||||
|
||||
if (!desc)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0)
|
||||
return ret;
|
||||
|
||||
if (!frame->linesize[0]) {
|
||||
for(i=1; i<=align; i+=i) {
|
||||
ret = av_image_fill_linesizes(frame->linesize, frame->format,
|
||||
FFALIGN(frame->width, i));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!(frame->linesize[0] & (align-1)))
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4 && frame->linesize[i]; i++)
|
||||
frame->linesize[i] = FFALIGN(frame->linesize[i], align);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4 && frame->linesize[i]; i++) {
|
||||
int h = FFALIGN(frame->height, 32);
|
||||
if (i == 1 || i == 2)
|
||||
h = AV_CEIL_RSHIFT(h, desc->log2_chroma_h);
|
||||
|
||||
frame->buf[i] = av_buffer_alloc(frame->linesize[i] * h + 16 + 16/*STRIDE_ALIGN*/ - 1);
|
||||
if (!frame->buf[i])
|
||||
goto fail;
|
||||
|
||||
frame->data[i] = frame->buf[i]->data;
|
||||
}
|
||||
if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
|
||||
av_buffer_unref(&frame->buf[1]);
|
||||
frame->buf[1] = av_buffer_alloc(AVPALETTE_SIZE);
|
||||
if (!frame->buf[1])
|
||||
goto fail;
|
||||
frame->data[1] = frame->buf[1]->data;
|
||||
}
|
||||
|
||||
frame->extended_data = frame->data;
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
av_frame_unref(frame);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
static int get_audio_buffer(AVFrame *frame, int align)
|
||||
{
|
||||
int channels;
|
||||
@ -275,8 +223,8 @@ int av_frame_get_buffer(AVFrame *frame, int align)
|
||||
if (frame->format < 0)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
if (frame->width > 0 && frame->height > 0)
|
||||
return get_video_buffer(frame, align);
|
||||
if (frame->width > 0 && frame->height > 0)
|
||||
return AVERROR(EINVAL);
|
||||
else if (frame->nb_samples > 0 && (frame->channel_layout || frame->channels > 0))
|
||||
return get_audio_buffer(frame, align);
|
||||
|
||||
@ -648,28 +596,6 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int frame_copy_video(AVFrame *dst, const AVFrame *src)
|
||||
{
|
||||
const uint8_t *src_data[4];
|
||||
int i, planes;
|
||||
|
||||
if (dst->width < src->width ||
|
||||
dst->height < src->height)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
planes = av_pix_fmt_count_planes(dst->format);
|
||||
for (i = 0; i < planes; i++)
|
||||
if (!dst->data[i] || !src->data[i])
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
memcpy(src_data, src->data, sizeof(src_data));
|
||||
av_image_copy(dst->data, dst->linesize,
|
||||
src_data, src->linesize,
|
||||
dst->format, src->width, src->height);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int frame_copy_audio(AVFrame *dst, const AVFrame *src)
|
||||
{
|
||||
int planar = av_sample_fmt_is_planar(dst->format);
|
||||
@ -700,7 +626,7 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
if (dst->width > 0 && dst->height > 0)
|
||||
return frame_copy_video(dst, src);
|
||||
return AVERROR(EINVAL);
|
||||
else if (dst->nb_samples > 0 && dst->channel_layout)
|
||||
return frame_copy_audio(dst, src);
|
||||
|
||||
|
34
ext/at3_standalone/intmath.c
Normal file
34
ext/at3_standalone/intmath.c
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 "intmath.h"
|
||||
|
||||
/* undef these to get the function prototypes from common.h */
|
||||
#undef av_log2
|
||||
#undef av_log2_16bit
|
||||
#include "common.h"
|
||||
|
||||
int av_log2(unsigned v)
|
||||
{
|
||||
return ff_log2(v);
|
||||
}
|
||||
|
||||
int av_log2_16bit(unsigned v)
|
||||
{
|
||||
return ff_log2_16bit(v);
|
||||
}
|
165
ext/at3_standalone/intmath.h
Normal file
165
ext/at3_standalone/intmath.h
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_INTMATH_H
|
||||
#define AVUTIL_INTMATH_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "attributes.h"
|
||||
|
||||
#if ARCH_ARM
|
||||
# include "arm/intmath.h"
|
||||
#endif
|
||||
#if ARCH_X86
|
||||
# include "x86/intmath.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_FAST_CLZ
|
||||
#if AV_GCC_VERSION_AT_LEAST(3,4)
|
||||
#ifndef ff_log2
|
||||
# define ff_log2(x) (31 - __builtin_clz((x)|1))
|
||||
# ifndef ff_log2_16bit
|
||||
# define ff_log2_16bit av_log2
|
||||
# endif
|
||||
#endif /* ff_log2 */
|
||||
#endif /* AV_GCC_VERSION_AT_LEAST(3,4) */
|
||||
#endif
|
||||
|
||||
extern const uint8_t ff_log2_tab[256];
|
||||
|
||||
#ifndef ff_log2
|
||||
#define ff_log2 ff_log2_c
|
||||
static av_always_inline av_const int ff_log2_c(unsigned int v)
|
||||
{
|
||||
int n = 0;
|
||||
if (v & 0xffff0000) {
|
||||
v >>= 16;
|
||||
n += 16;
|
||||
}
|
||||
if (v & 0xff00) {
|
||||
v >>= 8;
|
||||
n += 8;
|
||||
}
|
||||
n += ff_log2_tab[v];
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ff_log2_16bit
|
||||
#define ff_log2_16bit ff_log2_16bit_c
|
||||
static av_always_inline av_const int ff_log2_16bit_c(unsigned int v)
|
||||
{
|
||||
int n = 0;
|
||||
if (v & 0xff00) {
|
||||
v >>= 8;
|
||||
n += 8;
|
||||
}
|
||||
n += ff_log2_tab[v];
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define av_log2 ff_log2
|
||||
#define av_log2_16bit ff_log2_16bit
|
||||
|
||||
/**
|
||||
* @addtogroup lavu_math
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if HAVE_FAST_CLZ
|
||||
#if AV_GCC_VERSION_AT_LEAST(3,4)
|
||||
#ifndef ff_ctz
|
||||
#define ff_ctz(v) __builtin_ctz(v)
|
||||
#endif
|
||||
#ifndef ff_ctzll
|
||||
#define ff_ctzll(v) __builtin_ctzll(v)
|
||||
#endif
|
||||
#ifndef ff_clz
|
||||
#define ff_clz(v) __builtin_clz(v)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ff_ctz
|
||||
#define ff_ctz ff_ctz_c
|
||||
/**
|
||||
* Trailing zero bit count.
|
||||
*
|
||||
* @param v input value. If v is 0, the result is undefined.
|
||||
* @return the number of trailing 0-bits
|
||||
*/
|
||||
/* We use the De-Bruijn method outlined in:
|
||||
* http://supertech.csail.mit.edu/papers/debruijn.pdf. */
|
||||
static av_always_inline av_const int ff_ctz_c(int v)
|
||||
{
|
||||
static const uint8_t debruijn_ctz32[32] = {
|
||||
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
|
||||
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
|
||||
};
|
||||
return debruijn_ctz32[(uint32_t)((v & -v) * 0x077CB531U) >> 27];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ff_ctzll
|
||||
#define ff_ctzll ff_ctzll_c
|
||||
/* We use the De-Bruijn method outlined in:
|
||||
* http://supertech.csail.mit.edu/papers/debruijn.pdf. */
|
||||
static av_always_inline av_const int ff_ctzll_c(long long v)
|
||||
{
|
||||
static const uint8_t debruijn_ctz64[64] = {
|
||||
0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
|
||||
62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
|
||||
63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
|
||||
51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
|
||||
};
|
||||
return debruijn_ctz64[(uint64_t)((v & -v) * 0x022FDD63CC95386DU) >> 58];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ff_clz
|
||||
#define ff_clz ff_clz_c
|
||||
static av_always_inline av_const unsigned ff_clz_c(unsigned x)
|
||||
{
|
||||
unsigned i = sizeof(x) * 8;
|
||||
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
i--;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if AV_GCC_VERSION_AT_LEAST(3,4)
|
||||
#ifndef av_parity
|
||||
#define av_parity __builtin_parity
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* AVUTIL_INTMATH_H */
|
32
ext/at3_standalone/log2_tab.c
Normal file
32
ext/at3_standalone/log2_tab.c
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2012 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
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
const uint8_t ff_log2_tab[256]={
|
||||
0,0,1,1,2,2,2,2,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,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,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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
|
||||
};
|
210
ext/at3_standalone/mathematics.c
Normal file
210
ext/at3_standalone/mathematics.c
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 2005-2012 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
|
||||
* miscellaneous math routines and tables
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "mathematics.h"
|
||||
#include "intmath.h"
|
||||
#include "common.h"
|
||||
#include "version.h"
|
||||
|
||||
/* Stein's binary GCD algorithm:
|
||||
* https://en.wikipedia.org/wiki/Binary_GCD_algorithm */
|
||||
int64_t av_gcd(int64_t a, int64_t b) {
|
||||
int za, zb, k;
|
||||
int64_t u, v;
|
||||
if (a == 0)
|
||||
return b;
|
||||
if (b == 0)
|
||||
return a;
|
||||
za = ff_ctzll(a);
|
||||
zb = ff_ctzll(b);
|
||||
k = FFMIN(za, zb);
|
||||
u = llabs(a >> za);
|
||||
v = llabs(b >> zb);
|
||||
while (u != v) {
|
||||
if (u > v)
|
||||
FFSWAP(int64_t, v, u);
|
||||
v -= u;
|
||||
v >>= ff_ctzll(v);
|
||||
}
|
||||
return (uint64_t)u << k;
|
||||
}
|
||||
|
||||
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
|
||||
{
|
||||
int64_t r = 0;
|
||||
av_assert2(c > 0);
|
||||
av_assert2(b >=0);
|
||||
av_assert2((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4);
|
||||
|
||||
if (c <= 0 || b < 0 || !((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4))
|
||||
return INT64_MIN;
|
||||
|
||||
if (rnd & AV_ROUND_PASS_MINMAX) {
|
||||
if (a == INT64_MIN || a == INT64_MAX)
|
||||
return a;
|
||||
rnd -= AV_ROUND_PASS_MINMAX;
|
||||
}
|
||||
|
||||
if (a < 0)
|
||||
return -(uint64_t)av_rescale_rnd(-FFMAX(a, -INT64_MAX), b, c, rnd ^ ((rnd >> 1) & 1));
|
||||
|
||||
if (rnd == AV_ROUND_NEAR_INF)
|
||||
r = c / 2;
|
||||
else if (rnd & 1)
|
||||
r = c - 1;
|
||||
|
||||
if (b <= INT_MAX && c <= INT_MAX) {
|
||||
if (a <= INT_MAX)
|
||||
return (a * b + r) / c;
|
||||
else {
|
||||
int64_t ad = a / c;
|
||||
int64_t a2 = (a % c * b + r) / c;
|
||||
if (ad >= INT32_MAX && b && ad > (INT64_MAX - a2) / b)
|
||||
return INT64_MIN;
|
||||
return ad * b + a2;
|
||||
}
|
||||
} else {
|
||||
#if 1
|
||||
uint64_t a0 = a & 0xFFFFFFFF;
|
||||
uint64_t a1 = a >> 32;
|
||||
uint64_t b0 = b & 0xFFFFFFFF;
|
||||
uint64_t b1 = b >> 32;
|
||||
uint64_t t1 = a0 * b1 + a1 * b0;
|
||||
uint64_t t1a = t1 << 32;
|
||||
int i;
|
||||
|
||||
a0 = a0 * b0 + t1a;
|
||||
a1 = a1 * b1 + (t1 >> 32) + (a0 < t1a);
|
||||
a0 += r;
|
||||
a1 += a0 < r;
|
||||
|
||||
for (i = 63; i >= 0; i--) {
|
||||
a1 += a1 + ((a0 >> i) & 1);
|
||||
t1 += t1;
|
||||
if (c <= a1) {
|
||||
a1 -= c;
|
||||
t1++;
|
||||
}
|
||||
}
|
||||
if (t1 > INT64_MAX)
|
||||
return INT64_MIN;
|
||||
return t1;
|
||||
}
|
||||
#else
|
||||
AVInteger ai;
|
||||
ai = av_mul_i(av_int2i(a), av_int2i(b));
|
||||
ai = av_add_i(ai, av_int2i(r));
|
||||
|
||||
return av_i2int(av_div_i(ai, av_int2i(c)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
|
||||
{
|
||||
return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF);
|
||||
}
|
||||
|
||||
int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq,
|
||||
enum AVRounding rnd)
|
||||
{
|
||||
int64_t b = bq.num * (int64_t)cq.den;
|
||||
int64_t c = cq.num * (int64_t)bq.den;
|
||||
return av_rescale_rnd(a, b, c, rnd);
|
||||
}
|
||||
|
||||
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
|
||||
{
|
||||
return av_rescale_q_rnd(a, bq, cq, AV_ROUND_NEAR_INF);
|
||||
}
|
||||
|
||||
int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
|
||||
{
|
||||
int64_t a = tb_a.num * (int64_t)tb_b.den;
|
||||
int64_t b = tb_b.num * (int64_t)tb_a.den;
|
||||
if ((FFABS(ts_a)|a|FFABS(ts_b)|b) <= INT_MAX)
|
||||
return (ts_a*a > ts_b*b) - (ts_a*a < ts_b*b);
|
||||
if (av_rescale_rnd(ts_a, a, b, AV_ROUND_DOWN) < ts_b)
|
||||
return -1;
|
||||
if (av_rescale_rnd(ts_b, b, a, AV_ROUND_DOWN) < ts_a)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod)
|
||||
{
|
||||
int64_t c = (a - b) & (mod - 1);
|
||||
if (c > (mod >> 1))
|
||||
c -= mod;
|
||||
return c;
|
||||
}
|
||||
|
||||
int64_t av_rescale_delta(AVRational in_tb, int64_t in_ts, AVRational fs_tb, int duration, int64_t *last, AVRational out_tb){
|
||||
int64_t a, b, this;
|
||||
|
||||
av_assert0(in_ts != AV_NOPTS_VALUE);
|
||||
av_assert0(duration >= 0);
|
||||
|
||||
if (*last == AV_NOPTS_VALUE || !duration || in_tb.num*(int64_t)out_tb.den <= out_tb.num*(int64_t)in_tb.den) {
|
||||
simple_round:
|
||||
*last = av_rescale_q(in_ts, in_tb, fs_tb) + duration;
|
||||
return av_rescale_q(in_ts, in_tb, out_tb);
|
||||
}
|
||||
|
||||
a = av_rescale_q_rnd(2*in_ts-1, in_tb, fs_tb, AV_ROUND_DOWN) >>1;
|
||||
b = (av_rescale_q_rnd(2*in_ts+1, in_tb, fs_tb, AV_ROUND_UP )+1)>>1;
|
||||
if (*last < 2*a - b || *last > 2*b - a)
|
||||
goto simple_round;
|
||||
|
||||
this = av_clip64(*last, a, b);
|
||||
*last = this + duration;
|
||||
|
||||
return av_rescale_q(this, fs_tb, out_tb);
|
||||
}
|
||||
|
||||
int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc)
|
||||
{
|
||||
int64_t m, d;
|
||||
|
||||
if (inc != 1)
|
||||
inc_tb = av_mul_q(inc_tb, (AVRational) {inc, 1});
|
||||
|
||||
m = inc_tb.num * (int64_t)ts_tb.den;
|
||||
d = inc_tb.den * (int64_t)ts_tb.num;
|
||||
|
||||
if (m % d == 0)
|
||||
return ts + m / d;
|
||||
if (m < d)
|
||||
return ts;
|
||||
|
||||
{
|
||||
int64_t old = av_rescale_q(ts, ts_tb, inc_tb);
|
||||
int64_t old_ts = av_rescale_q(old, inc_tb, ts_tb);
|
||||
return av_rescale_q(old + 1, inc_tb, ts_tb) + (ts - old_ts);
|
||||
}
|
||||
}
|
213
ext/at3_standalone/mdct_template.c
Normal file
213
ext/at3_standalone/mdct_template.c
Normal file
@ -0,0 +1,213 @@
|
||||
/*
|
||||
* MDCT/IMDCT transforms
|
||||
* Copyright (c) 2002 Fabrice Bellard
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "common.h"
|
||||
#include "libm.h"
|
||||
#include "mathematics.h"
|
||||
#include "fft.h"
|
||||
#include "fft-internal.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* MDCT/IMDCT transforms.
|
||||
*/
|
||||
|
||||
#if FFT_FLOAT
|
||||
# define RSCALE(x) (x)
|
||||
#else
|
||||
#if FFT_FIXED_32
|
||||
# define RSCALE(x) (((x) + 32) >> 6)
|
||||
#else /* FFT_FIXED_32 */
|
||||
# define RSCALE(x) ((x) >> 1)
|
||||
#endif /* FFT_FIXED_32 */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* init MDCT or IMDCT computation.
|
||||
*/
|
||||
av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
|
||||
{
|
||||
int n, n4, i;
|
||||
double alpha, theta;
|
||||
int tstep;
|
||||
|
||||
memset(s, 0, sizeof(*s));
|
||||
n = 1 << nbits;
|
||||
s->mdct_bits = nbits;
|
||||
s->mdct_size = n;
|
||||
n4 = n >> 2;
|
||||
s->mdct_permutation = FF_MDCT_PERM_NONE;
|
||||
|
||||
if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0)
|
||||
goto fail;
|
||||
|
||||
s->tcos = av_malloc_array(n/2, sizeof(FFTSample));
|
||||
if (!s->tcos)
|
||||
goto fail;
|
||||
|
||||
switch (s->mdct_permutation) {
|
||||
case FF_MDCT_PERM_NONE:
|
||||
s->tsin = s->tcos + n4;
|
||||
tstep = 1;
|
||||
break;
|
||||
case FF_MDCT_PERM_INTERLEAVE:
|
||||
s->tsin = s->tcos + 1;
|
||||
tstep = 2;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0);
|
||||
scale = sqrt(fabs(scale));
|
||||
for(i=0;i<n4;i++) {
|
||||
alpha = 2 * M_PI * (i + theta) / n;
|
||||
#if FFT_FIXED_32
|
||||
s->tcos[i*tstep] = lrint(-cos(alpha) * 2147483648.0);
|
||||
s->tsin[i*tstep] = lrint(-sin(alpha) * 2147483648.0);
|
||||
#else
|
||||
s->tcos[i*tstep] = FIX15(-cos(alpha) * scale);
|
||||
s->tsin[i*tstep] = FIX15(-sin(alpha) * scale);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
ff_mdct_end(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the middle half of the inverse MDCT of size N = 2^nbits,
|
||||
* thus excluding the parts that can be derived by symmetry
|
||||
* @param output N/2 samples
|
||||
* @param input N/2 samples
|
||||
*/
|
||||
void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input)
|
||||
{
|
||||
int k, n8, n4, n2, n, j;
|
||||
const uint16_t *revtab = s->revtab;
|
||||
const FFTSample *tcos = s->tcos;
|
||||
const FFTSample *tsin = s->tsin;
|
||||
const FFTSample *in1, *in2;
|
||||
FFTComplex *z = (FFTComplex *)output;
|
||||
|
||||
n = 1 << s->mdct_bits;
|
||||
n2 = n >> 1;
|
||||
n4 = n >> 2;
|
||||
n8 = n >> 3;
|
||||
|
||||
/* pre rotation */
|
||||
in1 = input;
|
||||
in2 = input + n2 - 1;
|
||||
for(k = 0; k < n4; k++) {
|
||||
j=revtab[k];
|
||||
CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]);
|
||||
in1 += 2;
|
||||
in2 -= 2;
|
||||
}
|
||||
s->fft_calc(s, z);
|
||||
|
||||
/* post rotation + reordering */
|
||||
for(k = 0; k < n8; k++) {
|
||||
FFTSample r0, i0, r1, i1;
|
||||
CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]);
|
||||
CMUL(r1, i0, z[n8+k ].im, z[n8+k ].re, tsin[n8+k ], tcos[n8+k ]);
|
||||
z[n8-k-1].re = r0;
|
||||
z[n8-k-1].im = i0;
|
||||
z[n8+k ].re = r1;
|
||||
z[n8+k ].im = i1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute inverse MDCT of size N = 2^nbits
|
||||
* @param output N samples
|
||||
* @param input N/2 samples
|
||||
*/
|
||||
void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input)
|
||||
{
|
||||
int k;
|
||||
int n = 1 << s->mdct_bits;
|
||||
int n2 = n >> 1;
|
||||
int n4 = n >> 2;
|
||||
|
||||
ff_imdct_half_c(s, output+n4, input);
|
||||
|
||||
for(k = 0; k < n4; k++) {
|
||||
output[k] = -output[n2-k-1];
|
||||
output[n-k-1] = output[n2+k];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute MDCT of size N = 2^nbits
|
||||
* @param input N samples
|
||||
* @param out N/2 samples
|
||||
*/
|
||||
void ff_mdct_calc_c(FFTContext *s, FFTSample *out, const FFTSample *input)
|
||||
{
|
||||
int i, j, n, n8, n4, n2, n3;
|
||||
FFTDouble re, im;
|
||||
const uint16_t *revtab = s->revtab;
|
||||
const FFTSample *tcos = s->tcos;
|
||||
const FFTSample *tsin = s->tsin;
|
||||
FFTComplex *x = (FFTComplex *)out;
|
||||
|
||||
n = 1 << s->mdct_bits;
|
||||
n2 = n >> 1;
|
||||
n4 = n >> 2;
|
||||
n8 = n >> 3;
|
||||
n3 = 3 * n4;
|
||||
|
||||
/* pre rotation */
|
||||
for(i=0;i<n8;i++) {
|
||||
re = RSCALE(-input[2*i+n3] - input[n3-1-2*i]);
|
||||
im = RSCALE(-input[n4+2*i] + input[n4-1-2*i]);
|
||||
j = revtab[i];
|
||||
CMUL(x[j].re, x[j].im, re, im, -tcos[i], tsin[i]);
|
||||
|
||||
re = RSCALE( input[2*i] - input[n2-1-2*i]);
|
||||
im = RSCALE(-input[n2+2*i] - input[ n-1-2*i]);
|
||||
j = revtab[n8 + i];
|
||||
CMUL(x[j].re, x[j].im, re, im, -tcos[n8 + i], tsin[n8 + i]);
|
||||
}
|
||||
|
||||
s->fft_calc(s, x);
|
||||
|
||||
/* post rotation */
|
||||
for(i=0;i<n8;i++) {
|
||||
FFTSample r0, i0, r1, i1;
|
||||
CMUL(i1, r0, x[n8-i-1].re, x[n8-i-1].im, -tsin[n8-i-1], -tcos[n8-i-1]);
|
||||
CMUL(i0, r1, x[n8+i ].re, x[n8+i ].im, -tsin[n8+i ], -tcos[n8+i ]);
|
||||
x[n8-i-1].re = r0;
|
||||
x[n8-i-1].im = i0;
|
||||
x[n8+i ].re = r1;
|
||||
x[n8+i ].im = i1;
|
||||
}
|
||||
}
|
||||
|
||||
av_cold void ff_mdct_end(FFTContext *s)
|
||||
{
|
||||
av_freep(&s->tcos);
|
||||
ff_fft_end(s);
|
||||
}
|
@ -36,10 +36,9 @@
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "avassert.h"
|
||||
#include "compat.h"
|
||||
#include "avutil.h"
|
||||
#include "common.h"
|
||||
#include "dynarray.h"
|
||||
#include "intreadwrite.h"
|
||||
#include "mem.h"
|
||||
|
||||
@ -59,7 +58,24 @@ void free(void *ptr);
|
||||
|
||||
#endif /* MALLOC_PREFIX */
|
||||
|
||||
#include "mem_internal.h"
|
||||
int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc)
|
||||
{
|
||||
void *val;
|
||||
|
||||
memcpy(&val, ptr, sizeof(val));
|
||||
if (min_size <= *size) {
|
||||
av_assert0(val || !min_size);
|
||||
return 0;
|
||||
}
|
||||
min_size = FFMAX(min_size + min_size / 16 + 32, min_size);
|
||||
av_freep(ptr);
|
||||
val = zero_realloc ? av_mallocz(min_size) : av_malloc(min_size);
|
||||
memcpy(ptr, &val, sizeof(val));
|
||||
if (!val)
|
||||
min_size = 0;
|
||||
*size = min_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define ALIGN (HAVE_AVX ? 32 : 16)
|
||||
|
||||
@ -307,51 +323,6 @@ void *av_memdup(const void *p, size_t size)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem)
|
||||
{
|
||||
void **tab;
|
||||
memcpy(&tab, tab_ptr, sizeof(tab));
|
||||
|
||||
AV_DYNARRAY_ADD(INT_MAX, sizeof(*tab), tab, *nb_ptr, {
|
||||
tab[*nb_ptr] = elem;
|
||||
memcpy(tab_ptr, &tab, sizeof(tab));
|
||||
}, {
|
||||
return AVERROR(ENOMEM);
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
|
||||
void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem)
|
||||
{
|
||||
void **tab;
|
||||
memcpy(&tab, tab_ptr, sizeof(tab));
|
||||
|
||||
AV_DYNARRAY_ADD(INT_MAX, sizeof(*tab), tab, *nb_ptr, {
|
||||
tab[*nb_ptr] = elem;
|
||||
memcpy(tab_ptr, &tab, sizeof(tab));
|
||||
}, {
|
||||
*nb_ptr = 0;
|
||||
av_freep(tab_ptr);
|
||||
});
|
||||
}
|
||||
|
||||
void *av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size,
|
||||
const uint8_t *elem_data)
|
||||
{
|
||||
uint8_t *tab_elem_data = NULL;
|
||||
|
||||
AV_DYNARRAY_ADD(INT_MAX, elem_size, *tab_ptr, *nb_ptr, {
|
||||
tab_elem_data = (uint8_t *)*tab_ptr + (*nb_ptr) * elem_size;
|
||||
if (elem_data)
|
||||
memcpy(tab_elem_data, elem_data, elem_size);
|
||||
else if (CONFIG_MEMORY_POISONING)
|
||||
memset(tab_elem_data, FF_MEMORY_POISON, elem_size);
|
||||
}, {
|
||||
av_freep(tab_ptr);
|
||||
*nb_ptr = 0;
|
||||
});
|
||||
return tab_elem_data;
|
||||
}
|
||||
|
||||
static void fill16(uint8_t *dst, int len)
|
||||
{
|
||||
|
1593
ext/at3_standalone/opt.c
Normal file
1593
ext/at3_standalone/opt.c
Normal file
File diff suppressed because it is too large
Load Diff
865
ext/at3_standalone/opt.h
Normal file
865
ext/at3_standalone/opt.h
Normal file
@ -0,0 +1,865 @@
|
||||
/*
|
||||
* AVOptions
|
||||
* copyright (c) 2005 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 AVUTIL_OPT_H
|
||||
#define AVUTIL_OPT_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* AVOptions
|
||||
*/
|
||||
|
||||
#include "rational.h"
|
||||
#include "avutil.h"
|
||||
#include "dict.h"
|
||||
#include "log.h"
|
||||
#include "pixfmt.h"
|
||||
#include "samplefmt.h"
|
||||
#include "version.h"
|
||||
|
||||
/**
|
||||
* @defgroup avoptions AVOptions
|
||||
* @ingroup lavu_data
|
||||
* @{
|
||||
* AVOptions provide a generic system to declare options on arbitrary structs
|
||||
* ("objects"). An option can have a help text, a type and a range of possible
|
||||
* values. Options may then be enumerated, read and written to.
|
||||
*
|
||||
* @section avoptions_implement Implementing AVOptions
|
||||
* This section describes how to add AVOptions capabilities to a struct.
|
||||
*
|
||||
* All AVOptions-related information is stored in an AVClass. Therefore
|
||||
* the first member of the struct should be a pointer to an AVClass describing it.
|
||||
* The option field of the AVClass must be set to a NULL-terminated static array
|
||||
* of AVOptions. Each AVOption must have a non-empty name, a type, a default
|
||||
* value and for number-type AVOptions also a range of allowed values. It must
|
||||
* also declare an offset in bytes from the start of the struct, where the field
|
||||
* associated with this AVOption is located. Other fields in the AVOption struct
|
||||
* should also be set when applicable, but are not required.
|
||||
*
|
||||
* The following example illustrates an AVOptions-enabled struct:
|
||||
* @code
|
||||
* typedef struct test_struct {
|
||||
* AVClass *class;
|
||||
* int int_opt;
|
||||
* char *str_opt;
|
||||
* uint8_t *bin_opt;
|
||||
* int bin_len;
|
||||
* } test_struct;
|
||||
*
|
||||
* static const AVOption test_options[] = {
|
||||
* { "test_int", "This is a test option of int type.", offsetof(test_struct, int_opt),
|
||||
* AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX },
|
||||
* { "test_str", "This is a test option of string type.", offsetof(test_struct, str_opt),
|
||||
* AV_OPT_TYPE_STRING },
|
||||
* { "test_bin", "This is a test option of binary type.", offsetof(test_struct, bin_opt),
|
||||
* AV_OPT_TYPE_BINARY },
|
||||
* { NULL },
|
||||
* };
|
||||
*
|
||||
* static const AVClass test_class = {
|
||||
* .class_name = "test class",
|
||||
* .item_name = av_default_item_name,
|
||||
* .option = test_options,
|
||||
* .version = LIBAVUTIL_VERSION_INT,
|
||||
* };
|
||||
* @endcode
|
||||
*
|
||||
* Next, when allocating your struct, you must ensure that the AVClass pointer
|
||||
* is set to the correct value. Then, av_opt_set_defaults() can be called to
|
||||
* initialize defaults. After that the struct is ready to be used with the
|
||||
* AVOptions API.
|
||||
*
|
||||
* When cleaning up, you may use the av_opt_free() function to automatically
|
||||
* free all the allocated string and binary options.
|
||||
*
|
||||
* Continuing with the above example:
|
||||
*
|
||||
* @code
|
||||
* test_struct *alloc_test_struct(void)
|
||||
* {
|
||||
* test_struct *ret = av_malloc(sizeof(*ret));
|
||||
* ret->class = &test_class;
|
||||
* av_opt_set_defaults(ret);
|
||||
* return ret;
|
||||
* }
|
||||
* void free_test_struct(test_struct **foo)
|
||||
* {
|
||||
* av_opt_free(*foo);
|
||||
* av_freep(foo);
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @subsection avoptions_implement_nesting Nesting
|
||||
* It may happen that an AVOptions-enabled struct contains another
|
||||
* AVOptions-enabled struct as a member (e.g. AVCodecContext in
|
||||
* libavcodec exports generic options, while its priv_data field exports
|
||||
* codec-specific options). In such a case, it is possible to set up the
|
||||
* parent struct to export a child's options. To do that, simply
|
||||
* implement AVClass.child_next() and AVClass.child_class_next() in the
|
||||
* parent struct's AVClass.
|
||||
* Assuming that the test_struct from above now also contains a
|
||||
* child_struct field:
|
||||
*
|
||||
* @code
|
||||
* typedef struct child_struct {
|
||||
* AVClass *class;
|
||||
* int flags_opt;
|
||||
* } child_struct;
|
||||
* static const AVOption child_opts[] = {
|
||||
* { "test_flags", "This is a test option of flags type.",
|
||||
* offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX },
|
||||
* { NULL },
|
||||
* };
|
||||
* static const AVClass child_class = {
|
||||
* .class_name = "child class",
|
||||
* .item_name = av_default_item_name,
|
||||
* .option = child_opts,
|
||||
* .version = LIBAVUTIL_VERSION_INT,
|
||||
* };
|
||||
*
|
||||
* void *child_next(void *obj, void *prev)
|
||||
* {
|
||||
* test_struct *t = obj;
|
||||
* if (!prev && t->child_struct)
|
||||
* return t->child_struct;
|
||||
* return NULL
|
||||
* }
|
||||
* const AVClass child_class_next(const AVClass *prev)
|
||||
* {
|
||||
* return prev ? NULL : &child_class;
|
||||
* }
|
||||
* @endcode
|
||||
* Putting child_next() and child_class_next() as defined above into
|
||||
* test_class will now make child_struct's options accessible through
|
||||
* test_struct (again, proper setup as described above needs to be done on
|
||||
* child_struct right after it is created).
|
||||
*
|
||||
* From the above example it might not be clear why both child_next()
|
||||
* and child_class_next() are needed. The distinction is that child_next()
|
||||
* iterates over actually existing objects, while child_class_next()
|
||||
* iterates over all possible child classes. E.g. if an AVCodecContext
|
||||
* was initialized to use a codec which has private options, then its
|
||||
* child_next() will return AVCodecContext.priv_data and finish
|
||||
* iterating. OTOH child_class_next() on AVCodecContext.av_class will
|
||||
* iterate over all available codecs with private options.
|
||||
*
|
||||
* @subsection avoptions_implement_named_constants Named constants
|
||||
* It is possible to create named constants for options. Simply set the unit
|
||||
* field of the option the constants should apply to a string and
|
||||
* create the constants themselves as options of type AV_OPT_TYPE_CONST
|
||||
* with their unit field set to the same string.
|
||||
* Their default_val field should contain the value of the named
|
||||
* constant.
|
||||
* For example, to add some named constants for the test_flags option
|
||||
* above, put the following into the child_opts array:
|
||||
* @code
|
||||
* { "test_flags", "This is a test option of flags type.",
|
||||
* offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX, "test_unit" },
|
||||
* { "flag1", "This is a flag with value 16", 0, AV_OPT_TYPE_CONST, { .i64 = 16 }, 0, 0, "test_unit" },
|
||||
* @endcode
|
||||
*
|
||||
* @section avoptions_use Using AVOptions
|
||||
* This section deals with accessing options in an AVOptions-enabled struct.
|
||||
* Such structs in FFmpeg are e.g. AVCodecContext in libavcodec or
|
||||
* AVFormatContext in libavformat.
|
||||
*
|
||||
* @subsection avoptions_use_examine Examining AVOptions
|
||||
* The basic functions for examining options are av_opt_next(), which iterates
|
||||
* over all options defined for one object, and av_opt_find(), which searches
|
||||
* for an option with the given name.
|
||||
*
|
||||
* The situation is more complicated with nesting. An AVOptions-enabled struct
|
||||
* may have AVOptions-enabled children. Passing the AV_OPT_SEARCH_CHILDREN flag
|
||||
* to av_opt_find() will make the function search children recursively.
|
||||
*
|
||||
* For enumerating there are basically two cases. The first is when you want to
|
||||
* get all options that may potentially exist on the struct and its children
|
||||
* (e.g. when constructing documentation). In that case you should call
|
||||
* av_opt_child_class_next() recursively on the parent struct's AVClass. The
|
||||
* second case is when you have an already initialized struct with all its
|
||||
* children and you want to get all options that can be actually written or read
|
||||
* from it. In that case you should call av_opt_child_next() recursively (and
|
||||
* av_opt_next() on each result).
|
||||
*
|
||||
* @subsection avoptions_use_get_set Reading and writing AVOptions
|
||||
* When setting options, you often have a string read directly from the
|
||||
* user. In such a case, simply passing it to av_opt_set() is enough. For
|
||||
* non-string type options, av_opt_set() will parse the string according to the
|
||||
* option type.
|
||||
*
|
||||
* Similarly av_opt_get() will read any option type and convert it to a string
|
||||
* which will be returned. Do not forget that the string is allocated, so you
|
||||
* have to free it with av_free().
|
||||
*
|
||||
* In some cases it may be more convenient to put all options into an
|
||||
* AVDictionary and call av_opt_set_dict() on it. A specific case of this
|
||||
* are the format/codec open functions in lavf/lavc which take a dictionary
|
||||
* filled with option as a parameter. This makes it possible to set some options
|
||||
* that cannot be set otherwise, since e.g. the input file format is not known
|
||||
* before the file is actually opened.
|
||||
*/
|
||||
|
||||
enum AVOptionType{
|
||||
AV_OPT_TYPE_FLAGS,
|
||||
AV_OPT_TYPE_INT,
|
||||
AV_OPT_TYPE_INT64,
|
||||
AV_OPT_TYPE_DOUBLE,
|
||||
AV_OPT_TYPE_FLOAT,
|
||||
AV_OPT_TYPE_STRING,
|
||||
AV_OPT_TYPE_RATIONAL,
|
||||
AV_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length
|
||||
AV_OPT_TYPE_DICT,
|
||||
AV_OPT_TYPE_CONST = 128,
|
||||
AV_OPT_TYPE_IMAGE_SIZE = MKBETAG('S','I','Z','E'), ///< offset must point to two consecutive integers
|
||||
AV_OPT_TYPE_PIXEL_FMT = MKBETAG('P','F','M','T'),
|
||||
AV_OPT_TYPE_SAMPLE_FMT = MKBETAG('S','F','M','T'),
|
||||
AV_OPT_TYPE_VIDEO_RATE = MKBETAG('V','R','A','T'), ///< offset must point to AVRational
|
||||
AV_OPT_TYPE_DURATION = MKBETAG('D','U','R',' '),
|
||||
AV_OPT_TYPE_COLOR = MKBETAG('C','O','L','R'),
|
||||
AV_OPT_TYPE_CHANNEL_LAYOUT = MKBETAG('C','H','L','A'),
|
||||
AV_OPT_TYPE_BOOL = MKBETAG('B','O','O','L'),
|
||||
};
|
||||
|
||||
/**
|
||||
* AVOption
|
||||
*/
|
||||
typedef struct AVOption {
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* short English help text
|
||||
* @todo What about other languages?
|
||||
*/
|
||||
const char *help;
|
||||
|
||||
/**
|
||||
* The offset relative to the context structure where the option
|
||||
* value is stored. It should be 0 for named constants.
|
||||
*/
|
||||
int offset;
|
||||
enum AVOptionType type;
|
||||
|
||||
/**
|
||||
* the default value for scalar options
|
||||
*/
|
||||
union {
|
||||
int64_t i64;
|
||||
double dbl;
|
||||
const char *str;
|
||||
/* TODO those are unused now */
|
||||
AVRational q;
|
||||
} default_val;
|
||||
double min; ///< minimum valid value for the option
|
||||
double max; ///< maximum valid value for the option
|
||||
|
||||
int flags;
|
||||
#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding
|
||||
#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding
|
||||
#if FF_API_OPT_TYPE_METADATA
|
||||
#define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ...
|
||||
#endif
|
||||
#define AV_OPT_FLAG_AUDIO_PARAM 8
|
||||
#define AV_OPT_FLAG_VIDEO_PARAM 16
|
||||
#define AV_OPT_FLAG_SUBTITLE_PARAM 32
|
||||
/**
|
||||
* The option is inteded for exporting values to the caller.
|
||||
*/
|
||||
#define AV_OPT_FLAG_EXPORT 64
|
||||
/**
|
||||
* The option may not be set through the AVOptions API, only read.
|
||||
* This flag only makes sense when AV_OPT_FLAG_EXPORT is also set.
|
||||
*/
|
||||
#define AV_OPT_FLAG_READONLY 128
|
||||
#define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering
|
||||
//FIXME think about enc-audio, ... style flags
|
||||
|
||||
/**
|
||||
* The logical unit to which the option belongs. Non-constant
|
||||
* options and corresponding named constants share the same
|
||||
* unit. May be NULL.
|
||||
*/
|
||||
const char *unit;
|
||||
} AVOption;
|
||||
|
||||
/**
|
||||
* A single allowed range of values, or a single allowed value.
|
||||
*/
|
||||
typedef struct AVOptionRange {
|
||||
const char *str;
|
||||
/**
|
||||
* Value range.
|
||||
* For string ranges this represents the min/max length.
|
||||
* For dimensions this represents the min/max pixel count or width/height in multi-component case.
|
||||
*/
|
||||
double value_min, value_max;
|
||||
/**
|
||||
* Value's component range.
|
||||
* For string this represents the unicode range for chars, 0-127 limits to ASCII.
|
||||
*/
|
||||
double component_min, component_max;
|
||||
/**
|
||||
* Range flag.
|
||||
* If set to 1 the struct encodes a range, if set to 0 a single value.
|
||||
*/
|
||||
int is_range;
|
||||
} AVOptionRange;
|
||||
|
||||
/**
|
||||
* List of AVOptionRange structs.
|
||||
*/
|
||||
typedef struct AVOptionRanges {
|
||||
/**
|
||||
* Array of option ranges.
|
||||
*
|
||||
* Most of option types use just one component.
|
||||
* Following describes multi-component option types:
|
||||
*
|
||||
* AV_OPT_TYPE_IMAGE_SIZE:
|
||||
* component index 0: range of pixel count (width * height).
|
||||
* component index 1: range of width.
|
||||
* component index 2: range of height.
|
||||
*
|
||||
* @note To obtain multi-component version of this structure, user must
|
||||
* provide AV_OPT_MULTI_COMPONENT_RANGE to av_opt_query_ranges or
|
||||
* av_opt_query_ranges_default function.
|
||||
*
|
||||
* Multi-component range can be read as in following example:
|
||||
*
|
||||
* @code
|
||||
* int range_index, component_index;
|
||||
* AVOptionRanges *ranges;
|
||||
* AVOptionRange *range[3]; //may require more than 3 in the future.
|
||||
* av_opt_query_ranges(&ranges, obj, key, AV_OPT_MULTI_COMPONENT_RANGE);
|
||||
* for (range_index = 0; range_index < ranges->nb_ranges; range_index++) {
|
||||
* for (component_index = 0; component_index < ranges->nb_components; component_index++)
|
||||
* range[component_index] = ranges->range[ranges->nb_ranges * component_index + range_index];
|
||||
* //do something with range here.
|
||||
* }
|
||||
* av_opt_freep_ranges(&ranges);
|
||||
* @endcode
|
||||
*/
|
||||
AVOptionRange **range;
|
||||
/**
|
||||
* Number of ranges per component.
|
||||
*/
|
||||
int nb_ranges;
|
||||
/**
|
||||
* Number of componentes.
|
||||
*/
|
||||
int nb_components;
|
||||
} AVOptionRanges;
|
||||
|
||||
/**
|
||||
* Show the obj options.
|
||||
*
|
||||
* @param req_flags requested flags for the options to show. Show only the
|
||||
* options for which it is opt->flags & req_flags.
|
||||
* @param rej_flags rejected flags for the options to show. Show only the
|
||||
* options for which it is !(opt->flags & req_flags).
|
||||
* @param av_log_obj log context to use for showing the options
|
||||
*/
|
||||
int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags);
|
||||
|
||||
/**
|
||||
* Set the values of all AVOption fields to their default values.
|
||||
*
|
||||
* @param s an AVOption-enabled struct (its first member must be a pointer to AVClass)
|
||||
*/
|
||||
void av_opt_set_defaults(void *s);
|
||||
|
||||
/**
|
||||
* Set the values of all AVOption fields to their default values. Only these
|
||||
* AVOption fields for which (opt->flags & mask) == flags will have their
|
||||
* default applied to s.
|
||||
*
|
||||
* @param s an AVOption-enabled struct (its first member must be a pointer to AVClass)
|
||||
* @param mask combination of AV_OPT_FLAG_*
|
||||
* @param flags combination of AV_OPT_FLAG_*
|
||||
*/
|
||||
void av_opt_set_defaults2(void *s, int mask, int flags);
|
||||
|
||||
/**
|
||||
* Parse the key/value pairs list in opts. For each key/value pair
|
||||
* found, stores the value in the field in ctx that is named like the
|
||||
* key. ctx must be an AVClass context, storing is done using
|
||||
* AVOptions.
|
||||
*
|
||||
* @param opts options string to parse, may be NULL
|
||||
* @param key_val_sep a 0-terminated list of characters used to
|
||||
* separate key from value
|
||||
* @param pairs_sep a 0-terminated list of characters used to separate
|
||||
* two pairs from each other
|
||||
* @return the number of successfully set key/value pairs, or a negative
|
||||
* value corresponding to an AVERROR code in case of error:
|
||||
* AVERROR(EINVAL) if opts cannot be parsed,
|
||||
* the error code issued by av_opt_set() if a key/value pair
|
||||
* cannot be set
|
||||
*/
|
||||
int av_set_options_string(void *ctx, const char *opts,
|
||||
const char *key_val_sep, const char *pairs_sep);
|
||||
|
||||
/**
|
||||
* Parse the key-value pairs list in opts. For each key=value pair found,
|
||||
* set the value of the corresponding option in ctx.
|
||||
*
|
||||
* @param ctx the AVClass object to set options on
|
||||
* @param opts the options string, key-value pairs separated by a
|
||||
* delimiter
|
||||
* @param shorthand a NULL-terminated array of options names for shorthand
|
||||
* notation: if the first field in opts has no key part,
|
||||
* the key is taken from the first element of shorthand;
|
||||
* then again for the second, etc., until either opts is
|
||||
* finished, shorthand is finished or a named option is
|
||||
* found; after that, all options must be named
|
||||
* @param key_val_sep a 0-terminated list of characters used to separate
|
||||
* key from value, for example '='
|
||||
* @param pairs_sep a 0-terminated list of characters used to separate
|
||||
* two pairs from each other, for example ':' or ','
|
||||
* @return the number of successfully set key=value pairs, or a negative
|
||||
* value corresponding to an AVERROR code in case of error:
|
||||
* AVERROR(EINVAL) if opts cannot be parsed,
|
||||
* the error code issued by av_set_string3() if a key/value pair
|
||||
* cannot be set
|
||||
*
|
||||
* Options names must use only the following characters: a-z A-Z 0-9 - . / _
|
||||
* Separators must use characters distinct from option names and from each
|
||||
* other.
|
||||
*/
|
||||
int av_opt_set_from_string(void *ctx, const char *opts,
|
||||
const char *const *shorthand,
|
||||
const char *key_val_sep, const char *pairs_sep);
|
||||
/**
|
||||
* Free all allocated objects in obj.
|
||||
*/
|
||||
void av_opt_free(void *obj);
|
||||
|
||||
/**
|
||||
* Check whether a particular flag is set in a flags field.
|
||||
*
|
||||
* @param field_name the name of the flag field option
|
||||
* @param flag_name the name of the flag to check
|
||||
* @return non-zero if the flag is set, zero if the flag isn't set,
|
||||
* isn't of the right type, or the flags field doesn't exist.
|
||||
*/
|
||||
int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name);
|
||||
|
||||
/**
|
||||
* Set all the options from a given dictionary on an object.
|
||||
*
|
||||
* @param obj a struct whose first element is a pointer to AVClass
|
||||
* @param options options to process. This dictionary will be freed and replaced
|
||||
* by a new one containing all options not found in obj.
|
||||
* Of course this new dictionary needs to be freed by caller
|
||||
* with av_dict_free().
|
||||
*
|
||||
* @return 0 on success, a negative AVERROR if some option was found in obj,
|
||||
* but could not be set.
|
||||
*
|
||||
* @see av_dict_copy()
|
||||
*/
|
||||
int av_opt_set_dict(void *obj, struct AVDictionary **options);
|
||||
|
||||
|
||||
/**
|
||||
* Set all the options from a given dictionary on an object.
|
||||
*
|
||||
* @param obj a struct whose first element is a pointer to AVClass
|
||||
* @param options options to process. This dictionary will be freed and replaced
|
||||
* by a new one containing all options not found in obj.
|
||||
* Of course this new dictionary needs to be freed by caller
|
||||
* with av_dict_free().
|
||||
* @param search_flags A combination of AV_OPT_SEARCH_*.
|
||||
*
|
||||
* @return 0 on success, a negative AVERROR if some option was found in obj,
|
||||
* but could not be set.
|
||||
*
|
||||
* @see av_dict_copy()
|
||||
*/
|
||||
int av_opt_set_dict2(void *obj, struct AVDictionary **options, int search_flags);
|
||||
|
||||
/**
|
||||
* Extract a key-value pair from the beginning of a string.
|
||||
*
|
||||
* @param ropts pointer to the options string, will be updated to
|
||||
* point to the rest of the string (one of the pairs_sep
|
||||
* or the final NUL)
|
||||
* @param key_val_sep a 0-terminated list of characters used to separate
|
||||
* key from value, for example '='
|
||||
* @param pairs_sep a 0-terminated list of characters used to separate
|
||||
* two pairs from each other, for example ':' or ','
|
||||
* @param flags flags; see the AV_OPT_FLAG_* values below
|
||||
* @param rkey parsed key; must be freed using av_free()
|
||||
* @param rval parsed value; must be freed using av_free()
|
||||
*
|
||||
* @return >=0 for success, or a negative value corresponding to an
|
||||
* AVERROR code in case of error; in particular:
|
||||
* AVERROR(EINVAL) if no key is present
|
||||
*
|
||||
*/
|
||||
int av_opt_get_key_value(const char **ropts,
|
||||
const char *key_val_sep, const char *pairs_sep,
|
||||
unsigned flags,
|
||||
char **rkey, char **rval);
|
||||
|
||||
enum {
|
||||
|
||||
/**
|
||||
* Accept to parse a value without a key; the key will then be returned
|
||||
* as NULL.
|
||||
*/
|
||||
AV_OPT_FLAG_IMPLICIT_KEY = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* @defgroup opt_eval_funcs Evaluating option strings
|
||||
* @{
|
||||
* This group of functions can be used to evaluate option strings
|
||||
* and get numbers out of them. They do the same thing as av_opt_set(),
|
||||
* except the result is written into the caller-supplied pointer.
|
||||
*
|
||||
* @param obj a struct whose first element is a pointer to AVClass.
|
||||
* @param o an option for which the string is to be evaluated.
|
||||
* @param val string to be evaluated.
|
||||
* @param *_out value of the string will be written here.
|
||||
*
|
||||
* @return 0 on success, a negative number on failure.
|
||||
*/
|
||||
int av_opt_eval_flags (void *obj, const AVOption *o, const char *val, int *flags_out);
|
||||
int av_opt_eval_int (void *obj, const AVOption *o, const char *val, int *int_out);
|
||||
int av_opt_eval_int64 (void *obj, const AVOption *o, const char *val, int64_t *int64_out);
|
||||
int av_opt_eval_float (void *obj, const AVOption *o, const char *val, float *float_out);
|
||||
int av_opt_eval_double(void *obj, const AVOption *o, const char *val, double *double_out);
|
||||
int av_opt_eval_q (void *obj, const AVOption *o, const char *val, AVRational *q_out);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define AV_OPT_SEARCH_CHILDREN (1 << 0) /**< Search in possible children of the
|
||||
given object first. */
|
||||
/**
|
||||
* The obj passed to av_opt_find() is fake -- only a double pointer to AVClass
|
||||
* instead of a required pointer to a struct containing AVClass. This is
|
||||
* useful for searching for options without needing to allocate the corresponding
|
||||
* object.
|
||||
*/
|
||||
#define AV_OPT_SEARCH_FAKE_OBJ (1 << 1)
|
||||
|
||||
/**
|
||||
* In av_opt_get, return NULL if the option has a pointer type and is set to NULL,
|
||||
* rather than returning an empty string.
|
||||
*/
|
||||
#define AV_OPT_ALLOW_NULL (1 << 2)
|
||||
|
||||
/**
|
||||
* Allows av_opt_query_ranges and av_opt_query_ranges_default to return more than
|
||||
* one component for certain option types.
|
||||
* @see AVOptionRanges for details.
|
||||
*/
|
||||
#define AV_OPT_MULTI_COMPONENT_RANGE (1 << 12)
|
||||
|
||||
/**
|
||||
* Look for an option in an object. Consider only options which
|
||||
* have all the specified flags set.
|
||||
*
|
||||
* @param[in] obj A pointer to a struct whose first element is a
|
||||
* pointer to an AVClass.
|
||||
* Alternatively a double pointer to an AVClass, if
|
||||
* AV_OPT_SEARCH_FAKE_OBJ search flag is set.
|
||||
* @param[in] name The name of the option to look for.
|
||||
* @param[in] unit When searching for named constants, name of the unit
|
||||
* it belongs to.
|
||||
* @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG).
|
||||
* @param search_flags A combination of AV_OPT_SEARCH_*.
|
||||
*
|
||||
* @return A pointer to the option found, or NULL if no option
|
||||
* was found.
|
||||
*
|
||||
* @note Options found with AV_OPT_SEARCH_CHILDREN flag may not be settable
|
||||
* directly with av_opt_set(). Use special calls which take an options
|
||||
* AVDictionary (e.g. avformat_open_input()) to set options found with this
|
||||
* flag.
|
||||
*/
|
||||
const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
|
||||
int opt_flags, int search_flags);
|
||||
|
||||
/**
|
||||
* Look for an option in an object. Consider only options which
|
||||
* have all the specified flags set.
|
||||
*
|
||||
* @param[in] obj A pointer to a struct whose first element is a
|
||||
* pointer to an AVClass.
|
||||
* Alternatively a double pointer to an AVClass, if
|
||||
* AV_OPT_SEARCH_FAKE_OBJ search flag is set.
|
||||
* @param[in] name The name of the option to look for.
|
||||
* @param[in] unit When searching for named constants, name of the unit
|
||||
* it belongs to.
|
||||
* @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG).
|
||||
* @param search_flags A combination of AV_OPT_SEARCH_*.
|
||||
* @param[out] target_obj if non-NULL, an object to which the option belongs will be
|
||||
* written here. It may be different from obj if AV_OPT_SEARCH_CHILDREN is present
|
||||
* in search_flags. This parameter is ignored if search_flags contain
|
||||
* AV_OPT_SEARCH_FAKE_OBJ.
|
||||
*
|
||||
* @return A pointer to the option found, or NULL if no option
|
||||
* was found.
|
||||
*/
|
||||
const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
|
||||
int opt_flags, int search_flags, void **target_obj);
|
||||
|
||||
/**
|
||||
* Iterate over all AVOptions belonging to obj.
|
||||
*
|
||||
* @param obj an AVOptions-enabled struct or a double pointer to an
|
||||
* AVClass describing it.
|
||||
* @param prev result of the previous call to av_opt_next() on this object
|
||||
* or NULL
|
||||
* @return next AVOption or NULL
|
||||
*/
|
||||
const AVOption *av_opt_next(const void *obj, const AVOption *prev);
|
||||
|
||||
/**
|
||||
* Iterate over AVOptions-enabled children of obj.
|
||||
*
|
||||
* @param prev result of a previous call to this function or NULL
|
||||
* @return next AVOptions-enabled child or NULL
|
||||
*/
|
||||
void *av_opt_child_next(void *obj, void *prev);
|
||||
|
||||
/**
|
||||
* Iterate over potential AVOptions-enabled children of parent.
|
||||
*
|
||||
* @param prev result of a previous call to this function or NULL
|
||||
* @return AVClass corresponding to next potential child or NULL
|
||||
*/
|
||||
const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev);
|
||||
|
||||
/**
|
||||
* @defgroup opt_set_funcs Option setting functions
|
||||
* @{
|
||||
* Those functions set the field of obj with the given name to value.
|
||||
*
|
||||
* @param[in] obj A struct whose first element is a pointer to an AVClass.
|
||||
* @param[in] name the name of the field to set
|
||||
* @param[in] val The value to set. In case of av_opt_set() if the field is not
|
||||
* of a string type, then the given string is parsed.
|
||||
* SI postfixes and some named scalars are supported.
|
||||
* If the field is of a numeric type, it has to be a numeric or named
|
||||
* scalar. Behavior with more than one scalar and +- infix operators
|
||||
* is undefined.
|
||||
* If the field is of a flags type, it has to be a sequence of numeric
|
||||
* scalars or named flags separated by '+' or '-'. Prefixing a flag
|
||||
* with '+' causes it to be set without affecting the other flags;
|
||||
* similarly, '-' unsets a flag.
|
||||
* @param search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN
|
||||
* is passed here, then the option may be set on a child of obj.
|
||||
*
|
||||
* @return 0 if the value has been set, or an AVERROR code in case of
|
||||
* error:
|
||||
* AVERROR_OPTION_NOT_FOUND if no matching option exists
|
||||
* AVERROR(ERANGE) if the value is out of range
|
||||
* AVERROR(EINVAL) if the value is not valid
|
||||
*/
|
||||
int av_opt_set (void *obj, const char *name, const char *val, int search_flags);
|
||||
int av_opt_set_int (void *obj, const char *name, int64_t val, int search_flags);
|
||||
int av_opt_set_double (void *obj, const char *name, double val, int search_flags);
|
||||
int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags);
|
||||
int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, int search_flags);
|
||||
int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags);
|
||||
int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags);
|
||||
int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags);
|
||||
int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags);
|
||||
int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags);
|
||||
/**
|
||||
* @note Any old dictionary present is discarded and replaced with a copy of the new one. The
|
||||
* caller still owns val is and responsible for freeing it.
|
||||
*/
|
||||
int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags);
|
||||
|
||||
/**
|
||||
* Set a binary option to an integer list.
|
||||
*
|
||||
* @param obj AVClass object to set options on
|
||||
* @param name name of the binary option
|
||||
* @param val pointer to an integer list (must have the correct type with
|
||||
* regard to the contents of the list)
|
||||
* @param term list terminator (usually 0 or -1)
|
||||
* @param flags search flags
|
||||
*/
|
||||
#define av_opt_set_int_list(obj, name, val, term, flags) \
|
||||
(av_int_list_length(val, term) > INT_MAX / sizeof(*(val)) ? \
|
||||
AVERROR(EINVAL) : \
|
||||
av_opt_set_bin(obj, name, (const uint8_t *)(val), \
|
||||
av_int_list_length(val, term) * sizeof(*(val)), flags))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup opt_get_funcs Option getting functions
|
||||
* @{
|
||||
* Those functions get a value of the option with the given name from an object.
|
||||
*
|
||||
* @param[in] obj a struct whose first element is a pointer to an AVClass.
|
||||
* @param[in] name name of the option to get.
|
||||
* @param[in] search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN
|
||||
* is passed here, then the option may be found in a child of obj.
|
||||
* @param[out] out_val value of the option will be written here
|
||||
* @return >=0 on success, a negative error code otherwise
|
||||
*/
|
||||
/**
|
||||
* @note the returned string will be av_malloc()ed and must be av_free()ed by the caller
|
||||
*
|
||||
* @note if AV_OPT_ALLOW_NULL is set in search_flags in av_opt_get, and the option has
|
||||
* AV_OPT_TYPE_STRING or AV_OPT_TYPE_BINARY and is set to NULL, *out_val will be set
|
||||
* to NULL instead of an allocated empty string.
|
||||
*/
|
||||
int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val);
|
||||
int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val);
|
||||
int av_opt_get_double (void *obj, const char *name, int search_flags, double *out_val);
|
||||
int av_opt_get_q (void *obj, const char *name, int search_flags, AVRational *out_val);
|
||||
int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out);
|
||||
int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt);
|
||||
int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt);
|
||||
int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val);
|
||||
int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout);
|
||||
/**
|
||||
* @param[out] out_val The returned dictionary is a copy of the actual value and must
|
||||
* be freed with av_dict_free() by the caller
|
||||
*/
|
||||
int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* Gets a pointer to the requested field in a struct.
|
||||
* This function allows accessing a struct even when its fields are moved or
|
||||
* renamed since the application making the access has been compiled,
|
||||
*
|
||||
* @returns a pointer to the field, it can be cast to the correct type and read
|
||||
* or written to.
|
||||
*/
|
||||
void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name);
|
||||
|
||||
/**
|
||||
* Free an AVOptionRanges struct and set it to NULL.
|
||||
*/
|
||||
void av_opt_freep_ranges(AVOptionRanges **ranges);
|
||||
|
||||
/**
|
||||
* Get a list of allowed ranges for the given option.
|
||||
*
|
||||
* The returned list may depend on other fields in obj like for example profile.
|
||||
*
|
||||
* @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
|
||||
* AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
|
||||
* AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges
|
||||
*
|
||||
* The result must be freed with av_opt_freep_ranges.
|
||||
*
|
||||
* @return number of compontents returned on success, a negative errro code otherwise
|
||||
*/
|
||||
int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags);
|
||||
|
||||
/**
|
||||
* Copy options from src object into dest object.
|
||||
*
|
||||
* Options that require memory allocation (e.g. string or binary) are malloc'ed in dest object.
|
||||
* Original memory allocated for such options is freed unless both src and dest options points to the same memory.
|
||||
*
|
||||
* @param dest Object to copy from
|
||||
* @param src Object to copy into
|
||||
* @return 0 on success, negative on error
|
||||
*/
|
||||
int av_opt_copy(void *dest, const void *src);
|
||||
|
||||
/**
|
||||
* Get a default list of allowed ranges for the given option.
|
||||
*
|
||||
* This list is constructed without using the AVClass.query_ranges() callback
|
||||
* and can be used as fallback from within the callback.
|
||||
*
|
||||
* @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
|
||||
* AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
|
||||
* AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges
|
||||
*
|
||||
* The result must be freed with av_opt_free_ranges.
|
||||
*
|
||||
* @return number of compontents returned on success, a negative errro code otherwise
|
||||
*/
|
||||
int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags);
|
||||
|
||||
/**
|
||||
* Check if given option is set to its default value.
|
||||
*
|
||||
* Options o must belong to the obj. This function must not be called to check child's options state.
|
||||
* @see av_opt_is_set_to_default_by_name().
|
||||
*
|
||||
* @param obj AVClass object to check option on
|
||||
* @param o option to be checked
|
||||
* @return >0 when option is set to its default,
|
||||
* 0 when option is not set its default,
|
||||
* <0 on error
|
||||
*/
|
||||
int av_opt_is_set_to_default(void *obj, const AVOption *o);
|
||||
|
||||
/**
|
||||
* Check if given option is set to its default value.
|
||||
*
|
||||
* @param obj AVClass object to check option on
|
||||
* @param name option name
|
||||
* @param search_flags combination of AV_OPT_SEARCH_*
|
||||
* @return >0 when option is set to its default,
|
||||
* 0 when option is not set its default,
|
||||
* <0 on error
|
||||
*/
|
||||
int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags);
|
||||
|
||||
|
||||
#define AV_OPT_SERIALIZE_SKIP_DEFAULTS 0x00000001 ///< Serialize options that are not set to default values only.
|
||||
#define AV_OPT_SERIALIZE_OPT_FLAGS_EXACT 0x00000002 ///< Serialize options that exactly match opt_flags only.
|
||||
|
||||
/**
|
||||
* Serialize object's options.
|
||||
*
|
||||
* Create a string containing object's serialized options.
|
||||
* Such string may be passed back to av_opt_set_from_string() in order to restore option values.
|
||||
* A key/value or pairs separator occurring in the serialized value or
|
||||
* name string are escaped through the av_escape() function.
|
||||
*
|
||||
* @param[in] obj AVClass object to serialize
|
||||
* @param[in] opt_flags serialize options with all the specified flags set (AV_OPT_FLAG)
|
||||
* @param[in] flags combination of AV_OPT_SERIALIZE_* flags
|
||||
* @param[out] buffer Pointer to buffer that will be allocated with string containg serialized options.
|
||||
* Buffer must be freed by the caller when is no longer needed.
|
||||
* @param[in] key_val_sep character used to separate key from value
|
||||
* @param[in] pairs_sep character used to separate two pairs from each other
|
||||
* @return >= 0 on success, negative on error
|
||||
* @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the same.
|
||||
*/
|
||||
int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
|
||||
const char key_val_sep, const char pairs_sep);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVUTIL_OPT_H */
|
487
ext/at3_standalone/options.c
Normal file
487
ext/at3_standalone/options.c
Normal file
@ -0,0 +1,487 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
* Copyright (c) 2002-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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Options definition for AVCodecContext.
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "internal.h"
|
||||
#include "util_internal.h"
|
||||
#include "mem.h"
|
||||
#include "opt.h"
|
||||
#include <float.h> /* FLT_MIN, FLT_MAX */
|
||||
#include <string.h>
|
||||
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
#include "options_table.h"
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
|
||||
static const char* context_to_name(void* ptr) {
|
||||
AVCodecContext *avc= ptr;
|
||||
|
||||
if(avc && avc->codec && avc->codec->name)
|
||||
return avc->codec->name;
|
||||
else
|
||||
return "NULL";
|
||||
}
|
||||
|
||||
static void *codec_child_next(void *obj, void *prev)
|
||||
{
|
||||
AVCodecContext *s = obj;
|
||||
if (!prev && s->codec && s->codec->priv_class && s->priv_data)
|
||||
return s->priv_data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const AVClass *codec_child_class_next(const AVClass *prev)
|
||||
{
|
||||
AVCodec *c = NULL;
|
||||
|
||||
/* find the codec that corresponds to prev */
|
||||
while (prev && (c = av_codec_next(c)))
|
||||
if (c->priv_class == prev)
|
||||
break;
|
||||
|
||||
/* find next codec with priv options */
|
||||
while (c = av_codec_next(c))
|
||||
if (c->priv_class)
|
||||
return c->priv_class;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static AVClassCategory get_category(void *ptr)
|
||||
{
|
||||
AVCodecContext* avctx = ptr;
|
||||
if(avctx->codec && avctx->codec->decode) return AV_CLASS_CATEGORY_DECODER;
|
||||
else return AV_CLASS_CATEGORY_ENCODER;
|
||||
}
|
||||
|
||||
static const AVClass av_codec_context_class = {
|
||||
.class_name = "AVCodecContext",
|
||||
.item_name = context_to_name,
|
||||
.option = avcodec_options,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
.log_level_offset_offset = offsetof(AVCodecContext, log_level_offset),
|
||||
.child_next = codec_child_next,
|
||||
.child_class_next = codec_child_class_next,
|
||||
.category = AV_CLASS_CATEGORY_ENCODER,
|
||||
.get_category = get_category,
|
||||
};
|
||||
|
||||
int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
|
||||
{
|
||||
int flags=0;
|
||||
memset(s, 0, sizeof(AVCodecContext));
|
||||
|
||||
s->av_class = &av_codec_context_class;
|
||||
|
||||
s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN;
|
||||
if (codec) {
|
||||
s->codec = codec;
|
||||
s->codec_id = codec->id;
|
||||
}
|
||||
|
||||
if(s->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||
flags= AV_OPT_FLAG_AUDIO_PARAM;
|
||||
else if(s->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
flags= AV_OPT_FLAG_VIDEO_PARAM;
|
||||
else if(s->codec_type == AVMEDIA_TYPE_SUBTITLE)
|
||||
flags= AV_OPT_FLAG_SUBTITLE_PARAM;
|
||||
av_opt_set_defaults2(s, flags, flags);
|
||||
|
||||
s->time_base = (AVRational){0,1};
|
||||
s->framerate = (AVRational){ 0, 1 };
|
||||
s->pkt_timebase = (AVRational){ 0, 1 };
|
||||
s->get_buffer2 = avcodec_default_get_buffer2;
|
||||
s->get_format = avcodec_default_get_format;
|
||||
s->execute = avcodec_default_execute;
|
||||
s->execute2 = avcodec_default_execute2;
|
||||
s->sample_aspect_ratio = (AVRational){0,1};
|
||||
s->pix_fmt = AV_PIX_FMT_NONE;
|
||||
s->sample_fmt = AV_SAMPLE_FMT_NONE;
|
||||
|
||||
s->reordered_opaque = AV_NOPTS_VALUE;
|
||||
if(codec && codec->priv_data_size){
|
||||
if(!s->priv_data){
|
||||
s->priv_data= av_mallocz(codec->priv_data_size);
|
||||
if (!s->priv_data) {
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
}
|
||||
if(codec->priv_class){
|
||||
*(const AVClass**)s->priv_data = codec->priv_class;
|
||||
av_opt_set_defaults(s->priv_data);
|
||||
}
|
||||
}
|
||||
if (codec && codec->defaults) {
|
||||
int ret;
|
||||
const AVCodecDefault *d = codec->defaults;
|
||||
/*
|
||||
while (d->key) {
|
||||
ret = av_opt_set(s, d->key, d->value, 0);
|
||||
av_assert0(ret >= 0);
|
||||
d++;
|
||||
}
|
||||
*/
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)
|
||||
{
|
||||
AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));
|
||||
|
||||
if (!avctx)
|
||||
return NULL;
|
||||
|
||||
if(avcodec_get_context_defaults3(avctx, codec) < 0){
|
||||
av_free(avctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return avctx;
|
||||
}
|
||||
|
||||
void avcodec_free_context(AVCodecContext **pavctx)
|
||||
{
|
||||
AVCodecContext *avctx = *pavctx;
|
||||
|
||||
if (!avctx)
|
||||
return;
|
||||
|
||||
avcodec_close(avctx);
|
||||
|
||||
av_freep(&avctx->extradata);
|
||||
av_freep(&avctx->subtitle_header);
|
||||
av_freep(&avctx->intra_matrix);
|
||||
av_freep(&avctx->inter_matrix);
|
||||
av_freep(&avctx->rc_override);
|
||||
|
||||
av_freep(pavctx);
|
||||
}
|
||||
|
||||
int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src)
|
||||
{
|
||||
const AVCodec *orig_codec = dest->codec;
|
||||
uint8_t *orig_priv_data = dest->priv_data;
|
||||
|
||||
if (avcodec_is_open(dest)) { // check that the dest context is uninitialized
|
||||
av_log(dest, AV_LOG_ERROR,
|
||||
"Tried to copy AVCodecContext %p into already-initialized %p\n",
|
||||
src, dest);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
av_opt_free(dest);
|
||||
av_freep(&dest->rc_override);
|
||||
av_freep(&dest->intra_matrix);
|
||||
av_freep(&dest->inter_matrix);
|
||||
av_freep(&dest->extradata);
|
||||
av_freep(&dest->subtitle_header);
|
||||
|
||||
memcpy(dest, src, sizeof(*dest));
|
||||
av_opt_copy(dest, src);
|
||||
|
||||
dest->priv_data = orig_priv_data;
|
||||
dest->codec = orig_codec;
|
||||
|
||||
if (orig_priv_data && src->codec && src->codec->priv_class &&
|
||||
dest->codec && dest->codec->priv_class)
|
||||
av_opt_copy(orig_priv_data, src->priv_data);
|
||||
|
||||
|
||||
/* set values specific to opened codecs back to their default state */
|
||||
dest->slice_offset = NULL;
|
||||
dest->hwaccel = NULL;
|
||||
dest->internal = NULL;
|
||||
#if FF_API_CODED_FRAME
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
dest->coded_frame = NULL;
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
||||
/* reallocate values that should be allocated separately */
|
||||
dest->extradata = NULL;
|
||||
dest->intra_matrix = NULL;
|
||||
dest->inter_matrix = NULL;
|
||||
dest->rc_override = NULL;
|
||||
dest->subtitle_header = NULL;
|
||||
|
||||
#define alloc_and_copy_or_fail(obj, size, pad) \
|
||||
if (src->obj && size > 0) { \
|
||||
dest->obj = av_malloc(size + pad); \
|
||||
if (!dest->obj) \
|
||||
goto fail; \
|
||||
memcpy(dest->obj, src->obj, size); \
|
||||
if (pad) \
|
||||
memset(((uint8_t *) dest->obj) + size, 0, pad); \
|
||||
}
|
||||
alloc_and_copy_or_fail(extradata, src->extradata_size,
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
dest->extradata_size = src->extradata_size;
|
||||
alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0);
|
||||
alloc_and_copy_or_fail(inter_matrix, 64 * sizeof(int16_t), 0);
|
||||
alloc_and_copy_or_fail(rc_override, src->rc_override_count * sizeof(*src->rc_override), 0);
|
||||
alloc_and_copy_or_fail(subtitle_header, src->subtitle_header_size, 1);
|
||||
av_assert0(dest->subtitle_header_size == src->subtitle_header_size);
|
||||
#undef alloc_and_copy_or_fail
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
av_freep(&dest->rc_override);
|
||||
av_freep(&dest->intra_matrix);
|
||||
av_freep(&dest->inter_matrix);
|
||||
av_freep(&dest->extradata);
|
||||
av_freep(&dest->subtitle_header);
|
||||
dest->subtitle_header_size = 0;
|
||||
dest->extradata_size = 0;
|
||||
av_opt_free(dest);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
const AVClass *avcodec_get_class(void)
|
||||
{
|
||||
return &av_codec_context_class;
|
||||
}
|
||||
|
||||
#define FOFFSET(x) offsetof(AVFrame,x)
|
||||
|
||||
static const AVOption frame_options[]={
|
||||
{"best_effort_timestamp", "", FOFFSET(best_effort_timestamp), AV_OPT_TYPE_INT64, {.i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, 0},
|
||||
{"pkt_pos", "", FOFFSET(pkt_pos), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0},
|
||||
{"pkt_size", "", FOFFSET(pkt_size), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0},
|
||||
{"sample_aspect_ratio", "", FOFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0},
|
||||
{"width", "", FOFFSET(width), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
|
||||
{"height", "", FOFFSET(height), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
|
||||
{"format", "", FOFFSET(format), AV_OPT_TYPE_INT, {.i64 = -1 }, 0, INT_MAX, 0},
|
||||
{"channel_layout", "", FOFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, 0},
|
||||
{"sample_rate", "", FOFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static const AVClass av_frame_class = {
|
||||
.class_name = "AVFrame",
|
||||
.item_name = NULL,
|
||||
.option = frame_options,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
};
|
||||
|
||||
const AVClass *avcodec_get_frame_class(void)
|
||||
{
|
||||
return &av_frame_class;
|
||||
}
|
||||
|
||||
#define SROFFSET(x) offsetof(AVSubtitleRect,x)
|
||||
|
||||
static const AVOption subtitle_rect_options[]={
|
||||
{"x", "", SROFFSET(x), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
|
||||
{"y", "", SROFFSET(y), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
|
||||
{"w", "", SROFFSET(w), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
|
||||
{"h", "", SROFFSET(h), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
|
||||
{"type", "", SROFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
|
||||
{"flags", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0, "flags"},
|
||||
{"forced", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static const AVClass av_subtitle_rect_class = {
|
||||
.class_name = "AVSubtitleRect",
|
||||
.item_name = NULL,
|
||||
.option = subtitle_rect_options,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
};
|
||||
|
||||
const AVClass *avcodec_get_subtitle_rect_class(void)
|
||||
{
|
||||
return &av_subtitle_rect_class;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
static int dummy_init(AVCodecContext *ctx)
|
||||
{
|
||||
//TODO: this code should set every possible pointer that could be set by codec and is not an option;
|
||||
ctx->extradata_size = 8;
|
||||
ctx->extradata = av_malloc(ctx->extradata_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dummy_close(AVCodecContext *ctx)
|
||||
{
|
||||
av_freep(&ctx->extradata);
|
||||
ctx->extradata_size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dummy_encode(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
|
||||
{
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
|
||||
typedef struct Dummy12Context {
|
||||
AVClass *av_class;
|
||||
int num;
|
||||
char* str;
|
||||
} Dummy12Context;
|
||||
|
||||
typedef struct Dummy3Context {
|
||||
void *fake_av_class;
|
||||
int num;
|
||||
char* str;
|
||||
} Dummy3Context;
|
||||
|
||||
#define OFFSET(x) offsetof(Dummy12Context, x)
|
||||
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
|
||||
static const AVOption dummy_options[] = {
|
||||
{ "str", "set str", OFFSET(str), AV_OPT_TYPE_STRING, { .str = "i'm src default value" }, 0, 0, VE},
|
||||
{ "num", "set num", OFFSET(num), AV_OPT_TYPE_INT, { .i64 = 1500100900 }, 0, INT_MAX, VE},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static const AVClass dummy_v1_class = {
|
||||
.class_name = "dummy_v1_class",
|
||||
.item_name = av_default_item_name,
|
||||
.option = dummy_options,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
};
|
||||
|
||||
static const AVClass dummy_v2_class = {
|
||||
.class_name = "dummy_v2_class",
|
||||
.item_name = av_default_item_name,
|
||||
.option = dummy_options,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
};
|
||||
|
||||
/* codec with options */
|
||||
static AVCodec dummy_v1_encoder = {
|
||||
.name = "dummy_v1_codec",
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = AV_CODEC_ID_NONE - 1,
|
||||
.encode2 = dummy_encode,
|
||||
.init = dummy_init,
|
||||
.close = dummy_close,
|
||||
.priv_class = &dummy_v1_class,
|
||||
.priv_data_size = sizeof(Dummy12Context),
|
||||
};
|
||||
|
||||
/* codec with options, different class */
|
||||
static AVCodec dummy_v2_encoder = {
|
||||
.name = "dummy_v2_codec",
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = AV_CODEC_ID_NONE - 2,
|
||||
.encode2 = dummy_encode,
|
||||
.init = dummy_init,
|
||||
.close = dummy_close,
|
||||
.priv_class = &dummy_v2_class,
|
||||
.priv_data_size = sizeof(Dummy12Context),
|
||||
};
|
||||
|
||||
/* codec with priv data, but no class */
|
||||
static AVCodec dummy_v3_encoder = {
|
||||
.name = "dummy_v3_codec",
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = AV_CODEC_ID_NONE - 3,
|
||||
.encode2 = dummy_encode,
|
||||
.init = dummy_init,
|
||||
.close = dummy_close,
|
||||
.priv_data_size = sizeof(Dummy3Context),
|
||||
};
|
||||
|
||||
/* codec without priv data */
|
||||
static AVCodec dummy_v4_encoder = {
|
||||
.name = "dummy_v4_codec",
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = AV_CODEC_ID_NONE - 4,
|
||||
.encode2 = dummy_encode,
|
||||
.init = dummy_init,
|
||||
.close = dummy_close,
|
||||
};
|
||||
|
||||
static void test_copy_print_codec(const AVCodecContext *ctx)
|
||||
{
|
||||
printf("%-14s: %dx%d prv: %s",
|
||||
ctx->codec ? ctx->codec->name : "NULL",
|
||||
ctx->width, ctx->height,
|
||||
ctx->priv_data ? "set" : "null");
|
||||
if (ctx->codec && ctx->codec->priv_class && ctx->codec->priv_data_size) {
|
||||
int64_t i64;
|
||||
char *str = NULL;
|
||||
av_opt_get_int(ctx->priv_data, "num", 0, &i64);
|
||||
av_opt_get(ctx->priv_data, "str", 0, (uint8_t**)&str);
|
||||
printf(" opts: %"PRId64" %s", i64, str);
|
||||
av_free(str);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void test_copy(const AVCodec *c1, const AVCodec *c2)
|
||||
{
|
||||
AVCodecContext *ctx1, *ctx2;
|
||||
printf("%s -> %s\nclosed:\n", c1 ? c1->name : "NULL", c2 ? c2->name : "NULL");
|
||||
ctx1 = avcodec_alloc_context3(c1);
|
||||
ctx2 = avcodec_alloc_context3(c2);
|
||||
ctx1->width = ctx1->height = 128;
|
||||
if (ctx2->codec && ctx2->codec->priv_class && ctx2->codec->priv_data_size) {
|
||||
av_opt_set(ctx2->priv_data, "num", "667", 0);
|
||||
av_opt_set(ctx2->priv_data, "str", "i'm dest value before copy", 0);
|
||||
}
|
||||
avcodec_copy_context(ctx2, ctx1);
|
||||
test_copy_print_codec(ctx1);
|
||||
test_copy_print_codec(ctx2);
|
||||
if (ctx1->codec) {
|
||||
printf("opened:\n");
|
||||
avcodec_open2(ctx1, ctx1->codec, NULL);
|
||||
if (ctx2->codec && ctx2->codec->priv_class && ctx2->codec->priv_data_size) {
|
||||
av_opt_set(ctx2->priv_data, "num", "667", 0);
|
||||
av_opt_set(ctx2->priv_data, "str", "i'm dest value before copy", 0);
|
||||
}
|
||||
avcodec_copy_context(ctx2, ctx1);
|
||||
test_copy_print_codec(ctx1);
|
||||
test_copy_print_codec(ctx2);
|
||||
avcodec_close(ctx1);
|
||||
}
|
||||
avcodec_free_context(&ctx1);
|
||||
avcodec_free_context(&ctx2);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
AVCodec *dummy_codec[] = {
|
||||
&dummy_v1_encoder,
|
||||
&dummy_v2_encoder,
|
||||
&dummy_v3_encoder,
|
||||
&dummy_v4_encoder,
|
||||
NULL,
|
||||
};
|
||||
int i, j;
|
||||
|
||||
for (i = 0; dummy_codec[i]; i++)
|
||||
avcodec_register(dummy_codec[i]);
|
||||
|
||||
printf("testing avcodec_copy_context()\n");
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(dummy_codec); i++)
|
||||
for (j = 0; j < FF_ARRAY_ELEMS(dummy_codec); j++)
|
||||
test_copy(dummy_codec[i], dummy_codec[j]);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
550
ext/at3_standalone/options_table.h
Normal file
550
ext/at3_standalone/options_table.h
Normal file
@ -0,0 +1,550 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
* Copyright (c) 2002-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_OPTIONS_TABLE_H
|
||||
#define AVCODEC_OPTIONS_TABLE_H
|
||||
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "opt.h"
|
||||
#include "avcodec.h"
|
||||
#include "version.h"
|
||||
|
||||
#define OFFSET(x) offsetof(AVCodecContext,x)
|
||||
#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C
|
||||
//these names are too long to be readable
|
||||
#define V AV_OPT_FLAG_VIDEO_PARAM
|
||||
#define A AV_OPT_FLAG_AUDIO_PARAM
|
||||
#define S AV_OPT_FLAG_SUBTITLE_PARAM
|
||||
#define E AV_OPT_FLAG_ENCODING_PARAM
|
||||
#define D AV_OPT_FLAG_DECODING_PARAM
|
||||
|
||||
#define AV_CODEC_DEFAULT_BITRATE 200*1000
|
||||
|
||||
static const AVOption avcodec_options[] = {
|
||||
{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = AV_CODEC_DEFAULT_BITRATE }, 0, INT64_MAX, A|V|E},
|
||||
{"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = 128*1000 }, 0, INT_MAX, A|E},
|
||||
{"bt", "Set video bitrate tolerance (in bits/s). In 1-pass mode, bitrate tolerance specifies how far "
|
||||
"ratecontrol is willing to deviate from the target average bitrate value. This is not related "
|
||||
"to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.",
|
||||
OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E},
|
||||
{"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|S|E|D, "flags"},
|
||||
{"unaligned", "allow decoders to produce unaligned output", 0, AV_OPT_TYPE_CONST, { .i64 = AV_CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, "flags" },
|
||||
{"mv4", "use four motion vectors per macroblock (MPEG-4)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"},
|
||||
{"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"},
|
||||
{"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"},
|
||||
{"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"},
|
||||
#if FF_API_GMC
|
||||
{"gmc", "use gmc", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_GMC }, INT_MIN, INT_MAX, V|E, "flags"},
|
||||
#endif
|
||||
#if FF_API_MV0
|
||||
{"mv0", "always try a mb with mv=<0,0>", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_MV0 }, INT_MIN, INT_MAX, V|E, "flags"},
|
||||
#endif
|
||||
#if FF_API_INPUT_PRESERVED
|
||||
{"input_preserved", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_INPUT_PRESERVED }, INT_MIN, INT_MAX, 0, "flags"},
|
||||
#endif
|
||||
{"pass1", "use internal 2-pass ratecontrol in first pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"},
|
||||
{"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"},
|
||||
{"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"},
|
||||
#if FF_API_EMU_EDGE
|
||||
{"emu_edge", "do not draw edges", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_EMU_EDGE }, INT_MIN, INT_MAX, 0, "flags"},
|
||||
#endif
|
||||
{"psnr", "error[?] variables will be set during encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PSNR }, INT_MIN, INT_MAX, V|E, "flags"},
|
||||
{"truncated", "Input bitstream might be randomly truncated", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_TRUNCATED }, INT_MIN, INT_MAX, V|D, "flags"},
|
||||
#if FF_API_NORMALIZE_AQP
|
||||
{"naq", "normalize adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_NORMALIZE_AQP }, INT_MIN, INT_MAX, V|E, "flags"},
|
||||
#endif
|
||||
{"ildct", "use interlaced DCT", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, "flags"},
|
||||
{"low_delay", "force low delay", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, "flags"},
|
||||
{"global_header", "place global headers in extradata instead of every keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, "flags"},
|
||||
{"bitexact", "use only bitexact functions (except (I)DCT)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, "flags"},
|
||||
{"aic", "H.263 advanced intra coding / MPEG-4 AC prediction", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"},
|
||||
{"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"},
|
||||
{"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"},
|
||||
{"output_corrupt", "Output even potentially corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, "flags"},
|
||||
{"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"},
|
||||
{"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"},
|
||||
{"ignorecrop", "ignore cropping information from sps", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"},
|
||||
{"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"},
|
||||
{"chunks", "Frame data might be split into multiple chunks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, "flags2"},
|
||||
{"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, "flags2"},
|
||||
{"export_mvs", "export motion vectors through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_EXPORT_MVS}, INT_MIN, INT_MAX, V|D, "flags2"},
|
||||
{"skip_manual", "do not skip samples and export skip information as frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SKIP_MANUAL}, INT_MIN, INT_MAX, V|D, "flags2"},
|
||||
#if FF_API_MOTION_EST
|
||||
{"me_method", "set motion estimation method", OFFSET(me_method), AV_OPT_TYPE_INT, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method"},
|
||||
{"zero", "zero motion estimation (fastest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ZERO }, INT_MIN, INT_MAX, V|E, "me_method" },
|
||||
{"full", "full motion estimation (slowest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
|
||||
{"epzs", "EPZS motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" },
|
||||
{"esa", "esa motion estimation (alias for full)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
|
||||
{"tesa", "tesa motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_TESA }, INT_MIN, INT_MAX, V|E, "me_method" },
|
||||
{"dia", "diamond motion estimation (alias for EPZS)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" },
|
||||
{"log", "log motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_LOG }, INT_MIN, INT_MAX, V|E, "me_method" },
|
||||
{"phods", "phods motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_PHODS }, INT_MIN, INT_MAX, V|E, "me_method" },
|
||||
{"x1", "X1 motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_X1 }, INT_MIN, INT_MAX, V|E, "me_method" },
|
||||
{"hex", "hex motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_HEX }, INT_MIN, INT_MAX, V|E, "me_method" },
|
||||
{"umh", "umh motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_UMH }, INT_MIN, INT_MAX, V|E, "me_method" },
|
||||
{"iter", "iter motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ITER }, INT_MIN, INT_MAX, V|E, "me_method" },
|
||||
#endif
|
||||
{"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, INT_MIN, INT_MAX},
|
||||
{"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E},
|
||||
{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E},
|
||||
{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E},
|
||||
{"cutoff", "set cutoff bandwidth", OFFSET(cutoff), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E},
|
||||
{"frame_size", NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E},
|
||||
{"frame_number", NULL, OFFSET(frame_number), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"delay", NULL, OFFSET(delay), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"qcomp", "video quantizer scale compression (VBR). Constant of ratecontrol equation. "
|
||||
"Recommended range for default rc_eq: 0.0-1.0",
|
||||
OFFSET(qcompress), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -FLT_MAX, FLT_MAX, V|E},
|
||||
{"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -1, FLT_MAX, V|E},
|
||||
{"qmin", "minimum video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 = 2 }, -1, 69, V|E},
|
||||
{"qmax", "maximum video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 = 31 }, -1, 1024, V|E},
|
||||
{"qdiff", "maximum difference between the quantizer scales (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 = 3 }, INT_MIN, INT_MAX, V|E},
|
||||
{"bf", "set maximum number of B frames between non-B-frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, INT_MAX, V|E},
|
||||
{"b_qfactor", "QP factor between P- and B-frames", OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
|
||||
#if FF_API_RC_STRATEGY
|
||||
{"rc_strategy", "ratecontrol method", OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"b_strategy", "strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, V|E},
|
||||
{"ps", "RTP payload size in bytes", OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
#if FF_API_STAT_BITS
|
||||
{"mv_bits", NULL, OFFSET(mv_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"header_bits", NULL, OFFSET(header_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"i_tex_bits", NULL, OFFSET(i_tex_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"p_tex_bits", NULL, OFFSET(p_tex_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"i_count", NULL, OFFSET(i_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"p_count", NULL, OFFSET(p_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"skip_count", NULL, OFFSET(skip_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"misc_bits", NULL, OFFSET(misc_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"frame_bits", NULL, OFFSET(frame_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
#endif
|
||||
{"codec_tag", NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"bug", "work around not autodetected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
#if FF_API_OLD_MSMPEG4
|
||||
{"old_msmpeg4", "some old lavc-generated MSMPEG4v3 files (no autodetection)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_OLD_MSMPEG4 }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
#endif
|
||||
{"xvid_ilace", "Xvid interlacing bug (autodetected if FOURCC == XVIX)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"ump4", "(autodetected if FOURCC == UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"amv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
#if FF_API_AC_VLC
|
||||
{"ac_vlc", "illegal VLC bug (autodetected per FOURCC)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AC_VLC }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
#endif
|
||||
{"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"std_qpel", "old standard qpel (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"direct_blocksize", "direct-qpel-blocksize bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DIRECT_BLOCKSIZE }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"edge", "edge padding bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"hpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_HPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"dc_clip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"ms", "work around various bugs in Microsoft's broken decoders", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"trunc", "truncated frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, "bug"},
|
||||
{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
|
||||
{"very", "strictly conform to a older more strict version of the spec or reference software", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, V|D|E, "strict"},
|
||||
{"strict", "strictly conform to all the things in the spec no matter what the consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, V|D|E, "strict"},
|
||||
{"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
|
||||
{"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
|
||||
{"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
|
||||
{"b_qoffset", "QP offset between P- and B-frames", OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
|
||||
{"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
|
||||
{"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
|
||||
{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
|
||||
{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
|
||||
{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
|
||||
{"ignore_err", "ignore errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_IGNORE_ERR }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
|
||||
{"careful", "consider things that violate the spec, are fast to check and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
|
||||
{"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
|
||||
{"aggressive", "consider things that a sane encoder should not do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
|
||||
{"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
#if FF_API_MPV_OPT
|
||||
{"qsquish", "deprecated, use encoder private options instead", OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 99, V|E},
|
||||
{"rc_qmod_amp", "deprecated, use encoder private options instead", OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
|
||||
{"rc_qmod_freq", "deprecated, use encoder private options instead", OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
{"rc_override_count", NULL, OFFSET(rc_override_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
#if FF_API_MPV_OPT
|
||||
{"rc_eq", "deprecated, use encoder private options instead", OFFSET(rc_eq), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, V|E},
|
||||
#endif
|
||||
{"maxrate", "maximum bitrate (in bits/s). Used for VBV together with bufsize.", OFFSET(rc_max_rate), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT_MAX, V|A|E},
|
||||
{"minrate", "minimum bitrate (in bits/s). Most useful in setting up a CBR encode. It is of little use otherwise.",
|
||||
OFFSET(rc_min_rate), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
|
||||
{"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|E},
|
||||
#if FF_API_MPV_OPT
|
||||
{"rc_buf_aggressivity", "deprecated, use encoder private options instead", OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, V|E},
|
||||
#endif
|
||||
{"i_qfactor", "QP factor between P- and I-frames", OFFSET(i_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = -0.8 }, -FLT_MAX, FLT_MAX, V|E},
|
||||
{"i_qoffset", "QP offset between P- and I-frames", OFFSET(i_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, -FLT_MAX, FLT_MAX, V|E},
|
||||
#if FF_API_MPV_OPT
|
||||
{"rc_init_cplx", "deprecated, use encoder private options instead", OFFSET(rc_initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
|
||||
#endif
|
||||
{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"},
|
||||
{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"},
|
||||
{"fastint", "fast integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"},
|
||||
{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"},
|
||||
{"mmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"},
|
||||
{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"},
|
||||
{"faan", "floating point AAN DCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"},
|
||||
{"lumi_mask", "compresses bright areas stronger than medium ones", OFFSET(lumi_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
|
||||
{"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
|
||||
{"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
|
||||
{"p_mask", "inter masking", OFFSET(p_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
|
||||
{"dark_mask", "compresses dark areas stronger than medium ones", OFFSET(dark_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
|
||||
{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, "idct"},
|
||||
{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
{"int", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
{"simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
{"simplemmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
{"arm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
#if FF_API_ARCH_SH4
|
||||
{"sh4", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SH4 }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
#endif
|
||||
{"simplearm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
{"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
{"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
{"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
#if FF_API_ARCH_ALPHA
|
||||
{"simplealpha", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
#endif
|
||||
#if FF_API_UNUSED_MEMBERS
|
||||
{"ipp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
#endif /* FF_API_UNUSED_MEMBERS */
|
||||
{"xvid", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
{"xvidmmx", "deprecated, for compatibility only", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
{"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"},
|
||||
{"simpleauto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
|
||||
{"slice_count", NULL, OFFSET(slice_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"ec", "set error concealment strategy", OFFSET(error_concealment), AV_OPT_TYPE_FLAGS, {.i64 = 3 }, INT_MIN, INT_MAX, V|D, "ec"},
|
||||
{"guess_mvs", "iterative motion vector (MV) search (slow)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_GUESS_MVS }, INT_MIN, INT_MAX, V|D, "ec"},
|
||||
{"deblock", "use strong deblock filter for damaged MBs", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, "ec"},
|
||||
{"favor_inter", "favor predicting from the previous frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_FAVOR_INTER }, INT_MIN, INT_MAX, V|D, "ec"},
|
||||
{"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"pred", "prediction method", OFFSET(prediction_method), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "pred"},
|
||||
{"left", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_LEFT }, INT_MIN, INT_MAX, V|E, "pred"},
|
||||
{"plane", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_PLANE }, INT_MIN, INT_MAX, V|E, "pred"},
|
||||
{"median", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_MEDIAN }, INT_MIN, INT_MAX, V|E, "pred"},
|
||||
#endif
|
||||
{"aspect", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E},
|
||||
{"debug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|A|S|E|D, "debug"},
|
||||
{"pict", "picture info", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PICT_INFO }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
{"rc", "rate control", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_RC }, INT_MIN, INT_MAX, V|E, "debug"},
|
||||
{"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
{"mb_type", "macroblock (MB) type", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
{"qp", "per-block quantization parameter (QP)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
#if FF_API_DEBUG_MV
|
||||
{"mv", "motion vector", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MV }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
#endif
|
||||
{"dct_coeff", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
{"green_metadata", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_GREEN_MD }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
{"skip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
{"startcode", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
#if FF_API_UNUSED_MEMBERS
|
||||
{"pts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PTS }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
#endif /* FF_API_UNUSED_MEMBERS */
|
||||
{"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
{"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
{"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
#if FF_API_DEBUG_MV
|
||||
{"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
{"vis_mb_type", "visualize block types", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
#endif
|
||||
{"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"},
|
||||
{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"},
|
||||
{"nomc", "skip motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, "debug"},
|
||||
#if FF_API_VISMV
|
||||
{"vismv", "visualize motion vectors (MVs) (deprecated)", OFFSET(debug_mv), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|D, "debug_mv"},
|
||||
{"pf", "forward predicted MVs of P-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_P_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"},
|
||||
{"bf", "forward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"},
|
||||
{"bb", "backward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_BACK }, INT_MIN, INT_MAX, V|D, "debug_mv"},
|
||||
#endif
|
||||
{"cmp", "full-pel ME compare function", OFFSET(me_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"subcmp", "sub-pel ME compare function", OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"mbcmp", "macroblock compare function", OFFSET(mb_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"ildctcmp", "interlaced DCT compare function", OFFSET(ildct_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"dia_size", "diamond type & size for motion estimation", OFFSET(dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
{"last_pred", "amount of motion predictors from the previous frame", OFFSET(last_predictor_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"preme", "pre motion estimation", OFFSET(pre_me), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
{"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"sad", "sum of absolute differences, fast", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"sse", "sum of squared errors", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"satd", "sum of absolute Hadamard transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SATD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"dct", "sum of absolute DCT transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"psnr", "sum of squared quantization errors (avoid, low quality)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_PSNR }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"bit", "number of bits needed for the block", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_BIT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"rd", "rate distortion optimal, slow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_RD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"zero", "0", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_ZERO }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"vsad", "sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"vsse", "sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"nsse", "noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
#if CONFIG_SNOW_ENCODER
|
||||
{"w53", "5/3 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W53 }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"w97", "9/7 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W97 }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
#endif
|
||||
{"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
{"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
{"subq", "sub-pel motion estimation quality", OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
|
||||
#if FF_API_AFD
|
||||
{"dtg_active_format", NULL, OFFSET(dtg_active_format), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
#endif
|
||||
{"me_range", "limit motion vectors range (1023 for DivX player)", OFFSET(me_range), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#if FF_API_QUANT_BIAS
|
||||
{"ibias", "intra quant bias", OFFSET(intra_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E},
|
||||
{"pbias", "inter quant bias", OFFSET(inter_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
{"global_quality", NULL, OFFSET(global_quality), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
|
||||
#if FF_API_CODER_TYPE
|
||||
{"coder", NULL, OFFSET(coder_type), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "coder"},
|
||||
{"vlc", "variable length coder / Huffman coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_VLC }, INT_MIN, INT_MAX, V|E, "coder"},
|
||||
{"ac", "arithmetic coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_AC }, INT_MIN, INT_MAX, V|E, "coder"},
|
||||
{"raw", "raw (no encoding)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_RAW }, INT_MIN, INT_MAX, V|E, "coder"},
|
||||
{"rle", "run-length coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_RLE }, INT_MIN, INT_MAX, V|E, "coder"},
|
||||
#if FF_API_UNUSED_MEMBERS
|
||||
{"deflate", "deflate-based coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_DEFLATE }, INT_MIN, INT_MAX, V|E, "coder"},
|
||||
#endif /* FF_API_UNUSED_MEMBERS */
|
||||
#endif /* FF_API_CODER_TYPE */
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"context", "context model", OFFSET(context_model), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
{"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
#if FF_API_XVMC
|
||||
{"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
#endif /* FF_API_XVMC */
|
||||
{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 2, V|E, "mbd"},
|
||||
{"simple", "use mbcmp", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"},
|
||||
{"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"},
|
||||
{"rd", "use best rate distortion", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, "mbd"},
|
||||
#if FF_API_STREAM_CODEC_TAG
|
||||
{"stream_codec_tag", NULL, OFFSET(stream_codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
#endif
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"sc_threshold", "scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
#if FF_API_MPV_OPT
|
||||
{"lmin", "deprecated, use encoder private options instead", OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E},
|
||||
{"lmax", "deprecated, use encoder private options instead", OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E},
|
||||
#endif
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"nr", "noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
{"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
{"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D, "flags2"},
|
||||
#if FF_API_ERROR_RATE
|
||||
{"error", NULL, OFFSET(error_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
{"threads", "set the number of threads", OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|A|E|D, "threads"},
|
||||
{"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"},
|
||||
#if FF_API_MPV_OPT
|
||||
{"me_threshold", "motion estimation threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
{"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
{"dc", "intra_dc_precision", OFFSET(intra_dc_precision), AV_OPT_TYPE_INT, {.i64 = 0 }, -8, 16, V|E},
|
||||
{"nssew", "nsse weight", OFFSET(nsse_weight), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
|
||||
{"skip_top", "number of macroblock rows at the top which are skipped", OFFSET(skip_top), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D},
|
||||
{"skip_bottom", "number of macroblock rows at the bottom which are skipped", OFFSET(skip_bottom), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D},
|
||||
{"profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"},
|
||||
{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"},
|
||||
{"aac_main", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_MAIN }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"aac_ssr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_SSR }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"aac_ltp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LTP }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"aac_he_v2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE_V2 }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"aac_ld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LD }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"aac_eld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_ELD }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"mpeg2_aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"mpeg2_aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"dts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"dts_es", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_ES }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"dts_96_24", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_96_24 }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"dts_hd_hra", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_HRA }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"dts_hd_ma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_MA }, INT_MIN, INT_MAX, A|E, "profile"},
|
||||
{"mpeg4_sp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"},
|
||||
{"mpeg4_core", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_CORE }, INT_MIN, INT_MAX, V|E, "profile"},
|
||||
{"mpeg4_main", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_MAIN }, INT_MIN, INT_MAX, V|E, "profile"},
|
||||
{"mpeg4_asp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_ADVANCED_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"},
|
||||
{"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"},
|
||||
{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"},
|
||||
{"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|A|D},
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"skip_threshold", "frame skip threshold", OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
{"skip_factor", "frame skip factor", OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
{"skip_exp", "frame skip exponent", OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
{"skipcmp", "frame skip compare function", OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
|
||||
#endif
|
||||
#if FF_API_MPV_OPT
|
||||
{"border_mask", "deprecated, use encoder private options instead", OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
|
||||
#endif
|
||||
{"mblmin", "minimum macroblock Lagrange factor (VBR)", OFFSET(mb_lmin), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 2 }, 1, FF_LAMBDA_MAX, V|E},
|
||||
{"mblmax", "maximum macroblock Lagrange factor (VBR)", OFFSET(mb_lmax), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 31 }, 1, FF_LAMBDA_MAX, V|E},
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"mepc", "motion estimation bitrate penalty compensation (1.0 = 256)", OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
{"skip_loop_filter", "skip loop filtering process for the selected frames", OFFSET(skip_loop_filter), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
|
||||
{"skip_idct" , "skip IDCT/dequantization for the selected frames", OFFSET(skip_idct), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
|
||||
{"skip_frame" , "skip decoding for the selected frames", OFFSET(skip_frame), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
|
||||
{"none" , "discard no frame", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONE }, INT_MIN, INT_MAX, V|D, "avdiscard"},
|
||||
{"default" , "discard useless frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
|
||||
{"noref" , "discard all non-reference frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONREF }, INT_MIN, INT_MAX, V|D, "avdiscard"},
|
||||
{"bidir" , "discard all bidirectional frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_BIDIR }, INT_MIN, INT_MAX, V|D, "avdiscard"},
|
||||
{"nokey" , "discard all frames except keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONKEY }, INT_MIN, INT_MAX, V|D, "avdiscard"},
|
||||
{"nointra" , "discard all frames except I frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONINTRA}, INT_MIN, INT_MAX, V|D, "avdiscard"},
|
||||
{"all" , "discard all frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_ALL }, INT_MIN, INT_MAX, V|D, "avdiscard"},
|
||||
{"bidir_refine", "refine the two motion vectors used in bidirectional macroblocks", OFFSET(bidir_refine), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, 4, V|E},
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"brd_scale", "downscale frames for dynamic B-frame decision", OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 10, V|E},
|
||||
#endif
|
||||
{"keyint_min", "minimum interval between IDR-frames", OFFSET(keyint_min), AV_OPT_TYPE_INT, {.i64 = 25 }, INT_MIN, INT_MAX, V|E},
|
||||
{"refs", "reference frames to consider for motion compensation", OFFSET(refs), AV_OPT_TYPE_INT, {.i64 = 1 }, INT_MIN, INT_MAX, V|E},
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"chromaoffset", "chroma QP offset from luma", OFFSET(chromaoffset), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
|
||||
#endif
|
||||
{"trellis", "rate-distortion optimal quantization", OFFSET(trellis), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
|
||||
#if FF_API_UNUSED_MEMBERS
|
||||
{"sc_factor", "multiplied by qscale for each frame and added to scene_change_score", OFFSET(scenechange_factor), AV_OPT_TYPE_INT, {.i64 = 6 }, 0, INT_MAX, V|E},
|
||||
#endif /* FF_API_UNUSED_MEMBERS */
|
||||
{"mv0_threshold", NULL, OFFSET(mv0_threshold), AV_OPT_TYPE_INT, {.i64 = 256 }, 0, INT_MAX, V|E},
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"b_sensitivity", "adjust sensitivity of b_frame_strategy 1", OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, V|E},
|
||||
#endif
|
||||
{"compression_level", NULL, OFFSET(compression_level), AV_OPT_TYPE_INT, {.i64 = FF_COMPRESSION_DEFAULT }, INT_MIN, INT_MAX, V|A|E},
|
||||
#if FF_API_PRIVATE_OPT
|
||||
{"min_prediction_order", NULL, OFFSET(min_prediction_order), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, A|E},
|
||||
{"max_prediction_order", NULL, OFFSET(max_prediction_order), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, A|E},
|
||||
{"timecode_frame_start", "GOP timecode frame start number, in non-drop-frame format", OFFSET(timecode_frame_start), AV_OPT_TYPE_INT64, {.i64 = -1 }, -1, INT64_MAX, V|E},
|
||||
#endif
|
||||
{"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
|
||||
{"channel_layout", NULL, OFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT64_MAX, A|E|D, "channel_layout"},
|
||||
{"request_channel_layout", NULL, OFFSET(request_channel_layout), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT64_MAX, A|D, "request_channel_layout"},
|
||||
{"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0.0, FLT_MAX, V|E},
|
||||
{"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use), AV_OPT_TYPE_FLOAT, {.dbl = 3 }, 0.0, FLT_MAX, V|E},
|
||||
{"ticks_per_frame", NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, INT_MAX, A|V|E|D},
|
||||
{"color_primaries", "color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, AVCOL_PRI_NB-1, V|E|D, "color_primaries_type"},
|
||||
{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
|
||||
{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
|
||||
{"bt470m", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
|
||||
{"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470BG }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
|
||||
{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
|
||||
{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
|
||||
{"film", "Film", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_FILM }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
|
||||
{"bt2020", "BT.2020", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT2020 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
|
||||
{"smpte428_1", "SMPTE ST 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTEST428_1 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
|
||||
{"color_trc", "color transfer characteristics", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, AVCOL_TRC_NB-1, V|E|D, "color_trc_type"},
|
||||
{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"gamma22", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"gamma28", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA28 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"linear", "Linear", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LINEAR }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"log", "Log", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"log_sqrt", "Log square root", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"iec61966_2_4", "IEC 61966-2-4", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"bt1361", "BT.1361", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"iec61966_2_1", "IEC 61966-2-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"bt2020_10bit", "BT.2020 - 10 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"bt2020_12bit", "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"smpte2084", "SMPTE ST 2084", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTEST2084 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"smpte428_1", "SMPTE ST 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTEST428_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
|
||||
{"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, AVCOL_SPC_NB-1, V|E|D, "colorspace_type"},
|
||||
{"rgb", "RGB", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_RGB }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
|
||||
{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
|
||||
{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
|
||||
{"fcc", "FCC", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_FCC }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
|
||||
{"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT470BG }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
|
||||
{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
|
||||
{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
|
||||
{"ycocg", "YCOCG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCOCG }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
|
||||
{"bt2020_ncl", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
|
||||
{"bt2020_cl", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
|
||||
{"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, AVCOL_RANGE_NB-1, V|E|D, "color_range_type"},
|
||||
{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
|
||||
{"mpeg", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
|
||||
{"jpeg", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
|
||||
{"chroma_sample_location", "chroma sample location", OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, V|E|D, "chroma_sample_location_type"},
|
||||
{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
|
||||
{"left", "Left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_LEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
|
||||
{"center", "Center", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_CENTER }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
|
||||
{"topleft", "Top-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOPLEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
|
||||
{"top", "Top", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOP }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
|
||||
{"bottomleft", "Bottom-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOMLEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
|
||||
{"bottom", "Bottom", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOM }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
|
||||
{"log_level_offset", "set the log level offset", OFFSET(log_level_offset), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX },
|
||||
{"slices", "set the number of slices, used in parallelized encoding", OFFSET(slices), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E},
|
||||
{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|A|E|D, "thread_type"},
|
||||
{"slice", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
|
||||
{"frame", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
|
||||
{"audio_service_type", "audio service type", OFFSET(audio_service_type), AV_OPT_TYPE_INT, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"},
|
||||
{"ma", "Main Audio Service", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
|
||||
{"ef", "Effects", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EFFECTS }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
|
||||
{"vi", "Visually Impaired", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
|
||||
{"hi", "Hearing Impaired", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
|
||||
{"di", "Dialogue", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_DIALOGUE }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
|
||||
{"co", "Commentary", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_COMMENTARY }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
|
||||
{"em", "Emergency", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EMERGENCY }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
|
||||
{"vo", "Voice Over", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VOICE_OVER }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
|
||||
{"ka", "Karaoke", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_KARAOKE }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
|
||||
{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64=AV_SAMPLE_FMT_NONE}, -1, INT_MAX, A|D, "request_sample_fmt"},
|
||||
{"pkt_timebase", NULL, OFFSET(pkt_timebase), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0},
|
||||
{"sub_charenc", "set input text subtitles character encoding", OFFSET(sub_charenc), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, S|D},
|
||||
{"sub_charenc_mode", "set input text subtitles character encoding mode", OFFSET(sub_charenc_mode), AV_OPT_TYPE_FLAGS, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, -1, INT_MAX, S|D, "sub_charenc_mode"},
|
||||
{"do_nothing", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_DO_NOTHING}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
|
||||
{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
|
||||
{"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
|
||||
{"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, A|V|D },
|
||||
#if FF_API_SIDEDATA_ONLY_PKT
|
||||
{"side_data_only_packets", NULL, OFFSET(side_data_only_packets), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, A|V|E },
|
||||
#endif
|
||||
{"skip_alpha", "Skip processing alpha", OFFSET(skip_alpha), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, V|D },
|
||||
{"field_order", "Field order", OFFSET(field_order), AV_OPT_TYPE_INT, {.i64 = AV_FIELD_UNKNOWN }, 0, 5, V|D|E, "field_order" },
|
||||
{"progressive", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_PROGRESSIVE }, 0, 0, V|D|E, "field_order" },
|
||||
{"tt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TT }, 0, 0, V|D|E, "field_order" },
|
||||
{"bb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BB }, 0, 0, V|D|E, "field_order" },
|
||||
{"tb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TB }, 0, 0, V|D|E, "field_order" },
|
||||
{"bt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BT }, 0, 0, V|D|E, "field_order" },
|
||||
{"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, A|V|S|D|E},
|
||||
{"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, A|V|S|D },
|
||||
{"pixel_format", "set pixel format", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64=AV_PIX_FMT_NONE}, -1, INT_MAX, 0 },
|
||||
{"video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str=NULL}, 0, INT_MAX, 0 },
|
||||
{NULL},
|
||||
};
|
||||
|
||||
#undef A
|
||||
#undef V
|
||||
#undef S
|
||||
#undef E
|
||||
#undef D
|
||||
#undef DEFAULT
|
||||
#undef OFFSET
|
||||
|
||||
#endif /* AVCODEC_OPTIONS_TABLE_H */
|
122
ext/at3_standalone/qsort.h
Normal file
122
ext/at3_standalone/qsort.h
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* copyright (c) 2012 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 AVUTIL_QSORT_H
|
||||
#define AVUTIL_QSORT_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/**
|
||||
* Quicksort
|
||||
* This sort is fast, and fully inplace but not stable and it is possible
|
||||
* to construct input that requires O(n^2) time but this is very unlikely to
|
||||
* happen with non constructed input.
|
||||
*/
|
||||
#define AV_QSORT(p, num, type, cmp) do {\
|
||||
void *stack[64][2];\
|
||||
int sp= 1;\
|
||||
stack[0][0] = p;\
|
||||
stack[0][1] = (p)+(num)-1;\
|
||||
while(sp){\
|
||||
type *start= stack[--sp][0];\
|
||||
type *end = stack[ sp][1];\
|
||||
while(start < end){\
|
||||
if(start < end-1) {\
|
||||
int checksort=0;\
|
||||
type *right = end-2;\
|
||||
type *left = start+1;\
|
||||
type *mid = start + ((end-start)>>1);\
|
||||
if(cmp(start, end) > 0) {\
|
||||
if(cmp( end, mid) > 0) FFSWAP(type, *start, *mid);\
|
||||
else FFSWAP(type, *start, *end);\
|
||||
}else{\
|
||||
if(cmp(start, mid) > 0) FFSWAP(type, *start, *mid);\
|
||||
else checksort= 1;\
|
||||
}\
|
||||
if(cmp(mid, end) > 0){ \
|
||||
FFSWAP(type, *mid, *end);\
|
||||
checksort=0;\
|
||||
}\
|
||||
if(start == end-2) break;\
|
||||
FFSWAP(type, end[-1], *mid);\
|
||||
while(left <= right){\
|
||||
while(left<=right && cmp(left, end-1) < 0)\
|
||||
left++;\
|
||||
while(left<=right && cmp(right, end-1) > 0)\
|
||||
right--;\
|
||||
if(left <= right){\
|
||||
FFSWAP(type, *left, *right);\
|
||||
left++;\
|
||||
right--;\
|
||||
}\
|
||||
}\
|
||||
FFSWAP(type, end[-1], *left);\
|
||||
if(checksort && (mid == left-1 || mid == left)){\
|
||||
mid= start;\
|
||||
while(mid<end && cmp(mid, mid+1) <= 0)\
|
||||
mid++;\
|
||||
if(mid==end)\
|
||||
break;\
|
||||
}\
|
||||
if(end-left < left-start){\
|
||||
stack[sp ][0]= start;\
|
||||
stack[sp++][1]= right;\
|
||||
start = left+1;\
|
||||
}else{\
|
||||
stack[sp ][0]= left+1;\
|
||||
stack[sp++][1]= end;\
|
||||
end = right;\
|
||||
}\
|
||||
}else{\
|
||||
if(cmp(start, end) > 0)\
|
||||
FFSWAP(type, *start, *end);\
|
||||
break;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Merge sort, this sort requires a temporary buffer and is stable, its worst
|
||||
* case time is O(n log n)
|
||||
* @param p must be a lvalue pointer, this function may exchange it with tmp
|
||||
* @param tmp must be a lvalue pointer, this function may exchange it with p
|
||||
*/
|
||||
#define AV_MSORT(p, tmp, num, type, cmp) do {\
|
||||
unsigned i, j, step;\
|
||||
for(step=1; step<(num); step+=step){\
|
||||
for(i=0; i<(num); i+=2*step){\
|
||||
unsigned a[2] = {i, i+step};\
|
||||
unsigned end = FFMIN(i+2*step, (num));\
|
||||
for(j=i; a[0]<i+step && a[1]<end; j++){\
|
||||
int idx= cmp(p+a[0], p+a[1]) > 0;\
|
||||
tmp[j] = p[ a[idx]++ ];\
|
||||
}\
|
||||
if(a[0]>=i+step) a[0] = a[1];\
|
||||
for(; j<end; j++){\
|
||||
tmp[j] = p[ a[0]++ ];\
|
||||
}\
|
||||
}\
|
||||
FFSWAP(type*, p, tmp);\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#endif /* AVUTIL_QSORT_H */
|
298
ext/at3_standalone/rational.c
Normal file
298
ext/at3_standalone/rational.c
Normal file
@ -0,0 +1,298 @@
|
||||
/*
|
||||
* rational numbers
|
||||
* 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
|
||||
* rational numbers
|
||||
* @author Michael Niedermayer <michaelni@gmx.at>
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "mathematics.h"
|
||||
#include "rational.h"
|
||||
|
||||
int av_reduce(int *dst_num, int *dst_den,
|
||||
int64_t num, int64_t den, int64_t max)
|
||||
{
|
||||
AVRational a0 = { 0, 1 }, a1 = { 1, 0 };
|
||||
int sign = (num < 0) ^ (den < 0);
|
||||
int64_t gcd = av_gcd(FFABS(num), FFABS(den));
|
||||
|
||||
if (gcd) {
|
||||
num = FFABS(num) / gcd;
|
||||
den = FFABS(den) / gcd;
|
||||
}
|
||||
if (num <= max && den <= max) {
|
||||
a1 = (AVRational) { num, den };
|
||||
den = 0;
|
||||
}
|
||||
|
||||
while (den) {
|
||||
uint64_t x = num / den;
|
||||
int64_t next_den = num - den * x;
|
||||
int64_t a2n = x * a1.num + a0.num;
|
||||
int64_t a2d = x * a1.den + a0.den;
|
||||
|
||||
if (a2n > max || a2d > max) {
|
||||
if (a1.num) x = (max - a0.num) / a1.num;
|
||||
if (a1.den) x = FFMIN(x, (max - a0.den) / a1.den);
|
||||
|
||||
if (den * (2 * x * a1.den + a0.den) > num * a1.den)
|
||||
a1 = (AVRational) { x * a1.num + a0.num, x * a1.den + a0.den };
|
||||
break;
|
||||
}
|
||||
|
||||
a0 = a1;
|
||||
a1 = (AVRational) { a2n, a2d };
|
||||
num = den;
|
||||
den = next_den;
|
||||
}
|
||||
av_assert2(av_gcd(a1.num, a1.den) <= 1U);
|
||||
av_assert2(a1.num <= max && a1.den <= max);
|
||||
|
||||
*dst_num = sign ? -a1.num : a1.num;
|
||||
*dst_den = a1.den;
|
||||
|
||||
return den == 0;
|
||||
}
|
||||
|
||||
AVRational av_mul_q(AVRational b, AVRational c)
|
||||
{
|
||||
av_reduce(&b.num, &b.den,
|
||||
b.num * (int64_t) c.num,
|
||||
b.den * (int64_t) c.den, INT_MAX);
|
||||
return b;
|
||||
}
|
||||
|
||||
AVRational av_div_q(AVRational b, AVRational c)
|
||||
{
|
||||
return av_mul_q(b, (AVRational) { c.den, c.num });
|
||||
}
|
||||
|
||||
AVRational av_add_q(AVRational b, AVRational c) {
|
||||
av_reduce(&b.num, &b.den,
|
||||
b.num * (int64_t) c.den +
|
||||
c.num * (int64_t) b.den,
|
||||
b.den * (int64_t) c.den, INT_MAX);
|
||||
return b;
|
||||
}
|
||||
|
||||
AVRational av_sub_q(AVRational b, AVRational c)
|
||||
{
|
||||
return av_add_q(b, (AVRational) { -c.num, c.den });
|
||||
}
|
||||
|
||||
AVRational av_d2q(double d, int max)
|
||||
{
|
||||
AVRational a;
|
||||
int exponent;
|
||||
int64_t den;
|
||||
if (isnan(d))
|
||||
return (AVRational) { 0,0 };
|
||||
if (fabs(d) > INT_MAX + 3LL)
|
||||
return (AVRational) { d < 0 ? -1 : 1, 0 };
|
||||
frexp(d, &exponent);
|
||||
exponent = FFMAX(exponent-1, 0);
|
||||
den = 1LL << (61 - exponent);
|
||||
// (int64_t)rint() and llrint() do not work with gcc on ia64 and sparc64
|
||||
av_reduce(&a.num, &a.den, floor(d * den + 0.5), den, max);
|
||||
if ((!a.num || !a.den) && d && max>0 && max<INT_MAX)
|
||||
av_reduce(&a.num, &a.den, floor(d * den + 0.5), den, INT_MAX);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
int av_nearer_q(AVRational q, AVRational q1, AVRational q2)
|
||||
{
|
||||
/* n/d is q, a/b is the median between q1 and q2 */
|
||||
int64_t a = q1.num * (int64_t)q2.den + q2.num * (int64_t)q1.den;
|
||||
int64_t b = 2 * (int64_t)q1.den * q2.den;
|
||||
|
||||
/* rnd_up(a*d/b) > n => a*d/b > n */
|
||||
int64_t x_up = av_rescale_rnd(a, q.den, b, AV_ROUND_UP);
|
||||
|
||||
/* rnd_down(a*d/b) < n => a*d/b < n */
|
||||
int64_t x_down = av_rescale_rnd(a, q.den, b, AV_ROUND_DOWN);
|
||||
|
||||
return ((x_up > q.num) - (x_down < q.num)) * av_cmp_q(q2, q1);
|
||||
}
|
||||
|
||||
int av_find_nearest_q_idx(AVRational q, const AVRational* q_list)
|
||||
{
|
||||
int i, nearest_q_idx = 0;
|
||||
for (i = 0; q_list[i].den; i++)
|
||||
if (av_nearer_q(q, q_list[i], q_list[nearest_q_idx]) > 0)
|
||||
nearest_q_idx = i;
|
||||
|
||||
return nearest_q_idx;
|
||||
}
|
||||
|
||||
uint32_t av_q2intfloat(AVRational q) {
|
||||
int64_t n;
|
||||
int shift;
|
||||
int sign = 0;
|
||||
|
||||
if (q.den < 0) {
|
||||
q.den *= -1;
|
||||
q.num *= -1;
|
||||
}
|
||||
if (q.num < 0) {
|
||||
q.num *= -1;
|
||||
sign = 1;
|
||||
}
|
||||
|
||||
if (!q.num && !q.den) return 0xFFC00000;
|
||||
if (!q.num) return 0;
|
||||
if (!q.den) return 0x7F800000 | (q.num & 0x80000000);
|
||||
|
||||
shift = 23 + av_log2(q.den) - av_log2(q.num);
|
||||
if (shift >= 0) n = av_rescale(q.num, 1LL<<shift, q.den);
|
||||
else n = av_rescale(q.num, 1, ((int64_t)q.den) << -shift);
|
||||
|
||||
shift -= n >= (1<<24);
|
||||
shift += n < (1<<23);
|
||||
|
||||
if (shift >= 0) n = av_rescale(q.num, 1LL<<shift, q.den);
|
||||
else n = av_rescale(q.num, 1, ((int64_t)q.den) << -shift);
|
||||
|
||||
av_assert1(n < (1<<24));
|
||||
av_assert1(n >= (1<<23));
|
||||
|
||||
return sign<<31 | (150-shift)<<23 | (n - (1<<23));
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
AVRational a,b,r;
|
||||
int i,j,k;
|
||||
static const int64_t numlist[] = {
|
||||
INT64_MIN, INT64_MIN+1, INT64_MAX, INT32_MIN, INT32_MAX, 1,0,-1,
|
||||
123456789, INT32_MAX-1, INT32_MAX+1LL, UINT32_MAX-1, UINT32_MAX, UINT32_MAX+1LL
|
||||
};
|
||||
|
||||
for (a.num = -2; a.num <= 2; a.num++) {
|
||||
for (a.den = -2; a.den <= 2; a.den++) {
|
||||
for (b.num = -2; b.num <= 2; b.num++) {
|
||||
for (b.den = -2; b.den <= 2; b.den++) {
|
||||
int c = av_cmp_q(a,b);
|
||||
double d = av_q2d(a) == av_q2d(b) ?
|
||||
0 : (av_q2d(a) - av_q2d(b));
|
||||
if (d > 0) d = 1;
|
||||
else if (d < 0) d = -1;
|
||||
else if (d != d) d = INT_MIN;
|
||||
if (c != d)
|
||||
av_log(NULL, AV_LOG_ERROR, "%d/%d %d/%d, %d %f\n", a.num,
|
||||
a.den, b.num, b.den, c,d);
|
||||
r = av_sub_q(av_add_q(b,a), b);
|
||||
if(b.den && (r.num*a.den != a.num*r.den || !r.num != !a.num || !r.den != !a.den))
|
||||
av_log(NULL, AV_LOG_ERROR, "%d/%d ", r.num, r.den);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(numlist); i++) {
|
||||
int64_t a = numlist[i];
|
||||
|
||||
for (j = 0; j < FF_ARRAY_ELEMS(numlist); j++) {
|
||||
int64_t b = numlist[j];
|
||||
if (b<=0)
|
||||
continue;
|
||||
for (k = 0; k < FF_ARRAY_ELEMS(numlist); k++) {
|
||||
int64_t c = numlist[k];
|
||||
int64_t res;
|
||||
AVInteger ai;
|
||||
|
||||
if (c<=0)
|
||||
continue;
|
||||
res = av_rescale_rnd(a,b,c, AV_ROUND_ZERO);
|
||||
|
||||
ai = av_mul_i(av_int2i(a), av_int2i(b));
|
||||
ai = av_div_i(ai, av_int2i(c));
|
||||
|
||||
if (av_cmp_i(ai, av_int2i(INT64_MAX)) > 0 && res == INT64_MIN)
|
||||
continue;
|
||||
if (av_cmp_i(ai, av_int2i(INT64_MIN)) < 0 && res == INT64_MIN)
|
||||
continue;
|
||||
if (av_cmp_i(ai, av_int2i(res)) == 0)
|
||||
continue;
|
||||
|
||||
// Special exception for INT64_MIN, remove this in case INT64_MIN is handled without off by 1 error
|
||||
if (av_cmp_i(ai, av_int2i(res-1)) == 0 && a == INT64_MIN)
|
||||
continue;
|
||||
|
||||
av_log(NULL, AV_LOG_ERROR, "%"PRId64" * %"PRId64" / %"PRId64" = %"PRId64" or %"PRId64"\n", a,b,c, res, av_i2int(ai));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (a.num = 1; a.num <= 10; a.num++) {
|
||||
for (a.den = 1; a.den <= 10; a.den++) {
|
||||
if (av_gcd(a.num, a.den) > 1)
|
||||
continue;
|
||||
for (b.num = 1; b.num <= 10; b.num++) {
|
||||
for (b.den = 1; b.den <= 10; b.den++) {
|
||||
int start;
|
||||
if (av_gcd(b.num, b.den) > 1)
|
||||
continue;
|
||||
if (av_cmp_q(b, a) < 0)
|
||||
continue;
|
||||
for (start = 0; start < 10 ; start++) {
|
||||
int acc= start;
|
||||
int i;
|
||||
|
||||
for (i = 0; i<100; i++) {
|
||||
int exact = start + av_rescale_q(i+1, b, a);
|
||||
acc = av_add_stable(a, acc, b, 1);
|
||||
if (FFABS(acc - exact) > 2) {
|
||||
av_log(NULL, AV_LOG_ERROR, "%d/%d %d/%d, %d %d\n", a.num,
|
||||
a.den, b.num, b.den, acc, exact);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (a.den = 1; a.den < 0x100000000U/3; a.den*=3) {
|
||||
for (a.num = -1; a.num < (1<<27); a.num += 1 + a.num/100) {
|
||||
float f = av_int2float(av_q2intfloat(a));
|
||||
float f2 = av_q2d(a);
|
||||
if (fabs(f - f2) > fabs(f)/5000000) {
|
||||
av_log(NULL, AV_LOG_ERROR, "%d/%d %f %f\n", a.num,
|
||||
a.den, f, f2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "attributes.h"
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,8 @@
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "libavutil/mathematics.h"
|
||||
|
||||
#include "mathematics.h"
|
||||
#include "rdft.h"
|
||||
|
||||
/**
|
||||
|
252
ext/at3_standalone/samplefmt.c
Normal file
252
ext/at3_standalone/samplefmt.c
Normal file
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* 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 "common.h"
|
||||
#include "samplefmt.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct SampleFmtInfo {
|
||||
char name[8];
|
||||
int bits;
|
||||
int planar;
|
||||
enum AVSampleFormat altform; ///< planar<->packed alternative form
|
||||
} SampleFmtInfo;
|
||||
|
||||
/** this table gives more information about formats */
|
||||
static const SampleFmtInfo sample_fmt_info[AV_SAMPLE_FMT_NB] = {
|
||||
[AV_SAMPLE_FMT_U8] = { .name = "u8", .bits = 8, .planar = 0, .altform = AV_SAMPLE_FMT_U8P },
|
||||
[AV_SAMPLE_FMT_S16] = { .name = "s16", .bits = 16, .planar = 0, .altform = AV_SAMPLE_FMT_S16P },
|
||||
[AV_SAMPLE_FMT_S32] = { .name = "s32", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_S32P },
|
||||
[AV_SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_FLTP },
|
||||
[AV_SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_DBLP },
|
||||
[AV_SAMPLE_FMT_U8P] = { .name = "u8p", .bits = 8, .planar = 1, .altform = AV_SAMPLE_FMT_U8 },
|
||||
[AV_SAMPLE_FMT_S16P] = { .name = "s16p", .bits = 16, .planar = 1, .altform = AV_SAMPLE_FMT_S16 },
|
||||
[AV_SAMPLE_FMT_S32P] = { .name = "s32p", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_S32 },
|
||||
[AV_SAMPLE_FMT_FLTP] = { .name = "fltp", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_FLT },
|
||||
[AV_SAMPLE_FMT_DBLP] = { .name = "dblp", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_DBL },
|
||||
};
|
||||
|
||||
const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
|
||||
return NULL;
|
||||
return sample_fmt_info[sample_fmt].name;
|
||||
}
|
||||
|
||||
enum AVSampleFormat av_get_sample_fmt(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AV_SAMPLE_FMT_NB; i++)
|
||||
if (!strcmp(sample_fmt_info[i].name, name))
|
||||
return i;
|
||||
return AV_SAMPLE_FMT_NONE;
|
||||
}
|
||||
|
||||
enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar)
|
||||
{
|
||||
if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
|
||||
return AV_SAMPLE_FMT_NONE;
|
||||
if (sample_fmt_info[sample_fmt].planar == planar)
|
||||
return sample_fmt;
|
||||
return sample_fmt_info[sample_fmt].altform;
|
||||
}
|
||||
|
||||
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
|
||||
return AV_SAMPLE_FMT_NONE;
|
||||
if (sample_fmt_info[sample_fmt].planar)
|
||||
return sample_fmt_info[sample_fmt].altform;
|
||||
return sample_fmt;
|
||||
}
|
||||
|
||||
enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
|
||||
return AV_SAMPLE_FMT_NONE;
|
||||
if (sample_fmt_info[sample_fmt].planar)
|
||||
return sample_fmt;
|
||||
return sample_fmt_info[sample_fmt].altform;
|
||||
}
|
||||
|
||||
char *av_get_sample_fmt_string (char *buf, int buf_size, enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
/* print header */
|
||||
if (sample_fmt < 0)
|
||||
snprintf(buf, buf_size, "name " " depth");
|
||||
else if (sample_fmt < AV_SAMPLE_FMT_NB) {
|
||||
SampleFmtInfo info = sample_fmt_info[sample_fmt];
|
||||
snprintf (buf, buf_size, "%-6s" " %2d ", info.name, info.bits);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
return sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB ?
|
||||
0 : sample_fmt_info[sample_fmt].bits >> 3;
|
||||
}
|
||||
|
||||
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
|
||||
return 0;
|
||||
return sample_fmt_info[sample_fmt].planar;
|
||||
}
|
||||
|
||||
int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
|
||||
enum AVSampleFormat sample_fmt, int align)
|
||||
{
|
||||
int line_size;
|
||||
int sample_size = av_get_bytes_per_sample(sample_fmt);
|
||||
int planar = av_sample_fmt_is_planar(sample_fmt);
|
||||
|
||||
/* validate parameter ranges */
|
||||
if (!sample_size || nb_samples <= 0 || nb_channels <= 0)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
/* auto-select alignment if not specified */
|
||||
if (!align) {
|
||||
if (nb_samples > INT_MAX - 31)
|
||||
return AVERROR(EINVAL);
|
||||
align = 1;
|
||||
nb_samples = FFALIGN(nb_samples, 32);
|
||||
}
|
||||
|
||||
/* check for integer overflow */
|
||||
if (nb_channels > INT_MAX / align ||
|
||||
(int64_t)nb_channels * nb_samples > (INT_MAX - (align * nb_channels)) / sample_size)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
line_size = planar ? FFALIGN(nb_samples * sample_size, align) :
|
||||
FFALIGN(nb_samples * sample_size * nb_channels, align);
|
||||
if (linesize)
|
||||
*linesize = line_size;
|
||||
|
||||
return planar ? line_size * nb_channels : line_size;
|
||||
}
|
||||
|
||||
int av_samples_fill_arrays(uint8_t **audio_data, int *linesize,
|
||||
const uint8_t *buf, int nb_channels, int nb_samples,
|
||||
enum AVSampleFormat sample_fmt, int align)
|
||||
{
|
||||
int ch, planar, buf_size, line_size;
|
||||
|
||||
planar = av_sample_fmt_is_planar(sample_fmt);
|
||||
buf_size = av_samples_get_buffer_size(&line_size, nb_channels, nb_samples,
|
||||
sample_fmt, align);
|
||||
if (buf_size < 0)
|
||||
return buf_size;
|
||||
|
||||
audio_data[0] = (uint8_t *)buf;
|
||||
for (ch = 1; planar && ch < nb_channels; ch++)
|
||||
audio_data[ch] = audio_data[ch-1] + line_size;
|
||||
|
||||
if (linesize)
|
||||
*linesize = line_size;
|
||||
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
|
||||
int nb_samples, enum AVSampleFormat sample_fmt, int align)
|
||||
{
|
||||
uint8_t *buf;
|
||||
int size = av_samples_get_buffer_size(NULL, nb_channels, nb_samples,
|
||||
sample_fmt, align);
|
||||
if (size < 0)
|
||||
return size;
|
||||
|
||||
buf = av_malloc(size);
|
||||
if (!buf)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
size = av_samples_fill_arrays(audio_data, linesize, buf, nb_channels,
|
||||
nb_samples, sample_fmt, align);
|
||||
if (size < 0) {
|
||||
av_free(buf);
|
||||
return size;
|
||||
}
|
||||
|
||||
av_samples_set_silence(audio_data, 0, nb_samples, nb_channels, sample_fmt);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels,
|
||||
int nb_samples, enum AVSampleFormat sample_fmt, int align)
|
||||
{
|
||||
int ret, nb_planes = av_sample_fmt_is_planar(sample_fmt) ? nb_channels : 1;
|
||||
|
||||
*audio_data = av_calloc(nb_planes, sizeof(**audio_data));
|
||||
if (!*audio_data)
|
||||
return AVERROR(ENOMEM);
|
||||
ret = av_samples_alloc(*audio_data, linesize, nb_channels,
|
||||
nb_samples, sample_fmt, align);
|
||||
if (ret < 0)
|
||||
av_freep(audio_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset,
|
||||
int src_offset, int nb_samples, int nb_channels,
|
||||
enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
int planar = av_sample_fmt_is_planar(sample_fmt);
|
||||
int planes = planar ? nb_channels : 1;
|
||||
int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels);
|
||||
int data_size = nb_samples * block_align;
|
||||
int i;
|
||||
|
||||
dst_offset *= block_align;
|
||||
src_offset *= block_align;
|
||||
|
||||
if((dst[0] < src[0] ? src[0] - dst[0] : dst[0] - src[0]) >= data_size) {
|
||||
for (i = 0; i < planes; i++)
|
||||
memcpy(dst[i] + dst_offset, src[i] + src_offset, data_size);
|
||||
} else {
|
||||
for (i = 0; i < planes; i++)
|
||||
memmove(dst[i] + dst_offset, src[i] + src_offset, data_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples,
|
||||
int nb_channels, enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
int planar = av_sample_fmt_is_planar(sample_fmt);
|
||||
int planes = planar ? nb_channels : 1;
|
||||
int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels);
|
||||
int data_size = nb_samples * block_align;
|
||||
int fill_char = (sample_fmt == AV_SAMPLE_FMT_U8 ||
|
||||
sample_fmt == AV_SAMPLE_FMT_U8P) ? 0x80 : 0x00;
|
||||
int i;
|
||||
|
||||
offset *= block_align;
|
||||
|
||||
for (i = 0; i < planes; i++)
|
||||
memset(audio_data[i] + offset, fill_char, data_size);
|
||||
|
||||
return 0;
|
||||
}
|
@ -27,9 +27,10 @@
|
||||
// do not use libavutil/libm.h since this is compiled both
|
||||
// for the host and the target and config.h is only valid for the target
|
||||
#include <math.h>
|
||||
#include "libavcodec/aac_defines.h"
|
||||
#include "libavutil/attributes.h"
|
||||
#include "libavutil/common.h"
|
||||
|
||||
#include "aac_defines.h"
|
||||
#include "attributes.h"
|
||||
#include "common.h"
|
||||
|
||||
#if !CONFIG_HARDCODED_TABLES
|
||||
SINETABLE( 32);
|
||||
|
1590
ext/at3_standalone/utils.c
Normal file
1590
ext/at3_standalone/utils.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -225,7 +225,7 @@
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;d3dx9d.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;d3dx9d.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<BaseAddress>0x00400000</BaseAddress>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<FixedBaseAddress>true</FixedBaseAddress>
|
||||
|
@ -205,7 +205,7 @@
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86_64/lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
|
Loading…
Reference in New Issue
Block a user