static void update_image (APP_STATE_T * state, GstBuffer * buffer) { GstVideoGLTextureUploadMeta *meta = NULL; if (state->current_buffer) { gst_buffer_unref (state->current_buffer); } else { /* Setup the model world */ init_model_proj (state); TRACE_VC_MEMORY ("after init_model_proj"); /* initialize the OGLES texture(s) */ init_textures (state, buffer); TRACE_VC_MEMORY ("after init_textures"); } state->current_buffer = gst_buffer_ref (buffer); TRACE_VC_MEMORY_ONCE_FOR_ID ("before GstVideoGLTextureUploadMeta", gid0); if (state->can_avoid_upload) { GstMemory *mem = gst_buffer_peek_memory (state->current_buffer, 0); g_assert (gst_is_gl_memory (mem)); state->tex = ((GstGLMemory *) mem)->tex_id; } else if ((meta = gst_buffer_get_video_gl_texture_upload_meta (buffer))) { if (meta->n_textures == 1) { guint ids[4] = { state->tex, 0, 0, 0 }; if (!gst_video_gl_texture_upload_meta_upload (meta, ids)) { GST_WARNING ("failed to upload to texture"); } } } TRACE_VC_MEMORY_ONCE_FOR_ID ("after GstVideoGLTextureUploadMeta", gid1); }
/** * gst_gl_memory_pbo_download_transfer: * @gl_mem: a #GstGLMemoryPBO * * Transfer the texture data from the texture into the PBO if necessary. * * Since: 1.8 */ void gst_gl_memory_pbo_download_transfer (GstGLMemoryPBO * gl_mem) { g_return_if_fail (gst_is_gl_memory ((GstMemory *) gl_mem)); gst_gl_context_thread_add (gl_mem->mem.mem.context, (GstGLContextThreadFunc) _download_transfer, gl_mem); }
/** * gst_gl_memory_pbo_download_transfer: * @gl_mem: a #GstGLMemoryPBO * * Transfer the texture data from the PBO into the texture if necessary. * * Since: 1.8 */ void gst_gl_memory_pbo_upload_transfer (GstGLMemoryPBO * gl_mem) { g_return_if_fail (gst_is_gl_memory ((GstMemory *) gl_mem)); if (gl_mem->pbo && CONTEXT_SUPPORTS_PBO_UPLOAD (gl_mem->mem.mem.context)) gst_gl_context_thread_add (gl_mem->mem.mem.context, (GstGLContextThreadFunc) _upload_transfer, gl_mem); }
gboolean gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf) { guint i; GList *walk; guint out_tex; gboolean res = TRUE; guint array_index = 0; GstVideoFrame out_frame; gboolean out_gl_wrapped = FALSE; GstElement *element = GST_ELEMENT (mix); GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix); GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix); GstGLMixerPrivate *priv = mix->priv; GST_TRACE ("Processing buffers"); if (!gst_video_frame_map (&out_frame, &vagg->info, outbuf, GST_MAP_WRITE | GST_MAP_GL)) { return FALSE; } if (gst_is_gl_memory (out_frame.map[0].memory)) { out_tex = *(guint *) out_frame.data[0]; } else { GST_INFO ("Output Buffer does not contain correct memory, " "attempting to wrap for download"); out_tex = mix->out_tex_id;; if (!mix->download) mix->download = gst_gl_download_new (mix->context); gst_gl_download_set_format (mix->download, &out_frame.info); out_gl_wrapped = TRUE; } GST_OBJECT_LOCK (mix); walk = element->sinkpads; i = mix->frames->len; g_ptr_array_set_size (mix->frames, element->numsinkpads); for (; i < element->numsinkpads; i++) mix->frames->pdata[i] = g_slice_new0 (GstGLMixerFrameData); while (walk) { GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data); GstVideoAggregatorPad *vaggpad = walk->data; GstGLMixerFrameData *frame; frame = g_ptr_array_index (mix->frames, array_index); frame->pad = pad; frame->texture = 0; walk = g_list_next (walk); if (vaggpad->buffer != NULL) { guint in_tex; if (!pad->upload) { pad->upload = gst_gl_upload_new (mix->context); gst_gl_upload_set_format (pad->upload, &vaggpad->info); } if (!gst_gl_upload_perform_with_buffer (pad->upload, vaggpad->buffer, &in_tex)) { ++array_index; pad->mapped = FALSE; continue; } pad->mapped = TRUE; frame->texture = in_tex; } ++array_index; } g_mutex_lock (&priv->gl_resource_lock); if (!priv->gl_resource_ready) g_cond_wait (&priv->gl_resource_cond, &priv->gl_resource_lock); if (!priv->gl_resource_ready) { g_mutex_unlock (&priv->gl_resource_lock); GST_ERROR_OBJECT (mix, "fbo used to render can't be created, do not run process_textures"); res = FALSE; goto out; } mix_class->process_textures (mix, mix->frames, out_tex); g_mutex_unlock (&priv->gl_resource_lock); if (out_gl_wrapped) { if (!gst_gl_download_perform_with_data (mix->download, out_tex, out_frame.data)) { GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s", "Failed to download video frame"), (NULL)); res = FALSE; goto out; } } out: i = 0; walk = GST_ELEMENT (mix)->sinkpads; while (walk) { GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data); if (pad->mapped) gst_gl_upload_release_buffer (pad->upload); pad->mapped = FALSE; walk = g_list_next (walk); i++; } GST_OBJECT_UNLOCK (mix); gst_video_frame_unmap (&out_frame); return res; }
gboolean gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf) { guint i; GList *walk; guint out_tex, out_tex_target; gboolean res = TRUE; guint array_index = 0; GstVideoFrame out_frame; GstElement *element = GST_ELEMENT (mix); GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix); GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix); GstGLMixerPrivate *priv = mix->priv; gboolean to_download = gst_caps_features_is_equal (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY, gst_caps_get_features (mix->out_caps, 0)); GstMapFlags out_map_flags = GST_MAP_WRITE; GST_TRACE ("Processing buffers"); to_download |= !gst_is_gl_memory (gst_buffer_peek_memory (outbuf, 0)); if (!to_download) out_map_flags |= GST_MAP_GL; if (!gst_video_frame_map (&out_frame, &vagg->info, outbuf, out_map_flags)) { return FALSE; } if (!to_download) { out_tex = *(guint *) out_frame.data[0]; out_tex_target = ((GstGLMemory *) gst_buffer_peek_memory (outbuf, 0))->tex_target; } else { GST_INFO ("Output Buffer does not contain correct memory, " "attempting to wrap for download"); if (!mix->download) mix->download = gst_gl_download_new (mix->context); gst_gl_download_set_format (mix->download, &out_frame.info); out_tex = mix->out_tex_id; out_tex_target = GL_TEXTURE_2D; } GST_OBJECT_LOCK (mix); walk = element->sinkpads; i = mix->frames->len; g_ptr_array_set_size (mix->frames, element->numsinkpads); for (; i < element->numsinkpads; i++) mix->frames->pdata[i] = g_slice_new0 (GstGLMixerFrameData); while (walk) { GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data); GstGLMixerPadClass *pad_class = GST_GL_MIXER_PAD_GET_CLASS (pad); GstVideoAggregatorPad *vaggpad = walk->data; GstGLMixerFrameData *frame; frame = g_ptr_array_index (mix->frames, array_index); frame->pad = pad; frame->texture = 0; walk = g_list_next (walk); if (vaggpad->buffer != NULL) { g_assert (pad_class->upload_buffer); if (pad->gl_buffer) gst_buffer_unref (pad->gl_buffer); pad->gl_buffer = pad_class->upload_buffer (mix, frame, vaggpad->buffer); GST_DEBUG_OBJECT (pad, "uploaded buffer %" GST_PTR_FORMAT " from buffer %" GST_PTR_FORMAT, pad->gl_buffer, vaggpad->buffer); } ++array_index; } g_mutex_lock (&priv->gl_resource_lock); if (!priv->gl_resource_ready) g_cond_wait (&priv->gl_resource_cond, &priv->gl_resource_lock); if (!priv->gl_resource_ready) { g_mutex_unlock (&priv->gl_resource_lock); GST_ERROR_OBJECT (mix, "fbo used to render can't be created, do not run process_textures"); res = FALSE; goto out; } mix_class->process_textures (mix, mix->frames, out_tex); g_mutex_unlock (&priv->gl_resource_lock); if (to_download) { if (!gst_gl_download_perform_with_data (mix->download, out_tex, out_tex_target, out_frame.data)) { GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s", "Failed to download video frame"), (NULL)); res = FALSE; goto out; } } out: i = 0; walk = GST_ELEMENT (mix)->sinkpads; while (walk) { GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data); if (pad->upload) gst_gl_upload_release_buffer (pad->upload); walk = g_list_next (walk); i++; } GST_OBJECT_UNLOCK (mix); gst_video_frame_unmap (&out_frame); return res; }
GstFlowReturn ofGstVideoUtils::process_sample(shared_ptr<GstSample> sample){ GstBuffer * _buffer = gst_sample_get_buffer(sample.get()); #ifdef OF_USE_GST_GL if (gst_buffer_map (_buffer, &mapinfo, (GstMapFlags)(GST_MAP_READ | GST_MAP_GL))){ if (gst_is_gl_memory (mapinfo.memory)) { bufferQueue.push(sample); gst_buffer_unmap(_buffer, &mapinfo); bool newTexture=false; std::unique_lock<std::mutex> lock(mutex); while(bufferQueue.size()>2){ backBuffer = bufferQueue.front(); bufferQueue.pop(); newTexture = true; } if(newTexture){ GstBuffer * _buffer = gst_sample_get_buffer(backBuffer.get()); gst_buffer_map (_buffer, &mapinfo, (GstMapFlags)(GST_MAP_READ | GST_MAP_GL)); auto texId = *(guint*)mapinfo.data; backTexture.setUseExternalTextureID(texId); ofTextureData & texData = backTexture.getTextureData(); texData.bAllocated = true; texData.bFlipTexture = false; texData.glTypeInternal = GL_RGBA; texData.height = getHeight(); texData.width = getWidth(); texData.magFilter = GL_LINEAR; texData.minFilter = GL_LINEAR; texData.tex_h = getHeight(); texData.tex_w = getWidth(); texData.tex_u = 1; texData.tex_t = 1; texData.textureID = texId; texData.textureTarget = GL_TEXTURE_2D; texData.wrapModeHorizontal = GL_CLAMP_TO_EDGE; texData.wrapModeVertical = GL_CLAMP_TO_EDGE; bBackPixelsChanged=true; gst_buffer_unmap(_buffer,&mapinfo); } return GST_FLOW_OK; } } #endif // video frame has normal texture gst_buffer_map (_buffer, &mapinfo, GST_MAP_READ); guint size = mapinfo.size; int stride = 0; if(pixels.isAllocated() && pixels.getTotalBytes()!=(int)size){ GstVideoInfo v_info = getVideoInfo(sample.get()); stride = v_info.stride[0]; if(stride == (pixels.getWidth() * pixels.getBytesPerPixel())) { ofLogError("ofGstVideoUtils") << "buffer_cb(): error on new buffer, buffer size: " << size << "!= init size: " << pixels.getTotalBytes(); return GST_FLOW_ERROR; } } mutex.lock(); if(!copyPixels){ backBuffer = sample; } if(pixels.isAllocated()){ if(stride > 0) { backPixels.setFromAlignedPixels(mapinfo.data,pixels.getWidth(),pixels.getHeight(),pixels.getPixelFormat(),stride); } else if(!copyPixels){ backPixels.setFromExternalPixels(mapinfo.data,pixels.getWidth(),pixels.getHeight(),pixels.getPixelFormat()); eventPixels.setFromExternalPixels(mapinfo.data,pixels.getWidth(),pixels.getHeight(),pixels.getPixelFormat()); }else{ backPixels.setFromPixels(mapinfo.data,pixels.getWidth(),pixels.getHeight(),pixels.getPixelFormat()); } bBackPixelsChanged=true; mutex.unlock(); if(stride == 0) { ofNotifyEvent(prerollEvent,eventPixels); } }else{ mutex.unlock(); if(appsink){ appsink->on_stream_prepared(); }else{ GstVideoInfo v_info = getVideoInfo(sample.get()); allocate(v_info.width,v_info.height,getOFFormat(v_info.finfo->format)); } } gst_buffer_unmap(_buffer, &mapinfo); return GST_FLOW_OK; }
/** * gst_gl_filter_filter_texture: * @filter: a #GstGLFilter * @inbuf: an input buffer * @outbuf: an output buffer * * Perform automatic upload if needed, call filter_texture vfunc and then an * automatic download if needed. * * Returns: whether the transformation succeeded */ gboolean gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf, GstBuffer * outbuf) { GstGLFilterClass *filter_class; guint in_tex, out_tex; GstVideoFrame out_frame; gboolean ret, out_gl_mem; GstVideoGLTextureUploadMeta *out_tex_upload_meta; filter_class = GST_GL_FILTER_GET_CLASS (filter); if (!gst_gl_upload_perform_with_buffer (filter->upload, inbuf, &in_tex)) return FALSE; if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf, GST_MAP_WRITE | GST_MAP_GL)) { ret = FALSE; goto inbuf_error; } out_gl_mem = gst_is_gl_memory (out_frame.map[0].memory); out_tex_upload_meta = gst_buffer_get_video_gl_texture_upload_meta (outbuf); if (out_gl_mem) { out_tex = *(guint *) out_frame.data[0]; } else { GST_LOG ("Output Buffer does not contain correct memory, " "attempting to wrap for download"); if (!filter->download) { filter->download = gst_gl_download_new (filter->context); if (!gst_gl_download_init_format (filter->download, GST_VIDEO_FRAME_FORMAT (&out_frame), GST_VIDEO_FRAME_WIDTH (&out_frame), GST_VIDEO_FRAME_HEIGHT (&out_frame))) { GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, ("%s", "Failed to init download format"), (NULL)); ret = FALSE; goto error; } } out_tex = filter->out_tex_id; } GST_DEBUG ("calling filter_texture with textures in:%i out:%i", in_tex, out_tex); g_assert (filter_class->filter_texture); ret = filter_class->filter_texture (filter, in_tex, out_tex); if (!out_gl_mem && !out_tex_upload_meta) { if (!gst_gl_download_perform_with_data (filter->download, out_tex, out_frame.data)) { GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, ("%s", "Failed to download video frame"), (NULL)); ret = FALSE; goto error; } } error: gst_video_frame_unmap (&out_frame); inbuf_error: gst_gl_upload_release_buffer (filter->upload); return ret; }
/* Called by the idle function in the gl thread */ void _do_convert (GstGLContext * context, GstGLColorConvert * convert) { guint in_width, in_height, out_width, out_height; struct ConvertInfo *c_info = &convert->priv->convert_info; GstMapInfo out_info[GST_VIDEO_MAX_PLANES], in_info[GST_VIDEO_MAX_PLANES]; gboolean res = TRUE; gint i, j = 0; out_width = GST_VIDEO_INFO_WIDTH (&convert->out_info); out_height = GST_VIDEO_INFO_HEIGHT (&convert->out_info); in_width = GST_VIDEO_INFO_WIDTH (&convert->in_info); in_height = GST_VIDEO_INFO_HEIGHT (&convert->in_info); convert->outbuf = NULL; if (!_init_convert (convert)) { convert->priv->result = FALSE; return; } convert->outbuf = gst_buffer_new (); if (!gst_gl_memory_setup_buffer (convert->context, &convert->out_info, convert->outbuf)) { convert->priv->result = FALSE; return; } gst_buffer_add_video_meta_full (convert->outbuf, 0, GST_VIDEO_INFO_FORMAT (&convert->out_info), GST_VIDEO_INFO_WIDTH (&convert->out_info), GST_VIDEO_INFO_HEIGHT (&convert->out_info), GST_VIDEO_INFO_N_PLANES (&convert->out_info), convert->out_info.offset, convert->out_info.stride); for (i = 0; i < c_info->in_n_textures; i++) { convert->priv->in_tex[i] = (GstGLMemory *) gst_buffer_peek_memory (convert->inbuf, i); if (!gst_is_gl_memory ((GstMemory *) convert->priv->in_tex[i])) { GST_ERROR_OBJECT (convert, "input must be GstGLMemory"); res = FALSE; goto out; } if (!gst_memory_map ((GstMemory *) convert->priv->in_tex[i], &in_info[i], GST_MAP_READ | GST_MAP_GL)) { GST_ERROR_OBJECT (convert, "failed to map input memory %p", convert->priv->in_tex[i]); res = FALSE; goto out; } } for (j = 0; j < c_info->out_n_textures; j++) { GstGLMemory *out_tex = (GstGLMemory *) gst_buffer_peek_memory (convert->outbuf, j); gint mem_width, mem_height; if (!gst_is_gl_memory ((GstMemory *) out_tex)) { GST_ERROR_OBJECT (convert, "output must be GstGLMemory"); res = FALSE; goto out; } mem_width = gst_gl_memory_get_texture_width (out_tex); mem_height = gst_gl_memory_get_texture_height (out_tex); if (out_tex->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE || out_tex->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA || out_width != mem_width || out_height != mem_height) { /* Luminance formats are not color renderable */ /* renderering to a framebuffer only renders the intersection of all * the attachments i.e. the smallest attachment size */ GstVideoInfo temp_info; gst_video_info_set_format (&temp_info, GST_VIDEO_FORMAT_RGBA, out_width, out_height); if (!convert->priv->out_tex[j]) convert->priv->out_tex[j] = (GstGLMemory *) gst_gl_memory_alloc (context, &temp_info, 0); } else { convert->priv->out_tex[j] = out_tex; } if (!gst_memory_map ((GstMemory *) convert->priv->out_tex[j], &out_info[j], GST_MAP_WRITE | GST_MAP_GL)) { GST_ERROR_OBJECT (convert, "failed to map output memory %p", convert->priv->out_tex[i]); res = FALSE; goto out; } } GST_LOG_OBJECT (convert, "converting to textures:%p,%p,%p,%p " "dimensions:%ux%u, from textures:%p,%p,%p,%p dimensions:%ux%u", convert->priv->out_tex[0], convert->priv->out_tex[1], convert->priv->out_tex[2], convert->priv->out_tex[3], out_width, out_height, convert->priv->in_tex[0], convert->priv->in_tex[1], convert->priv->in_tex[2], convert->priv->in_tex[3], in_width, in_height); if (!_do_convert_draw (context, convert)) res = FALSE; out: for (j--; j >= 0; j--) { GstGLMemory *out_tex = (GstGLMemory *) gst_buffer_peek_memory (convert->outbuf, j); gint mem_width, mem_height; gst_memory_unmap ((GstMemory *) convert->priv->out_tex[j], &out_info[j]); mem_width = gst_gl_memory_get_texture_width (out_tex); mem_height = gst_gl_memory_get_texture_height (out_tex); if (out_tex->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE || out_tex->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA || out_width != mem_width || out_height != mem_height) { GstMapInfo to_info, from_info; if (!gst_memory_map ((GstMemory *) convert->priv->out_tex[j], &from_info, GST_MAP_READ | GST_MAP_GL)) { gst_gl_context_set_error (convert->context, "Failed to map " "intermediate memory"); res = FALSE; continue; } if (!gst_memory_map ((GstMemory *) out_tex, &to_info, GST_MAP_WRITE | GST_MAP_GL)) { gst_gl_context_set_error (convert->context, "Failed to map " "intermediate memory"); res = FALSE; continue; } gst_gl_memory_copy_into_texture (convert->priv->out_tex[j], out_tex->tex_id, out_tex->tex_type, mem_width, mem_height, GST_VIDEO_INFO_PLANE_STRIDE (&out_tex->info, out_tex->plane), FALSE); gst_memory_unmap ((GstMemory *) convert->priv->out_tex[j], &from_info); gst_memory_unmap ((GstMemory *) out_tex, &to_info); } else { convert->priv->out_tex[j] = NULL; } } /* YV12 the same as I420 except planes 1+2 swapped */ if (GST_VIDEO_INFO_FORMAT (&convert->out_info) == GST_VIDEO_FORMAT_YV12) { GstMemory *mem1 = gst_buffer_get_memory (convert->outbuf, 1); GstMemory *mem2 = gst_buffer_get_memory (convert->outbuf, 2); gst_buffer_replace_memory (convert->outbuf, 1, mem2); gst_buffer_replace_memory (convert->outbuf, 2, mem1); } for (i--; i >= 0; i--) { gst_memory_unmap ((GstMemory *) convert->priv->in_tex[i], &in_info[i]); } if (!res) { gst_buffer_unref (convert->outbuf); convert->outbuf = NULL; } convert->priv->result = res; return; }
/** * gst_gl_upload_perform_with_buffer: * @upload: a #GstGLUpload * @buffer: a #GstBuffer * @tex_id: resulting texture * * Uploads @buffer to the texture given by @tex_id. @tex_id is valid * until gst_gl_upload_release_buffer() is called. * * Returns: whether the upload was successful */ gboolean gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer, guint * tex_id) { GstMemory *mem; GstVideoGLTextureUploadMeta *gl_tex_upload_meta; guint texture_ids[] = { 0, 0, 0, 0 }; gint i; gboolean ret; g_return_val_if_fail (upload != NULL, FALSE); g_return_val_if_fail (buffer != NULL, FALSE); g_return_val_if_fail (tex_id != NULL, FALSE); g_return_val_if_fail (gst_buffer_n_memory (buffer) > 0, FALSE); gst_gl_upload_release_buffer (upload); /* GstGLMemory */ mem = gst_buffer_peek_memory (buffer, 0); if (gst_is_gl_memory (mem)) { if (GST_VIDEO_INFO_FORMAT (&upload->in_info) == GST_VIDEO_FORMAT_RGBA) { GstMapInfo map_info; gst_memory_map (mem, &map_info, GST_MAP_READ | GST_MAP_GL); gst_memory_unmap (mem, &map_info); *tex_id = ((GstGLMemory *) mem)->tex_id; return TRUE; } GST_LOG_OBJECT (upload, "Attempting upload with GstGLMemory"); for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->in_info); i++) { upload->in_tex[i] = (GstGLMemory *) gst_buffer_peek_memory (buffer, i); } ret = _upload_memory (upload); *tex_id = upload->out_tex->tex_id; for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->in_info); i++) { upload->in_tex[i] = NULL; } return ret; } #if GST_GL_HAVE_PLATFORM_EGL if (!upload->priv->tex_id && gst_is_egl_image_memory (mem)) gst_gl_context_gen_texture (upload->context, &upload->priv->tex_id, GST_VIDEO_FORMAT_RGBA, 0, 0); #endif if (!upload->priv->tex_id) gst_gl_context_gen_texture (upload->context, &upload->priv->tex_id, GST_VIDEO_FORMAT_RGBA, GST_VIDEO_INFO_WIDTH (&upload->in_info), GST_VIDEO_INFO_HEIGHT (&upload->in_info)); /* GstVideoGLTextureUploadMeta */ gl_tex_upload_meta = gst_buffer_get_video_gl_texture_upload_meta (buffer); if (gl_tex_upload_meta) { GST_LOG_OBJECT (upload, "Attempting upload with " "GstVideoGLTextureUploadMeta"); texture_ids[0] = upload->priv->tex_id; if (!gst_gl_upload_perform_with_gl_texture_upload_meta (upload, gl_tex_upload_meta, texture_ids)) { GST_DEBUG_OBJECT (upload, "Upload with GstVideoGLTextureUploadMeta " "failed"); } else { upload->priv->mapped = FALSE; *tex_id = upload->priv->tex_id; return TRUE; } } GST_LOG_OBJECT (upload, "Attempting upload with raw data"); /* GstVideoMeta map */ if (!gst_video_frame_map (&upload->priv->frame, &upload->in_info, buffer, GST_MAP_READ)) { GST_ERROR_OBJECT (upload, "Failed to map memory"); return FALSE; } upload->priv->mapped = TRUE; /* update the video info from the one updated by frame_map using video meta */ gst_gl_upload_set_format (upload, &upload->priv->frame.info); if (!gst_gl_upload_perform_with_data (upload, tex_id, upload->priv->frame.data)) { return FALSE; } return TRUE; }