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