ffmpeg 硬编码时avcodec_encode_video2返回错误码-11(Resource temporarily unavailable)

用ffmpeg将bmp文件序列编码为h264,使用软编码器AV_CODEC_ID_H264时
程序可以正常运行,换成硬编码器h264_nvenc后,程序有时可以正常运行,但有时会报错,错误现象为:
编码生成的h264文件大小为0KB,avcodec_encode_video2()函数返回错误码-11,使用av_strerror显示错误码映射为“Resource temporarily unavailable”。
换成新的API(avcodec_send_frame和avcodec_receive_packet)后,已经返回-11。程序如下:

#include<stdio.h>
#include<iostream>
#include<afx.h>
using namespace std;
extern"C"
{
#include <libavcodec\avcodec.h>  
#include <libavformat\avformat.h>
#include <libswscale\swscale.h>
#include <libavutil\pixfmt.h>
#include <libavutil\imgutils.h>
#include <libavutil/opt.h>
#include "libavutil/time.h"
}
#define bmpImagePath "F:/laboratory/holiday/bmp2H264/image_bmp1/%03d.bmp" //bmp图像路径
#define H264FilePath "F:/laboratory/holiday/bmp2H264/h264/text.h264"     //H264文件输出路径
const int image_number = 100; //bmp图片数量
int main()
{
    CFile file[image_number + 1000];
    BYTE *szTxt[image_number + 1000];
    int nWidth = 0;
    int nHeight = 0;
    int nDataLen = 0;
    int nLen;
    CString csFileName;
    for (int fileI = 1; fileI <= image_number; fileI++)
    {
        csFileName.Format(bmpImagePath, fileI);
        file[fileI - 1].Open(csFileName, CFile::modeRead | CFile::typeBinary);
        nLen = file[fileI - 1].GetLength();

        szTxt[fileI - 1] = new BYTE[nLen];
        file[fileI - 1].Read(szTxt[fileI - 1], nLen);
        file[fileI - 1].Close();

        BITMAPFILEHEADER bmpFHeader;
        BITMAPINFOHEADER bmpIHeader;
        memcpy(&bmpFHeader, szTxt[fileI - 1], sizeof(BITMAPFILEHEADER));
        int nHeadLen = bmpFHeader.bfOffBits - sizeof(BITMAPFILEHEADER);
        memcpy(&bmpIHeader, szTxt[fileI - 1] + sizeof(BITMAPFILEHEADER), nHeadLen);
        nWidth = bmpIHeader.biWidth;
        nHeight = bmpIHeader.biHeight;
        szTxt[fileI - 1] += bmpFHeader.bfOffBits;
        nDataLen = nLen - bmpFHeader.bfOffBits;
        cout << "fileI:" << fileI << endl;
    }

    av_register_all();
    avcodec_register_all();
    AVFrame *m_pRGBFrame = new AVFrame[1];  //RGB帧数据  
    AVFrame *m_pYUVFrame = new AVFrame[1];;  //YUV帧数据
    AVCodecContext *c = NULL;
    //AVCodecContext *in_c = NULL;
    AVCodec *pCodecH264 = NULL; //编码器
    uint8_t * yuv_buff = NULL;//

                              //查找h264编码器
                              //pCodecH264 = avcodec_find_encoder(AV_CODEC_ID_H264); //软编码器
    pCodecH264 = avcodec_find_encoder_by_name("h264_nvenc"); //硬编码器
    if (!pCodecH264)
    {
        fprintf(stderr, "h264 codec not found\n");
        exit(1);
    }

    c = avcodec_alloc_context3(pCodecH264);
    if (!c) {
        throw exception("avcodec_alloc_context3 failed!");
    }

    c->bit_rate = 3000000;// put sample parameters 
                          //c->bit_rate = 2500000;// put sample parameters
    c->width = nWidth;
    c->height = nHeight;

    AVRational rate;
    rate.num = 1;
    rate.den = 25;
    c->time_base = rate;//(AVRational){1,25};
    c->gop_size = 10; // emit one intra frame every ten frames 
    c->max_b_frames = 1;
    c->thread_count = 1;
    c->pix_fmt = AV_PIX_FMT_YUV420P;//PIX_FMT_RGB24;


    if (avcodec_open2(c, pCodecH264, NULL)<0)   //打开编码器
        TRACE("不能打开编码库");

    int size = c->width * c->height;

    yuv_buff = (uint8_t *)malloc((size * 3) / 2); // size for YUV 420 


    uint8_t * rgb_buff = new uint8_t[nDataLen]; //将rgb图像数据填充rgb帧

                                                //图象编码
                                                //int outbuf_size = 100000000;
    int outbuf_size = nWidth * nHeight * 3;
    uint8_t * outbuf = (uint8_t*)malloc(outbuf_size);
    int u_size = 0;
    FILE *f = NULL;
    char * filename = H264FilePath;
    f = fopen(filename, "wb");
    if (!f)
    {
        TRACE("could not open %s\n", filename);
        exit(1);
    }

    //初始化SwsContext
    SwsContext * scxt = sws_getContext(c->width, c->height, AV_PIX_FMT_BGR24, c->width, c->height, AV_PIX_FMT_YUV420P, SWS_POINT, NULL, NULL, NULL);

    AVPacket avpkt;

    //AVFrame *pTFrame=new AVFrame
    int num = 0;
    long long int vpts = 0;

    for (int i = 0; i< image_number; ++i)
    {

        int index = i;
        memcpy(rgb_buff, szTxt[index], nDataLen);

        avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, AV_PIX_FMT_RGB24, nWidth, nHeight);

        //将YUV buffer 填充YUV Frame
        avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, AV_PIX_FMT_YUV420P, nWidth, nHeight);

        // 翻转RGB图像
        m_pRGBFrame->data[0] += m_pRGBFrame->linesize[0] * (nHeight - 1);
        m_pRGBFrame->linesize[0] *= -1;
        m_pRGBFrame->data[1] += m_pRGBFrame->linesize[1] * (nHeight / 2 - 1);
        m_pRGBFrame->linesize[1] *= -1;
        m_pRGBFrame->data[2] += m_pRGBFrame->linesize[2] * (nHeight / 2 - 1);
        m_pRGBFrame->linesize[2] *= -1;


        //将RGB转化为YUV
        sws_scale(scxt, m_pRGBFrame->data, m_pRGBFrame->linesize, 0, c->height, m_pYUVFrame->data, m_pYUVFrame->linesize);
        int got_packet_ptr = 0;
        av_init_packet(&avpkt);
        avpkt.data = outbuf;
        avpkt.size = outbuf_size;
        //m_pYUVFrame->pts = vpts;
        /*u_size = avcodec_send_frame(c, m_pYUVFrame);
        if (u_size != 0)
        {
            char errorbuf[1024] = { 0 };
            av_strerror(u_size, errorbuf, sizeof(errorbuf));
            cout << "error number:" << u_size << "avcodec_send_frame error:" << errorbuf << endl;
        }
        u_size = avcodec_receive_packet(c, &avpkt);
        if (u_size != 0)
        {
            char errorbuf[1024] = { 0 };
            av_strerror(u_size, errorbuf, sizeof(errorbuf));
            cout << "error number:"<< u_size << " avcodec_receive_packet error:" << errorbuf << endl;
        }*/
        u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr);
        if (u_size != 0)
        {
            char errorbuf[1024] = { 0 };
            av_strerror(u_size, errorbuf, sizeof(errorbuf));
            cout << "error number:" << u_size << "avcodec_encode_video2 error:" << errorbuf << endl;
        }
        m_pYUVFrame->pts++;
        //cout << "encode frame" << index + 1 << " successfully!" << endl;
        cout << "u_size:" << u_size << endl;
        if (u_size == 0)
        {
            cout << "encode frame" << index + 1 << " successfully!" << endl;
            cout << "*************" << ++num << "************" << endl;
            fwrite(avpkt.data, 1, avpkt.size, f);
        }
        //vpts++;
        else
        {
            avcodec_send_packet(c, &avpkt);
        }
    }
    cout << "nWidth" << nWidth << endl;
    cout << "nHeight" << nHeight << endl;
    fclose(f);
    delete[]m_pRGBFrame;
    delete[]m_pYUVFrame;
    delete[]rgb_buff;
    free(outbuf);
    free(yuv_buff);
    avcodec_close(c);
    av_free(c);
    //avcodec_free_context(&c);
    system("pause");

    return 0;
}

错误结果截图如下:
图片说明

c++
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问