1
0
mirror of https://github.com/nu774/fdkaac.git synced 2025-06-05 23:29:14 +02:00

16 Commits

Author SHA1 Message Date
59455af10a bump 2022-08-04 21:14:35 +09:00
ae1f4c3afd fdk-aac.vcxproj: support vs2022 2022-08-04 21:13:18 +09:00
0ce71d066a extrapolater: don't return more samples than required
fixes https://github.com/nu774/fdkaac/issues/54
2022-08-04 21:11:53 +09:00
ecddb7d633 wav/caf parser: add format checks
fixes https://github.com/nu774/fdkaac/issues/54
2022-08-04 21:06:10 +09:00
1a1ee2924f update ChangeLog 2022-07-13 21:03:53 +09:00
cdfb81d7c6 bump 2022-07-13 20:59:03 +09:00
4ec1422bd9 wav/caf parser: ensure fmt/desc chunk
fixes https://github.com/nu774/fdkaac/issues/52
2022-07-13 20:56:49 +09:00
53fe239bf6 vcxproj: support Visual Studio 2022 2021-11-15 01:18:51 +09:00
347e995cfc bump 2021-04-23 22:57:27 +09:00
9d65d3b3bf m4af: fix mvhd/tkhd duration
According to 14496-12, duration of mvhd/tkhd shall be the sum of
duration of edits
2021-04-23 22:53:46 +09:00
fdf5c2f251 bump 2020-09-21 22:41:03 +09:00
ef17c9436e add Windows 10 long pathname manifest 2020-09-21 22:41:03 +09:00
c0919b049a fix indent 2019-09-27 21:05:12 +09:00
353e4fcd7a process 32-bit input if possible (i.e. respect aac:INT_PCM type)
switch AAC-FDK from pcm16 to pcm32:
    typedef LONG INT_PCM;
    #define SAMPLE_BITS 32
2019-09-27 12:10:30 +03:00
130e249ebf vcxproj: support visual studio 2019 2019-04-04 19:55:18 +09:00
65ee26fb61 don't inject timestamp 2018-12-10 14:59:48 +03:00
18 changed files with 164 additions and 34 deletions

View File

@ -1,8 +1,76 @@
2022-07-13 nu774 <honeycomb77@gmail.com>
* bump [HEAD -> master]
* wav/caf parser: ensure fmt/desc chunk
2021-11-15 nu774 <honeycomb77@gmail.com>
* vcxproj: support Visual Studio 2022 [origin/master]
2021-04-23 nu774 <honeycomb77@gmail.com>
* bump [v1.0.2]
* m4af: fix mvhd/tkhd duration
2020-09-21 nu774 <honeycomb77@gmail.com>
* bump [v1.0.1]
* add Windows 10 long pathname manifest
2019-09-27 nu774 <honeycomb77@gmail.com>
* fix indent
2019-09-19 Dima <yudind@gmail.com>
* process 32-bit input if possible (i.e. respect aac:INT_PCM type)
2019-04-04 nu774 <honeycomb77@gmail.com>
* vcxproj: support visual studio 2019
2018-12-10 tico-tico <sergei.ivn@gmx.com>
* don't inject timestamp
2018-09-04 nu774 <honeycomb77@gmail.com>
* bump version 1.0.0 [1.0.0]
* Fix LD/ELD issue: priming samples are too short to be discarded
2018-09-03 nu774 <honeycomb77@gmail.com>
* FDKv2 API change: encoderDelay -> nDelay/nDelayCore
* update MSVC projects for FDKv2
* use different IntDir for fdk-aac build
* remove zombies from fdk-aac.vcxproj.filters
* fix: -L option was not working (resulted in segfault)
2017-03-16 nu774 <honeycomb77@gmail.com>
* MSVC projects: update for VS2017
2017-01-16 nu774 <honeycomb77@gmail.com>
* address issue#26
2016-08-27 nu774 <honeycomb77@gmail.com>
* remove aacenc_hcr.* from MSVC project
2016-08-26 nu774 <honeycomb77@gmail.com>
* update ChangeLog [HEAD -> master]
* update ChangeLog
* bump [origin/master]
* bump [v0.6.3]
* Ticket #23: quit supporting MPEG-2 AOT

View File

@ -24,6 +24,8 @@
<RootNamespace>fdk-aac</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(MSBuildToolsVersion)' == '17.0'">v143</PlatformToolset>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(MSBuildToolsVersion)' == '16.0'">v142</PlatformToolset>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(MSBuildToolsVersion)' == '15.0'">v141_xp</PlatformToolset>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(MSBuildToolsVersion)' == '14.0'">v140_xp</PlatformToolset>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(MSBuildToolsVersion)' == '12.0'">v120_xp</PlatformToolset>

