[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