qt ffmpeg C++ 对磁盘指定文件视频进行h264编码
时间: 2023-12-19 18:05:18 浏览: 110
C++ 解析H264文件
要对磁盘上的视频文件进行编码,需要做一些修改以读取视频文件并将编码后的数据写入新的文件中。以下是一个示例代码,演示了如何对指定的视频文件进行编码:
```c++
#include <QtCore/QCoreApplication>
#include <QDebug>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// Open input file
AVFormatContext *inputContext;
avformat_open_input(&inputContext, "input.mp4", NULL, NULL);
avformat_find_stream_info(inputContext, NULL);
// Find video stream
int videoStreamIdx = -1;
for (int i = 0; i < inputContext->nb_streams; i++) {
if (inputContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStreamIdx = i;
break;
}
}
if (videoStreamIdx == -1) {
qWarning() << "No video stream found in input file!";
return -1;
}
// Set up codec parameters
AVCodecParameters *codecParams = inputContext->streams[videoStreamIdx]->codecpar;
codecParams->codec_id = AV_CODEC_ID_H264;
codecParams->bit_rate = 400000;
// Set up output file
AVFormatContext *outputContext;
avformat_alloc_output_context2(&outputContext, NULL, NULL, "output.mp4");
AVStream *outputStream = avformat_new_stream(outputContext, NULL);
outputStream->codecpar = codecParams;
// Open codec
AVCodec *codec = avcodec_find_encoder(codecParams->codec_id);
AVCodecContext *codecContext = avcodec_alloc_context3(codec);
avcodec_parameters_to_context(codecContext, codecParams);
avcodec_open2(codecContext, codec, NULL);
// Open output file
avio_open(&outputContext->pb, "output.mp4", AVIO_FLAG_WRITE);
avformat_write_header(outputContext, NULL);
// Set up scaling context
SwsContext *imgConvertCtx = sws_getContext(codecParams->width, codecParams->height, codecParams->format,
codecParams->width, codecParams->height, codecParams->format,
SWS_BICUBIC, NULL, NULL, NULL);
// Loop through frames
AVPacket *inputPacket = av_packet_alloc();
AVFrame *inputFrame = av_frame_alloc();
AVPacket *outputPacket = av_packet_alloc();
while (av_read_frame(inputContext, inputPacket) >= 0) {
if (inputPacket->stream_index == videoStreamIdx) {
// Decode frame
avcodec_send_packet(codecContext, inputPacket);
avcodec_receive_frame(codecContext, inputFrame);
// Convert frame to codec format
AVFrame *outputFrame = av_frame_alloc();
outputFrame->width = codecParams->width;
outputFrame->height = codecParams->height;
outputFrame->format = codecParams->format;
av_image_alloc(outputFrame->data, outputFrame->linesize, codecParams->width, codecParams->height, codecParams->format, 32);
sws_scale(imgConvertCtx, inputFrame->data, inputFrame->linesize, 0, codecParams->height,
outputFrame->data, outputFrame->linesize);
// Encode frame
avcodec_send_frame(codecContext, outputFrame);
avcodec_receive_packet(codecContext, outputPacket);
// Write encoded frame to output file
av_interleaved_write_frame(outputContext, outputPacket);
// Clean up
av_packet_unref(outputPacket);
av_frame_unref(outputFrame);
}
av_packet_unref(inputPacket);
}
// Flush codec
avcodec_send_frame(codecContext, NULL);
while (avcodec_receive_packet(codecContext, outputPacket) == 0) {
av_interleaved_write_frame(outputContext, outputPacket);
av_packet_unref(outputPacket);
}
// Close codec, input file, output file, and cleanup
avcodec_close(codecContext);
avformat_close_input(&inputContext);
avio_close(outputContext->pb);
avformat_free_context(outputContext);
sws_freeContext(imgConvertCtx);
av_packet_free(&inputPacket);
av_frame_free(&inputFrame);
av_packet_free(&outputPacket);
return a.exec();
}
```
这个示例代码会打开一个名为 "input.mp4" 的视频文件,并将编码数据写入一个名为 "output.mp4" 的新文件中。请注意,这只是一个大致的示例,可能需要根据您的具体情况进行修改。此外,为了简化代码,一些错误检查和异常处理可能被省略了。
阅读全文