ref: 27191ef56ec52ba2688d941198aca82588904274
parent: 281db6ceec174d040229ca88d20499d006541c78
author: menno <menno>
date: Mon Sep 22 16:05:32 EDT 2003
Added option to extract the decoded AAC file to and MPEG-4 AAC ADTS file
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: main.c,v 1.46 2003/09/22 18:22:19 menno Exp $
+** $Id: main.c,v 1.47 2003/09/22 20:05:31 menno Exp $
**/
#ifdef _WIN32
@@ -111,9 +111,10 @@
b->bytes_into_buffer -= bytes;
}
+static int adts_sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0};
+
int adts_parse(aac_buffer *b, int *bitrate, float *length)
{
- static int sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};
int frames, frame_length;
int t_framelength = 0;
int samplerate;
@@ -131,7 +132,7 @@
break;
if (frames == 0)
- samplerate = sample_rates[(b->buffer[2]&0x3c)>>2];
+ samplerate = adts_sample_rates[(b->buffer[2]&0x3c)>>2];
frame_length = ((((unsigned int)b->buffer[3] & 0x3)) << 11)
| (((unsigned int)b->buffer[4]) << 3) | (b->buffer[5] >> 5);
@@ -246,7 +247,86 @@
printf("\n");
}
+int FindAdtsSRIndex(int sr)
+{
+ int i;
+ for (i = 0; i < 16; i++)
+ {
+ if (sr == adts_sample_rates[i])
+ return i;
+ }
+ return 16 - 1;
+}
+
+unsigned char *MakeAdtsHeader(int *dataSize, faacDecFrameInfo *hInfo)
+{
+ unsigned char *data;
+ int profile = (hInfo->object_type - 1) & 0x3;
+ int sr_index = ((hInfo->sbr == SBR_UPSAMPLED) || (hInfo->sbr == NO_SBR_UPSAMPLED)) ?
+ FindAdtsSRIndex(hInfo->samplerate / 2) : FindAdtsSRIndex(hInfo->samplerate);
+ int framesize = 7 + hInfo->bytesconsumed;
+
+ if (hInfo->header_type == ADTS)
+ framesize -= 7;
+
+ *dataSize = 7;
+
+ data = malloc(*dataSize * sizeof(unsigned char));
+ memset(data, 0, *dataSize * sizeof(unsigned char));
+
+ data[0] += 0xFF; /* 8b: syncword */
+
+ data[1] += 0xF0; /* 4b: syncword */
+ /* 1b: mpeg id = 0 */
+ /* 2b: layer = 0 */
+ data[1] += 1; /* 1b: protection absent */
+
+ data[2] += ((profile << 6) & 0xC0); /* 2b: profile */
+ data[2] += ((sr_index << 2) & 0x3C); /* 4b: sampling_frequency_index */
+ /* 1b: private = 0 */
+ data[2] += ((hInfo->channels >> 2) & 0x1); /* 1b: channel_configuration */
+
+ data[3] += ((hInfo->channels << 6) & 0xC0); /* 2b: channel_configuration */
+ /* 1b: original */
+ /* 1b: home */
+ /* 1b: copyright_id */
+ /* 1b: copyright_id_start */
+ data[3] += ((framesize >> 11) & 0x3); /* 2b: aac_frame_length */
+
+ data[4] += ((framesize >> 3) & 0xFF); /* 8b: aac_frame_length */
+
+ data[5] += ((framesize << 5) & 0xE0); /* 3b: aac_frame_length */
+ data[5] += ((0x7FF >> 6) & 0x1F); /* 5b: adts_buffer_fullness */
+
+ data[6] += ((0x7FF << 2) & 0x3F); /* 6b: adts_buffer_fullness */
+ /* 2b: num_raw_data_blocks */
+
+ return data;
+
+#if 0
+ // build adts header
+ adts.PutBits(0xFFF, 12); // syncword
+ adts.PutBits(isMpeg2, 1); // id
+ adts.PutBits(0, 2); // layer
+ adts.PutBits(1, 1); // protection_absent
+ adts.PutBits(profile, 2); // profile
+ adts.PutBits(
+ MP4AV_AdtsFindSamplingRateIndex(samplingFrequency),
+ 4); // sampling_frequency_index
+ adts.PutBits(0, 1); // private
+ adts.PutBits(channels, 3); // channel_configuration
+ adts.PutBits(0, 1); // original
+ adts.PutBits(0, 1); // home
+
+ adts.PutBits(0, 1); // copyright_id
+ adts.PutBits(0, 1); // copyright_id_start
+ adts.PutBits(*pAdtsDataLength, 13); // aac_frame_length
+ adts.PutBits(0x7FF, 11); // adts_buffer_fullness
+ adts.PutBits(0, 2); // num_raw_data_blocks
+#endif
+}
+
/* globals */
char *progName;
@@ -268,6 +348,7 @@
fprintf(stdout, "Options:\n");
fprintf(stdout, " -h Shows this help screen.\n");
fprintf(stdout, " -i Shows info about the input file.\n");
+ fprintf(stdout, " -a X Write MPEG-4 AAC ADTS output file.\n");
fprintf(stdout, " -o X Set output filename.\n");
fprintf(stdout, " -f X Set output format. Valid values for X are:\n");
fprintf(stdout, " 1: Microsoft WAV format (default).\n");
@@ -299,9 +380,9 @@
return;
}
-int decodeAACfile(char *aacfile, char *sndfile, int to_stdout,
+int decodeAACfile(char *aacfile, char *sndfile, char *adts_fn, int to_stdout,
int def_srate, int object_type, int outputFormat, int fileType,
- int downMatrix, int infoOnly)
+ int downMatrix, int infoOnly, int adts_out)
{
int tagsize;
unsigned long samplerate;
@@ -310,6 +391,10 @@
audio_file *aufile;
+ FILE *adtsFile;
+ unsigned char *adtsData;
+ int adtsDataSize;
+
faacDecHandle hDecoder;
faacDecFrameInfo frameInfo;
faacDecConfigurationPtr config;
@@ -327,6 +412,16 @@
memset(&b, 0, sizeof(aac_buffer));
+ if (adts_out)
+ {
+ adtsFile = fopen(adts_fn, "wb");
+ if (adtsFile == NULL)
+ {
+ fprintf(stderr, "Error opening file: %s\n", adts_fn);
+ return 1;
+ }
+ }
+
b.infile = fopen(aacfile, "rb");
if (b.infile == NULL)
{
@@ -459,6 +554,20 @@
sample_buffer = faacDecDecode(hDecoder, &frameInfo,
b.buffer, b.bytes_into_buffer);
+ if (adts_out == 1)
+ {
+ adtsData = MakeAdtsHeader(&adtsDataSize, &frameInfo);
+
+ /* write the adts header */
+ fwrite(adtsData, 1, adtsDataSize, adtsFile);
+
+ /* write the frame data */
+ if (frameInfo.header_type == ADTS)
+ fwrite(b.buffer + 7, 1, frameInfo.bytesconsumed - 7, adtsFile);
+ else
+ fwrite(b.buffer, 1, frameInfo.bytesconsumed, adtsFile);
+ }
+
/* update buffer indices */
advance_buffer(&b, frameInfo.bytesconsumed);
@@ -474,23 +583,28 @@
/* print some channel info */
print_channel_info(&frameInfo);
- /* open output file */
- if (!to_stdout)
+ if (!adts_out)
{
- aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
- outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
+ /* open output file */
+ if (!to_stdout)
+ {
+ aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
+ outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
+ } else {
+ aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
+ outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
+ }
+ if (aufile == NULL)
+ {
+ if (b.buffer)
+ free(b.buffer);
+ faacDecClose(hDecoder);
+ fclose(b.infile);
+ return 0;
+ }
} else {
- aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
- outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
+ fprintf(stderr, "Writing output MPEG-4 AAC ADTS file.\n\n");
}
- if (aufile == NULL)
- {
- if (b.buffer)
- free(b.buffer);
- faacDecClose(hDecoder);
- fclose(b.infile);
- return 0;
- }
first_time = 0;
}
@@ -505,7 +619,7 @@
#endif
}
- if ((frameInfo.error == 0) && (frameInfo.samples > 0))
+ if ((frameInfo.error == 0) && (frameInfo.samples > 0) && (!adts_out))
{
write_audio_file(aufile, sample_buffer, frameInfo.samples, 0);
}
@@ -521,9 +635,14 @@
faacDecClose(hDecoder);
+ if (adts_out == 1)
+ {
+ fclose(adtsFile);
+ }
+
fclose(b.infile);
- if (!first_time)
+ if (!first_time && !adts_out)
close_audio_file(aufile);
if (b.buffer)
@@ -573,8 +692,9 @@
12000, 11025, 8000
};
-int decodeMP4file(char *mp4file, char *sndfile, int to_stdout,
- int outputFormat, int fileType, int downMatrix, int noGapless, int infoOnly)
+int decodeMP4file(char *mp4file, char *sndfile, char *adts_fn, int to_stdout,
+ int outputFormat, int fileType, int downMatrix, int noGapless,
+ int infoOnly, int adts_out)
{
int track;
unsigned long samplerate;
@@ -586,6 +706,10 @@
audio_file *aufile;
+ FILE *adtsFile;
+ unsigned char *adtsData;
+ int adtsDataSize;
+
faacDecHandle hDecoder;
faacDecConfigurationPtr config;
faacDecFrameInfo frameInfo;
@@ -612,6 +736,16 @@
config->downMatrix = downMatrix;
faacDecSetConfiguration(hDecoder, config);
+ if (adts_out)
+ {
+ adtsFile = fopen(adts_fn, "wb");
+ if (adtsFile == NULL)
+ {
+ fprintf(stderr, "Error opening file: %s\n", adts_fn);
+ return 1;
+ }
+ }
+
infile = MP4Read(mp4file, 0);
if (!infile)
{
@@ -702,6 +836,16 @@
sample_buffer = faacDecDecode(hDecoder, &frameInfo, buffer, buffer_size);
+ if (adts_out == 1)
+ {
+ adtsData = MakeAdtsHeader(&adtsDataSize, &frameInfo);
+
+ /* write the adts header */
+ fwrite(adtsData, 1, adtsDataSize, adtsFile);
+
+ fwrite(buffer, 1, frameInfo.bytesconsumed, adtsFile);
+ }
+
if (buffer) free(buffer);
if (!noGapless)
@@ -732,24 +876,27 @@
/* print some channel info */
print_channel_info(&frameInfo);
- /* open output file */
- if(!to_stdout)
+ if (!adts_out)
{
- aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
- outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
- } else {
+ /* open output file */
+ if(!to_stdout)
+ {
+ aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
+ outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
+ } else {
#ifdef _WIN32
- setmode(fileno(stdout), O_BINARY);
+ setmode(fileno(stdout), O_BINARY);
#endif
- aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
- outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
+ aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
+ outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
+ }
+ if (aufile == NULL)
+ {
+ faacDecClose(hDecoder);
+ MP4Close(infile);
+ return 0;
+ }
}
- if (aufile == NULL)
- {
- faacDecClose(hDecoder);
- MP4Close(infile);
- return 0;
- }
first_time = 0;
}
@@ -766,7 +913,7 @@
#endif
}
- if ((frameInfo.error == 0) && (sample_count > 0))
+ if ((frameInfo.error == 0) && (sample_count > 0) && (!adts_out))
{
write_audio_file(aufile, sample_buffer, sample_count, delay);
}
@@ -781,9 +928,14 @@
faacDecClose(hDecoder);
+ if (adts_out == 1)
+ {
+ fclose(adtsFile);
+ }
+
MP4Close(infile);
- if (!first_time)
+ if (!first_time && !adts_out)
close_audio_file(aufile);
return frameInfo.error;
@@ -800,6 +952,7 @@
int format = 1;
int outputFormat = FAAD_FMT_16BIT;
int outfile_set = 0;
+ int adts_out = 0;
int showHelp = 0;
int mp4file = 0;
int noGapless = 0;
@@ -806,6 +959,7 @@
char *fnp;
char aacFileName[255];
char audioFileName[255];
+ char adtsFileName[255];
MP4FileHandle infile;
/* System dependant types */
@@ -836,6 +990,7 @@
int option_index = 0;
static struct option long_options[] = {
{ "outfile", 0, 0, 'o' },
+ { "adtsout", 0, 0, 'a' },
{ "format", 0, 0, 'f' },
{ "bits", 0, 0, 'b' },
{ "samplerate", 0, 0, 's' },
@@ -847,7 +1002,7 @@
{ "help", 0, 0, 'h' }
};
- c = getopt_long(argc, argv, "o:s:f:b:l:wgdhi",
+ c = getopt_long(argc, argv, "o:a:s:f:b:l:wgdhi",
long_options, &option_index);
if (c == -1)
@@ -855,13 +1010,22 @@
switch (c) {
case 'o':
- if (optarg) {
+ if (optarg)
+ {
outfile_set = 1;
strcpy(audioFileName, optarg);
}
break;
+ case 'a':
+ if (optarg)
+ {
+ adts_out = 1;
+ strcpy(adtsFileName, optarg);
+ }
+ break;
case 's':
- if (optarg) {
+ if (optarg)
+ {
char dr[10];
if (sscanf(optarg, "%s", dr) < 1) {
def_srate = 0;
@@ -871,9 +1035,11 @@
}
break;
case 'f':
- if (optarg) {
+ if (optarg)
+ {
char dr[10];
- if (sscanf(optarg, "%s", dr) < 1) {
+ if (sscanf(optarg, "%s", dr) < 1)
+ {
format = 1;
} else {
format = atoi(dr);
@@ -883,9 +1049,11 @@
}
break;
case 'b':
- if (optarg) {
+ if (optarg)
+ {
char dr[10];
- if (sscanf(optarg, "%s", dr) < 1) {
+ if (sscanf(optarg, "%s", dr) < 1)
+ {
outputFormat = FAAD_FMT_16BIT; /* just use default */
} else {
outputFormat = atoi(dr);
@@ -895,9 +1063,11 @@
}
break;
case 'l':
- if (optarg) {
+ if (optarg)
+ {
char dr[10];
- if (sscanf(optarg, "%s", dr) < 1) {
+ if (sscanf(optarg, "%s", dr) < 1)
+ {
object_type = LC; /* default */
} else {
object_type = atoi(dr);
@@ -971,11 +1141,11 @@
if (mp4file)
{
- result = decodeMP4file(aacFileName, audioFileName, writeToStdio,
- outputFormat, format, downMatrix, noGapless, infoOnly);
+ result = decodeMP4file(aacFileName, audioFileName, adtsFileName, writeToStdio,
+ outputFormat, format, downMatrix, noGapless, infoOnly, adts_out);
} else {
- result = decodeAACfile(aacFileName, audioFileName, writeToStdio,
- def_srate, object_type, outputFormat, format, downMatrix, infoOnly);
+ result = decodeAACfile(aacFileName, audioFileName, adtsFileName, writeToStdio,
+ def_srate, object_type, outputFormat, format, downMatrix, infoOnly, adts_out);
}
--- a/include/faad.h
+++ b/include/faad.h
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: faad.h,v 1.30 2003/09/22 18:22:19 menno Exp $
+** $Id: faad.h,v 1.31 2003/09/22 20:05:31 menno Exp $
**/
#ifndef __AACDEC_H__
@@ -155,6 +155,9 @@
/* MPEG-4 ObjectType */
unsigned char object_type;
+
+ /* AAC header type; MP4 will be signalled as RAW also */
+ unsigned char header_type;
/* multichannel configuration */
unsigned char num_front_channels;
--- a/libfaad/decoder.c
+++ b/libfaad/decoder.c
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: decoder.c,v 1.68 2003/09/22 18:22:19 menno Exp $
+** $Id: decoder.c,v 1.69 2003/09/22 20:05:32 menno Exp $
**/
#include "common.h"
@@ -914,6 +914,12 @@
hInfo->object_type = hDecoder->object_type;
/* sbr */
hInfo->sbr = NO_SBR;
+ /* header type */
+ hInfo->header_type = RAW;
+ if (hDecoder->adif_header_present)
+ hInfo->header_type = ADIF;
+ if (hDecoder->adts_header_present)
+ hInfo->header_type = ADTS;
/* check if frame has channel elements */
if (channels == 0)
--- a/libfaad/structs.h
+++ b/libfaad/structs.h
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: structs.h,v 1.14 2003/09/22 18:22:19 menno Exp $
+** $Id: structs.h,v 1.15 2003/09/22 20:05:32 menno Exp $
**/
#ifndef __STRUCTS_H__
@@ -342,6 +342,9 @@
/* MPEG-4 ObjectType */
uint8_t object_type;
+
+ /* AAC header type; MP4 will be signalled as RAW also */
+ uint8_t header_type;
/* multichannel configuration */
uint8_t num_front_channels;
--- a/libfaad/syntax.h
+++ b/libfaad/syntax.h
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: syntax.h,v 1.34 2003/09/22 18:22:19 menno Exp $
+** $Id: syntax.h,v 1.35 2003/09/22 20:05:32 menno Exp $
**/
#ifndef __SYNTAX_H__
@@ -44,6 +44,11 @@
#define ER_LC 17
#define ER_LTP 19
#define DRM_ER_LC 27 /* special object type for DRM */
+
+/* header types */
+#define RAW 0
+#define ADIF 1
+#define ADTS 2
/* SBR signalling */
#define NO_SBR 0