SDL音频 - 仅播放静电噪声

时间:2016-04-30 18:02:21

标签: c audio ffmpeg sdl

我遇到播放音频的问题。

我是SDL世界的新手,所以我要从教程中学习。

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

就音频而言,我完全放下了他所说的并且没有得到他说我应该得到的结果。在课程结束时,他指定音频应该正常播放。然而,我得到的是过大的静电噪音。这让我相信数据包没有被正确读取。但是我不知道如何调试或查找问题。

这是我解析数据包的主循环​​:

 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;

         }

     }

这是我对音频设备的初始化:

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);

回叫(与教程相同):|

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;
    }
}

1 个答案:

答案 0 :(得分:0)

我在学习教程3时也遇到了同样的问题。https://github.com/mpenkov/ffmpeg-tutorial/issues/11中pprahul的评论解决了播放带有mp2格式音频的.MPG文件时的问题。但是当我播放带有AAC格式音频的.MP4文件时,仍然会出现问题。

该注释的快照是通过以下方式手动设置解码格式:

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

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

//...

似乎早期版本的FFmpeg(1.01及更低版本)不会出现此问题。

相关问题