簡體   English   中英

YUV到ffmpeg的JPG編碼

[英]YUV to JPG encoding using ffmpeg

我正在嘗試對YVU文件進行編碼並將其另存為jpg文件。 但我不明白以下內容

1.為什么數據包的大小是大小* 3。

av_new_packet(&pkt,size * 3);`

2.為什么我們使用size * 3/2。

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

3,他們如何在這里填充數據

frame-> data [0] =緩沖區;

frame-> data [1] =緩沖區+ siz;

frame-> data [2] =緩沖區+ siz * 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;

我對您上面提供的代碼不太了解。 但是,如果您要對yuv視頻進行編碼並另存為jpeg,則可以在ffmpeg中直接使用以下命令

ffmpeg -f rawvideo -vcodec rawvideo -s <resolution> -r 25 -pix_fmt yuv420p -i video.yuv -preset ultrafast -qp 0 %d.jpg

用視頻的分辨率替換<resolution> ,例如。 1920x1080

如果您查看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個字節。 要查看該代碼,需要附加代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM