ffmpeg mp4转h264 cpp代码
时间: 2023-10-09 08:05:10 浏览: 191
以下是使用FFmpeg库将MP4文件转换为H.264格式视频的C++代码示例:
```cpp
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}
int main(int argc, char *argv[]) {
AVFormatContext *pFormatCtx = NULL;
int videoIndex = -1;
AVCodecContext *pCodecCtx = NULL;
AVCodec *pCodec = NULL;
AVFrame *pFrame = NULL;
AVPacket packet;
int frameFinished;
int numBytes;
uint8_t *buffer = NULL;
struct SwsContext *sws_ctx = NULL;
AVDictionary *optionsDict = NULL;
if (argc < 3) {
std::cout << "Usage: " << argv[0] << " <input file> <output file>" << std::endl;
return -1;
}
av_register_all();
if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0) {
std::cout << "Could not open input file." << std::endl;
return -1;
}
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
std::cout << "Could not find stream information." << std::endl;
return -1;
}
for (int i = 0; i < pFormatCtx->nb_streams; ++i) {
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoIndex = i;
break;
}
}
if (videoIndex == -1) {
std::cout << "Could not find video stream." << std::endl;
return -1;
}
pCodecCtx = avcodec_alloc_context3(NULL);
avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoIndex]->codecpar);
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
std::cout << "Unsupported codec." << std::endl;
return -1;
}
if (avcodec_open2(pCodecCtx, pCodec, &optionsDict) < 0) {
std::cout << "Could not open codec." << std::endl;
return -1;
}
pFrame = av_frame_alloc();
AVFormatContext *outFormatCtx = NULL;
AVStream *outStream = NULL;
AVCodecContext *outCodecCtx = NULL;
AVCodec *outCodec = NULL;
int outVideoIndex = -1;
int outWidth = pCodecCtx->width / 2;
int outHeight = pCodecCtx->height / 2;
outCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!outCodec) {
std::cout << "Unsupported output codec." << std::endl;
return -1;
}
outStream = avformat_new_stream(outFormatCtx, outCodec);
if (!outStream) {
std::cout << "Failed to allocate output stream." << std::endl;
return -1;
}
outCodecCtx = avcodec_alloc_context3(outCodec);
if (!outCodecCtx) {
std::cout << "Failed to allocate output codec context." << std::endl;
return -1;
}
outCodecCtx->codec_id = AV_CODEC_ID_H264;
outCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
outCodecCtx->width = outWidth;
outCodecCtx->height = outHeight;
outCodecCtx->time_base = pCodecCtx->time_base;
outCodecCtx->bit_rate = pCodecCtx->bit_rate;
outCodecCtx->gop_size = 10;
outCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
if (avcodec_open2(outCodecCtx, outCodec, NULL) < 0) {
std::cout << "Failed to open output codec." << std::endl;
return -1;
}
buffer = (uint8_t *) av_malloc(numBytes);
avformat_alloc_output_context2(&outFormatCtx, NULL, NULL, argv[2]);
if (!outFormatCtx) {
std::cout << "Failed to allocate output format context." << std::endl;
return -1;
}
if (avio_open(&outFormatCtx->pb, argv[2], AVIO_FLAG_WRITE) < 0) {
std::cout << "Failed to open output file." << std::endl;
return -1;
}
avformat_new_stream(outFormatCtx, NULL);
avcodec_parameters_from_context(outFormatCtx->streams[0]->codecpar, outCodecCtx);
outStream = outFormatCtx->streams[0];
if (avformat_write_header(outFormatCtx, NULL) < 0) {
std::cout << "Failed to write output file header." << std::endl;
return -1;
}
sws_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
outCodecCtx->width, outCodecCtx->height, outCodecCtx->pix_fmt, SWS_BILINEAR, NULL, NULL, NULL);
while (av_read_frame(pFormatCtx, &packet) >= 0) {
if (packet.stream_index == videoIndex) {
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
if (frameFinished) {
sws_scale(sws_ctx, (const uint8_t *const *) pFrame->data, pFrame->linesize, 0,
pCodecCtx->height, outFrame->data, outFrame->linesize);
outFrame->pts = av_rescale_q(pFrame->pts, pCodecCtx->time_base, outCodecCtx->time_base);
outFrame->pkt_dts = av_rescale_q(pFrame->pkt_dts, pCodecCtx->time_base, outCodecCtx->time_base);
outFrame->pkt_duration = av_rescale_q(pFrame->pkt_duration, pCodecCtx->time_base, outCodecCtx->time_base);
av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;
if (avcodec_send_frame(outCodecCtx, outFrame) < 0) {
std::cout << "Error while sending a frame to the encoder." << std::endl;
return -1;
}
while (1) {
int ret = avcodec_receive_packet(outCodecCtx, &packet);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
else if (ret < 0) {
std::cout << "Error during encoding." << std::endl;
return -1;
}
av_write_frame(outFormatCtx, &packet);
av_packet_unref(&packet);
}
}
}
av_packet_unref(&packet);
}
av_write_trailer(outFormatCtx);
avcodec_free_context(&pCodecCtx);
avformat_close_input(&pFormatCtx);
av_frame_free(&pFrame);
av_free(buffer);
return 0;
}
```
请注意,这只是一个示例代码,并且可能需要进行定制和调整才能适应您的需求。另外,这个代码只是将MP4文件转换为H.264格式视频,如果您需要更高级的功能,例如转换其他格式的视频或更改视频的分辨率、比特率和帧速率等,请查阅FFmpeg文档以获取更多信息。
阅读全文