数据包(AV_PIX_FMT_UYVY422)到Planar(AV_PIX_FMT_YUVJ422P)格式转换

时间:2017-07-25 09:04:05

标签: visual-c++ ffmpeg packed

我的图片格式为“YUV422_8_UYVY”,其中包含 AV_PIX_FMT_UYVY422 格式,我尝试在平面“ AV_PIX_FMT_YUVJ422P ”中尝试转换,但是尚未成功,下面是我正在工作的代码。

错误消息:使用[swscaler @ 004b3fa0] deprecetd像素格式,确保正确设置了范围

具有0 k大小的结果图像(文件)

av_image_alloc()的最后一个参数,如16,32等转换

我的目标是以平面yuv格式转换数据包yuv图像

    static  AVCodecContext      *pCodecCtx; 
    static  AVFormatContext     *pFormatCtx;
    static  AVCodec             *pCodec;
    static  AVOutputFormat*     fmt;
    static  AVFrame             *RawPic;
    static  AVFrame             *ScalePic;
    static  AVPacket            pkt;
    static  AVStream*           video_st;
    static  FILE                *file;
    static  struct SwsContext   *sws_ctx;

enum    AVPixelFormat       src_pix_fmt     =   AV_PIX_FMT_UYVY422;
enum    AVPixelFormat       dst_pix_fmt     =   AV_PIX_FMT_YUVJ422P;

int main(  ) {

        FILE    *in_file            =   NULL;               //packed Source 
        FILE    *out_file           =   NULL;               //planar output
         int        in_width        =   2448;               //YUV's width 
         int        in_height       =   2050;               //YUV's heigh

         int        out_width       =   2448;               //YUV's width 
         int        out_height      =   2050;               //YUV's heigh


        unsigned long int       ret;

        in_file = fopen("c:\\yuv422_8_uyvy.yuv","rb");      //Source Input File
        if(in_file == NULL) { printf("\n\tinput File Opening error...!!"); exit(1); }



        out_file = fopen("d:\\test_Planar.yuv", "wb");              //Source Input File
        if(out_file == NULL) {  printf("\n\toutput File Opening error...!!"); exit(1); }
        else                 {  printf("\n\tOutput File Created...!!");  }  


//------Loads the whole database of available codecs and formats------
        av_register_all();  
        printf("\t\n\tCodac database Loaded...\n");

//------Contex Variable assignment--------------------------------
        pFormatCtx              =   avformat_alloc_context();       
        fmt                     =   NULL;
        fmt                     =   av_guess_format("mjpeg",NULL,NULL);
        pFormatCtx->oformat     =   fmt;


        video_st = avformat_new_stream(pFormatCtx, 0);  if (video_st==NULL)    return -1;

        pCodecCtx               =   video_st->codec;
        pCodecCtx->codec_id     =   fmt->video_codec;
        pCodecCtx->codec_type   =   AVMEDIA_TYPE_VIDEO;
        pCodecCtx->pix_fmt      =   src_pix_fmt;
        printf("\t\n\tContex Variable assigned...\n");

//------Allocate Source Image Buffer--------------------------------
        AVFrame *RawPic =   av_frame_alloc();   
        if(!RawPic) {   printf("\nCould not allocate Raw Image frame\n");   exit(1);} 
        RawPic->format  =   pCodecCtx->pix_fmt;
        RawPic->width   =   in_width;
        RawPic->height  =   in_height;      
        ret =   av_image_alloc(RawPic->data,RawPic->linesize,in_width,in_height,src_pix_fmt, 16);
        if(ret < 0) {   printf("\nCould not allocate raw picture buffer\n"); exit(1);}
        printf("\n\tAllocate Source Image Buffer");

//------Allocate Desitnation Image Buffer-------------------
        AVFrame *ScalePic   =   av_frame_alloc();
        if(!ScalePic)   {   printf("\nCould not allocate Scale Image frame\n"); exit(1);}       
        ScalePic->format    =   pCodecCtx->pix_fmt;
        ScalePic->width     =   out_width;
        ScalePic->height    =   out_height;     
        ret =   av_image_alloc(ScalePic->data,ScalePic->linesize,out_width,out_height,dst_pix_fmt, 32);
        if(ret < 0) {   printf("\nCould not allocate Scale picture buffer\n"); exit(1);}
        dst_bufsize =   ret;
        printf("\n\tAllocate Destination Image Buffer");


//------Create scaling context------------------------------sws_getContex
        printf("\t\n\tCreating Scaling context..[sws_getContext]\n");

        sws_ctx =   sws_getContext( in_width,       in_height,      src_pix_fmt,
                                    out_width,      out_height,     dst_pix_fmt,
                                    SWS_BICUBIC, NULL, NULL, NULL);
        if(!sws_ctx) { printf("\nContext Error..\n"); }
        printf("\t\n\tScaling context...Created\n");   


//------Create scaling context---OR CONVERTED TO DESTINATION FORMAT--       
        sws_scale(sws_ctx, RawPic->data, RawPic->linesize, 0, in_height, ScalePic->data, ScalePic->linesize);       
        printf("\t\n\tCreating Scaling context...sws_scale...done\n");

        int num_bytes   =   avpicture_get_size(src_pix_fmt,in_width,in_height);
        uint8_t*    ScalePic_Buffer =   (uint8_t *)av_malloc(num_bytes*sizeof(int8_t));     
        avpicture_fill((AVPicture*)ScalePic,ScalePic_Buffer,AV_PIX_FMT_YUVJ422P,out_width,out_height);


//-----Write Scale Image to outputfile----------------------------
        fwrite(ScalePic->data,1,dst_bufsize,out_file);



//---Release all memory and close file----------------------------------
    fclose(in_file);
    fclose(out_file);
    avcodec_close(pCodecCtx);
    av_free(pCodecCtx);
    av_freep(&RawPic->data[0]);
    av_frame_free(&RawPic);
    av_freep(&ScalePic->data[0]);
    av_frame_free(&ScalePic);
    av_frame_free(&RawPic);

    printf("\n\n"); 
    system("PAUSE");
    exit(1);

}

