以下是使用FFmpeg库在C++中播放视频并修改分辨率的示例代码:
#include <iostream>
extern "C" {
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
int main() {
// 注册所有的ffmpeg组件
av_register_all();
AVFormatContext* formatCtx = nullptr;
AVCodecContext* codecCtx = nullptr;
SwsContext* swsCtx = nullptr;
const char* inputFilePath = "input.mp4";
// 打开输入文件
if (avformat_open_input(&formatCtx, inputFilePath, nullptr, nullptr) != 0) {
std::cout << "无法打开输入文件" << std::endl;
return -1;
}
// 查找流信息
if (avformat_find_stream_info(formatCtx, nullptr) < 0) {
std::cout << "无法获取流信息" << std::endl;
return -1;
}
int videoStreamIndex = -1;
// 寻找视频流索引
for (unsigned int i = 0; i < formatCtx->nb_streams; ++i) {
if (formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStreamIndex = i;
break;
}
}
if (videoStreamIndex == -1) {
std::cout << "找不到视频流" << std::endl;
return -1;
}
// 获取解码器参数
AVCodecParameters* codecParams = formatCtx->streams[videoStreamIndex]->codecpar;
// 查找解码器
AVCodec* codec = avcodec_find_decoder(codecParams->codec_id);
if (codec == nullptr) {
std::cout << "找不到解码器" << std::endl;
return -1;
}
// 创建解码器上下文
codecCtx = avcodec_alloc_context3(codec);
if (avcodec_parameters_to_context(codecCtx, codecParams) < 0) {
std::cout << "无法为解码器分配参数" << std::endl;
return -1;
}
// 打开解码器
if (avcodec_open2(codecCtx, codec, nullptr) < 0) {
std::cout << "无法打开解码器" << std::endl;
return -1;
}
// 获取源视频宽高
int srcWidth = codecCtx->width;
int srcHeight = codecCtx->height;
// 目标分辨率
int dstWidth = 640;
int dstHeight = 480;
// 创建swsContext以进行图像转换
swsCtx = sws_getContext(srcWidth, srcHeight, codecCtx->pix_fmt,
dstWidth, dstHeight, AV_PIX_FMT_RGB24,
SWS_BILINEAR, nullptr, nullptr, nullptr);
AVPacket packet;
while (av_read_frame(formatCtx, &packet) >= 0) {
if (packet.stream_index == videoStreamIndex) {
AVFrame* frame = av_frame_alloc();
int ret;
// 解码视频帧
ret = avcodec_send_packet(codecCtx, &packet);
if (ret < 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
ret = avcodec_receive_frame(codecCtx, frame);
if (ret < 0 || ret == AVERROR_EOF)
break;
// 图像转换和分辨率修改
AVFrame* convertedFrame = av_frame_alloc();
uint8_t* outBuffer = new uint8_t[dstWidth * dstHeight * 3];
sws_scale(swsCtx, frame->data, frame->linesize,
0, srcHeight, convertedFrame->data, convertedFrame->linesize);
// 在此处进行对图像进行处理,可以修改分辨率、添加滤镜等
// 模拟显示处理后的图像数据
std::cout << "显示处理后的图像数据" << std::endl;
delete[] outBuffer;
av_frame_free(&convertedFrame);
av_frame_free(&frame);
}
av_packet_unref(&packet);
}
// 清理资源
avcodec_close(codecCtx);
avformat_close_input(&formatCtx);
return 0;
}
这段代码打开了一个视频文件并从中提取视频流。然后使用FFmpeg库进行解码,通过sws_scale()函数将原始帧转换为目标分辨率。你可以在“在此处进行对图像进行处理”注释下添加自己的处理逻辑。最后,通过av_frame_free()和avformat_close_input()清理资源。
请注意,上述示例只展示了基本的操作,实际应用中可能需要更多的错误检查和其他参数设置。
内容由零声教学AI助手提供,问题来源于学员提问