ffmpeg 解码h264 qt显示
时间: 2023-10-05 17:14:26 浏览: 131
你可以使用`ffmpeg`库来解码H.264视频并在Qt应用程序中显示。下面是一个基本的示例代码:
```cpp
#include <QApplication>
#include <QLabel>
#include <QTimer>
#include <QDebug>
#include <QByteArray>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
AVFormatContext *pFormatCtx = nullptr;
AVCodecContext *pCodecCtx = nullptr;
AVCodec *pCodec = nullptr;
AVFrame *pFrame = nullptr;
AVFrame *pFrameRGB = nullptr;
uint8_t *buffer = nullptr;
struct SwsContext *sws_ctx = nullptr;
bool openVideo(const char *filename)
{
if (avformat_open_input(&pFormatCtx, filename, nullptr, nullptr) != 0)
{
qDebug() << "Could not open file";
return false;
}
if (avformat_find_stream_info(pFormatCtx, nullptr) < 0)
{
qDebug() << "Could not find stream information";
return false;
}
int videoStream = -1;
for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoStream = i;
break;
}
}
if (videoStream == -1)
{
qDebug() << "Could not find video stream";
return false;
}
pCodecCtx = avcodec_alloc_context3(nullptr);
if (avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStream]->codecpar) != 0)
{
qDebug() << "Could not initialize codec context";
return false;
}
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == nullptr)
{
qDebug() << "Codec not found";
return false;
}
if (avcodec_open2(pCodecCtx, pCodec, nullptr) < 0)
{
qDebug() << "Could not open codec";
return false;
}
pFrame = av_frame_alloc();
pFrameRGB = av_frame_alloc();
int numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height, 1);
buffer = new uint8_t[numBytes];
av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize, buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height, 1);
sws_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24,
SWS_BILINEAR, nullptr, nullptr, nullptr);
return true;
}
void closeVideo()
{
if (sws_ctx != nullptr)
sws_freeContext(sws_ctx);
if (pFrameRGB != nullptr)
av_frame_free(&pFrameRGB);
if (pFrame != nullptr)
av_frame_free(&pFrame);
if (pCodecCtx != nullptr)
avcodec_free_context(&pCodecCtx);
if (pFormatCtx != nullptr)
avformat_close_input(&pFormatCtx);
if (buffer != nullptr)
delete[] buffer;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel label;
label.show();
if (!openVideo("path/to/your/video.mp4"))
{
qDebug() << "Failed to open video";
return -1;
}
QTimer timer;
QObject::connect(&timer, &QTimer::timeout, [&]() {
AVPacket packet;
while (av_read_frame(pFormatCtx, &packet) >= 0)
{
if (packet.stream_index == pCodecCtx->video_stream_index)
{
avcodec_send_packet(pCodecCtx, &packet);
while (avcodec_receive_frame(pCodecCtx, pFrame) == 0)
{
sws_scale(sws_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
QImage img(pFrameRGB->data[0], pCodecCtx->width, pCodecCtx->height, QImage::Format_RGB888);
label.setPixmap(QPixmap::fromImage(img));
label.adjustSize();
}
}
av_packet_unref(&packet);
}
});
timer.start(33); // 30 FPS
int result = a.exec();
closeVideo();
return result;
}
```
你需要将路径 `path/to/your/video.mp4` 替换为你的H.264视频文件路径。这个示例会在一个Qt窗口中显示视频帧。请注意,你需要通过Qt的一些方法来显示图像,例如使用`QLabel`来显示 `QImage`。
阅读全文