我无法从正在读取到iOS FFmpeg项目的框架中获取UIImage。我需要能够读取框架,然后将其转换为UIImage以便在UIImageView中显示框架。我的代码似乎在阅读框架,但是我对如何转换它们迷失了,因为有关如何执行此操作的文档很少。有人可以帮忙吗?
while (!finished) {
if (av_read_frame(_formatContext, &packet) >= 0) {
if (packet.stream_index == _videoStream) {
int ret = avcodec_send_packet(_codecContext, &packet);
if (ret < 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
printf("av_codec_send_packet error ");
}
while (ret >= 0) {
ret = avcodec_receive_frame(_codecContext, _frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
printf("avcodec_receive_frame error ");
}
finished = true;
}
}
av_packet_unref(&packet);
}
}
答案 0 :(得分:0)
您应该了解rgb和yuv等像素格式。视频几乎总是使用yuv格式(例如yuv420p)。然后研究AVFrame结构,这里有一些信息:
AVFormat.format
:当前帧的像素格式,即AV_PIX_FMT_YUV420P
AVFormat.width
:当前帧的水平长度(因此宽度)单位:像素
AVFormat.height
:当前帧的垂直长度(因此高度)单位:像素
现在您可能要问的实际帧缓冲区在哪里,它在AVFormat.data[n]
中
n可以为0-3。根据格式,仅第一个可能包含整个框架或全部四个框架。即yuv420p使用0、1和2。可以通过读取相应的AVFormat.linesize[n]
值来获得其线距(也称为步幅)。
至于yuv420p:
data[0]
是Y平面
data[1]
是U平面
data[2]
是V平面
如果将linesize[0]
与AVFrame.height
相乘,您将获得该平面的大小(Y)作为字节数。
我不知道UIImage结构(或其任何形式),如果它需要RGB之类的特定格式,则需要使用swscale
将AVFrame转换为该格式。
以下是一些示例:https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/scaling_video.c
在libav(ffmpeg)中,缩放(调整大小)和像素格式转换是通过相同的功能完成的。
希望这些帮助。