c++ - 使用 ffmpeg 进行 YUV 到 JPG 编码

标签 c++ ffmpeg multimedia

我正在尝试对 YVU 文件进行编码并将其保存为 jpg 文件。但我不明白以下内容

1.为什么包大小是size*3。

av_new_packet(&pkt,size*3);`

2.为什么我们使用size*3/2。

if(fread(buffer, 1, size*3/2, ptrInputFile)<=0)`

3.他们如何在这里填写数据

帧->数据[0] = 缓冲区;

帧->数据[1] = 缓冲区 + 大小;

帧->数据[2] = 缓冲区 + 大小 * 5/4;

代码:

AVFormatContext *avFrameContext;
AVOutputFormat *avOutputFormat;
AVStream *avStream;
AVCodecContext *avCodecContext;
AVCodec *avCodec;
AVFrame *frame;
AVPacket pkt;

const char *output = "temp.jpg";
FILE *ptrInputFile;
const char *input = "cuc_view_480x272.yuv";

ptrInputFile = fopen(input ,"rb");
if(!ptrInputFile)
    return -1;

avFrameContext = avformat_alloc_context();
avOutputFormat = av_guess_format("mjpeg", NULL, NULL);
if(!avOutputFormat)
    return -1;
avFrameContext->oformat = avOutputFormat;

if(avio_open(&avFrameContext->pb ,output ,AVIO_FLAG_READ_WRITE)<0)
    return -1;


avStream = avformat_new_stream(avFrameContext,NULL);
if(!avStream)
    return -1;

avCodecContext = avStream->codec;
avCodecContext->codec_id = avOutputFormat->video_codec;
avCodecContext->codec_type = AVMEDIA_TYPE_VIDEO;
avCodecContext->pix_fmt = PIX_FMT_YUVJ420P;

avCodecContext->width = 480;
avCodecContext->height = 272;
avCodecContext->time_base.num = 1;
avCodecContext->time_base.den = 25;

avCodec = avcodec_find_encoder(avCodecContext->codec_id);

if(!avCodec)
    return -1;


if(avcodec_open2(avCodecContext ,avCodec,NULL)<0)
    return -1;

frame = av_frame_alloc();
int size = avpicture_get_size(PIX_FMT_YUVJ420P ,avCodecContext->width, avCodecContext->height);
uint8_t *buffer = (uint8_t*)av_malloc(size*sizeof(uint8_t));

avpicture_fill((AVPicture*)frame, buffer, avCodecContext->pix_fmt ,avCodecContext->width, avCodecContext->height);


//write header
avformat_write_header(avFrameContext, NULL);

int siz = avCodecContext->width*avCodecContext->height;

av_new_packet(&pkt,siz*3);

if(fread(buffer , 1, siz*3/2, ptrInputFile)<=0)
    return -1;

frame->data[0] = buffer;
frame->data[1] = buffer + siz;
frame->data[2] = buffer + siz*5/4;

最佳答案

如果您查看 yuv420p ( wiki ) 的格式,则文件中的数据格式为:

As there are 'siz' length of pixels in the image:
siz length of y value
siz/4 length of u value
siz/4 length of v value

所以对于问题 2:我们有 siz*3/2 长度的数据要读取。

对于问题3:y从buffer+0开始,u从buffer+siz开始,v从buffer+siz*5/4开始。

至于问题1:我不确定数据是否转换为RGB。如果它被转换,那么每个像素需要 3 个字节。需要额外的代码才能看到。

关于c++ - 使用 ffmpeg 进行 YUV 到 JPG 编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35388903/

相关文章:

c++ - 对 OOLUA::Proxy_class<T>::class_name 的 undefined reference

php - 是否可以使用ffmpeg读取php中的mp3 id3标签?如果是这样那怎么办?

plugins - ffmpeg Windows : how to run ffmpeg -i input -filter:v frei0r=pixeliz0r=0. 02 :0. 02 输出

c++ - ffmpeg 将无效的 fps 写入 mp4 容器(在 avi 中它是真的)。是什么原因?

c++ - 更改 .exe 文件版本(来自 C++ 项目)

c++ - 从 16UC3 到 8UC3 的高性能 OpenCV 矩阵转换

c++ - 使用 Vulkan 信号量等待 vkCmdCopyBuffer

audio - 我怎样才能生成qcelp

actionscript-3 - 如何从 Actionscript 3.0 使多个视频剪辑同时播放

delphi - Delphi中模拟多媒体按键