remove --sbr-signaling
authornu774 <honeycomb77@gmail.com>
Sun, 27 Oct 2013 10:27:18 +0000 (19:27 +0900)
committernu774 <honeycomb77@gmail.com>
Sun, 27 Oct 2013 12:15:12 +0000 (21:15 +0900)
Instead, we always use explicit/backward compatible SBR signaling by
ASC extension in case of m4a, which is not supported by FDK library
(so we do it on our side).
For LOAS, we use explicit hierarchical signaling.

src/aacenc.c
src/aacenc.h
src/main.c

index af9107d32e82630440952d9dbfcd0f8da2757cf7..d25be8a3570a0eb019d1355f14731fc12f3c268c 100644 (file)
@@ -10,6 +10,7 @@
 #endif
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include "aacenc.h"
 
 int aacenc_is_sbr_active(const aacenc_param_t *params)
@@ -25,6 +26,68 @@ int aacenc_is_sbr_active(const aacenc_param_t *params)
     return 0;
 }
 
+static const unsigned aacenc_sampling_freq_tab[] = {
+    96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 
+    16000, 12000, 11025, 8000, 7350, 0, 0, 0
+};
+
+static
+unsigned sampling_freq_index(unsigned rate)
+{
+    unsigned i;
+    for (i = 0; aacenc_sampling_freq_tab[i]; ++i)
+        if (aacenc_sampling_freq_tab[i] == rate)
+            return i;
+    return 0xf;
+}
+
+/*
+ * Append backward compatible SBR/PS signaling to implicit signaling ASC,
+ * if SBR/PS is present.
+ */
+int aacenc_mp4asc(const aacenc_param_t *params,
+                  const uint8_t *asc, uint32_t ascsize,
+                  uint8_t *outasc, uint32_t *outsize)
+{
+    unsigned asc_sfreq = aacenc_sampling_freq_tab[(asc[0]&0x7)<<1 |asc[1]>>7];
+
+    switch (params->profile) {
+    case AOT_SBR:
+    case AOT_PS:
+        if (*outsize < ascsize + 3)
+            return -1;
+        memcpy(outasc, asc, ascsize);
+        /* syncExtensionType:11 (value:0x2b7) */
+        outasc[ascsize+0] = 0x2b << 1;
+        outasc[ascsize+1] = 0x7 << 5;
+        /* extensionAudioObjectType:5 (value:5)*/
+        outasc[ascsize+1] |= 5;
+        /* sbrPresentFlag:1 (value:1) */
+        outasc[ascsize+2] = 0x80;
+        /* extensionSamplingFrequencyIndex:4 */
+        outasc[ascsize+2] |= sampling_freq_index(asc_sfreq << 1) << 3;
+        if (params->profile == AOT_SBR) {
+            *outsize = ascsize + 3;
+            break;
+        }
+        if (*outsize < ascsize + 5)
+            return -1;
+        /* syncExtensionType:11 (value:0x548) */
+        outasc[ascsize+2] |= 0x5;
+        outasc[ascsize+3] = 0x48;
+        /* psPresentFlag:1 (value:1) */
+        outasc[ascsize+4] = 0x80;
+        *outsize = ascsize + 5;
+        break;
+    default:
+        if (*outsize < ascsize)
+            return -1;
+        memcpy(outasc, asc, ascsize);
+        *outsize = ascsize;
+    }
+    return 0;
+}
+
 static
 int aacenc_channel_mode(const pcm_sample_description_t *format)
 {
index ebb0509df4adbe8a303cee89fd8a1b30cecbc8d8..2db945f6b7d0fae181bd3a4dc387fdc31fb7a661 100644 (file)
@@ -26,6 +26,10 @@ typedef struct aacenc_param_t {
 
 int aacenc_is_sbr_active(const aacenc_param_t *params);
 
+int aacenc_mp4asc(const aacenc_param_t *params,
+                  const uint8_t *asc, uint32_t ascsize,
+                  uint8_t *outasc, uint32_t *outsize);
+
 int aacenc_init(HANDLE_AACENCODER *encoder, const aacenc_param_t *params,
                 const pcm_sample_description_t *format,
                 AACENC_InfoStruct *info);
index 952cfbccc4b91fb92f416992bcdd7326c8b99e6f..9aa72d0502bd5ee292ffc5d120b3c820f7c232c2 100644 (file)
@@ -133,10 +133,6 @@ PROGNAME " %s\n"
 "                                 0: Off\n"
 "                                 1: On(default)\n"
 " -L, --lowdelay-sbr            Enable ELD-SBR (AAC ELD only)\n"
-" -s, --sbr-signaling <n>       SBR signaling mode\n"
-"                                 0: Implicit, backward compatible(default)\n"
-"                                 1: Explicit SBR and implicit PS\n"
-"                                 2: Explicit hierarchical signaling\n"
 " -f, --transport-format <n>    Transport format\n"
 "                                 0: RAW (default, muxed into M4A)\n"
 "                                 1: ADIF\n"
@@ -247,7 +243,6 @@ int parse_options(int argc, char **argv, aacenc_param_ex_t *params)
         { "bandwidth",        required_argument, 0, 'w' },
         { "afterburner",      required_argument, 0, 'a' },
         { "lowdelay-sbr",     no_argument,       0, 'L' },
-        { "sbr-signaling",    required_argument, 0, 's' },
         { "transport-format", required_argument, 0, 'f' },
         { "adts-crc-check",   no_argument,       0, 'C' },
         { "header-period",    required_argument, 0, 'P' },
@@ -326,13 +321,6 @@ int parse_options(int argc, char **argv, aacenc_param_ex_t *params)
         case 'L':
             params->lowdelay_sbr = 1;
             break;
-        case 's':
-            if (sscanf(optarg, "%u", &n) != 1 || n > 2) {
-                fprintf(stderr, "invalid arg for sbr-signaling\n");
-                return -1;
-            }
-            params->sbr_signaling = n;
-            break;
         case 'f':
             if (sscanf(optarg, "%u", &n) != 1) {
                 fprintf(stderr, "invalid arg for transport-format\n");
@@ -736,6 +724,7 @@ int main(int argc, char **argv)
     const pcm_sample_description_t *sample_format;
     int downsampled_timescale = 0;
     int frame_count = 0;
+    int sbr_mode = 0;
 
     setlocale(LC_CTYPE, "");
     setbuf(stderr, 0);
@@ -748,6 +737,17 @@ int main(int argc, char **argv)
 
     sample_format = pcm_get_format(reader);
 
+    /*
+     * We use explicit/hierarchical signaling for LOAS.
+     * Other than that, we request implicit signaling to FDK library, then 
+     * append explicit/backward-compatible signaling to ASC in case of MP4FF.
+     *
+     * Explicit/backward-compatible signaling of SBR is the most recommended
+     * way in MPEG4 part3 spec, and seems the only way supported by iTunes.
+     * Since FDK library does not support it, we have to do it on our side.
+     */
+    params.sbr_signaling = (params.transport_format == TT_MP4_LOAS) ? 2 : 0;
+
     if (aacenc_init(&encoder, (aacenc_param_t*)&params, sample_format,
                     &aacinfo) < 0)
         goto END;
@@ -764,19 +764,21 @@ int main(int argc, char **argv)
         goto END;
     }
     handle_signals();
+    sbr_mode = aacenc_is_sbr_active((aacenc_param_t*)&params);
     if (!params.transport_format) {
         uint32_t scale;
+        uint8_t mp4asc[32];
+        uint32_t ascsize = sizeof(mp4asc);
         unsigned framelen = aacinfo.frameLength;
-        int sbr_mode = aacenc_is_sbr_active((aacenc_param_t*)&params);
-        int sig_mode = aacEncoder_GetParam(encoder, AACENC_SIGNALING_MODE);
-        if (sbr_mode && !sig_mode)
+        if (sbr_mode)
             downsampled_timescale = 1;
         scale = sample_format->sample_rate >> downsampled_timescale;
         if ((m4af = m4af_create(M4AF_CODEC_MP4A, scale, &m4af_io,
                                 params.output_fp)) < 0)
             goto END;
-        m4af_set_decoder_specific_info(m4af, 0, aacinfo.confBuf,
-                                       aacinfo.confSize);
+        aacenc_mp4asc((aacenc_param_t*)&params, aacinfo.confBuf,
+                      aacinfo.confSize, mp4asc, &ascsize);
+        m4af_set_decoder_specific_info(m4af, 0, mp4asc, ascsize);
         m4af_set_fixed_frame_duration(m4af, 0,
                                       framelen >> downsampled_timescale);
         m4af_set_vbr_mode(m4af, 0, params.bitrate_mode);
This page took 0.013545 seconds and 4 git commands to generate.