visual-c++ - 数据包 (AV_PIX_FMT_UYVY422) 到平面 (AV_PIX_FMT_YUVJ422P) 格式转换

标签 visual-c++ ffmpeg packed

我的图片格式是“YUV422_8_UYVY”,打包 AV_PIX_FMT_UYVY422 格式,我是试图转换 它在平面“ AV_PIX_FMT_YUVJ422P ”中,但还不能成功,下面是我正在处理的代码。

错误信息:[swscaler @ 004b3fa0] deprecetd pixel format used,确保你正确设置了范围

具有 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);

}

最佳答案

您在代码中犯了很多错误。我可以给你一些关于它们的线索,但你应该试着把所有的事情都弄清楚,让它最终发挥作用。

  • dst_bufsize = ret;应删除,否则 dst_bufsize将始终为 0。
  • fwrite的第一个参数应该类似于 ScalePic->data[0]而不是 ScalePic->data .
  • 你永远不会调用 freadin_file ,这意味着您永远不会读取源图像文件。
  • 不要使用 avpicture_fill反对ScalePic ,它将覆盖 ScalePic 中的内容.

  • 对于您的问题:
  • av_image_alloc的最后一个参数是 align - 用于缓冲区大小对齐的值。
  • [swscaler @ 004b3fa0] deprecetd pixel format used, make sure you did set range correctly这不是错误消息,而是警告,不会导致转换失败。
  • 关于visual-c++ - 数据包 (AV_PIX_FMT_UYVY422) 到平面 (AV_PIX_FMT_YUVJ422P) 格式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45298631/

    相关文章:

    c++ - SendInput() 发送 '[' 时按下开始按钮 ?? C++

    c++ - 循环中的预递增/递减与使用 gcc 和 Visual C 的递增/递减

    opencv - 修复由 HD Home Run 制作的 TS 文件

    c++ - 如何在 C/C++ 中临时禁用宏扩展?

    c++ - 管理 C++ 项目 - 文件布局、依赖关系和版本控制

    php - 从 php 调用 ffmpeg

    android - ffmpeg 配置时的空过滤器(没有这样的过滤器 'eq' )

    c++ - 具有灵活阵列成员的打包结构的可移植替代方案

    list - PackedArrays 是否有快速的乘积操作?