[FFmpeg-user] How can I convert rbg to yuv420p loseless?

mokacao mokacao at gmail.com
Tue Aug 20 05:11:47 CEST 2013


I generated a test that contains a variety of colors pictures, red/green have
black dot.

Here is part of the core code:

void writeframe( Bitmap^ frame)
{
        libffmpeg::AVOutputFormat* outputFormat =
libffmpeg::av_guess_format( NULL, "test.mp4", NULL );

        if ( !outputFormat )
        {
                outputFormat = libffmpeg::av_guess_format( "mp4", NULL, NULL
);
        }

        libffmpeg::AVFrame*         videoFrame = NULL;
        libffmpeg::AVFormatContext* formatContext =
libffmpeg::avformat_alloc_context( );
        formatContext->oformat = outputFormat;

        libffmpeg::AVCodec *codec =
libffmpeg::avcodec_find_encoder(libffmpeg::CODEC_ID_H264);
        libffmpeg::AVCodecContext* codecContex;
        libffmpeg::AVStream* videoStream = libffmpeg::avformat_new_stream(
formatContext, codec );

        codecContex = videoStream->codec;
        codecContex->codec_id   = libffmpeg::CODEC_ID_H264;
        codecContex->codec_type = libffmpeg::AVMEDIA_TYPE_VIDEO;
        codecContex->bit_rate = 200;
        codecContex->width    = 1024;
        codecContex->height   = 768;
        codecContex->time_base.num = 1;
        codecContex->time_base.den = 25;

        libffmpeg::AVCodecContext* codecContext = videoStream->codec;

        libffmpeg::avcodec_open2( codecContext, codec, NULL );

        libffmpeg::AVFrame* picture;
        void* picture_buf;
        int size;

        picture = libffmpeg::avcodec_alloc_frame( );

        size = libffmpeg::avpicture_get_size( codecContext->pix_fmt,
codecContext->width, codecContext->height );
        picture_buf = libffmpeg::av_malloc( size );

        libffmpeg::avpicture_fill( (libffmpeg::AVPicture *) picture,
(libffmpeg::uint8_t *) picture_buf, codecContext->pix_fmt,
codecContext->width, codecContext->height );

        videoFrame = picture;

        ibffmpeg::SwsContext* swsContext = libffmpeg::sws_getContext( srcW,
srcH, libffmpeg::PIX_FMT_BGRA,codecContext->width, codecContext->height,
libffmpeg::PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);

        BitmapData^ bitmapData = frame->LockBits(
System::Drawing::Rectangle( 0, 0, frame->Width, frame->Height ),
                ImageLockMode::ReadOnly,
                System::Drawing::Imaging::PixelFormat::Format32bppArgb );

        libffmpeg::uint8_t* ptr = reinterpret_cast<libffmpeg::uint8_t*>(
static_cast<void*>( bitmapData->Scan0 ) );

        libffmpeg::uint8_t* srcData[4] = { ptr, NULL, NULL, NULL };
        int srcLinesize[4] = { bitmapData->Stride, 0, 0, 0 };

        libffmpeg::sws_scale( swsContext, srcData, srcLinesize, 0,
frame->Height, videoFrame->data, videoFrame->linesize );

        frame->UnlockBits( bitmapData );

        yuv420p_save(videoFrame, videoStream->codec);

}

void yuv420p_save(libffmpeg::AVFrame *pFrame, libffmpeg::AVCodecContext
*pCodecCtx)
{
        FILE *pfout = NULL;
        char ffrvout[128] = { 0 };
        sprintf(ffrvout, "%s", "c:\\test.yuv"); 

        pfout = fopen(ffrvout, "wb+"); 

        int i = 0;

        int width = pCodecCtx->width, height = pCodecCtx->height;
        int height_half = height / 2, width_half = width / 2;
        int y_wrap = pFrame->linesize[0];
        int u_wrap = pFrame->linesize[1];
        int v_wrap = pFrame->linesize[2];

        unsigned char *y_buf = pFrame->data[0];
        unsigned char *u_buf = pFrame->data[1];
        unsigned char *v_buf = pFrame->data[2];

        //save y
        for (i = 0; i < height; i++)
                fwrite(y_buf + i * y_wrap, 1, width, pfout);
        fprintf(stderr, "===>save Y success\n");
        //save u
        for (i = 0; i < height_half; i++)
                fwrite(u_buf + i * u_wrap, 1, width_half, pfout);
        fprintf(stderr, "===>save U success\n");
        //save v
        for (i = 0; i < height_half; i++)
                fwrite(v_buf + i * v_wrap, 1, width_half, pfout);
        fprintf(stderr, "===>save V success\n");

        fflush(pfout);
        fclose(pfout); 
}

original png file
<http://ffmpeg-users.933282.n4.nabble.com/file/n4660789/P0001.png> 
yuv420p zoom in 4x, use the software yuv
viewer(http://sourceforge.net/projects/yuviewer/), and screenshot
<http://ffmpeg-users.933282.n4.nabble.com/file/n4660789/P0001_yuv_zoom_in_4x.png> 
original png file to yuv420p use above code
P0001.yuv <http://ffmpeg-users.933282.n4.nabble.com/file/n4660789/P0001.yuv>  



--
View this message in context: http://ffmpeg-users.933282.n4.nabble.com/How-can-I-convert-rbg-to-yuv420p-loseless-tp4660765p4660789.html
Sent from the FFmpeg-users mailing list archive at Nabble.com.


More information about the ffmpeg-user mailing list