bcpermafrost
bcpermafrost

Reputation: 89

SDL Audio - Plays only Static Noise

Im having an issue with playing audio.

Im new to the SDL World of things so im learning from a tutorial.

http://dranger.com/ffmpeg/tutorial03.html

As far as audio goes, i have exactly what he put down and didnt get the result he says I should get. In the end of the lesson he specifies that the audio should play normally. However all i get is excessively loud static noise. This leads me to believe that the packets arent being read correctly. However I have no idea how to debug or look for the issue.

Here is my main loop for parsing the packets:

 while (av_read_frame(pFormatCtx, &packet) >= 0) {

         if (packet.stream_index == videoStream) {
             avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);

             if (frameFinished){

                 AVPicture pict;

                 pict.data[0] = yPlane;
                 pict.data[1] = uPlane;
                 pict.data[2] = vPlane;
                 pict.linesize[0] = pCodecCtx->width;
                 pict.linesize[1] = uvPitch;
                 pict.linesize[2] = uvPitch;

                 sws_scale(sws_ctx,
                     pFrame->data, pFrame->linesize,
                     0, pCodecCtx->height,
                     pict.data, pict.linesize);

                 //SDL_UnlockTexture(bmp);

                 SDL_UpdateYUVTexture(bmp, 0, 
                     yPlane, pCodecCtx->width, 
                     uPlane, uvPitch, 
                     vPlane, uvPitch);


                 SDL_RenderClear(renderer);
                 SDL_RenderCopy(renderer, bmp, NULL, NULL);
                 SDL_RenderPresent(renderer);


                 av_free_packet(&packet);


             }

         }
         else if (packet.stream_index == audioStream) { 
             packet_queue_put(&audioq, &packet);

         }
         else
             av_free_packet(&packet);



         SDL_PollEvent(&event);

         switch (event.type) {
         case SDL_QUIT:
             quit = 1;
             SDL_DestroyTexture(bmp);
             SDL_DestroyRenderer(renderer);
             SDL_DestroyWindow(screen);
             SDL_Quit();
             exit(0);
             break;
         default:
             break;

         }

     }

this is my initialization of the audio device :

aCodecCtxOrig = pFormatCtx->streams[audioStream]->codec;
    aCodec = avcodec_find_decoder(aCodecCtxOrig->codec_id);
    if (!aCodec) {
        fprintf(stderr, "Unsupported codec!\n");
        return -1;
    }

    // Copy context
    aCodecCtx = avcodec_alloc_context3(aCodec);
    if (avcodec_copy_context(aCodecCtx, aCodecCtxOrig) != 0) {
        fprintf(stderr, "Couldn't copy codec context");
        return -1; // Error copying codec context
    }


    wanted_spec.freq = aCodecCtx->sample_rate;
    wanted_spec.format = AUDIO_U16SYS;
    wanted_spec.channels = aCodecCtx->channels;
    wanted_spec.silence = 0;
    wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
    wanted_spec.callback = audio_callback;
    wanted_spec.userdata = aCodecCtx;


    if (SDL_OpenAudio( &wanted_spec, &spec) < 0) {
        fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
        return -1;
    }

    avcodec_open2(aCodecCtx, aCodec, NULL);

    // audio_st = pFormatCtx->streams[index]
    packet_queue_init(&audioq);
    SDL_PauseAudio(0);

The Call back (same as the tutorial):|

void audio_callback(void *userdata, Uint8 *stream, int len) {

    AVCodecContext *aCodecCtx = (AVCodecContext *)userdata;
    int len1, audio_size;

    static uint8_t audio_buf[(MAX_AUDIO_FRAME_SIZE * 3) / 2];
    static unsigned int audio_buf_size = 0;
    static unsigned int audio_buf_index = 0;

    while (len > 0) {
        if (audio_buf_index >= audio_buf_size) {
            /* We have already sent all our data; get more */
            audio_size = audio_decode_frame(aCodecCtx, audio_buf, sizeof(audio_buf));
            if (audio_size < 0) {
                /* If error, output silence */
                audio_buf_size = 1024; // arbitrary?
                memset(audio_buf, 0, audio_buf_size);
            }
            else {
                audio_buf_size = audio_size;
            }
            audio_buf_index = 0;
        }
        len1 = audio_buf_size - audio_buf_index;
        if (len1 > len)
            len1 = len;
        memcpy(stream, (uint8_t *)audio_buf + audio_buf_index, len1);
        len -= len1;
        stream += len1;
        audio_buf_index += len1;
    }
}

Upvotes: 1

Views: 603

Answers (1)

hefty
hefty

Reputation: 11

I also had same problem when I learn tutorial 3. The comments by pprahul in https://github.com/mpenkov/ffmpeg-tutorial/issues/11 solve my problem when playing .MPG file with mp2 format audio. But the problem still occur when I play .MP4 file with AAC format audio.

A snapshot of that comment is to set the decode format manually, by

//after get the AVCodecContext *codecCtx(aCodecCtx in tutorial).

if (codecCtx->sample_fmt == AV_SAMPLE_FMT_S16P) {
    codecCtx->request_sample_fmt = AV_SAMPLE_FMT_S16;
}

//...

It seems that the problem will not occur with early version of FFmpeg (1.01 and below).

Upvotes: 0

Related Questions