c-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: %sn", 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;
    }
}

我在学习教程3时也遇到了同样的问题。pprahul在https://github.com/mpenkov/ffmpeg-tutorial/issues/11解决我在播放带有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及以下版本)似乎不会出现此问题。

最新更新