我正试图学习如何使用FFmpeg的libav库。当我运行我的代码时,它给出了 "无效参数",当我第一次尝试编码一帧。我使用mp4作为输入,输出为mp4。它为什么会给出这个错误的可能性是什么?它在寻找什么参数可能是错误的?
#include <libavformat/avformat.h>
#include <stdio.h>
#include <stdlib.h>
void die(const char *msg)
{
printf("ERROR: %s\n", msg);
exit(1);
}
void checkRC(int rc, const char *msg)
{
if (rc != 0) {
char avErrMsg[1024];
av_strerror(rc, avErrMsg, sizeof(avErrMsg));
int length = strlen(avErrMsg) + strlen(msg) + 2 + 1;
char *errMsg = (char *)malloc(length);
sprintf(errMsg, "%s: %s", msg, avErrMsg);
die(errMsg);
}
}
void checkNull(void *ptr, const char *msg)
{
if (ptr == NULL) {
die(msg);
}
}
char *copyString(const char *str)
{
int length = strlen(str);
char *newStr = (char *)malloc(length + 1);
strcpy(newStr, str);
return newStr;
}
int main(int argc, char const *argv[])
{
argc--;
argv++;
if (argc != 2) {
die("Please give an input file and output file");
}
int rc = 0;
const char *inputFile = argv[0];
const char *outputFile = argv[1];
AVFormatContext *inputFmtCtx = NULL;
AVFormatContext *outputFmtCtx = NULL;
AVIOContext *ioCtx = NULL;
AVStream *inputStream = NULL;
AVStream *outputStream = NULL;
AVCodec *decoder = NULL;
AVCodec *encoder = NULL;
AVCodecContext *inputCodecCtx = NULL;
AVCodecContext *outputCodecCtx = NULL;
AVFrame *frame = NULL;
AVPacket inPacket;
rc = avformat_open_input(&inputFmtCtx, inputFile, NULL, NULL);
checkRC(rc, "Failed to open input format");
rc = avformat_find_stream_info(inputFmtCtx, NULL);
checkRC(rc, "Failed to find input streams");
rc = avio_open(&ioCtx, outputFile, AVIO_FLAG_WRITE);
checkRC(rc, "Failed to open output IO context");
outputFmtCtx = avformat_alloc_context();
checkNull(outputFmtCtx, "Failed to allocate output format context");
outputFmtCtx->pb = ioCtx;
outputFmtCtx->oformat = av_guess_format(NULL, outputFile, NULL);
outputFmtCtx->url = copyString(outputFile);
inputStream = inputFmtCtx->streams[0];
decoder = avcodec_find_decoder(inputStream->codecpar->codec_id);
checkNull(decoder, "Failed to find decoder");
inputCodecCtx = avcodec_alloc_context3(decoder);
checkNull(inputCodecCtx, "Failed to allocate codec context");
rc = avcodec_parameters_to_context(inputCodecCtx, inputStream->codecpar);
checkRC(rc, "Failed to copy parameters to context");
rc = avcodec_open2(inputCodecCtx, decoder, NULL);
checkRC(rc, "Failed to open codec");
outputStream = avformat_new_stream(outputFmtCtx, NULL);
checkNull(outputStream, "Failed to create new stream");
encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
checkNull(encoder, "Failed to find encoder");
outputCodecCtx = avcodec_alloc_context3(encoder);
checkNull(outputCodecCtx, "Failed to allocate encoder context");
outputCodecCtx->bit_rate = inputCodecCtx->bit_rate;
outputCodecCtx->width = inputCodecCtx->width;
outputCodecCtx->height = inputCodecCtx->height;
outputCodecCtx->time_base = (AVRational){1, 25};
outputCodecCtx->framerate = (AVRational){25, 1};
outputCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
outputCodecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
rc = avcodec_parameters_from_context(outputStream->codecpar, outputCodecCtx);
checkRC(rc, "Failed to copy parameters from context");
frame = av_frame_alloc();
checkNull(frame, "Failed to allocate frame");
rc = avformat_write_header(outputFmtCtx, NULL);
checkRC(rc, "Failed to write header");
rc = av_read_frame(inputFmtCtx, &inPacket);
checkRC(rc, "Failed to read frame");
rc = avcodec_send_packet(inputCodecCtx, &inPacket);
checkRC(rc, "Failed to send packet");
rc = avcodec_receive_frame(inputCodecCtx, frame);
checkRC(rc, "Failed to receive frame");
rc = avcodec_send_frame(outputCodecCtx, frame);
checkRC(rc, "Faied to send frame");
return 0;
}