[Portaudio] PortAudio and ffmpeg

Andrew Udvare audvare at gmail.com
Thu Mar 3 20:39:04 EST 2011


Thanks for the tip. I have implemented this:

  static int16_t buf[AVCODEC_MAX_AUDIO_FRAME_SIZE + 
FF_INPUT_BUFFER_PADDING_SIZE];
  int data_size;
  while (av_read_frame(av_ctx, &packet) >= 0) {
    data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
    size = avcodec_decode_audio3(av_codec_ctx, buf, &data_size, &packet);
    if (size < 0) {
      memset(buf, 0, sizeof(buf));
    }
    
    ret = Pa_WriteStream(pa_stream, buf, size);
    if (ret) {
      goto error;
    }
  }

The only problem is it goes too fast (and sounds choppy). Am I missing 
something or is it the fault of ffmpeg? The sample rate is taken from the 
file, most cases 44100 but in some cases 22050. Frames per buffer is set at 
1024, changing this doesn't seem to have any effect.

  pa_params->device = Pa_GetDefaultOutputDevice();
  pa_params->channelCount = av_codec_ctx->channels;
  pa_params->sampleFormat = paInt16; // 16-bit integer
  pa_params->suggestedLatency = Pa_GetDeviceInfo(pa_params->device)-
>defaultLowOutputLatency;
  pa_params->hostApiSpecificStreamInfo = NULL;

  // Initialise stream playback
  ret = Pa_OpenStream(
          &pa_stream,
          NULL, // no input
          pa_params,
          av_codec_ctx->sample_rate,
          1024, // frames per buffer
          paClipOff, // Do not output of range samples
          NULL,
          NULL
        );

Thanks

On Thursday 03 March 2011 19:25:04 Phil Burk wrote:
> Hello Andrew,
> 
> On 3/3/11 3:54 PM, Andrew Udvare wrote:
> > I think I have almost figured this out. I have changed from
> > paFloat32 to paInt16 (int16_t) to better match with ffmpeg. Now I
> > have audio that sounds correct but it's clipping and too slow, and I
> > keep running into a memory corruption problem.
> 
> I can see a number of problems with the code that you sent.
> 
> On 3/3/11 2:12 PM, Andrew Udvare wrote:
>  > I have pasted code here:  <http://paste.pocoo.org/show/347705/>
>  > This is heavily based on code at
>  > <http://dranger.com/ffmpeg/tutorial03.html>
> 
> I see that you removed the mutex locks from the original code. Those 
> were there for a very good reason.  You are also allocating memory in 
> one thread and freeing it the callback thread. That is probably not 
> thread safe. Also it can cause lockup in the callback thread if the 
> av_free() function blocks.
> 
> I highly recommend that you use the PortAudio blocking read/write 
> interface instead of the callback interface. Then you can simply decode 
> in the foreground and write the audio directly to the stream. PortAudio 
> will take care of all the dangerous thread synchronization issues. You 
> don't have to manage the queue.
> 
> Just pass a NULL for the callback pointer and then call Pa_WriteStream() 
> in your decoder loop.
> 
>     http://www.portaudio.com/trac/wiki/TutorialDir/BlockingReadWrite
> 
> Thank you,
> Phil Burk
> -------------------------------------------------
> Mobileer Inc, http://www.mobileer.com/
> 75 Pleasant Lane, San Rafael, CA, 94901 USA
> Office/Fax: +1-415-453-4320
> Mobile: +1-415-846-4370
> -------------------------------------------------
> 
> On 3/3/11 3:54 PM, Andrew Udvare wrote:
> > I think I have almost figured this out. I have changed from
> > paFloat32 to paInt16 (int16_t) to better match with ffmpeg. Now I
> > have audio that sounds correct but it's clipping and too slow, and I
> > keep running into a memory corruption problem.
> >
> > Here is my callback now: int pa_callback(const void *input, void
> > *output, unsigned long frame_count, const PaStreamCallbackTimeInfo
> > *time_info, PaStreamCallbackFlags status_flags, void *data) {
> > AVCodecContext *ctx = (AVCodecContext *)data; static int16_t
> > buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]; // example with
> > SDL_Audio uses this size for buffer int16_t *out = (int16_t *)output;
> > int size = 0;
> >
> > size = audio_decode_frame(ctx, buf, sizeof(buf)); if (size<  0) {
> > memset(buf, 0, sizeof(buf)); } memcpy(out, buf, size);
> >
> > return paContinue; // Never done }
> >
> > size is determined by ffmpeg, and I do not know how large you can
> > write into output, nor have I really done it this way before
> > (usually I would use *out++ = (int16_t)*buf + 1, however no sound
> > happens that way).
> >
> > The sound plays with the memcpy way of doing it but after a few
> > seconds the program quits with either a double free or memory
> > corruption or corrupted linked-list.
> >
> > On Thursday 03 March 2011 17:36:44 Peter wrote:
> >> Hi,
> >>
> >> what, in detail, is  "the audio sounds completely wrong" ?
> >>
> > _______________________________________________ Portaudio mailing
> > list Portaudio at music.columbia.edu
> > http://music.columbia.edu/mailman/listinfo/portaudio
> >
> >
> _______________________________________________
> Portaudio mailing list
> Portaudio at music.columbia.edu
> http://music.columbia.edu/mailman/listinfo/portaudio
> 


More information about the Portaudio mailing list