FFmpeg如何使用avcodec_send_frame()和avcodec_receive_packet()新API

FFmpeg如何使用avcodec_send_frame()和avcodec_receive_packet()新API,ffmpeg,Ffmpeg,我正在尝试将CMSampleBufferRef转换为AVPacket并将其写入文件,但avcodec_encode_video2()方法已被弃用,请调用新API avcodec_receive_packet()。此方法始终返回Averor(EAGAIN),如何使用此API 这是我的密码: - (void)encodeFrameWithSampleBufferRef:(CMSampleBufferRef)sampleBuffer { CVImageBufferRef imageBuffer

我正在尝试将CMSampleBufferRef转换为AVPacket并将其写入文件,但avcodec_encode_video2()方法已被弃用,请调用新API avcodec_receive_packet()。此方法始终返回Averor(EAGAIN),如何使用此API

这是我的密码:

- (void)encodeFrameWithSampleBufferRef:(CMSampleBufferRef)sampleBuffer {
    CVImageBufferRef imageBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer);

    if (CVPixelBufferLockBaseAddress(imageBufferRef, 0) == kCVReturnSuccess) {

        UInt8 *bufferYPtr = (UInt8 *)CVPixelBufferGetBaseAddressOfPlane(imageBufferRef, 0);
        UInt8 *bufferUVPtr = (UInt8 *)CVPixelBufferGetBaseAddressOfPlane(imageBufferRef, 1);

        size_t realWidth = CVPixelBufferGetWidth(imageBufferRef);
        size_t realHeight = CVPixelBufferGetHeight(imageBufferRef);
        size_t yBytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBufferRef, 0);
        size_t uvBytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBufferRef, 1);

        UInt8 *dateYUV420 = (UInt8 *)malloc(realWidth * realHeight * 3 / 2);
        UInt8 *pU = dateYUV420 + realWidth * realHeight;
        UInt8 *pV = pU + realWidth * realHeight * 1 / 4;

        for (int i = 0; i < realHeight; i++) {
            memcpy(dateYUV420 + i * realWidth, bufferYPtr + i * yBytesPerRow, realWidth);
        }
        for (int i = 0; i < realHeight / 2; i++) {
            for (int j = 0; j < realWidth / 2; j++) {
                *(pU++) = bufferUVPtr[j<<1];
                *(pV++) = bufferUVPtr[((j<<1) + 1)];
            }
            bufferUVPtr += uvBytesPerRow;
        }

        _frame -> data[0] = dateYUV420;
        _frame -> data[1] = dateYUV420 + realWidth * realHeight;
        _frame -> data[2] = dateYUV420 + realWidth * realHeight + realWidth * realHeight * 1 / 4;
        _frame -> width = (CGFloat)realWidth;
        _frame -> height = (CGFloat)realHeight;
        _frame -> format = AV_PIX_FMT_YUV420P;

        // encode
        int ret = avcodec_send_frame(_codecContext, _frame);
        if (ret < 0) {
            fprintf(stderr, "Error sending a frame for encoding\n");
            exit(1);
        }
        while (ret >= 0) {
            ret = avcodec_receive_packet(_codecContext, &_packet);
            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                return;
            } else if (ret < 0) {
                fprintf(stderr, "Error during encoding\n");
                exit(1);
            }
            av_write_frame(_formatContext, &_packet);
            av_packet_unref(&_packet);
        }

        free(dateYUV420);
    }

    CVPixelBufferUnlockBaseAddress(imageBufferRef, 0);
}
-(void)encodeFrameWithSampleBufferRef:(CMSampleBufferRef)sampleBuffer{
CVImageBufferRef imageBufferRef=CMSampleBufferGetImageBuffer(sampleBuffer);
if(CVPixelBufferLockBaseAddress(imageBufferRef,0)=kCVReturnSuccess){
UInt8*bufferYPtr=(UInt8*)CVPixelBufferGetBaseAddressOfPlane(imageBufferRef,0);
UInt8*bufferUVPtr=(UInt8*)CVPixelBufferGetBaseAddressOfPlane(imageBufferRef,1);
大小\u t realWidth=CVPixelBufferGetWidth(imageBufferRef);
size\u t realHeight=CVPixelBufferGetHeight(imageBufferRef);
size_t yBytesPerRow=CVPixelBufferGetBytesPerrowof平面(imageBufferRef,0);
size_t uvBytesPerRow=cvpixelbuffergetbytesperowof平面(imageBufferRef,1);
UInt8*dateYUV420=(UInt8*)malloc(realWidth*realHeight*3/2);
UInt8*pU=dateYUV420+realWidth*realHeight;
UInt8*pV=pU+realWidth*realHeight*1/4;
for(int i=0;i高度=(CGFloat)真实高度;
_帧->格式=AV\U PIX\U FMT\U YUV420P;
//编码
int-ret=avcodec\u send\u frame(\u codecContext,\u frame);
如果(ret<0){
fprintf(stderr,“发送编码帧时出错”);
出口(1);
}
而(ret>=0){
ret=avcodec_接收_数据包(_编解码器上下文,&_数据包);
如果(ret==AVERROR(EAGAIN)| | ret==AVERROR_EOF){
返回;
}否则如果(ret<0){
fprintf(stderr,“编码过程中出错\n”);
出口(1);
}
av写入帧(格式化上下文和数据包);
av_数据包&u unref(&u数据包);
}
免费(dateYUV420);
}
CVPixelBufferUnlockBaseAddress(imageBufferRef,0);
}

1.尝试为
\u帧设置增量pts
.2.使用默认编码参数时,编码器通常会在开始时返回几十个
EAGAIN
s。谢谢,我将尝试您的答案