2 个答案:

答案 0 :(得分:0)

你的代码中有很多错误。我可以给你一些关于它们的线索,但是你应该尝试将所有的东西都放下来让它最终发挥作用。

    应删除
  1. dst_bufsize = ret;,否则dst_bufsize将始终为0.
  2. fwrite的第一个参数应该是ScalePic->data[0]而不是ScalePic->data
  3. 您永远不会在fread上致电in_file,这意味着您从未在源图片文件中阅读。
  4. 不要对avpicture_fill使用ScalePic,它会覆盖ScalePic中的内容。
  5. 对于你的问题:

    1. av_image_alloc的最后一个参数是align - 用于缓冲区大小对齐的值。
    2. [swscaler @ 004b3fa0] deprecetd pixel format used, make sure you did set range correctly这不是错误消息,而是警告,不会导致转换失败。

答案 1 :(得分:0)

我已成功使用以下代码

转换平面格式的YUV打包图像
FILE    *in_file    =   NULL;  //fopen("myHexFile.yuv","rb"); input PACKED
FILE    *out_file   =   NULL;  //Output File Planar format

 int    in_width        =   2448;               //YUV's width 
 int    in_height       =   2050;               //YUV's heigh
 int    out_width       =   2448;               //YUV's width 
 int    out_height      =   2050;               //YUV's heigh

int     in_linesize[4];
int     out_linesize[4];
uint8_t     *in_data[4], *out_data[4];

unsigned long int       out_bufsize,in_bufsize;

in_file = fopen("myHexFile.yuv","rb"); //This is YUV422-UYVY Input packed image

if(in_file == NULL) 
{  
this->Print2TextBox1(L"Input File Opening error...!"); 
exit(1); 
}

out_file = fopen("d:\\myHexFile_Planar.yuv", "wb");     //Source Input File
if(out_file == NULL) 
{    
this->Print2TextBox1(L"toutput File Opening error...!!"); 
exit(1); 
}

else  {  this->Print2TextBox1(L"Output File Created...!!\n");  }    

//-Loads the whole database of available codecs and formats-------
    av_register_all();  
    this->Print2TextBox1(L"Codac database Loaded...\n");

//---Create scaling context------------------------sws_getContex
this->Print2TextBox1(L"Creating Scaling context..\n");

sws_ctx =   sws_getContext( in_width, in_height, src_pix_fmt,
                            out_width,out_height,dst_pix_fmt,
                            SWS_BICUBIC, NULL, NULL, NULL);

if(!sws_ctx) { this->Print2TextBox1(L"Context Error..\n"); }



  //--Allocate Source Image Buffer--------------------------
    this->Print2TextBox1(L"Allocate Source Image Buffer...\n");
AVFrame *RawPic =   av_frame_alloc();   
if(!RawPic) 
   {    
   this->Print2TextBox1(L"Could not allocate Raw Image frame\n");   
   exit(1);
   }



RawPic->format  =   src_pix_fmt;
RawPic->width   =   in_width;
RawPic->height  =   in_height;  

int num_bytes1  =   avpicture_get_size(src_pix_fmt,in_width,in_height);
uint8_t* RawPic_Buffer  =   (uint8_t*)av_malloc(num_bytes1*sizeof(int8_t));
ret =av_image_alloc(RawPic->data,in_linesize,in_width,in_height,src_pix_fmt, 1); 

if(ret < 0) 
{   
this->Print2TextBox1(L"Could not allocate raw picture buffer\n"); 
exit(1);
}

in_bufsize  =   ret;
//------Reading Input Image and Store in RawPic->Data Pointer---
fread(RawPic->data[0],1,in_bufsize,in_file);

//----Allocate Desitnation Image Buffer-------------------
this->Print2TextBox1(L"Allocate Destination Image Buffer...\n");

AVFrame *ScalePic   =   av_frame_alloc();

if(!ScalePic)   
{   
this->Print2TextBox1(L"Could not allocate Scale Image frame\n");    
exit(1);
}       

ScalePic->format    =   dst_pix_fmt;//pCodecCtx->pix_fmt;
ScalePic->width     =   out_width;
ScalePic->height    =   out_height;     
int num_bytes2  =   avpicture_get_size(dst_pix_fmt,out_width,out_height);
uint8_t*    ScalePic_Buffer =   (uint8_t *)av_malloc(num_bytes2*sizeof(int8_t));

ret =   av_image_alloc(ScalePic->data,out_linesize,out_width,out_height,dst_pix_fmt, 1); //16

if(ret < 0) {   this->Print2TextBox1(L"Could not allocate Scale picture buffer\n"); exit(1);}
out_bufsize =   ret;

//-Create scaling context-OR CONVERTED TO DESTINATION FORMAT-----sws_scale  
this->Print2TextBox1(L"Creating Scaling context...sws_scale\n");


sws_scale(sws_ctx, RawPic->data, in_linesize, 0, ScalePic->height, ScalePic->data, out_linesize);   

//-----Write Scale Image to outputfile-

    this->Print2TextBox1(L"Write Scale Image to outputfile..\n");
    fwrite(ScalePic->data[0],1,out_bufsize,out_file);

//---Release all memory and close file--
                fclose(in_file);
                fclose(out_file);

        av_freep(&RawPic->data[0]);
        av_freep(&ScalePic->data[0]);

        av_frame_free(&ScalePic);
        av_frame_free(&RawPic);