I'm trying to encode a series of .jpg files into a video using the ffmpeg library, and I can't seem to get the frames to encode. (I have to use the ffmpeg library, and using ffmpeg from a command line is not an option in my case.)
我正在尝试使用ffmpeg库将一系列.jpg文件编码到一个视频中,但我似乎无法让这些帧进行编码。(我必须使用ffmpeg库,使用命令行中的ffmpeg不是我的选项。)
Except for the part where I'm trying to open JPG files as AVFrames, my code is more or less the same thing as found in api-example.c from the ffmpeg library. When I populate the frames as the example does, everything works as expected. In the code below, I fail to encode any frames. Obviously the trouble is related to how I'm opening the JPG files, but I can't figure out what.
除了尝试将JPG文件作为avframe打开的部分之外,我的代码与api示例中的代码差不多。来自ffmpeg库。当我像示例那样填充帧时,一切都按预期运行。在下面的代码中,我没有对任何帧进行编码。很明显,问题在于我如何打开JPG文件,但是我搞不清楚是什么。
I'm opening the image like this:
我这样打开图片:
AVFrame* open_image(const char* imageFileName, int width, int height, long * bufSize)
{
AVFormatContext *pFormatCtx;
if(av_open_input_file(&pFormatCtx, imageFileName, NULL, 0, NULL)!=0)
{
printf("Can't open image file '%s'\n", imageFileName);
return NULL;
}
AVCodecContext *pCodecCtx;
pCodecCtx = pFormatCtx->streams[0]->codec;
pCodecCtx->width = width;
pCodecCtx->height = height;
pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
// Find the decoder for the video stream
AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (!pCodec)
{
printf("Codec not found\n");
return NULL;
}
// Open codec
if(avcodec_open(pCodecCtx, pCodec)<0)
{
printf("Could not open codec\n");
return NULL;
}
AVFrame *pFrame = avcodec_alloc_frame();
if (!pFrame)
{
LOGV(TAG, "Can't allocate memory for AVFrame\n");
return NULL;
}
int frameFinished;
int numBytes;
// Determine required buffer size and allocate buffer
numBytes = avpicture_get_size(PIX_FMT_YUVJ420P, pCodecCtx->width, pCodecCtx->height);
// ***
*bufSize = numBytes;
// ***
uint8_t *buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
avpicture_fill((AVPicture *) pFrame, buffer, PIX_FMT_YUVJ420P, pCodecCtx->width, pCodecCtx->height);
// Read frame
AVPacket packet;
int framesNumber = 0;
while (av_read_frame(pFormatCtx, &packet) >= 0)
{
if(packet.stream_index != 0)
continue;
int ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
if (ret > 0)
{
sprintf(buf, "Frame is decoded, size %d", ret);
LOGV(TAG, buf);
pFrame->quality = 4;
return pFrame;
}
else {
// printf("Error [%d] while decoding frame: %s\n", ret, strerror(AVERROR(ret)));
sprintf(buf, "Error %d decoding frame: %s", ret, strerror(AVERROR(ret)));
LOGV(TAG, buf);
}
}
}
...and attempting to encode them like this:
…试着这样对它们进行编码:
DIR * dir = opendir(path);
int i = 0;
if (dir != NULL) {
for(struct dirent *ent = readdir(dir); ent != NULL; ent = readdir(dir)) {
fflush(stdout);
printf("%s/%s", path, ent->d_name);
LOGV(TAG, filename);
// If not a jpg file, pass it over
const char * ext = strrchr(filename, '.');
if((!ext) || (strcmp(ext, ".jpg"))) {
continue;
}
/*** NOTE: Is this where I've gone wrong? Bufsize is set in open_image based on av_picture_size() */
long bufSize = 0L;
AVFrame * frame = open_image(filename, width, height, &bufSize);
if(frame) {
// This is what it needs to do, and it does not work.
// Causes:
// Wrong format?
// Wrong buffer size?
uint8_t * picBuf = (uint8_t *)malloc(bufSize);
out_size = avcodec_encode_video(c, picBuf, bufSize, frame);
printf("encoding frame %3d (size=%5d)\n", i++, out_size);
/** On the first image, out_size is 0. On the next, it's -1, and fails. */
if(out_size < 0) {
printf("Error encoding frame");
return -6;
}
fwrite(picBuf, 1, bufSize, f);
free(picBuf);
av_free(frame);
}
else {
printf("Couldn't open image");
return -5;
}
}
closedir(dir);
}
else {
printf("Couldn't open directory %s\n", path);
return -4;
}
Could someone point me in the right direction?
有人能给我指出正确的方向吗?
1 个解决方案
#1
1
What exactly is the error you are getting? Examine the Encoding context after opening it to see it's supported pixel formats, you might have to use sws_scale to convert to a format the encoder supports.
你得到的错误是什么?在打开它以查看支持的像素格式之后,检查编码上下文,您可能需要使用sws_scale来转换成编码器支持的格式。
#1
1
What exactly is the error you are getting? Examine the Encoding context after opening it to see it's supported pixel formats, you might have to use sws_scale to convert to a format the encoder supports.
你得到的错误是什么?在打开它以查看支持的像素格式之后,检查编码上下文,您可能需要使用sws_scale来转换成编码器支持的格式。