将mat编码为h264流, 使用ffmpeg, cpp代码
时间: 2024-05-11 08:14:04 浏览: 230
使用ffmpeg h264解码
以下是使用FFmpeg将Mat编码为H.264流的示例C++代码:
```cpp
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
void encodeMatToH264(cv::Mat& frame, AVFormatContext* formatContext, AVStream* stream, AVCodecContext* codecContext) {
AVFrame* avFrame = nullptr;
uint8_t* buffer = nullptr;
int bufferLength = 0;
// Allocate an AVFrame structure
avFrame = av_frame_alloc();
if (!avFrame) {
throw std::runtime_error("Failed to allocate AVFrame");
}
// Fill the AVFrame with the input frame data
avFrame->width = frame.cols;
avFrame->height = frame.rows;
avFrame->format = AV_PIX_FMT_BGR24;
av_frame_get_buffer(avFrame, 0);
// Convert the input frame to the required pixel format
SwsContext* swsContext = sws_getContext(
frame.cols, frame.rows, AV_PIX_FMT_BGR24,
frame.cols, frame.rows, AV_PIX_FMT_YUV420P,
SWS_BILINEAR, nullptr, nullptr, nullptr);
sws_scale(swsContext, frame.data, frame.step, 0, frame.rows, avFrame->data, avFrame->linesize);
// Allocate a buffer for the output data
bufferLength = av_image_get_buffer_size(codecContext->pix_fmt, codecContext->width, codecContext->height, 1);
buffer = (uint8_t*)av_malloc(bufferLength);
// Allocate an output packet
AVPacket packet;
av_init_packet(&packet);
packet.data = nullptr;
packet.size = 0;
// Encode the frame
int ret = avcodec_send_frame(codecContext, avFrame);
if (ret < 0) {
throw std::runtime_error("Failed to send frame for encoding");
}
while (ret >= 0) {
ret = avcodec_receive_packet(codecContext, &packet);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
}
else if (ret < 0) {
throw std::runtime_error("Error during encoding");
}
// Write the encoded data to the output stream
av_packet_rescale_ts(&packet, codecContext->time_base, stream->time_base);
packet.stream_index = stream->index;
av_interleaved_write_frame(formatContext, &packet);
}
// Free resources
av_frame_free(&avFrame);
av_free(buffer);
av_packet_unref(&packet);
sws_freeContext(swsContext);
}
```
此代码使用FFmpeg将输入的cv::Mat转换为YUV420P格式,然后使用H.264编码器进行编码,并将编码的数据写入输出流中。
阅读全文