diff --git a/sys/applemedia/coremediabuffer.c b/sys/applemedia/coremediabuffer.c index fa512fd5ed..1e6c1d5fd0 100644 --- a/sys/applemedia/coremediabuffer.c +++ b/sys/applemedia/coremediabuffer.c @@ -23,12 +23,38 @@ #include "coremediabuffer.h" #include "corevideomemory.h" +static const GstMetaInfo *gst_core_media_meta_get_info (void); + +static void +gst_core_media_meta_add (GstBuffer * buffer, CMSampleBufferRef sample_buf, + CVImageBufferRef image_buf, CMBlockBufferRef block_buf) +{ + GstCoreMediaMeta *meta; + + meta = + (GstCoreMediaMeta *) gst_buffer_add_meta (buffer, + gst_core_media_meta_get_info (), NULL); + CFRetain (sample_buf); + if (image_buf) + CVBufferRetain (image_buf); + if (block_buf) + CFRetain (block_buf); + meta->sample_buf = sample_buf; + meta->image_buf = image_buf; + meta->block_buf = block_buf; + if (image_buf != NULL && CFGetTypeID (image_buf) == CVPixelBufferGetTypeID ()) + meta->pixel_buf = (CVPixelBufferRef) image_buf; + else + meta->pixel_buf = NULL; +} + static void gst_core_media_meta_free (GstCoreMediaMeta * meta, GstBuffer * buf) { if (meta->image_buf != NULL) { CVBufferRelease (meta->image_buf); } + if (meta->block_buf != NULL) { CFRelease (meta->block_buf); } @@ -36,6 +62,22 @@ gst_core_media_meta_free (GstCoreMediaMeta * meta, GstBuffer * buf) CFRelease (meta->sample_buf); } +static gboolean +gst_core_media_meta_transform (GstBuffer * transbuf, GstCoreMediaMeta * meta, + GstBuffer * buffer, GQuark type, GstMetaTransformCopy * data) +{ + if (!data->region) { + /* only copy if the complete data is copied as well */ + gst_core_media_meta_add (transbuf, meta->sample_buf, meta->image_buf, + meta->block_buf); + } else { + GST_WARNING_OBJECT (transbuf, + "dropping Core Media metadata due to partial buffer"); + } + + return TRUE; /* retval unused */ +} + GType gst_core_media_meta_api_get_type (void) { @@ -59,7 +101,7 @@ gst_core_media_meta_get_info (void) "GstCoreMediaMeta", sizeof (GstCoreMediaMeta), (GstMetaInitFunction) NULL, (GstMetaFreeFunction) gst_core_media_meta_free, - (GstMetaTransformFunction) NULL); + (GstMetaTransformFunction) gst_core_media_meta_transform); g_once_init_leave (&core_media_meta_info, meta); } return core_media_meta_info; @@ -190,7 +232,6 @@ gst_core_media_buffer_new (CMSampleBufferRef sample_buf, { CVImageBufferRef image_buf; CMBlockBufferRef block_buf; - GstCoreMediaMeta *meta; GstBuffer *buf; image_buf = CMSampleBufferGetImageBuffer (sample_buf); @@ -198,29 +239,18 @@ gst_core_media_buffer_new (CMSampleBufferRef sample_buf, buf = gst_buffer_new (); - meta = (GstCoreMediaMeta *) gst_buffer_add_meta (buf, - gst_core_media_meta_get_info (), NULL); - CFRetain (sample_buf); - if (image_buf) - CVBufferRetain (image_buf); - if (block_buf) - CFRetain (block_buf); - meta->sample_buf = sample_buf; - meta->image_buf = image_buf; - meta->pixel_buf = NULL; - meta->block_buf = block_buf; + gst_core_media_meta_add (buf, sample_buf, image_buf, block_buf); if (image_buf != NULL && CFGetTypeID (image_buf) == CVPixelBufferGetTypeID ()) { GstVideoInfo info; gboolean has_padding = FALSE; + CVPixelBufferRef pixel_buf = (CVPixelBufferRef) image_buf; - meta->pixel_buf = (CVPixelBufferRef) image_buf; - if (!gst_video_info_init_from_pixel_buffer (&info, meta->pixel_buf)) { + if (!gst_video_info_init_from_pixel_buffer (&info, pixel_buf)) { goto error; } - gst_core_video_wrap_pixel_buffer (buf, &info, meta->pixel_buf, &has_padding, - map); + gst_core_video_wrap_pixel_buffer (buf, &info, pixel_buf, &has_padding, map); /* If the video meta API is not supported, remove padding by * copying the core media buffer to a system memory buffer */ diff --git a/sys/applemedia/corevideobuffer.c b/sys/applemedia/corevideobuffer.c index 5979cb3b07..2dfa91a994 100644 --- a/sys/applemedia/corevideobuffer.c +++ b/sys/applemedia/corevideobuffer.c @@ -20,12 +20,40 @@ #include "corevideobuffer.h" #include "corevideomemory.h" +static const GstMetaInfo *gst_core_video_meta_get_info (void); + +static void +gst_core_video_meta_add (GstBuffer * buffer, CVBufferRef cvbuf) +{ + GstCoreVideoMeta *meta; + + meta = (GstCoreVideoMeta *) gst_buffer_add_meta (buffer, + gst_core_video_meta_get_info (), NULL); + meta->cvbuf = CVBufferRetain (cvbuf); + meta->pixbuf = (CVPixelBufferRef) cvbuf; +} + static void gst_core_video_meta_free (GstCoreVideoMeta * meta, GstBuffer * buf) { CVBufferRelease (meta->cvbuf); } +static gboolean +gst_core_video_meta_transform (GstBuffer * transbuf, GstCoreVideoMeta * meta, + GstBuffer * buffer, GQuark type, GstMetaTransformCopy * data) +{ + if (!data->region) { + /* only copy if the complete data is copied as well */ + gst_core_video_meta_add (transbuf, meta->cvbuf); + } else { + GST_WARNING_OBJECT (transbuf, + "dropping Core Video metadata due to partial buffer"); + } + + return TRUE; /* retval unused */ +} + GType gst_core_video_meta_api_get_type (void) { @@ -49,7 +77,7 @@ gst_core_video_meta_get_info (void) "GstCoreVideoMeta", sizeof (GstCoreVideoMeta), (GstMetaInitFunction) NULL, (GstMetaFreeFunction) gst_core_video_meta_free, - (GstMetaTransformFunction) NULL); + (GstMetaTransformFunction) gst_core_video_meta_transform); g_once_init_leave (&core_video_meta_info, meta); } return core_video_meta_info; @@ -140,7 +168,7 @@ gst_core_video_buffer_new (CVBufferRef cvbuf, GstVideoInfo * vinfo, buf = gst_buffer_new (); - /* add the corevideo meta to free the underlying corevideo buffer */ + /* add the corevideo meta to pass the underlying corevideo buffer */ meta = (GstCoreVideoMeta *) gst_buffer_add_meta (buf, gst_core_video_meta_get_info (), NULL); meta->cvbuf = CVBufferRetain (cvbuf);