SFML community forums

General => Feature requests => Topic started by: danverde on June 29, 2015, 09:25:38 pm

Title: Image non const getPixelsPtr
Post by: danverde on June 29, 2015, 09:25:38 pm
I would like to see a non-const getPixelsPtr method so that I can load the image data directly from another API.
I set the image size with the create method, I then would like to pass the address return by getPixelsPtr to the ffmpeg image convert methods so that it loads my image directly.  Currently I have to create a temporary location and then call he loadfrommemory  This results in an extra memcpy that I would like to avoid.  I would like to pass the getPixelsPtr directly into the avpicture_fill method directly.  Below is how I would use it.

thoughts?

  IMAGE_PTR_T pImage = m_ImageCache.create(dPTS,
    m_pAVStrm->codec->width, m_pAVStrm->codec->height);

  ffmpeg::avpicture_fill(&pict, pImage->image.getPixelsPtr(), ffmpeg::PIX_FMT_RGBA,
    m_pAVStrm->codec->width, m_pAVStrm->codec->height);

  m_pImgConvertCtx = ffmpeg::sws_getCachedContext(m_pImgConvertCtx,
    m_pAVStrm->codec->width, m_pAVStrm->codec->height, m_pAVStrm->codec->pix_fmt, // src size / fmt
    m_pAVStrm->codec->width, m_pAVStrm->codec->height, ffmpeg::PIX_FMT_RGBA, // dest size / fmt
    SWS_FAST_BILINEAR, NULL, NULL, NULL);
  if (m_pImgConvertCtx == 0)
  {
    throw std::runtime_error("Cannot initialize the conversion context");
  }

  sws_scale(m_pImgConvertCtx, pFrame->data, pFrame->linesize,
    0, m_pAVStrm->codec->height, pict.data, pict.linesize);
 
Title: Re: Image non const getPixelsPtr
Post by: eXpl0it3r on June 30, 2015, 08:27:11 pm
Create your own vector of Uint8 and then pass the data() pointer to the FFmpeg and Image class. Actually if you want to draw said image and thus need to upload it to the GPU, you can call update() on a texture directly with your pixel vector. That way you avoid the copy and go straight to the GPU which will always require a data transfer from RAM to VRAM.

Also depending on what you want to do, you might want to checkout already created libraries (https://github.com/SFML/SFML/wiki/Projects#video) which use FFmpeg.
Title: Re: Image non const getPixelsPtr
Post by: danverde on July 01, 2015, 02:28:41 am
Is there a sf::Image method that will use my data pointer directly without doing a memcpy into it's internal vector?  I don't see one.  I am hoping to avoid this extra memcpy as I am decompressing many frames and do not want the extra overhead of the extra memcpy.

from Image.cpp
////////////////////////////////////////////////////////////
void Image::create(unsigned int width, unsigned int height, const Uint8* pixels)
{
    if (pixels && width && height)
    {
        ...
       I want to avoid the step below

        // Copy the pixels
        std::size_t size = width * height * 4;
        m_pixels.resize(size);
        std::memcpy(&m_pixels[0], pixels, size); // faster than vector::assign
    }
    else
    ...
 
Title: Re: Image non const getPixelsPtr
Post by: eXpl0it3r on July 01, 2015, 09:43:43 am
Did you read what I wrote?

You don't need to use an sf::Image. Work with your own vector of Uint8 and once filled, pass it to the texture via update().
Title: Re: Image non const getPixelsPtr
Post by: dabbertorres on July 01, 2015, 10:46:01 pm
As I understand it, he is wanting to manually decompress into the Image/Texture/etc.

Rather than decompress to a vector/array/etc, then pass the decompressed array into the Image/Texture to be copied.
Title: Re: Image non const getPixelsPtr
Post by: eXpl0it3r on July 01, 2015, 11:27:40 pm
I understood that, that's why I said he can "decompress" into his own vector of Uint8 and then pass that to the texture's update method. ;)
Title: Re: Image non const getPixelsPtr
Post by: danverde on July 02, 2015, 06:19:49 am
I did read what you wrote, but I miss understood that you meant write it directly to the texture, skipping the image altogether.  Thanks, the piece I have been missing.