首页 > 解决方案 > Qt平台使用ffmpeg解码时,是否有任何控制属性来解决视频播放速度问题?

问题描述

我想在 Qt 平台上使用 ffmpeg 解码播放本地视频文件。除了播放速度是正常的两倍之外,一切都很好。我想到的第一件事就是必须涉及采样频率。但是对于ffmpeg的新手,我不知道如何解决这个问题。以上是我阅读框架的代码,有人能告诉我代码有什么问题吗?

void VideoThread::run()
{
    m_pInFmtCtx = avformat_alloc_context(); //ini struct
    char path[] = "d:/test.mp4";
    // open specific file
    if(avformat_open_input(&m_pInFmtCtx, *path, NULL, NULL)){ 
    {
        qDebug()<<"get rtsp failed";
        return;
    }
    else
    {
        qDebug()<<"get rtsp success";
    }


    if(avformat_find_stream_info(m_pInFmtCtx, NULL) < 0)
    {
        qDebug()<<"could not find stream information";
        return;
    }
    int nVideoIndex = -1;
    for(int i = 0; i < m_pInFmtCtx->nb_streams; i++)
    {
        if(m_pInFmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            nVideoIndex = i;
            break;
        }
    }
    if(nVideoIndex == -1)
    {
        qDebug()<<"could not find video stream";
        return;
    }

    qDebug("---------------- File Information ---------------");
    m_pCodecCtx = m_pInFmtCtx->streams[nVideoIndex]->codec;
    m_pCodec = avcodec_find_decoder(m_pCodecCtx->codec_id);
    if(!m_pCodec)
    {
        qDebug()<<"could not find codec";
        return;
    }
    //start Decoder
    if (avcodec_open2(m_pCodecCtx, m_pCodec, NULL) < 0) {
        qDebug("Could not open codec.\n");
        return;
    }


    //malloc space for stroring frame
    m_pFrame     = av_frame_alloc();
    m_pFrameRGB  = av_frame_alloc();
    m_pOutBuf = (uint8_t*)av_malloc(avpicture_get_size(AV_PIX_FMT_RGB32, m_pCodecCtx->width, m_pCodecCtx->height));
    avpicture_fill((AVPicture*)m_pFrameRGB, m_pOutBuf, AV_PIX_FMT_RGB32, m_pCodecCtx->width, m_pCodecCtx->height);

    //for color switch,from YUV to RGB
    struct SwsContext *pImgCtx = sws_getContext(m_pCodecCtx->width, m_pCodecCtx->height, m_pCodecCtx->pix_fmt,
                                                m_pCodecCtx->width, m_pCodecCtx->height, AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);


    int nSize = m_pCodecCtx->width * m_pCodecCtx->height;
    m_pPacket = (AVPacket *)av_malloc(sizeof(AVPacket));
    if(av_new_packet(m_pPacket, nSize) != 0)
    {
        qDebug()<<"new packet failed";
    }

    //isInterruptionRequested is a flag,determine whether the thread is over
    // read each frame from specific video file
    while (!isInterruptionRequested())
    {
        int nGotPic = 0;
        if(av_read_frame(m_pInFmtCtx, m_pPacket) >= 0)
        {
            if(m_pPacket->stream_index == nVideoIndex)
            {
                //avcodec_decode_video2()transform from packet to frame
                if(avcodec_decode_video2(m_pCodecCtx, m_pFrame, &nGotPic, m_pPacket) < 0)
                {
                    qDebug()<<"decode failed";
                    return;
                }
                if(nGotPic)
                {   // transform to RGB color
                    sws_scale(pImgCtx, (const uint8_t* const*)m_pFrame->data,
                              m_pFrame->linesize, 0, m_pCodecCtx->height, m_pFrameRGB->data,
                              m_pFrameRGB->linesize);
                    // save to QImage,for later use
                    QImage *pImage = new QImage((uchar*)m_pOutBuf, m_pCodecCtx->width, m_pCodecCtx->height, QImage::Format_RGB32);
                }

            }
        }

        av_free_packet(m_pPacket);
        msleep(5);
    }
    exec();
}

标签: qtvideoffmpeg

解决方案


推荐阅读