Search code examples
ffmpegjpeg

AV_PIX_FMT_YUVJ422P to jpeg conversion


i am able to convert image from AV_PIX_FMT_YUVJ422P to jpeg format (below Code) but the resultant image having green shade on complete bottom half plz suggest where i am doing wrong. Following step i have taken

  1. Initially i have AV_PIX_FMT_UYVY422 image from camera, i have convert it in AV_PIX_FMT_YUVJ422P format and able to see this image on http://rawpixels.net/ the parameters shown by website is size 2448X2050, Bpp1= 8,Bpp2 = 8 and Bpp3 = 8,alignment 1, SubSampling H =2, and SubSampling V = 1, format: YUV422P so input image is Correct AV_PIX_FMT_YUVJ422P format. & also able to see on "YUV image viewer Software" using YUV422 format.

  2. Now i am trying to convert it in jpeg format using below Code and attached is the resultant Image having green shade on complete bottom half.

        AVFormatContext*    pFormatCtx;
        AVOutputFormat*     fmt;
        AVStream*           video_st;
        AVCodecContext*     pCodecCtx;
        AVCodec*            pCodec;
    
        uint8_t*            picture_buf;
        AVFrame*            picture;
        AVPacket            pkt;
        int                 y_size;
        int                 size;
        int                 got_picture=0;  
        int                 ret=0;
    
    int main( int argc, char* argv[] )
    {
    
        FILE *in_file                       =   NULL;   
        unsigned int        in_width        =   2448;    
        unsigned int        in_height       =   2050;   
        const char* out_file                =   "encoded_pic.jpg";    
    
    
            in_file =   fopen("c:\\test_Planar.yuv","rb");
            if(in_file == NULL) { printf("\n\tFile Opening error...!!"); exit(1); }
            else printf("\n\tYUV File Open Sucessfully...!!\n\n");
    
            av_register_all();  // Loads the whole database of available codecs and formats.
    
            pFormatCtx          =   avformat_alloc_context();           
            fmt             =   NULL;
            fmt             =   av_guess_format("mjpeg",NULL,NULL);
            pFormatCtx->oformat     =   fmt;
    
    //------Output URL-------------------------
    if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0)
    {
        printf("Couldn't open output file.");
        return -1;
    }
    
    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      =   AV_PIX_FMT_YUVJ422P;
    
    //--------------------------MY SOURCE PIXEL FORMAT--------------
    
    pCodecCtx->width        =   in_width;
    pCodecCtx->height       =   in_height;
    
    pCodecCtx->time_base.num = 1;
    pCodecCtx->time_base.den = 1;//25;
    
    //Output some information
    av_dump_format(pFormatCtx, 0, out_file, 1);
    
    // Determine if desired video encoder is installed 
    pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
    
    if (!pCodec)
    {
        printf("Codec not found.");
        return -1;
    }
    
    printf("\nCodec Identified done\n");
    
    if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){
        printf("Could not open codec.\n");
        return -1;
    }
    picture     =   av_frame_alloc();
    size            =   avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
    picture_buf     =   (uint8_t *)av_malloc(size);
    if (!picture_buf)    return -1;
    
    avpicture_fill((AVPicture *)picture, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
    
    printf("\t\nWrite Header..");
    avformat_write_header(pFormatCtx,NULL);
    y_size = pCodecCtx->width * pCodecCtx->height;
    av_new_packet(&pkt,y_size*3);
    
    
    //Read YUV
    if (fread(picture_buf, 1, y_size*3/2, in_file) <=0)
    {
        printf("Could not read input file.");
        return -1;
    }
     //--------------------------------------------input image format UYVY
    picture->data[0] = picture_buf;             // Y
    picture->data[1] = picture_buf+ y_size;         // U
    picture->data[2] = picture_buf+ y_size*5/4;     // V
    //-----------------------------------------------
    
    printf("\t\n Encode the image..\n");
    ret = avcodec_encode_video2(pCodecCtx, &pkt,picture, &got_picture);
    if(ret < 0)
    {
        printf("Encode Error.\n");
        return -1;
    }
    
    if (got_picture==1)
    {
        pkt.stream_index = video_st->index;
        ret = av_write_frame(pFormatCtx, &pkt);
    }
    
    av_free_packet(&pkt);
    //Write Trailer
    av_write_trailer(pFormatCtx);    
    printf("Encode Successful.\n");
    
    if (video_st)
    {
        avcodec_close(video_st->codec);
        av_free(picture);
        av_free(picture_buf);
    }
    
    avio_close(pFormatCtx->pb);
    avformat_free_context(pFormatCtx);    
    
        fclose(in_file);
        printf("\n\tYUV File Close Sucessfully...!!");    
    }
    

Resultant output jpeg encoded image from yuvj422p image having green shade


Solution

  • Changing the input Pixel format from AV_PIX_FMT_YUVJ422P to AV_PIX_FMT_YUVJ420P resolve the issue.