Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
FFmpeg:avcodec_encode_video()和JPEG图像_C_Linux_Video_Ffmpeg_Jpeg - Fatal编程技术网

FFmpeg:avcodec_encode_video()和JPEG图像

FFmpeg:avcodec_encode_video()和JPEG图像,c,linux,video,ffmpeg,jpeg,C,Linux,Video,Ffmpeg,Jpeg,我正在尝试使用ffmpeg库将一系列.jpg文件编码成视频,但似乎无法获得要编码的帧。(我必须使用ffmpeg库,在我的情况下,从命令行使用ffmpeg不是一个选项。) 除了我试图将JPG文件作为AVFrames打开的部分之外,我的代码或多或少与ffmpeg库中的api example.c中的代码相同。当我像示例那样填充框架时,一切都按预期进行。在下面的代码中,我无法对任何帧进行编码。显然,问题与我如何打开JPG文件有关,但我不知道是什么 我像这样打开图像: AVFrame* open_imag

我正在尝试使用ffmpeg库将一系列.jpg文件编码成视频,但似乎无法获得要编码的帧。(我必须使用ffmpeg库,在我的情况下,从命令行使用ffmpeg不是一个选项。)

除了我试图将JPG文件作为AVFrames打开的部分之外,我的代码或多或少与ffmpeg库中的api example.c中的代码相同。当我像示例那样填充框架时,一切都按预期进行。在下面的代码中,我无法对任何帧进行编码。显然,问题与我如何打开JPG文件有关,但我不知道是什么

我像这样打开图像:

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);
        }
    }
}
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;
}
AVFrame*open_image(const char*imageFileName,int-width,int-height,long*bufSize)
{
AVFormatContext*pFormatCtx;
如果(av_打开_输入_文件(&pFormatCtx,imageFileName,NULL,0,NULL)!=0)
{
printf(“无法打开图像文件“%s”\n”,imageFileName);
返回NULL;
}       
AVCodecContext*pCodecCtx;
pCodecCtx=pFormatCtx->streams[0]->编解码器;
PCODECTX->宽度=宽度;
pCodecCtx->height=高度;
pCodecCtx->pix_fmt=pix_fmt_YUV420P;
//查找视频流的解码器
AVCodec*pCodec=AVCodec\u find\u解码器(pCodecCtx->codec\u id);
如果(!pCodec)
{
printf(“未找到编解码器\n”);
返回NULL;
}
//开放式编解码器
如果(avcodec_打开(PCODECTX,pCodec)宽度,PCODECTX->高度);
// ***
*bufSize=numBytes;
// ***
uint8_t*缓冲区=(uint8_t*)av_malloc(numBytes*sizeof(uint8_t));
avpicture_fill((avpicture*)帧、缓冲区、PIX_FMT_YUVJ420P、PCODECTX->宽度、PCODECTX->高度);
//读框
数据包;
int framesNumber=0;
而(av_读取_帧(pFormatCtx和数据包)>=0)
{
if(packet.stream_index!=0)
继续;
int-ret=avcodec\u decode\u video2(pCodecCtx、pFrame、frameFinished和packet);
如果(ret>0)
{
sprintf(buf,“帧已解码,大小%d”,ret);
LOGV(标签,buf);
pFrame->质量=4;
返回帧;
}
否则{
//printf(“解码帧%s时出现错误[%d]”,ret,strerror(AVERROR(ret));
sprintf(buf,“错误%d解码帧:%s”,ret,strerror(AVERROR(ret));
LOGV(标签,buf);
}
}
}
…并尝试这样对它们进行编码:

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);
        }
    }
}
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;
}
DIR*DIR=opendir(路径);
int i=0;
if(dir!=NULL){
for(struct dirent*ent=readdir(dir);ent!=NULL;ent=readdir(dir)){
fflush(stdout);
printf(“%s/%s”,路径,ent->d_名称);
LOGV(标签、文件名);
//如果不是jpg文件,请将其传递过来
常量char*ext=strrchr(文件名“.”);
如果((!ext)| |(strcmp(ext,.jpg))){
继续;
}
/***注意:这是我出错的地方吗?Bufsize是在open_image中根据av_picture_size()设置的*/
长bufSize=0升;
AVFrame*frame=open_图像(文件名、宽度、高度和大小);
如果(帧){
//这是它需要做的,但它不起作用。
//原因:
//格式错误?
//缓冲区大小错误?
uint8_t*picBuf=(uint8_t*)malloc(bufSize);
out_size=avcodec_encode_视频(c、picBuf、bufSize、帧);
printf(“编码帧%3d(大小=%5d)\n”,i++,输出大小);
/**在第一个图像上,out_size为0。在下一个图像上,out_size为-1,并且失败*/
如果(输出尺寸<0){
printf(“错误编码帧”);
返回-6;
}
fwrite(picBuf,1,bufSize,f);
免费(picBuf);
无av_(帧);
}
否则{
printf(“无法打开图像”);
返回-5;
}
}
closedir(dir);
} 
否则{
printf(“无法打开目录%s\n”,路径);
返回-4;
}

有人能给我指出正确的方向吗

您得到的错误到底是什么?打开编码上下文以查看其支持的像素格式后,可能需要使用sws_scale将其转换为编码器支持的格式