Есть ли какое-либо свойство элемента управления для исправления проблемы со скоростью воспроизведения видео при использовании ffmpeg для декодирования на платформе Qt? - PullRequest
0 голосов
/ 16 февраля 2019

Я хочу воспроизвести локальный видеофайл на платформе 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...