intel / gstreamer-media-SDK

GNU Lesser General Public License v2.1
90 stars 53 forks source link

Unable to fill buffer from GstPushSrc-style plugin when interacting with gstmfxenc_h264 #173

Open kwende opened 5 years ago

kwende commented 5 years ago

Edit: I'm running into this on Windows 10. Intel Core i7-6700K

This relates to https://github.com/intel/gstreamer-media-SDK/blob/d4edf72ee2975186f11befbb24ea19d404b394fb/gst/mfx/gstmfxvideomemory.c#L236.

Specifically, looking at the map flags, WRITE is not an option. I do not understand how I am to optimally interact with a GstBuffer from a GstPushSrc-derived type, then. If you look at the GstPushSrc documentation here: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstPushSrc.html, there is a .fill() function you may implement. It gets passed to it a GstBuffer which is to be written to, and that buffer is then used by the downstream encoder. I wish to fill it with NV12 data coming directly off my webcam.

If, however, I am connecting my GstPushSrc class to an mfx h264 encoder and wish to interact with the buffer like this:

    FILE* f = fopen("D:/repos/gstreamer_examples/gstreamer_examples/Feynman/feynman.yuv", "rb+");
    fseek(f, 0, SEEK_END); 
    int length = ftell(f); 
    fseek(f, 0, SEEK_SET); 
    GstMapInfo info;
    gst_buffer_map(buffer, &info, GST_MAP_WRITE);
    char* buff = (char*)malloc(length);
    fread(buff, 1, length, f);
    memcpy(info.data, buff, length);
    gst_buffer_unmap(buffer, &info);
    fclose(f);

I cannot as the GST_MAP_WRITE fails. And it fails because of error_unsupported_map in the code I referenced above. In the "standard", off-the-shelf h264 encoder provided as part of the gstreamer plugin collection, the above code works for me. It fails with the Intel plugins. This is presumably because of the fact this is video memory? However, I know in Intel's OpenCL, for example, I'm able to map buffers and write to them from code operating on the CPU (shared memory between the two on-board chips, if I recall).

How can I optimally interact with this GstBuffer from my fill function with these plugins?

kwende commented 5 years ago

Furthermore, if this writability isn't supported, I'm confused by the code here:

https://github.com/intel/gstreamer-media-SDK/blob/d4edf72ee2975186f11befbb24ea19d404b394fb/gst/mfx/gstmfxvideobufferpool.c#L157

I notice the following code:

    if (GST_MFX_IS_VIDEO_MEMORY (mem)) {
      vmeta->map = gst_video_meta_map_mfx_surface;
      vmeta->unmap = gst_video_meta_unmap_mfx_surface;
    }

It looks as though within gst_video_meta_map_mfx_surface there is the following code too:

https://github.com/intel/gstreamer-media-SDK/blob/d4edf72ee2975186f11befbb24ea19d404b394fb/gst/mfx/gstmfxvideomemory.c#L118

  /* Map for writing */
  if (!ensure_surface (mem))
    goto error_ensure_surface;

So it appears as though there is some kind of functionality that allows for writing, and for mapping with the write flag.

ishmael1985 commented 5 years ago

@kwende well observed, write mapping is not supported here. Did you try GST_MAP_READWRITE in your code? Some changes can be done to this module to add mapping with the write flag for MFX surfaces that use system memory, but lately I don't have the time to look into this.