View File

@ -24,6 +24,8 @@
<RootNamespace>fdkaac</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(MSBuildToolsVersion)' == '17.0'">v143</PlatformToolset>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(MSBuildToolsVersion)' == '16.0'">v142</PlatformToolset>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(MSBuildToolsVersion)' == '15.0'">v141_xp</PlatformToolset>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(MSBuildToolsVersion)' == '14.0'">v140_xp</PlatformToolset>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(MSBuildToolsVersion)' == '12.0'">v120_xp</PlatformToolset>
@ -54,6 +56,9 @@
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Manifest>
<AdditionalManifestFiles>..\fdkaac.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
<PreBuildEvent>
<Command>copy ..\fdk-aac\libAACdec\include\aacdecoder_lib.h include\fdk-aac\
copy ..\fdk-aac\libAACenc\include\aacenc_lib.h include\fdk-aac\

View File

@ -25,6 +25,9 @@ dist_man_MANS = man/fdkaac.1
fdkaac_LDADD = \
@LIBICONV@ @CHARSET_LIB@ -lfdk-aac -lm
.rc.o:
$(RC) $< -o $@
if FDK_PLATFORM_POSIX
fdkaac_SOURCES += \
src/compat_posix.c
@ -33,6 +36,7 @@ endif
if FDK_PLATFORM_WIN32
fdkaac_SOURCES += \
src/compat_win32.c
fdkaac_SOURCES += fdkaac.rc
endif
if FDK_NO_GETOPT_LONG

View File

@ -11,6 +11,7 @@ AM_INIT_AUTOMAKE
AC_PROG_CC
AM_PROG_CC_C_O
AC_CHECK_TOOL(RC, windres,)
AC_CHECK_HEADERS([sys/time.h])
AC_CHECK_HEADERS([libcharset.h langinfo.h endian.h byteswap.h])

8
fdkaac.manifest Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
</assembly>

3
fdkaac.rc Normal file
View File

@ -0,0 +1,3 @@
#include <winresrc.h>
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "fdkaac.manifest"

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright (C) 2013 nu774
# For conditions of distribution and use, see copyright notice in COPYING
@ -39,6 +39,6 @@ with Popen(GITLOG_CMD, shell=False, stdout=PIPE).stdout as pipe:
commits = parse_gitlog(pipe)
commits_by_date_author = groupby(commits, key=lambda x: (x.date, x.author))
for (date, author), commits in commits_by_date_author:
output(u'{0} {1}\n\n'.format(date, author).encode('utf-8'))
output(f'{date} {author}\n\n')
for c in commits:
output(u' * {0}{1}\n\n'.format(c.subject, c.ref).encode('utf-8'))
output(f' * {c.subject}{c.ref}\n\n')

View File

