[Libav-user] Colour space conversion

wm4 nfxjfg at googlemail.com
Wed May 27 14:59:18 CEST 2015


On Wed, 27 May 2015 12:25:29 +0000
Jasleen Kaur <Jasleen at beesys.com> wrote:

> We have ARGB buffer to be compressed and then decoded also.
> But for encoding the data the input as ARGB wasnt accepted.
> The data was converted to YUV and then compressed, and on the receive side decoded and then converted back to ARGB.
> 
> The problem is that, While this conversion happens colours change.
> 
> Following is the code used to convert from ARGB to YUV and YUV to ARGB respectively.
> 
> 
> void ConvertToYUV(int iWidth, int iHeight, BYTE* pARGBBuff)
> {
> #define RNDTO2(X) ( ( (X) & 0xFFFFFFFE )
> #define RNDTO32(X) ( ( (X) % 32 ) ? ( ( (X) + 32 ) & 0xFFFFFFE0 ) : (X) )
> 
> //int ystride  = RNDTO32 ( iWidth );
>     //int uvstride = RNDTO32 ( iWidth / 2 );
> int ystride  = iWidth;
>     int uvstride = iWidth / 2;
>     int ysize    = ystride * iHeight;
>     int vusize   = uvstride * ( iHeight / 2 );
>     int size     = ysize + ( 2 * vusize );
> 
> if(m_sws_ctx == NULL)
> {
> //SwsFilter
> m_sws_ctx = sws_getContext(iWidth,
> iHeight,
> AV_PIX_FMT_BGRA,
> iWidth, iHeight,
> AV_PIX_FMT_YUV420P,
> SWS_FAST_BILINEAR, 0, 0, 0);
> 
> m_picture_buf = (uint8_t*)malloc(size);
> }
>     //uint8_t *plane[] = { m_picture_buf, m_picture_buf + ysize, m_picture_buf + ysize + vusize};
> uint8_t *plane[] = { m_picture_buf, m_picture_buf + ysize + vusize, m_picture_buf + ysize};
>     int stride[] = { ystride, uvstride, uvstride};
> 
> uint8_t *inData[1] = { pARGBBuff };
>     int inLinesize[1] = { 4 * iWidth};
> 
>     sws_scale(m_sws_ctx, inData, inLinesize, 0, iHeight, plane, stride);
> }
> 
> void ConvertToARGB(int iWidth, int iHeight)
> {
> #define RNDTO2(X) ( ( (X) & 0xFFFFFFFE )
> #define RNDTO32(X) ( ( (X) % 32 ) ? ( ( (X) + 32 ) & 0xFFFFFFE0 ) : (X) )
> 
> int iSize = iWidth * iHeight * 4;
> int ystride  = RNDTO32 ( iWidth );
>     int uvstride = RNDTO32 ( iWidth / 2 );
>     int ysize    = ystride * iHeight;
>     int vusize   = uvstride * ( iHeight / 2 );
> 
> 
> if(m_sws_ctx == NULL)
> {
> //SwsFilter
> m_sws_ctx = sws_getContext(iWidth,
> iHeight,
> AV_PIX_FMT_YUV420P,
> iWidth, iHeight,
> AV_PIX_FMT_BGRA,
> SWS_FAST_BILINEAR, 0, 0, 0);
> 
> m_picture_buf = (uint8_t*)malloc(iSize);
> }
> // src
> int srcstride[] = {ystride, uvstride, uvstride};
> 
> // dest
> uint8_t *destplane[] = {m_picture_buf};
>     int stride[] = { iWidth * 4};
>     int iHeightReturned = sws_scale(m_sws_ctx, m_picture->data, srcstride, 0, iHeight, destplane, stride);
> 
>   m_picture is the output of avcodec_decode_video2.
> }
> 
> 
> What correction needs to be done in the code, so that colours remain intact.
> 
> Thanks and regards
> Jasleen

AVFrame contains the correct strides in the linesize field. Also, if
you pass data pointers to libav* APIs, you typically need to align
them, which e.g. av_malloc() does.


More information about the Libav-user mailing list