0

FFmpeg has an example muxing code on https://ffmpeg.org/doxygen/4.0/muxing_8c-example.html

This code generates frame by frame video and audio. What I am trying to do is to change

ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout,
                                       c->sample_rate, nb_samples);

to

ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout,
                                       c->sample_rate, 3840);

so that it generates 3840 samples per channel instead of 1024 samples which is the default for nb_samples (aac codec).

I tried to combine code from https://ffmpeg.org/doxygen/4.0/transcode_aac_8c-example.html which has an example on buffering the frames.

My resulting program crashes when generating audio samples after a couple of frames when assigning *q++ a new value at the first iteration:

/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
 * 'nb_channels' channels. */
static AVFrame *get_audio_frame(OutputStream *ost)
{
    AVFrame *frame = ost->tmp_frame;
    int j, i, v;
    int16_t *q = (int16_t*)frame->data[0];
    /* check if we want to generate more frames */
    if (av_compare_ts(ost->next_pts, ost->enc->time_base,
                      STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
        return NULL;
    for (j = 0; j <frame->nb_samples; j++) {
        v = (int)(sin(ost->t) * 10000);
        for (i = 0; i < ost->enc->channels; i++)
            *q++ = v;
        ost->t     += ost->tincr;
        ost->tincr += ost->tincr2;
    }
    frame->pts = ost->next_pts;
    ost->next_pts  += frame->nb_samples;
    return frame;
}

Maybe I don't get the logic behind encoding.

Here is the full source that i've come up with:

https://paste.ee/p/b07qf

The reason i am trying to accomplish this task is that I have a capture card sdk that outputs 2 channel 16 bit raw pcm 48000Hz which has 3840 samples per channel and I am trying to encode its output to aac. So basically if I get the muxing example to work with 3840 nb_samples this will help me understand the concept.

I have already looked at How to encode resampled PCM-audio to AAC using ffmpeg-API when input pcm samples count not equal 1024 but the example uses "encodeFrame", which the examples on ffmpeg documentation doesn't use or I am mistaken.

Any help is greatly appreciated.

Gabulit
  • 36
  • 4
  • The AAC encoder employs a MDCT window of 1024 samples. 3840 is not supported. – Gyan Jul 03 '18 at 04:48
  • I have seen some examples that use buffering for unsupported windows samples, the link i provided has another example. I think it just sends 1024 samples at a time until it sends all the samples of a frame to the encoder or am i mistaken? – Gabulit Jul 03 '18 at 08:33
  • 1
    In my calculation (which depends on some assumptions). `nb_samples` should equal to *48000 / 25 = 1920*. Buffer needed for 1920 samples for 2 channel 16bit audio (pcm_s16) is *1920 x 2 x (16/8) = 7680* bytes. – the kamilz Jul 03 '18 at 11:10
  • Ok my bad, I thought nb_samples should equal to 1920x2channels. You are right the buffer I get from the raw pcm is exactly 7680 bytes. I just want to know how to input 1920 samples to a 1024 sample accepting codec such as aac. If I try to fill the AVFrame with my data then the nb_samples would be 1920. When I send it to encoder it complains about the nb_sample size. – Gabulit Jul 03 '18 at 14:31
  • Well I managed to do it with buffering the 1920 samples and sending 1024 at a time. – Gabulit Jul 04 '18 at 19:44

1 Answers1

0

Ok here is the solution for anyone interested.

Since the codec accepts 1024 samples, we need to put 1920 samples into a buffer and feed the codec 1024 samples at a time.

I barrowed buffering code from : How to encode resampled PCM-audio to AAC using ffmpeg-API when input pcm samples count not equal 1024

Gabulit
  • 36
  • 4