Dm365 gsttiaudenc1 and mp4 muxing fix

Paul Stuart paul_stuart at seektech.com
Tue Jan 31 09:18:37 PST 2012


Hi All,
 Using Ti's out-of-the-box gstreamer plugin, I had problems muxing AAC 
produced by gsttiaudenc1 with H.264 using qtmux. I made the following 
fixes to make it work for me. I cribbed some of this from faac, and some 
of it from RidgeRun's branch.



Step 1 is using extended params in gst_tiaudenc1_codec_start to turn off 
the default ADTS headers


gsttiaudenc1.c :  static gboolean 
gst_tiaudenc1_set_source_caps(GstTIAudenc1* audenc1)
<--Snip-->
 AUDENC1_Params            params    = Aenc1_Params_DEFAULT;
    ITTIAM_EAACPLUSENC_Params eparams; // extended codec parameters
    AUDENC1_DynamicParams     dynParams = Aenc1_DynamicParams_DEFAULT;
    Buffer_Attrs              bAttrs    = Buffer_Attrs_DEFAULT;

    /* Override the default parameters to use the defaults specified or the
     * user settings.
     * Order of setting is:
     *    1.  Parameters set on command line
     *    2.  Settings detected during caps negotiation
     *    3.  Default values defined in gsttiaudenc1.h
     */
    params.sampleRate = audenc1->samplefreq == 0 ? 
TIAUDENC1_SAMPLEFREQ_DEFAULT:
                            audenc1->samplefreq;
    params.bitRate = audenc1->bitrate = audenc1->bitrate == 0 ?
                            TIAUDENC1_BITRATE_DEFAULT : audenc1->bitrate;
    params.channelMode = audenc1->channels == 0 ? params.channelMode :
                            audenc1->channels == 1 ? IAUDIO_1_0 : 
IAUDIO_2_0;

    /* Initialize dynamic parameters */
    dynParams.sampleRate = params.sampleRate;
    dynParams.bitRate = params.bitRate;
    dynParams.channelMode = params.channelMode;

    /* Open the codec engine */
    GST_LOG("opening codec engine \"%s\"\n", audenc1->engineName);
    audenc1->hEngine = Engine_open((Char *) audenc1->engineName, NULL, 
NULL);

    if (audenc1->hEngine == NULL) {
        GST_ELEMENT_ERROR(audenc1, RESOURCE, READ,
        ("Failed to open codec engine \"%s\"\n", audenc1->engineName), 
(NULL));
        return FALSE;
    }

    // extended params
    eparams.s_iaudenc_params = params;
    eparams.s_iaudenc_params.size = sizeof(ITTIAM_EAACPLUSENC_Params);
    eparams.noChannels = 2;
    eparams.aacClassic = 1; // NA for LC build
    eparams.psEnable = 0;   // NA for LC build
    eparams.dualMono = 1;    // Available in multichannel build
    eparams.downmix = 0;    // Do not downmix
    eparams.useSpeechConfig = 0; // NA for LC build
    eparams.fNoStereoPreprocessing = 1; // Allow stereeo processing
    eparams.invQuant = 0;        // NA for LC build
    eparams.useTns = 0;          // Do not use temporal noise shaping
    eparams.use_ADTS = 0;        // ADTS header
    eparams.use_ADIF = 0;        // NP ADIF header
    eparams.full_bandwidth = 0;  // adjustable bandwidth based on bit rate

    /* The following parameters may not be necessary since
     * they only work for multichannel build
     */
    eparams.i_channels_mask = 0x0; // NA for stero build
    eparams.i_num_coupling_chan = 0; // NA for stero build
    eparams.write_program_config_element = 0; // NA for stero build
   

    /* Initialize audio encoder */
    GST_LOG("opening audio encoder \"%s\"\n", audenc1->codecName);
    audenc1->hAe = Aenc1_create(audenc1->hEngine, (Char*)audenc1->codecName,
                     (AUDENC1_Params *)&eparams, &dynParams);

<-- End of Snip -->


Step 2
In the same file, create codec_data on the source caps to provide qtmux 
with the stream header info
gsttiaudenc1.c :  static gboolean 
gst_tiaudenc1_set_source_caps(GstTIAudenc1* audenc1)
<--Snip-->
    GstCaps  *caps;
    gboolean  ret;
    char     *string;
    GstTICodec *aacCodec = NULL;
    GstBuffer *codec_data = NULL;
    aacCodec = gst_ticodec_get_codec("AAC Audio Encoder");

    /* Create AAC source caps */
    if (aacCodec && (!strcmp(aacCodec->CE_CodecName, audenc1->codecName))) {
        // CREATE HEADER //////////////////////////////////////
        #define LC_PROFILE 2
        int channels = audenc1->channels;
        guchar *data;
        guint sr_idx  = gst_get_aac_rateIdx(audenc1->samplefreq);
        gchar profile = LC_PROFILE;
        codec_data = gst_buffer_new_and_alloc(2);
        data = GST_BUFFER_DATA(codec_data);
        data[0] = ((profile & 0x1F) << 3) | ((sr_idx & 0xE) >> 1);
        data[1] = ((sr_idx & 0x1) << 7) | ((channels & 0xF) << 3);
        /////////////////////////////////////////////////////////
        caps =
            gst_caps_new_simple ("audio/mpeg",
                "mpegversion", G_TYPE_INT, 4,
                "channels", G_TYPE_INT, audenc1->channels,
                "rate", G_TYPE_INT, audenc1->samplefreq,
                "bitrate", G_TYPE_INT, audenc1->bitrate,
                "codec_data", GST_TYPE_BUFFER, codec_data,
                NULL);

        /* Set the source pad caps */
        string = gst_caps_to_string(caps);
        GST_INFO("setting source caps to AAC:  %s", string);
        g_free(string);
        gst_buffer_unref (codec_data);
    } else {
<-- End of Snip -->


Maybe someone is in the same predicament I was in. If so, I hope this helps.

Thanks,
Paul



More information about the gstreamer-devel mailing list