@ -247,7 +247,7 @@ FAIL:
int aac_encode_frame(HANDLE_AACENCODER encoder,
const pcm_sample_description_t *format,
const int16_t *input, unsigned iframes,
const INT_PCM *input, unsigned iframes,
aacenc_frame_t *output)
{
uint32_t ilen = iframes * format->channels_per_frame;
@ -258,9 +258,9 @@ int aac_encode_frame(HANDLE_AACENCODER encoder,
void *obufs[1];
INT ibuf_ids[] = { IN_AUDIO_DATA };
INT obuf_ids[] = { OUT_BITSTREAM_DATA };
INT ibuf_sizes[] = { ilen * sizeof(int16_t) };
INT ibuf_sizes[] = { ilen * sizeof(INT_PCM) };
INT obuf_sizes[1];
INT ibuf_el_sizes[] = { sizeof(int16_t) };
INT ibuf_el_sizes[] = { sizeof(INT_PCM) };
INT obuf_el_sizes[] = { 1 };
AACENC_ERROR err;
unsigned channel_mode, obytes;

View File

@ -50,7 +50,7 @@ int aacenc_init(HANDLE_AACENCODER *encoder, const aacenc_param_t *params,
int aac_encode_frame(HANDLE_AACENCODER encoder,
const pcm_sample_description_t *format,
const int16_t *input, unsigned iframes,
const INT_PCM *input, unsigned iframes,
aacenc_frame_t *output);
#endif

View File

@ -75,8 +75,10 @@ int caf_desc(caf_reader_t *reader, int64_t chunk_size)
ENSURE(mFormatID == M4AF_FOURCC('l','p','c','m'));
ENSURE(mSampleRate && mBytesPerPacket &&
mChannelsPerFrame >= 1 && mChannelsPerFrame <= 8 &&
mBitsPerChannel && mFramesPerPacket == 1 &&
mBitsPerChannel > 0 && mBitsPerChannel < 256 &&
mFramesPerPacket == 1 &&
mBytesPerPacket % mChannelsPerFrame == 0 &&
mBytesPerPacket < 256 &&
mBytesPerPacket >= mChannelsPerFrame * ((mBitsPerChannel + 7) / 8));
desc->sample_rate = mSampleRate;
@ -172,6 +174,7 @@ int caf_parse(caf_reader_t *reader, int64_t *data_length)
{
uint32_t fcc;
int64_t chunk_size;
int desc_seen = 0;
*data_length = 0;
@ -181,9 +184,10 @@ int caf_parse(caf_reader_t *reader, int64_t *data_length)
TRY_IO(pcm_skip(&reader->io, 4)); /* mFileVersion, mFileFlags */
while ((fcc = caf_next_chunk(reader, &chunk_size)) != 0) {
if (fcc == M4AF_FOURCC('d','e','s','c'))
if (fcc == M4AF_FOURCC('d','e','s','c')) {
desc_seen = 1;
TRY_IO(caf_desc(reader, chunk_size));
else if (fcc == M4AF_FOURCC('i','n','f','o'))
} else if (fcc == M4AF_FOURCC('i','n','f','o'))
TRY_IO(caf_info(reader, chunk_size));
else if (fcc == M4AF_FOURCC('c','h','a','n')) {
ENSURE(reader->sample_format.channels_per_frame);
@ -199,7 +203,7 @@ int caf_parse(caf_reader_t *reader, int64_t *data_length)
TRY_IO(pcm_skip(&reader->io, chunk_size));
}
ENSURE(reader->sample_format.channels_per_frame);
ENSURE(fcc == M4AF_FOURCC('d','a','t','a'));
ENSURE(desc_seen && fcc == M4AF_FOURCC('d','a','t','a'));
return 0;
FAIL:
return -1;

View File

@ -144,17 +144,22 @@ static int process1(extrapolater_t *self, void *buffer, unsigned nframes)
assert(bp->count <= nframes);
memcpy(buffer, bp->data, bp->count * sfmt->bytes_per_frame);
if (!fetch(self, nframes)) {
// got EOF
buffer_t *bbp = &self->buffer[self->nbuffer];
if (bp->count < 2 * LPC_ORDER) {
// final frame is too short, so we join with the pre-final frame
size_t total = bp->count + bbp->count;
if (bbp->count &&
realloc_buffer(bbp, total * sfmt->bytes_per_frame) == 0 &&
realloc_buffer(bp, total * sfmt->bytes_per_frame) == 0)
{
memcpy(bbp->data + bbp->count * sfmt->channels_per_frame,
bp->data, bp->count * sfmt->bytes_per_frame);
memcpy(bp->data, bbp->data, total * sfmt->bytes_per_frame);
bp->count = total;
bp->data,
bp->count * sfmt->bytes_per_frame);
memcpy(bp->data,
bbp->data + bp->count * sfmt->channels_per_frame,
bbp->count * sfmt->bytes_per_frame);
bp->count = bbp->count;
}
}
if (bp->count >= 2 * LPC_ORDER)

View File

@ -223,7 +223,7 @@ void m4af_write32_at(m4af_ctx_t *ctx, int64_t pos, uint32_t value)
}
m4af_ctx_t *m4af_create(uint32_t codec, uint32_t timescale,
m4af_io_callbacks_t *io, void *io_cookie)
m4af_io_callbacks_t *io, void *io_cookie, int no_timestamp)
{
m4af_ctx_t *ctx;
int64_t timestamp;
@ -237,7 +237,7 @@ m4af_ctx_t *m4af_create(uint32_t codec, uint32_t timescale,
memcpy(&ctx->io, io, sizeof(m4af_io_callbacks_t));
ctx->io_cookie = io_cookie;
ctx->timescale = timescale;
timestamp = m4af_timestamp();
timestamp = no_timestamp ? 0 : m4af_timestamp();
ctx->creation_time = timestamp;
ctx->modification_time = timestamp;
ctx->num_tracks = 1;
@ -1103,8 +1103,10 @@ void m4af_write_tkhd_box(m4af_ctx_t *ctx, uint32_t track_idx)
{
m4af_track_t *track = &ctx->track[track_idx];
int64_t pos = m4af_tell(ctx);
int64_t duration =
(double)track->duration / track->timescale * ctx->timescale + .5;
int64_t duration = track->duration;
if (ctx->priming_mode & M4AF_PRIMING_MODE_EDTS)
duration -= (track->encoder_delay + track->padding);
duration = (double)duration / track->timescale * ctx->timescale + .5;
uint8_t version = (track->creation_time > UINT32_MAX ||
track->modification_time > UINT32_MAX ||
duration > UINT32_MAX);
@ -1169,6 +1171,8 @@ int64_t m4af_movie_duration(m4af_ctx_t *ctx)
unsigned i;
for (i = 0; i < ctx->num_tracks; ++i) {
double x = ctx->track[i].duration;
if (ctx->priming_mode & M4AF_PRIMING_MODE_EDTS)
x -= (ctx->track[i].encoder_delay + ctx->track[i].padding);
int64_t duration = x / ctx->track[i].timescale * ctx->timescale + .5;
if (duration > movie_duration)
movie_duration = duration;

View File

@ -75,7 +75,7 @@ typedef struct m4af_ctx_t m4af_ctx_t;
m4af_ctx_t *m4af_create(uint32_t codec, uint32_t timescale,
m4af_io_callbacks_t *io, void *io_cookie);
m4af_io_callbacks_t *io, void *io_cookie, int no_timestamp);
int m4af_begin_write(m4af_ctx_t *ctx);

View File

@ -159,6 +159,7 @@ PROGNAME " %s\n"
" -I, --ignorelength Ignore length of WAV header\n"
" -S, --silent Don't print progress messages\n"
" --moov-before-mdat Place moov box before mdat box on m4a output\n"
" --no-timestamp Don't inject timestamp in the file\n"
"\n"
"Options for raw (headerless) input:\n"
" -R, --raw Treat input as raw (by default WAV is\n"
@ -221,6 +222,8 @@ typedef struct aacenc_param_ex_t {
unsigned raw_rate;
const char *raw_format;
int no_timestamp;
aacenc_tag_store_t tags;
aacenc_tag_store_t source_tags;
aacenc_translate_generic_text_tag_ctx_t source_tag_ctx;
@ -244,7 +247,7 @@ int parse_options(int argc, char **argv, aacenc_param_ex_t *params)
#define OPT_LONG_TAG M4AF_FOURCC('l','t','a','g')
#define OPT_TAG_FROM_JSON M4AF_FOURCC('t','f','j','s')
static struct option long_options[] = {
static const struct option long_options[] = {
{ "help", no_argument, 0, 'h' },
{ "profile", required_argument, 0, 'p' },
{ "bitrate", required_argument, 0, 'b' },
@ -284,6 +287,8 @@ int parse_options(int argc, char **argv, aacenc_param_ex_t *params)
{ "tag-from-file", required_argument, 0, OPT_SHORT_TAG_FILE },
{ "long-tag", required_argument, 0, OPT_LONG_TAG },
{ "tag-from-json", required_argument, 0, OPT_TAG_FROM_JSON },
{ "no-timestamp", no_argument, 0, '#' },
{ 0, 0, 0, 0 },
};
params->afterburner = 1;
@ -456,6 +461,9 @@ int parse_options(int argc, char **argv, aacenc_param_ex_t *params)
case OPT_TAG_FROM_JSON:
params->json_filename = optarg;
break;
case '#':
params->no_timestamp = 1;
break;
default:
return usage(), -1;
}
@ -513,7 +521,7 @@ int encode(aacenc_param_ex_t *params, pcm_reader_t *reader,
HANDLE_AACENCODER encoder, uint32_t frame_length,
m4af_ctx_t *m4af)
{
int16_t *ibuf = 0, *ip;
INT_PCM *ibuf = 0, *ip;
aacenc_frame_t obuf[2] = {{ 0 }}, *obp;
unsigned flip = 0;
int nread = 1;
@ -833,7 +841,7 @@ int main(int argc, char **argv)
unsigned framelen = aacinfo.frameLength;
scale = sample_format->sample_rate >> scale_shift;
if ((m4af = m4af_create(M4AF_CODEC_MP4A, scale, &m4af_io,
params.output_fp)) < 0)
params.output_fp, params.no_timestamp)) < 0)
goto END;
m4af_set_num_channels(m4af, 0, sample_format->channels_per_frame);
m4af_set_fixed_frame_duration(m4af, 0, framelen >> scale_shift);

View File

@ -10,6 +10,8 @@
#if HAVE_STDINT_H
# include <stdint.h>
#endif
#include <assert.h>
#include <fdk-aac/aacenc_lib.h>
#include "pcm_reader.h"
typedef struct pcm_sint16_converter_t {
@ -57,12 +59,18 @@ static int read_frames(pcm_reader_t *reader, void *buffer, unsigned nframes)
count = nframes * sfmt->channels_per_frame;
if (PCM_IS_FLOAT(sfmt)) {
float *ip = self->pivot;
int16_t *op = buffer;
INT_PCM *op = buffer;
#if SAMPLE_BITS == 16
for (i = 0; i < count; ++i)
op[i] = pcm_clip(ip[i] * 32768.0, -32768.0, 32767.0);
op[i] = (int16_t)pcm_clip(ip[i] * 32768.0, -32768.0, 32767.0);
#else
for (i = 0; i < count; ++i)
op[i] = (int32_t)pcm_clip(ip[i] * 2147483648.0, -2147483648.0, 2147483647.0);
#endif
} else {
int32_t *ip = self->pivot;
int16_t *op = buffer;
INT_PCM *op = buffer;
#if SAMPLE_BITS == 16
if (sfmt->bits_per_channel <= 16) {
for (i = 0; i < count; ++i)
op[i] = ip[i] >> 16;
@ -72,6 +80,10 @@ static int read_frames(pcm_reader_t *reader, void *buffer, unsigned nframes)
op[i] = (n == 0x8000) ? 0x7fff : n;
}
}
#else
for (i = 0; i < count; ++i)
op[i] = ip[i];
#endif
}
return nframes;
}
@ -94,14 +106,16 @@ pcm_reader_t *pcm_open_sint16_converter(pcm_reader_t *reader)
pcm_sint16_converter_t *self = 0;
pcm_sample_description_t *fmt;
assert((SAMPLE_BITS>>3) == sizeof(INT_PCM));
if ((self = calloc(1, sizeof(pcm_sint16_converter_t))) == 0)
return 0;
self->src = reader;
self->vtbl = &my_vtable;
memcpy(&self->format, pcm_get_format(reader), sizeof(self->format));
fmt = &self->format;
fmt->bits_per_channel = 16;
fmt->bits_per_channel = SAMPLE_BITS;
fmt->sample_type = PCM_TYPE_SINT;
fmt->bytes_per_frame = 2 * fmt->channels_per_frame;
fmt->bytes_per_frame = sizeof(INT_PCM) * fmt->channels_per_frame;
return (pcm_reader_t *)self;
}

View File

@ -113,8 +113,10 @@ int wav_fmt(wav_reader_t *reader, uint32_t size)
wValidBitsPerSample = wBitsPerSample;
ENSURE(wFormatTag == 1 || wFormatTag == 3 || wFormatTag == 0xfffe);
ENSURE(nChannels && nSamplesPerSec && nAvgBytesPerSec &&
nBlockAlign && wBitsPerSample && !(wBitsPerSample & 7) &&
ENSURE(nChannels > 0 && nChannels <= 8 &&
nSamplesPerSec && nAvgBytesPerSec &&
nBlockAlign && nBlockAlign < 256 &&
wBitsPerSample && wBitsPerSample < 256 && !(wBitsPerSample & 7) &&
nBlockAlign == nChannels * wBitsPerSample / 8);
if (wFormatTag == 3)
@ -155,6 +157,7 @@ static
int wav_parse(wav_reader_t *reader, int64_t *data_length)
{
uint32_t container, fcc, chunk_size;
int fmt_seen = 0;
*data_length = 0;
container = riff_next_chunk(reader, &chunk_size);
@ -167,6 +170,7 @@ int wav_parse(wav_reader_t *reader, int64_t *data_length)
riff_ds64(reader, data_length);
while ((fcc = riff_next_chunk(reader, &chunk_size)) != 0) {
if (fcc == RIFF_FOURCC('f','m','t',' ')) {
fmt_seen = 1;
if (wav_fmt(reader, chunk_size) < 0)
goto FAIL;
} else if (fcc == RIFF_FOURCC('d','a','t','a')) {
@ -178,8 +182,8 @@ int wav_parse(wav_reader_t *reader, int64_t *data_length)
TRY_IO(pcm_skip(&reader->io, (chunk_size + 1) & ~1));
}
}
if (fcc == RIFF_FOURCC('d','a','t','a'))
return 0;
ENSURE(fmt_seen && fcc == RIFF_FOURCC('d', 'a', 't', 'a'));
return 0;
FAIL:
return -1;
}

View File

@ -1,4 +1,4 @@
#ifndef VERSION_H
#define VERSION_H
const char *fdkaac_version = "1.0.0";
const char *fdkaac_version = "1.0.4";
#endif