diff options
author | Rodeo <[email protected]> | 2012-09-03 12:37:16 +0000 |
---|---|---|
committer | Rodeo <[email protected]> | 2012-09-03 12:37:16 +0000 |
commit | 8d9969febdcec59fee453888ed0bb6a64adf7679 (patch) | |
tree | dbe81e961c2ed4c0f3e38d44c5afa86cc475693a /contrib/faac | |
parent | 56bf9b80b9b55ecaec9855addda41898261d26b1 (diff) |
Audio improvements.
New supported samplerates: 8, 11.025, 12, 16 kHz.
Now 8, 11.025, 12, 16, 22.05, 24, 42, 44.1, 48 Khz are supported.
Unsupported samplerates are sanitized to the closest samplerate for all encoders.
Samplerates < 32 kHz are now forbidden for AC3 encoding (sanitized to 32 kHz). Most AC3 decoders don't support such samplerates.
New upmixing: 3.0 (Front Left, Right & Center) can now be upmixed to 5.1 to preserve the center channel.
New mixdowns:
6.1 (Front Left, Right & Center, Surround Left, Right & Center, LFE)
7.1 (Front Left, Right & Center, Surround Left & Right, Rear Left & Right, LFE)
-> available to Vorbis & FLAC encoders for compatible input channel layouts
7.1 (Front Left, Right & Center, Front Left & Right of Center, Surround Left & Right, LFE)
-> available to AAC encoders (ca_aac, ca_haac, faac) for compatible input channel layouts
Mono (Left Only): Stereo to Mono by discarding the Right channel
Mono (Right Only): Stereo to Mono by discarding the Left channel
-> available to all encoders for non-Dolby Stereo input
The "6-channel discrete" mixdown becomes "5.1 Channels".
New bitrates: 960 - 1536 Kbps.
This lets users work around poor audio quality in crappy encoders by throwing more bits at them.
Bitrate limits have been re-worked and re-tested for all encoders.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4930 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'contrib/faac')
-rw-r--r-- | contrib/faac/A00-bitrates.patch | 6 | ||||
-rw-r--r-- | contrib/faac/A01-multichannel-improvements.patch | 752 | ||||
-rw-r--r-- | contrib/faac/P00-cygwin.patch | 6 |
3 files changed, 758 insertions, 6 deletions
diff --git a/contrib/faac/A00-bitrates.patch b/contrib/faac/A00-bitrates.patch index 50b11ec78..49460768e 100644 --- a/contrib/faac/A00-bitrates.patch +++ b/contrib/faac/A00-bitrates.patch @@ -1,6 +1,6 @@ -diff -Naur faac-1.28/libfaac/frame.c ../build.debug/contrib/faac/faac-1.28/libfaac/frame.c ---- faac-1.28.orig/libfaac/frame.c 2004-11-17 06:26:06.000000000 -0800 -+++ faac-1.28/libfaac/frame.c 2010-04-10 12:26:28.200614437 -0700 +diff -Naur faac-1.28.old/libfaac/frame.c faac-1.28.new/libfaac/frame.c +--- faac-1.28.old/libfaac/frame.c 2004-11-17 06:26:06.000000000 -0800 ++++ faac-1.28.new/libfaac/frame.c 2010-04-10 12:26:28.200614437 -0700 @@ -196,6 +196,8 @@ {47000, 10000}, {64000, 16000}, diff --git a/contrib/faac/A01-multichannel-improvements.patch b/contrib/faac/A01-multichannel-improvements.patch new file mode 100644 index 000000000..d0ec5ce3c --- /dev/null +++ b/contrib/faac/A01-multichannel-improvements.patch @@ -0,0 +1,752 @@ +diff -Naur faac-1.28.old/frontend/main.c faac-1.28.new/frontend/main.c +--- faac-1.28.old/frontend/main.c 2009-01-24 02:10:20.000000000 +0100 ++++ faac-1.28.new/frontend/main.c 2012-08-06 21:15:34.000000000 +0200 +@@ -858,7 +858,7 @@ + break; + } + if (infile->channels >= 6) +- myFormat->useLfe = 1; ++ myFormat->numLFEChannels = 1; + myFormat->allowMidside = useMidSide; + if (bitRate) + myFormat->bitRate = bitRate / infile->channels; +diff -Naur faac-1.28.old/include/faaccfg.h faac-1.28.new/include/faaccfg.h +--- faac-1.28.old/include/faaccfg.h 2004-07-04 14:12:05.000000000 +0200 ++++ faac-1.28.new/include/faaccfg.h 2012-08-06 21:15:34.000000000 +0200 +@@ -66,8 +66,14 @@ + /* Allow mid/side coding */ + unsigned int allowMidside; + +- /* Use one of the channels as LFE channel */ +- unsigned int useLfe; ++ /* Channel configuration */ ++ unsigned int channelConfiguration; ++ ++ /* Number of front, side, back & LFE channels */ ++ unsigned int numFrontChannels; ++ unsigned int numSideChannels; ++ unsigned int numBackChannels; ++ unsigned int numLFEChannels; + + /* Use Temporal Noise Shaping */ + unsigned int useTns; +diff -Naur faac-1.28.old/libfaac/bitstream.c faac-1.28.new/libfaac/bitstream.c +--- faac-1.28.old/libfaac/bitstream.c 2007-06-05 20:59:47.000000000 +0200 ++++ faac-1.28.new/libfaac/bitstream.c 2012-08-06 21:15:34.000000000 +0200 +@@ -1032,6 +1032,219 @@ + return j; + } + ++/* write a program_config_element() */ ++int WritePCE(faacEncHandle hEncoder, ++ BitStream *bitStream, ++ int byte_alignment, ++ int instance_tag, ++ int writeFlag) ++{ ++ int i; ++ int bits = 0; ++ ++ /* we can have up to 29 full-bandwidth channels of each type: ++ * 4 bits -> 0 - 15 elements, 14 CPEs (28 channels) and 1 SCE (1 channel) ++ * we can have up to 3 LFE channels: ++ * 2 bits -> 0 - 3 elements, 3 LFEs (1 channel) */ ++ if (hEncoder->config.numFrontChannels > 29) { ++ fprintf(stderr, "WritePCE: too many front channels (%u)\n", ++ hEncoder->config.numFrontChannels); ++ return 0; ++ } ++ if (hEncoder->config.numSideChannels > 29) { ++ fprintf(stderr, "WritePCE: too many side channels (%u)\n", ++ hEncoder->config.numSideChannels); ++ return 0; ++ } ++ if (hEncoder->config.numBackChannels > 29) { ++ fprintf(stderr, "WritePCE: too many back channels (%u)\n", ++ hEncoder->config.numBackChannels); ++ return 0; ++ } ++ if (hEncoder->config.numLFEChannels > 3) { ++ fprintf(stderr, "WritePCE: too many LFE channels (%u)\n", ++ hEncoder->config.numLFEChannels); ++ return 0; ++ } ++ /* program_config_element() shall be used only for the audio object types: ++ * AAC main, AAC SSR, AAC LC and AAC LTP */ ++ if (hEncoder->config.aacObjectType > 4) { ++ fprintf(stderr, "WritePCE: unsupported AudioObjectType %u", ++ hEncoder->config.aacObjectType); ++ return 0; ++ } ++ ++ /* Determine the channel configuration (see GetChannelInfo) */ ++ int sceTag = 0; ++ int cpeTag = 0; ++ int lfeTag = 0; ++ int num_front_channel_elements = 0; ++ int front_element_is_cpe[15] = { 0 }; ++ int front_element_tag_select[15] = { 0 }; ++ int num_side_channel_elements = 0; ++ int side_element_is_cpe[15] = { 0 }; ++ int side_element_tag_select[15] = { 0 }; ++ int num_back_channel_elements = 0; ++ int back_element_is_cpe[15] = { 0 }; ++ int back_element_tag_select[15] = { 0 }; ++ int num_lfe_channel_elements = 0; ++ int lfe_element_tag_select[3] = { 0 }; ++ // Front channels ++ i = hEncoder->config.numFrontChannels; ++ if (i % 2) { ++ front_element_is_cpe[num_front_channel_elements] = 0; ++ front_element_tag_select[num_front_channel_elements] = sceTag; ++ num_front_channel_elements++; ++ sceTag++; ++ i--; ++ } ++ while (i) { ++ front_element_is_cpe[num_front_channel_elements] = 1; ++ front_element_tag_select[num_front_channel_elements] = cpeTag; ++ num_front_channel_elements++; ++ cpeTag++; ++ i -= 2; ++ } ++ // Side channels ++ i = hEncoder->config.numSideChannels; ++ while (i > 1) { ++ side_element_is_cpe[num_side_channel_elements] = 1; ++ side_element_tag_select[num_side_channel_elements] = cpeTag; ++ num_side_channel_elements++; ++ cpeTag++; ++ i -= 2; ++ } ++ if (i) { ++ side_element_is_cpe[num_side_channel_elements] = 0; ++ side_element_tag_select[num_side_channel_elements] = sceTag; ++ num_side_channel_elements++; ++ sceTag++; ++ i--; ++ } ++ // Back channels ++ i = hEncoder->config.numBackChannels; ++ while (i > 1) { ++ back_element_is_cpe[num_back_channel_elements] = 1; ++ back_element_tag_select[num_back_channel_elements] = cpeTag; ++ num_back_channel_elements++; ++ cpeTag++; ++ i -= 2; ++ } ++ if (i) { ++ back_element_is_cpe[num_back_channel_elements] = 0; ++ back_element_tag_select[num_back_channel_elements] = sceTag; ++ num_back_channel_elements++; ++ sceTag++; ++ i--; ++ } ++ // LFE channels ++ i = hEncoder->config.numLFEChannels; ++ while (i) { ++ lfe_element_tag_select[num_lfe_channel_elements] = lfeTag; ++ num_lfe_channel_elements++; ++ lfeTag++; ++ i--; ++ } ++ ++ /* element_instance_tag */ ++ if (writeFlag) ++ PutBit(bitStream, instance_tag, 4); ++ bits =+ 4; ++ ++ /* object_type */ ++ if (writeFlag) ++ PutBit(bitStream, hEncoder->config.aacObjectType - 1, 2); ++ bits += 2; ++ ++ /* sampling_frequency_index */ ++ if (writeFlag) ++ PutBit(bitStream, hEncoder->sampleRateIdx, 4); ++ bits += 4; ++ ++ /* num_front_channel_elements */ ++ if (writeFlag) ++ PutBit(bitStream, num_front_channel_elements, 4); ++ bits += 4; ++ ++ /* num_side_channel_elements */ ++ if (writeFlag) ++ PutBit(bitStream, num_side_channel_elements, 4); ++ bits += 4; ++ ++ /* num_back_channel_elements */ ++ if (writeFlag) ++ PutBit(bitStream, num_back_channel_elements, 4); ++ bits += 4; ++ ++ /* num_lfe_channel_elements */ ++ if (writeFlag) ++ PutBit(bitStream, num_lfe_channel_elements, 2); ++ bits += 2; ++ ++ /* num_assoc_data_elements */ ++ if (writeFlag) ++ PutBit(bitStream, 0, 3); ++ bits += 3; ++ ++ /* num_valid_cc_elements */ ++ if (writeFlag) ++ PutBit(bitStream, 0, 4); ++ bits += 4; ++ ++ /* mono_mixdown_present */ ++ if (writeFlag) ++ PutBit(bitStream, 0, 1); ++ bits++; ++ ++ /* stereo_mixdown_present */ ++ if (writeFlag) ++ PutBit(bitStream, 0, 1); ++ bits++; ++ ++ /* matrix_mixdown_idx_present */ ++ if (writeFlag) ++ PutBit(bitStream, 0, 1); ++ bits++; ++ ++ /* describe the channel configuration */ ++ for (i = 0; i < num_front_channel_elements; i++) { ++ if (writeFlag) { ++ PutBit(bitStream, front_element_is_cpe[i], 1); ++ PutBit(bitStream, front_element_tag_select[i], 4); ++ } ++ bits += 5; ++ } ++ for (i = 0; i < num_side_channel_elements; i++) { ++ if (writeFlag) { ++ PutBit(bitStream, side_element_is_cpe[i], 1); ++ PutBit(bitStream, side_element_tag_select[i], 4); ++ } ++ bits += 5; ++ } ++ for (i = 0; i < num_back_channel_elements; i++) { ++ if (writeFlag) { ++ PutBit(bitStream, back_element_is_cpe[i], 1); ++ PutBit(bitStream, back_element_tag_select[i], 4); ++ } ++ bits += 5; ++ } ++ for (i = 0; i < num_lfe_channel_elements; i++) { ++ if (writeFlag) ++ PutBit(bitStream, lfe_element_tag_select[i], 4); ++ bits += 4; ++ } ++ ++ /* byte_alignment() */ ++ bits += ByteAlign(bitStream, writeFlag, bits + byte_alignment); ++ ++ /* comment_field_bytes */ ++ if (writeFlag) ++ PutBit(bitStream, 0, 8); ++ bits += 8; ++ ++ return bits; ++} ++ + #ifdef DRM + /* + **************************************************************************** +diff -Naur faac-1.28.old/libfaac/bitstream.h faac-1.28.new/libfaac/bitstream.h +--- faac-1.28.old/libfaac/bitstream.h 2004-07-04 14:10:52.000000000 +0200 ++++ faac-1.28.new/libfaac/bitstream.h 2012-08-06 21:15:34.000000000 +0200 +@@ -164,6 +164,13 @@ + unsigned long data, + int numBit); + ++/* write a program_config_element() */ ++int WritePCE(faacEncHandle hEncoder, ++ BitStream *bitStream, ++ int byte_alignment, ++ int instance_tag, ++ int writeFlag); ++ + #ifdef __cplusplus + } + #endif /* __cplusplus */ +diff -Naur faac-1.28.old/libfaac/channels.c faac-1.28.new/libfaac/channels.c +--- faac-1.28.old/libfaac/channels.c 2001-09-04 20:39:35.000000000 +0200 ++++ faac-1.28.new/libfaac/channels.c 2012-08-06 21:15:34.000000000 +0200 +@@ -28,83 +28,112 @@ + #include "coder.h" + #include "util.h" + +-/* If LFE present */ +-/* Num channels # of SCE's # of CPE's #of LFE's */ +-/* ============ ========== ========== ========= */ +-/* 1 1 0 0 */ +-/* 2 0 1 0 */ +-/* 3 1 1 0 */ +-/* 4 1 1 1 */ +-/* 5 1 2 0 */ +-/* For more than 5 channels, use the following elements: */ +-/* 2*N 1 2*(N-1) 1 */ +-/* 2*N+1 1 2*N 0 */ +-/* */ +-/* Else: */ +-/* */ +-/* Num channels # of SCE's # of CPE's #of LFE's */ +-/* ============ ========== ========== ========= */ +-/* 1 1 0 0 */ +-/* 2 0 1 0 */ +-/* 3 1 1 0 */ +-/* 4 2 1 0 */ +-/* 5 1 2 0 */ +-/* For more than 5 channels, use the following elements: */ +-/* 2*N 2 2*(N-1) 0 */ +-/* 2*N+1 1 2*N 0 */ +- +-void GetChannelInfo(ChannelInfo *channelInfo, int numChannels, int useLfe) +-{ +- int sceTag = 0; +- int lfeTag = 0; +- int cpeTag = 0; +- int numChannelsLeft = numChannels; ++static void addSCE(ChannelInfo *channelInfo, int numChannels, int numChannelsLeft, int tag); ++static void addCPE(ChannelInfo *channelInfo, int numChannels, int numChannelsLeft, int tag); ++static void addLFE(ChannelInfo *channelInfo, int numChannels, int numChannelsLeft, int tag); + + +- /* First element is sce, except for 2 channel case */ +- if (numChannelsLeft != 2) { +- channelInfo[numChannels-numChannelsLeft].present = 1; +- channelInfo[numChannels-numChannelsLeft].tag = sceTag++; +- channelInfo[numChannels-numChannelsLeft].cpe = 0; +- channelInfo[numChannels-numChannelsLeft].lfe = 0; ++void GetChannelInfo(ChannelInfo *channelInfo, int numFrontChannels, int numSideChannels, int numBackChannels, int numLFEChannels) ++{ ++ int i; ++ int sceTag = 0; ++ int cpeTag = 0; ++ int lfeTag = 0; ++ int numChannels = (numFrontChannels + ++ numSideChannels + ++ numBackChannels + ++ numLFEChannels); ++ int numChannelsLeft = numChannels; ++ ++ /* Front channels */ ++ i = numFrontChannels; ++ if (i % 2) { ++ // Front Center ++ addSCE(channelInfo, numChannels, numChannelsLeft, sceTag); + numChannelsLeft--; ++ sceTag++; ++ i--; ++ } ++ while (i) { ++ // Front Left/Right, Front Left/Right of Center, ??? ++ addCPE(channelInfo, numChannels, numChannelsLeft, cpeTag); ++ numChannelsLeft -= 2; ++ cpeTag++; ++ i -= 2; + } + +- /* Next elements are cpe's */ +- while (numChannelsLeft > 1) { +- /* Left channel info */ +- channelInfo[numChannels-numChannelsLeft].present = 1; +- channelInfo[numChannels-numChannelsLeft].tag = cpeTag++; +- channelInfo[numChannels-numChannelsLeft].cpe = 1; +- channelInfo[numChannels-numChannelsLeft].common_window = 0; +- channelInfo[numChannels-numChannelsLeft].ch_is_left = 1; +- channelInfo[numChannels-numChannelsLeft].paired_ch = numChannels-numChannelsLeft+1; +- channelInfo[numChannels-numChannelsLeft].lfe = 0; ++ /* Side channels */ ++ i = numSideChannels; ++ while (i > 1) { ++ // Surround Left/Right (if rear surrounds present), ??? ++ addCPE(channelInfo, numChannels, numChannelsLeft, cpeTag); ++ numChannelsLeft -= 2; ++ cpeTag++; ++ i -= 2; ++ } ++ if (i) { ++ // ??? ++ addSCE(channelInfo, numChannels, numChannelsLeft, sceTag); + numChannelsLeft--; ++ sceTag++; ++ i--; ++ } + +- /* Right channel info */ +- channelInfo[numChannels-numChannelsLeft].present = 1; +- channelInfo[numChannels-numChannelsLeft].cpe = 1; +- channelInfo[numChannels-numChannelsLeft].common_window = 0; +- channelInfo[numChannels-numChannelsLeft].ch_is_left = 0; +- channelInfo[numChannels-numChannelsLeft].paired_ch = numChannels-numChannelsLeft-1; +- channelInfo[numChannels-numChannelsLeft].lfe = 0; ++ /* Back channels */ ++ i = numBackChannels; ++ while (i > 1) { ++ // Surround Left/Right (if rear surrounds absent), Rear Surround Left/Right, ??? ++ addCPE(channelInfo, numChannels, numChannelsLeft, cpeTag); ++ numChannelsLeft -= 2; ++ cpeTag++; ++ i -= 2; ++ } ++ if (i) { ++ // Surround Center ++ addSCE(channelInfo, numChannels, numChannelsLeft, sceTag); + numChannelsLeft--; ++ sceTag++; ++ i--; + } + +- /* Is there another channel left ? */ +- if (numChannelsLeft) { +- if (useLfe) { +- channelInfo[numChannels-numChannelsLeft].present = 1; +- channelInfo[numChannels-numChannelsLeft].tag = lfeTag++; +- channelInfo[numChannels-numChannelsLeft].cpe = 0; +- channelInfo[numChannels-numChannelsLeft].lfe = 1; +- } else { +- channelInfo[numChannels-numChannelsLeft].present = 1; +- channelInfo[numChannels-numChannelsLeft].tag = sceTag++; +- channelInfo[numChannels-numChannelsLeft].cpe = 0; +- channelInfo[numChannels-numChannelsLeft].lfe = 0; +- } ++ /* LFE channel */ ++ i = numLFEChannels; ++ while (i) { ++ addLFE(channelInfo, numChannels, numChannelsLeft, lfeTag); + numChannelsLeft--; ++ lfeTag++; ++ i--; + } + } ++ ++static void addSCE(ChannelInfo *channelInfo, int numChannels, int numChannelsLeft, int tag) { ++ channelInfo[numChannels-numChannelsLeft].present = 1; ++ channelInfo[numChannels-numChannelsLeft].cpe = 0; ++ channelInfo[numChannels-numChannelsLeft].lfe = 0; ++ channelInfo[numChannels-numChannelsLeft].tag = tag; ++} ++ ++static void addCPE(ChannelInfo *channelInfo, int numChannels, int numChannelsLeft, int tag) { ++ /* Left channel info */ ++ channelInfo[numChannels-numChannelsLeft].present = 1; ++ channelInfo[numChannels-numChannelsLeft].cpe = 1; ++ channelInfo[numChannels-numChannelsLeft].lfe = 0; ++ channelInfo[numChannels-numChannelsLeft].tag = tag; ++ channelInfo[numChannels-numChannelsLeft].ch_is_left = 1; ++ channelInfo[numChannels-numChannelsLeft].common_window = 0; ++ channelInfo[numChannels-numChannelsLeft].paired_ch = numChannels-numChannelsLeft+1; ++ /* Right channel info */ ++ channelInfo[numChannels-numChannelsLeft+1].present = 1; ++ channelInfo[numChannels-numChannelsLeft+1].cpe = 1; ++ channelInfo[numChannels-numChannelsLeft+1].lfe = 0; ++ channelInfo[numChannels-numChannelsLeft+1].ch_is_left = 0; ++ channelInfo[numChannels-numChannelsLeft+1].common_window = 0; ++ channelInfo[numChannels-numChannelsLeft+1].paired_ch = numChannels-numChannelsLeft; ++} ++ ++static void addLFE(ChannelInfo *channelInfo, int numChannels, int numChannelsLeft, int tag) { ++ channelInfo[numChannels-numChannelsLeft].present = 1; ++ channelInfo[numChannels-numChannelsLeft].cpe = 0; ++ channelInfo[numChannels-numChannelsLeft].lfe = 1; ++ channelInfo[numChannels-numChannelsLeft].tag = tag; ++} +diff -Naur faac-1.28.old/libfaac/channels.h faac-1.28.new/libfaac/channels.h +--- faac-1.28.old/libfaac/channels.h 2003-06-26 21:19:41.000000000 +0200 ++++ faac-1.28.new/libfaac/channels.h 2012-08-06 21:15:34.000000000 +0200 +@@ -45,7 +45,7 @@ + MSInfo msInfo; + } ChannelInfo; + +-void GetChannelInfo(ChannelInfo *channelInfo, int numChannels, int useLfe); ++void GetChannelInfo(ChannelInfo *channelInfo, int numFrontChannels, int numSideChannels, int numBackChannels, int numLFEChannels); + + #ifdef __cplusplus + } +diff -Naur faac-1.28.old/libfaac/frame.c faac-1.28.new/libfaac/frame.c +--- faac-1.28.old/libfaac/frame.c 2004-11-17 15:26:06.000000000 +0100 ++++ faac-1.28.new/libfaac/frame.c 2012-08-06 21:15:34.000000000 +0200 +@@ -99,21 +99,47 @@ + return -2; /* not supported */ + } + +- *pSizeOfDecoderSpecificInfo = 2; +- *ppBuffer = malloc(2); ++ if (hEncoder->config.channelConfiguration > 7) { ++ fprintf(stderr, "faacEncGetDecoderSpecificInfo: " ++ "invalid channel configuration %u\n", ++ hEncoder->config.channelConfiguration); ++ return -2; ++ } else if (hEncoder->config.channelConfiguration) { ++ // 16 bits ++ *pSizeOfDecoderSpecificInfo = 2; ++ } else { ++ // 16 bits + size of the program_config_element() ++ *pSizeOfDecoderSpecificInfo = 2 + (WritePCE(hEncoder, NULL, 0, 0, 0) / 8); ++ } + +- if(*ppBuffer != NULL){ ++ *ppBuffer = malloc(*pSizeOfDecoderSpecificInfo); + ++ if (*ppBuffer != NULL) { + memset(*ppBuffer,0,*pSizeOfDecoderSpecificInfo); + pBitStream = OpenBitStream(*pSizeOfDecoderSpecificInfo, *ppBuffer); + PutBit(pBitStream, hEncoder->config.aacObjectType, 5); + PutBit(pBitStream, hEncoder->sampleRateIdx, 4); +- PutBit(pBitStream, hEncoder->numChannels, 4); ++ PutBit(pBitStream, hEncoder->config.channelConfiguration, 4); ++ PutBit(pBitStream, 0, 1); // frameLengthFlag ++ PutBit(pBitStream, 0, 1); // dependsOnCoreCoder ++ PutBit(pBitStream, 0, 1); // extensionFlag ++ if (!hEncoder->config.channelConfiguration) { ++ /* a program_config_element() must be written */ ++ if (WritePCE(hEncoder, pBitStream, 0, 0, 1) <= 0) { ++ fprintf(stderr, ++ "faacEncGetDecoderSpecificInfo: WritePCE() failed!\n"); ++ *pSizeOfDecoderSpecificInfo = 0; ++ CloseBitStream(pBitStream); ++ free(*ppBuffer); ++ *ppBuffer = NULL; ++ return -3; ++ } ++ } + CloseBitStream(pBitStream); +- + return 0; + } else { +- return -3; ++ *pSizeOfDecoderSpecificInfo = 0; ++ return -4; + } + } + +@@ -131,7 +157,6 @@ + int i; + + hEncoder->config.allowMidside = config->allowMidside; +- hEncoder->config.useLfe = config->useLfe; + hEncoder->config.useTns = config->useTns; + hEncoder->config.aacObjectType = config->aacObjectType; + hEncoder->config.mpegVersion = config->mpegVersion; +@@ -139,6 +164,77 @@ + hEncoder->config.inputFormat = config->inputFormat; + hEncoder->config.shortctl = config->shortctl; + ++ if (!config->channelConfiguration) { ++ if (hEncoder->numChannels != (config->numFrontChannels + ++ config->numSideChannels + ++ config->numBackChannels + ++ config->numLFEChannels)) { ++ fprintf(stderr, "faacEncSetConfiguration: " ++ "numChannels doesn't match the custom channel configuration\n"); ++ return 0; ++ } ++ hEncoder->config.numFrontChannels = config->numFrontChannels; ++ hEncoder->config.numSideChannels = config->numSideChannels; ++ hEncoder->config.numBackChannels = config->numBackChannels; ++ hEncoder->config.numLFEChannels = config->numLFEChannels; ++ } else if (config->channelConfiguration > 7) { ++ fprintf(stderr, "faacEncSetConfiguration: " ++ "invalid channel configuration %u\n", ++ config->channelConfiguration); ++ return 0; ++ } else { ++ if ((config->channelConfiguration == 7 && hEncoder->numChannels != 8) || ++ (config->channelConfiguration != 7 && hEncoder->numChannels != config->channelConfiguration)) { ++ fprintf(stderr, "faacEncSetConfiguration: " ++ "numChannels doesn't match the channel configuration\n"); ++ return 0; ++ } ++ switch (config->channelConfiguration) { ++ case 7: ++ hEncoder->config.numFrontChannels = 5; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 2; ++ hEncoder->config.numLFEChannels = 1; ++ break; ++ case 6: ++ hEncoder->config.numFrontChannels = 3; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 2; ++ hEncoder->config.numLFEChannels = 1; ++ break; ++ case 5: ++ hEncoder->config.numFrontChannels = 3; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 2; ++ hEncoder->config.numLFEChannels = 0; ++ break; ++ case 4: ++ hEncoder->config.numFrontChannels = 3; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 1; ++ hEncoder->config.numLFEChannels = 0; ++ break; ++ case 3: ++ hEncoder->config.numFrontChannels = 3; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 0; ++ hEncoder->config.numLFEChannels = 0; ++ break; ++ case 2: ++ hEncoder->config.numFrontChannels = 2; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 0; ++ hEncoder->config.numLFEChannels = 0; ++ break; ++ case 1: ++ hEncoder->config.numFrontChannels = 1; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 0; ++ hEncoder->config.numLFEChannels = 0; ++ break; ++ } ++ } ++ + assert((hEncoder->config.outputFormat == 0) || (hEncoder->config.outputFormat == 1)); + + switch( hEncoder->config.inputFormat ) +@@ -306,6 +402,12 @@ + *maxOutputBytes += 1; /* for CRC */ + #endif + ++ if (!numChannels || numChannels > 64) { ++ fprintf(stderr, "faacEncOpen: invalid number of channels %u\n", ++ numChannels); ++ return NULL; ++ } ++ + hEncoder = (faacEncStruct*)AllocMemory(sizeof(faacEncStruct)); + SetMemory(hEncoder, 0, sizeof(faacEncStruct)); + +@@ -324,7 +426,6 @@ + hEncoder->config.mpegVersion = MPEG4; + hEncoder->config.aacObjectType = LTP; + hEncoder->config.allowMidside = 1; +- hEncoder->config.useLfe = 1; + hEncoder->config.useTns = 0; + hEncoder->config.bitRate = 0; /* default bitrate / channel */ + hEncoder->config.bandWidth = bwfac * hEncoder->sampleRate; +@@ -340,6 +441,91 @@ + /* default channel map is straight-through */ + for( channel = 0; channel < 64; channel++ ) + hEncoder->config.channel_map[channel] = channel; ++ ++ /* Define a sensible default channel configuration */ ++ if (numChannels <= 6 || numChannels == 8) { ++ switch (numChannels) { ++ case 8: ++ hEncoder->config.channelConfiguration = 7; ++ hEncoder->config.numFrontChannels = 5; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 2; ++ hEncoder->config.numLFEChannels = 1; ++ break; ++ case 6: ++ hEncoder->config.channelConfiguration = 6; ++ hEncoder->config.numFrontChannels = 3; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 2; ++ hEncoder->config.numLFEChannels = 1; ++ break; ++ case 5: ++ hEncoder->config.channelConfiguration = 5; ++ hEncoder->config.numFrontChannels = 3; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 2; ++ hEncoder->config.numLFEChannels = 0; ++ break; ++ case 4: ++ hEncoder->config.channelConfiguration = 4; ++ hEncoder->config.numFrontChannels = 3; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 1; ++ hEncoder->config.numLFEChannels = 0; ++ break; ++ case 3: ++ hEncoder->config.channelConfiguration = 3; ++ hEncoder->config.numFrontChannels = 3; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 0; ++ hEncoder->config.numLFEChannels = 0; ++ break; ++ case 2: ++ hEncoder->config.channelConfiguration = 2; ++ hEncoder->config.numFrontChannels = 2; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 0; ++ hEncoder->config.numLFEChannels = 0; ++ break; ++ case 1: ++ hEncoder->config.channelConfiguration = 1; ++ hEncoder->config.numFrontChannels = 1; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 0; ++ hEncoder->config.numLFEChannels = 0; ++ break; ++ } ++ } else { ++ hEncoder->config.channelConfiguration = 0; ++ hEncoder->config.numFrontChannels = 0; ++ hEncoder->config.numSideChannels = 0; ++ hEncoder->config.numBackChannels = 0; ++ hEncoder->config.numLFEChannels = 0; ++ for (channel = numChannels; channel > 0; channel--) { ++ // 7 channels: 7.0 (C L R Ls Rs Rls Rrs) ++ // 9 channels: 9.0 (Lc Rc L R Ls Rs Rls Rrs Cs) ++ // 10 channels: 10.0 (C Lc Rc L R Ls Rs Rls Rrs Cs) ++ // for more than 10 channels, use faacEncSetConfiguration() ++ if (hEncoder->config.numFrontChannels < 3) { ++ // C, L, R ++ hEncoder->config.numFrontChannels++; ++ } else if (hEncoder->config.numBackChannels < 2) { ++ // Ls or Rls, Rs or Rrs ++ hEncoder->config.numBackChannels++; ++ } else if (hEncoder->config.numSideChannels < 2) { ++ // Ls, Rs ++ hEncoder->config.numSideChannels++; ++ } else if (hEncoder->config.numBackChannels < 3) { ++ // Cs ++ hEncoder->config.numBackChannels++; ++ } else if (hEncoder->config.numFrontChannels < 5) { ++ // Lc, Rc ++ hEncoder->config.numFrontChannels++; ++ } else { ++ break; ++ } ++ } ++ } + + /* + by default we have to be compatible with all previous software +@@ -459,14 +645,13 @@ + double fix; + #endif + +- /* local copy's of parameters */ ++ /* local copies of parameters */ + ChannelInfo *channelInfo = hEncoder->channelInfo; + CoderInfo *coderInfo = hEncoder->coderInfo; + unsigned int numChannels = hEncoder->numChannels; + unsigned int sampleRate = hEncoder->sampleRate; + unsigned int aacObjectType = hEncoder->config.aacObjectType; + unsigned int mpegVersion = hEncoder->config.mpegVersion; +- unsigned int useLfe = hEncoder->config.useLfe; + unsigned int useTns = hEncoder->config.useTns; + unsigned int allowMidside = hEncoder->config.allowMidside; + unsigned int bandWidth = hEncoder->config.bandWidth; +@@ -484,7 +669,11 @@ + return 0; + + /* Determine the channel configuration */ +- GetChannelInfo(channelInfo, numChannels, useLfe); ++ GetChannelInfo(channelInfo, ++ hEncoder->config.numFrontChannels, ++ hEncoder->config.numSideChannels, ++ hEncoder->config.numBackChannels, ++ hEncoder->config.numLFEChannels); + + /* Update current sample buffers */ + for (channel = 0; channel < numChannels; channel++) diff --git a/contrib/faac/P00-cygwin.patch b/contrib/faac/P00-cygwin.patch index a5da42d87..bef152139 100644 --- a/contrib/faac/P00-cygwin.patch +++ b/contrib/faac/P00-cygwin.patch @@ -1,6 +1,6 @@ -diff -Naur faac-1.28.orig/include/faac.h faac-1.28/include/faac.h ---- faac-1.28.orig/include/faac.h 2009-01-25 13:50:32.000000000 -0500 -+++ faac-1.28/include/faac.h 2009-03-20 03:31:46.000000000 -0400 +diff -Naur faac-1.28.old/include/faac.h faac-1.28.new/include/faac.h +--- faac-1.28.old/include/faac.h 2009-01-25 13:50:32.000000000 -0500 ++++ faac-1.28.new/include/faac.h 2009-03-20 03:31:46.000000000 -0400 @@ -50,7 +50,7 @@ typedef void *faacEncHandle; |