mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
vtdec: implement the GL texture upload meta
This commit is contained in:
parent
cdfe90aaba
commit
d95a12e185
3 changed files with 154 additions and 43 deletions
|
@ -26,12 +26,11 @@
|
||||||
#endif
|
#endif
|
||||||
#include "corevideotexturecache.h"
|
#include "corevideotexturecache.h"
|
||||||
#include "coremediabuffer.h"
|
#include "coremediabuffer.h"
|
||||||
|
#include "corevideobuffer.h"
|
||||||
|
|
||||||
GstCoreVideoTextureCache *
|
GstCoreVideoTextureCache *
|
||||||
gst_core_video_texture_cache_new (GstGLContext * ctx)
|
gst_core_video_texture_cache_new (GstGLContext * ctx)
|
||||||
{
|
{
|
||||||
CVReturn err;
|
|
||||||
|
|
||||||
g_return_val_if_fail (ctx != NULL, NULL);
|
g_return_val_if_fail (ctx != NULL, NULL);
|
||||||
|
|
||||||
GstCoreVideoTextureCache *cache = g_new0 (GstCoreVideoTextureCache, 1);
|
GstCoreVideoTextureCache *cache = g_new0 (GstCoreVideoTextureCache, 1);
|
||||||
|
@ -41,21 +40,21 @@ gst_core_video_texture_cache_new (GstGLContext * ctx)
|
||||||
CGLPixelFormatAttribute attribs[1] = { 0 };
|
CGLPixelFormatAttribute attribs[1] = { 0 };
|
||||||
int numPixelFormats;
|
int numPixelFormats;
|
||||||
CGLPixelFormatObj pixelFormat;
|
CGLPixelFormatObj pixelFormat;
|
||||||
CGLChoosePixelFormat (attribs, &pixelFormat, &numPixelFormats); // 5
|
CGLChoosePixelFormat (attribs, &pixelFormat, &numPixelFormats); // 5
|
||||||
NSOpenGLContext *platform_ctx = (NSOpenGLContext *) gst_gl_context_get_gl_context (ctx);
|
NSOpenGLContext *platform_ctx =
|
||||||
err = CVOpenGLTextureCacheCreate (kCFAllocatorDefault, NULL,
|
(NSOpenGLContext *) gst_gl_context_get_gl_context (ctx);
|
||||||
[platform_ctx CGLContextObj], pixelFormat,
|
CVOpenGLTextureCacheCreate (kCFAllocatorDefault, NULL,
|
||||||
NULL, &cache->cache);
|
[platform_ctx CGLContextObj], pixelFormat, NULL, &cache->cache);
|
||||||
#else
|
#else
|
||||||
err = CVOpenGLESTextureCacheCreate (kCFAllocatorDefault, NULL,
|
CVOpenGLESTextureCacheCreate (kCFAllocatorDefault, NULL,
|
||||||
(CVEAGLContext) gst_gl_context_get_gl_context (ctx),
|
(CVEAGLContext) gst_gl_context_get_gl_context (ctx), NULL, &cache->cache);
|
||||||
NULL, &cache->cache);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gst_core_video_texture_cache_free (GstCoreVideoTextureCache * cache)
|
void
|
||||||
|
gst_core_video_texture_cache_free (GstCoreVideoTextureCache * cache)
|
||||||
{
|
{
|
||||||
g_return_if_fail (cache != NULL);
|
g_return_if_fail (cache != NULL);
|
||||||
|
|
||||||
|
@ -69,11 +68,13 @@ void gst_core_video_texture_cache_free (GstCoreVideoTextureCache * cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_core_video_texture_cache_upload (GstVideoGLTextureUploadMeta * meta, guint texture_id[4])
|
gst_core_video_texture_cache_upload (GstVideoGLTextureUploadMeta * meta,
|
||||||
|
guint texture_id[4])
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (meta != NULL, FALSE);
|
g_return_val_if_fail (meta != NULL, FALSE);
|
||||||
|
|
||||||
GstCoreVideoTextureCache *cache = (GstCoreVideoTextureCache *) meta->user_data;
|
GstCoreVideoTextureCache *cache =
|
||||||
|
(GstCoreVideoTextureCache *) meta->user_data;
|
||||||
const GstGLFuncs *gl = cache->ctx->gl_vtable;
|
const GstGLFuncs *gl = cache->ctx->gl_vtable;
|
||||||
#if !HAVE_IOS
|
#if !HAVE_IOS
|
||||||
CVOpenGLTextureRef texture = NULL;
|
CVOpenGLTextureRef texture = NULL;
|
||||||
|
@ -81,16 +82,25 @@ gst_core_video_texture_cache_upload (GstVideoGLTextureUploadMeta * meta, guint t
|
||||||
CVOpenGLESTextureRef texture = NULL;
|
CVOpenGLESTextureRef texture = NULL;
|
||||||
#endif
|
#endif
|
||||||
GstVideoMeta *video_meta = gst_buffer_get_video_meta (meta->buffer);
|
GstVideoMeta *video_meta = gst_buffer_get_video_meta (meta->buffer);
|
||||||
GstCoreMediaMeta *cv_meta = (GstCoreMediaMeta *) gst_buffer_get_meta (meta->buffer,
|
GstCoreMediaMeta *cm_meta =
|
||||||
gst_core_media_meta_api_get_type ());
|
(GstCoreMediaMeta *) gst_buffer_get_meta (meta->buffer,
|
||||||
|
gst_core_media_meta_api_get_type ());
|
||||||
|
GstCoreVideoMeta *cv_meta =
|
||||||
|
(GstCoreVideoMeta *) gst_buffer_get_meta (meta->buffer,
|
||||||
|
gst_core_video_meta_api_get_type ());
|
||||||
|
CVPixelBufferRef pixel_buf;
|
||||||
|
if (cm_meta)
|
||||||
|
pixel_buf = cm_meta->pixel_buf;
|
||||||
|
else
|
||||||
|
pixel_buf = cv_meta->pixbuf;
|
||||||
#if !HAVE_IOS
|
#if !HAVE_IOS
|
||||||
CVOpenGLTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
|
CVOpenGLTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
|
||||||
cache->cache, cv_meta->pixel_buf, NULL, &texture);
|
cache->cache, pixel_buf, NULL, &texture);
|
||||||
#else
|
#else
|
||||||
CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
|
CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
|
||||||
cache->cache, cv_meta->image_buf, NULL, GL_TEXTURE_2D,
|
cache->cache, cm_meta->image_buf, NULL, GL_TEXTURE_2D,
|
||||||
GL_RGBA, video_meta->width, video_meta->height, GL_RGBA, GL_UNSIGNED_BYTE,
|
GL_RGBA, video_meta->width, video_meta->height, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||||
0, &texture);
|
0, &texture);
|
||||||
#endif
|
#endif
|
||||||
GLuint fboId;
|
GLuint fboId;
|
||||||
gl->GenFramebuffers (1, &fboId);
|
gl->GenFramebuffers (1, &fboId);
|
||||||
|
@ -98,13 +108,14 @@ gst_core_video_texture_cache_upload (GstVideoGLTextureUploadMeta * meta, guint t
|
||||||
|
|
||||||
gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
#if !HAVE_IOS
|
#if !HAVE_IOS
|
||||||
CVOpenGLTextureGetTarget(texture), CVOpenGLTextureGetName(texture),
|
CVOpenGLTextureGetTarget (texture), CVOpenGLTextureGetName (texture),
|
||||||
#else
|
#else
|
||||||
CVOpenGLESTextureGetTarget(texture), CVOpenGLESTextureGetName(texture),
|
CVOpenGLESTextureGetTarget (texture), CVOpenGLESTextureGetName (texture),
|
||||||
#endif
|
#endif
|
||||||
0);
|
0);
|
||||||
gl->BindTexture (GL_TEXTURE_2D, texture_id[0]);
|
gl->BindTexture (GL_TEXTURE_2D, texture_id[0]);
|
||||||
gl->CopyTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, video_meta->width, video_meta->height, 0);
|
gl->CopyTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, video_meta->width,
|
||||||
|
video_meta->height, 0);
|
||||||
gl->BindTexture (GL_TEXTURE_2D, 0);
|
gl->BindTexture (GL_TEXTURE_2D, 0);
|
||||||
gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
|
gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||||
gl->DeleteFramebuffers (1, &fboId);
|
gl->DeleteFramebuffers (1, &fboId);
|
||||||
|
|
|
@ -35,13 +35,15 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include <gst/video/gstvideodecoder.h>
|
#include <gst/video/gstvideodecoder.h>
|
||||||
|
#include <gst/gl/gstglcontext.h>
|
||||||
#include "vtdec.h"
|
#include "vtdec.h"
|
||||||
#include "vtutil.h"
|
#include "vtutil.h"
|
||||||
#include "corevideobuffer.h"
|
#include "corevideobuffer.h"
|
||||||
#include <string.h>
|
#include "coremediabuffer.h"
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_vtdec_debug_category);
|
GST_DEBUG_CATEGORY_STATIC (gst_vtdec_debug_category);
|
||||||
#define GST_CAT_DEFAULT gst_vtdec_debug_category
|
#define GST_CAT_DEFAULT gst_vtdec_debug_category
|
||||||
|
@ -50,6 +52,8 @@ static void gst_vtdec_finalize (GObject * object);
|
||||||
|
|
||||||
static gboolean gst_vtdec_start (GstVideoDecoder * decoder);
|
static gboolean gst_vtdec_start (GstVideoDecoder * decoder);
|
||||||
static gboolean gst_vtdec_stop (GstVideoDecoder * decoder);
|
static gboolean gst_vtdec_stop (GstVideoDecoder * decoder);
|
||||||
|
static gboolean gst_vtdec_decide_allocation (GstVideoDecoder * decoder,
|
||||||
|
GstQuery * query);
|
||||||
static gboolean gst_vtdec_set_format (GstVideoDecoder * decoder,
|
static gboolean gst_vtdec_set_format (GstVideoDecoder * decoder,
|
||||||
GstVideoCodecState * state);
|
GstVideoCodecState * state);
|
||||||
static gboolean gst_vtdec_flush (GstVideoDecoder * decoder);
|
static gboolean gst_vtdec_flush (GstVideoDecoder * decoder);
|
||||||
|
@ -57,7 +61,8 @@ static GstFlowReturn gst_vtdec_finish (GstVideoDecoder * decoder);
|
||||||
static GstFlowReturn gst_vtdec_handle_frame (GstVideoDecoder * decoder,
|
static GstFlowReturn gst_vtdec_handle_frame (GstVideoDecoder * decoder,
|
||||||
GstVideoCodecFrame * frame);
|
GstVideoCodecFrame * frame);
|
||||||
|
|
||||||
static gboolean gst_vtdec_create_session (GstVtdec * vtdec);
|
static gboolean gst_vtdec_create_session (GstVtdec * vtdec,
|
||||||
|
GstVideoFormat format);
|
||||||
static void gst_vtdec_invalidate_session (GstVtdec * vtdec);
|
static void gst_vtdec_invalidate_session (GstVtdec * vtdec);
|
||||||
static CMSampleBufferRef cm_sample_buffer_from_gst_buffer (GstVtdec * vtdec,
|
static CMSampleBufferRef cm_sample_buffer_from_gst_buffer (GstVtdec * vtdec,
|
||||||
GstBuffer * buf);
|
GstBuffer * buf);
|
||||||
|
@ -86,16 +91,6 @@ static GstStaticPadTemplate gst_vtdec_sink_template =
|
||||||
"video/mpeg, mpegversion=2;" "image/jpeg")
|
"video/mpeg, mpegversion=2;" "image/jpeg")
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef HAVE_IOS
|
|
||||||
#define GST_VTDEC_VIDEO_FORMAT_STR "NV12"
|
|
||||||
#define GST_VTDEC_VIDEO_FORMAT GST_VIDEO_FORMAT_NV12
|
|
||||||
#define GST_VTDEC_CV_VIDEO_FORMAT kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
|
|
||||||
#else
|
|
||||||
#define GST_VTDEC_VIDEO_FORMAT_STR "UYVY"
|
|
||||||
#define GST_VTDEC_VIDEO_FORMAT GST_VIDEO_FORMAT_UYVY
|
|
||||||
#define GST_VTDEC_CV_VIDEO_FORMAT kCVPixelFormatType_422YpCbCr8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* define EnableHardwareAcceleratedVideoDecoder in < 10.9 */
|
/* define EnableHardwareAcceleratedVideoDecoder in < 10.9 */
|
||||||
#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < 1090
|
#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < 1090
|
||||||
const CFStringRef
|
const CFStringRef
|
||||||
|
@ -103,8 +98,17 @@ const CFStringRef
|
||||||
CFSTR ("EnableHardwareAcceleratedVideoDecoder");
|
CFSTR ("EnableHardwareAcceleratedVideoDecoder");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_IOS
|
||||||
|
#define GST_VTDEC_VIDEO_FORMAT_STR "NV12"
|
||||||
|
#else
|
||||||
|
#define GST_VTDEC_VIDEO_FORMAT_STR "UYVY"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define VIDEO_SRC_CAPS \
|
#define VIDEO_SRC_CAPS \
|
||||||
GST_VIDEO_CAPS_MAKE("{" GST_VTDEC_VIDEO_FORMAT_STR "}")
|
GST_VIDEO_CAPS_MAKE(GST_VTDEC_VIDEO_FORMAT_STR) ";" \
|
||||||
|
GST_VIDEO_CAPS_MAKE_WITH_FEATURES \
|
||||||
|
(GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, \
|
||||||
|
"RGBA") ";"
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GstVtdec, gst_vtdec, GST_TYPE_VIDEO_DECODER,
|
G_DEFINE_TYPE_WITH_CODE (GstVtdec, gst_vtdec, GST_TYPE_VIDEO_DECODER,
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_vtdec_debug_category, "vtdec", 0,
|
GST_DEBUG_CATEGORY_INIT (gst_vtdec_debug_category, "vtdec", 0,
|
||||||
|
@ -134,6 +138,8 @@ gst_vtdec_class_init (GstVtdecClass * klass)
|
||||||
gobject_class->finalize = gst_vtdec_finalize;
|
gobject_class->finalize = gst_vtdec_finalize;
|
||||||
video_decoder_class->start = GST_DEBUG_FUNCPTR (gst_vtdec_start);
|
video_decoder_class->start = GST_DEBUG_FUNCPTR (gst_vtdec_start);
|
||||||
video_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_vtdec_stop);
|
video_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_vtdec_stop);
|
||||||
|
video_decoder_class->decide_allocation =
|
||||||
|
GST_DEBUG_FUNCPTR (gst_vtdec_decide_allocation);
|
||||||
video_decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_vtdec_set_format);
|
video_decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_vtdec_set_format);
|
||||||
video_decoder_class->flush = GST_DEBUG_FUNCPTR (gst_vtdec_flush);
|
video_decoder_class->flush = GST_DEBUG_FUNCPTR (gst_vtdec_flush);
|
||||||
video_decoder_class->finish = GST_DEBUG_FUNCPTR (gst_vtdec_finish);
|
video_decoder_class->finish = GST_DEBUG_FUNCPTR (gst_vtdec_finish);
|
||||||
|
@ -156,6 +162,7 @@ gst_vtdec_finalize (GObject * object)
|
||||||
|
|
||||||
g_async_queue_unref (vtdec->reorder_queue);
|
g_async_queue_unref (vtdec->reorder_queue);
|
||||||
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (gst_vtdec_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gst_vtdec_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,11 +184,64 @@ gst_vtdec_stop (GstVideoDecoder * decoder)
|
||||||
if (vtdec->session)
|
if (vtdec->session)
|
||||||
gst_vtdec_invalidate_session (vtdec);
|
gst_vtdec_invalidate_session (vtdec);
|
||||||
|
|
||||||
|
if (vtdec->texture_cache)
|
||||||
|
gst_core_video_texture_cache_free (vtdec->texture_cache);
|
||||||
|
vtdec->texture_cache = NULL;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (vtdec, "stop");
|
GST_DEBUG_OBJECT (vtdec, "stop");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_vtdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
GstVtdec *vtdec = GST_VTDEC (decoder);
|
||||||
|
|
||||||
|
ret =
|
||||||
|
GST_VIDEO_DECODER_CLASS (gst_vtdec_parent_class)->decide_allocation
|
||||||
|
(decoder, query);
|
||||||
|
if (ret) {
|
||||||
|
guint idx;
|
||||||
|
|
||||||
|
if (gst_query_find_allocation_meta (query,
|
||||||
|
GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx)) {
|
||||||
|
GstGLContext *context;
|
||||||
|
const GstStructure *upload_meta_params;
|
||||||
|
|
||||||
|
gst_query_parse_nth_allocation_meta (query, idx, &upload_meta_params);
|
||||||
|
if (gst_structure_get (upload_meta_params, "gst.gl.GstGLContext",
|
||||||
|
GST_GL_TYPE_CONTEXT, &context, NULL) && context) {
|
||||||
|
vtdec->texture_cache = gst_core_video_texture_cache_new (context);
|
||||||
|
gst_object_unref (context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVideoFormat
|
||||||
|
gst_vtdec_negotiate_output_format (GstVtdec * vtdec)
|
||||||
|
{
|
||||||
|
GstCaps *caps = NULL;
|
||||||
|
GstVideoFormat format;
|
||||||
|
GstStructure *structure;
|
||||||
|
const gchar *s;
|
||||||
|
|
||||||
|
caps = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (vtdec));
|
||||||
|
if (!caps)
|
||||||
|
caps = gst_pad_query_caps (GST_VIDEO_DECODER_SRC_PAD (vtdec), NULL);
|
||||||
|
caps = gst_caps_truncate (caps);
|
||||||
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
|
s = gst_structure_get_string (structure, "format");
|
||||||
|
format = gst_video_format_from_string (s);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vtdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
|
gst_vtdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
|
||||||
{
|
{
|
||||||
|
@ -190,6 +250,8 @@ gst_vtdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
|
||||||
CMFormatDescriptionRef format_description = NULL;
|
CMFormatDescriptionRef format_description = NULL;
|
||||||
const char *caps_name;
|
const char *caps_name;
|
||||||
GstVtdec *vtdec = GST_VTDEC (decoder);
|
GstVtdec *vtdec = GST_VTDEC (decoder);
|
||||||
|
GstVideoFormat output_format;
|
||||||
|
GstVideoCodecState *output_state;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (vtdec, "set_format");
|
GST_DEBUG_OBJECT (vtdec, "set_format");
|
||||||
|
|
||||||
|
@ -229,12 +291,19 @@ gst_vtdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
|
||||||
CFRelease (vtdec->format_description);
|
CFRelease (vtdec->format_description);
|
||||||
vtdec->format_description = format_description;
|
vtdec->format_description = format_description;
|
||||||
|
|
||||||
if (!gst_vtdec_create_session (vtdec))
|
output_format = gst_vtdec_negotiate_output_format (vtdec);
|
||||||
|
|
||||||
|
if (!gst_vtdec_create_session (vtdec, output_format))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
gst_video_decoder_set_output_state (decoder,
|
output_state = gst_video_decoder_set_output_state (decoder,
|
||||||
GST_VTDEC_VIDEO_FORMAT, vtdec->video_info.width, vtdec->video_info.height,
|
output_format, vtdec->video_info.width, vtdec->video_info.height, state);
|
||||||
state);
|
output_state->caps = gst_video_info_to_caps (&output_state->info);
|
||||||
|
if (output_state->info.finfo->format == GST_VIDEO_FORMAT_RGBA) {
|
||||||
|
gst_caps_set_features (output_state->caps, 0,
|
||||||
|
gst_caps_features_new
|
||||||
|
(GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -312,12 +381,28 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vtdec_create_session (GstVtdec * vtdec)
|
gst_vtdec_create_session (GstVtdec * vtdec, GstVideoFormat format)
|
||||||
{
|
{
|
||||||
CFMutableDictionaryRef output_image_buffer_attrs;
|
CFMutableDictionaryRef output_image_buffer_attrs;
|
||||||
VTDecompressionOutputCallbackRecord callback;
|
VTDecompressionOutputCallbackRecord callback;
|
||||||
CFMutableDictionaryRef videoDecoderSpecification;
|
CFMutableDictionaryRef videoDecoderSpecification;
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
|
guint32 cv_format;
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case GST_VIDEO_FORMAT_NV12:
|
||||||
|
cv_format = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
|
cv_format = kCVPixelFormatType_422YpCbCr8;
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_FORMAT_RGBA:
|
||||||
|
cv_format = kCVPixelFormatType_32BGRA;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_warn_if_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
videoDecoderSpecification =
|
videoDecoderSpecification =
|
||||||
CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
|
CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
|
||||||
|
@ -333,7 +418,7 @@ gst_vtdec_create_session (GstVtdec * vtdec)
|
||||||
CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
|
CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
|
||||||
&kCFTypeDictionaryValueCallBacks);
|
&kCFTypeDictionaryValueCallBacks);
|
||||||
gst_vtutil_dict_set_i32 (output_image_buffer_attrs,
|
gst_vtutil_dict_set_i32 (output_image_buffer_attrs,
|
||||||
kCVPixelBufferPixelFormatTypeKey, GST_VTDEC_CV_VIDEO_FORMAT);
|
kCVPixelBufferPixelFormatTypeKey, cv_format);
|
||||||
gst_vtutil_dict_set_i32 (output_image_buffer_attrs, kCVPixelBufferWidthKey,
|
gst_vtutil_dict_set_i32 (output_image_buffer_attrs, kCVPixelBufferWidthKey,
|
||||||
vtdec->video_info.width);
|
vtdec->video_info.width);
|
||||||
gst_vtutil_dict_set_i32 (output_image_buffer_attrs, kCVPixelBufferHeightKey,
|
gst_vtutil_dict_set_i32 (output_image_buffer_attrs, kCVPixelBufferHeightKey,
|
||||||
|
@ -557,13 +642,12 @@ gst_vtdec_session_output_callback (void *decompression_output_ref_con,
|
||||||
}
|
}
|
||||||
buf = gst_core_video_buffer_new (image_buffer, &state->info);
|
buf = gst_core_video_buffer_new (image_buffer, &state->info);
|
||||||
gst_video_codec_state_unref (state);
|
gst_video_codec_state_unref (state);
|
||||||
frame->output_buffer = buf;
|
|
||||||
|
|
||||||
gst_buffer_copy_into (buf, frame->input_buffer,
|
gst_buffer_copy_into (buf, frame->input_buffer,
|
||||||
GST_BUFFER_COPY_METADATA | GST_BUFFER_COPY_FLAGS, 0, -1);
|
GST_BUFFER_COPY_METADATA | GST_BUFFER_COPY_FLAGS, 0, -1);
|
||||||
GST_BUFFER_PTS (buf) = pts.value;
|
GST_BUFFER_PTS (buf) = pts.value;
|
||||||
GST_BUFFER_DURATION (buf) = duration.value;
|
GST_BUFFER_DURATION (buf) = duration.value;
|
||||||
|
frame->output_buffer = buf;
|
||||||
g_async_queue_push_sorted (vtdec->reorder_queue, frame,
|
g_async_queue_push_sorted (vtdec->reorder_queue, frame,
|
||||||
sort_frames_by_pts, NULL);
|
sort_frames_by_pts, NULL);
|
||||||
|
|
||||||
|
@ -590,6 +674,11 @@ gst_vtdec_push_frames_if_needed (GstVtdec * vtdec, gboolean drain,
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GstVideoDecoder *decoder = GST_VIDEO_DECODER (vtdec);
|
GstVideoDecoder *decoder = GST_VIDEO_DECODER (vtdec);
|
||||||
|
|
||||||
|
/* negotiate now so that we know whether we need to use the GL upload meta or
|
||||||
|
* not */
|
||||||
|
if (gst_pad_check_reconfigure (decoder->srcpad))
|
||||||
|
gst_video_decoder_negotiate (decoder);
|
||||||
|
|
||||||
if (drain)
|
if (drain)
|
||||||
VTDecompressionSessionWaitForAsynchronousFrames (vtdec->session);
|
VTDecompressionSessionWaitForAsynchronousFrames (vtdec->session);
|
||||||
|
|
||||||
|
@ -599,6 +688,15 @@ gst_vtdec_push_frames_if_needed (GstVtdec * vtdec, gboolean drain,
|
||||||
while ((g_async_queue_length (vtdec->reorder_queue) >=
|
while ((g_async_queue_length (vtdec->reorder_queue) >=
|
||||||
vtdec->reorder_queue_length) || drain || flush) {
|
vtdec->reorder_queue_length) || drain || flush) {
|
||||||
frame = (GstVideoCodecFrame *) g_async_queue_try_pop (vtdec->reorder_queue);
|
frame = (GstVideoCodecFrame *) g_async_queue_try_pop (vtdec->reorder_queue);
|
||||||
|
if (vtdec->texture_cache != NULL) {
|
||||||
|
GstVideoGLTextureType texture_types[4] =
|
||||||
|
{ GST_VIDEO_GL_TEXTURE_TYPE_RGBA, 0 };
|
||||||
|
gst_buffer_add_video_gl_texture_upload_meta (frame->output_buffer,
|
||||||
|
GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, 1, texture_types,
|
||||||
|
gst_core_video_texture_cache_upload, vtdec->texture_cache, NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* we need to check this in case reorder_queue_length=0 (jpeg for
|
/* we need to check this in case reorder_queue_length=0 (jpeg for
|
||||||
* example) or we're draining/flushing
|
* example) or we're draining/flushing
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <gst/video/gstvideodecoder.h>
|
#include <gst/video/gstvideodecoder.h>
|
||||||
#include <CoreMedia/CoreMedia.h>
|
#include <CoreMedia/CoreMedia.h>
|
||||||
#include <VideoToolbox/VideoToolbox.h>
|
#include <VideoToolbox/VideoToolbox.h>
|
||||||
|
#include "corevideotexturecache.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ struct _GstVtdec
|
||||||
VTDecompressionSessionRef session;
|
VTDecompressionSessionRef session;
|
||||||
GAsyncQueue *reorder_queue;
|
GAsyncQueue *reorder_queue;
|
||||||
gint reorder_queue_length;
|
gint reorder_queue_length;
|
||||||
|
GstCoreVideoTextureCache *texture_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstVtdecClass
|
struct _GstVtdecClass
|
||||||
|
|
Loading…
Reference in a new issue