2016-02-14 89 views
0

我想編碼YVU文件並將其保存爲jpg文件。但我不明白以下內容YUV到JPG編碼使用ffmpeg

1.爲什麼數據包大小是大小* 3。

av_new_packet(& PKT,大小* 3);爲什麼我們使用尺寸* 3/2`

2.In的fread。

如果(的fread(緩衝液,1,尺寸* 3/2,ptrInputFile)< = 0)`

3.how他們在這裏的填充數據

幀 - >數據[0] =緩衝器;

frame-> data [1] = buffer + siz;

frame-> data [2] = buffer + 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; 

回答

0

如果你看一下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從緩衝區+ 0開始,u從緩衝區+ siz開始,並且v從緩衝區+ siz * 5/4開始。

至於問題1:我不確定數據是否轉換爲RGB。如果它被轉換,那麼每個像素需要3個字節。需要額外的代碼才能看到。

0

我不知道很多關於你上面提供的代碼。但是,如果你正在嘗試編碼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>。 1920×1080

+0

我剛更新了代碼。請看看,我正在使用C++ – Jeggu