gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 23:25:02 24 4
gpt4 key购买 nike

我正在尝试将 CMSampleBufferRef 转换为 AVPacket 并将其写入文件,但不推荐使用 avcodec_encode_video2() 方法,调用新的 API avcodec_receive_packet() 此方法始终返回 AVERROR(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);
}

最佳答案

可以在此处找到用新方法替换已弃用方法的并排示例:https://github.com/ferdymercury/amide/pull/23/files
也有用:https://blog.fearcat.in/a?ID=01000-97990449-e9f9-4b26-839a-b8c4cad60efa

关于FFmpeg 如何使用 avcodec_send_frame() 和 avcodec_receive_packet() 新 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51725454/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com