mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 14:36:24 +00:00
applemedia: implement copying of meta
Before this, buffers would lose their Core Video / Core Media meta over intervideo* boundary. https://bugzilla.gnome.org/show_bug.cgi?id=747216
This commit is contained in:
parent
936b2fdfbc
commit
8577224c74
2 changed files with 77 additions and 19 deletions
|
@ -23,12 +23,38 @@
|
||||||
#include "coremediabuffer.h"
|
#include "coremediabuffer.h"
|
||||||
#include "corevideomemory.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
|
static void
|
||||||
gst_core_media_meta_free (GstCoreMediaMeta * meta, GstBuffer * buf)
|
gst_core_media_meta_free (GstCoreMediaMeta * meta, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
if (meta->image_buf != NULL) {
|
if (meta->image_buf != NULL) {
|
||||||
CVBufferRelease (meta->image_buf);
|
CVBufferRelease (meta->image_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta->block_buf != NULL) {
|
if (meta->block_buf != NULL) {
|
||||||
CFRelease (meta->block_buf);
|
CFRelease (meta->block_buf);
|
||||||
}
|
}
|
||||||
|
@ -36,6 +62,22 @@ gst_core_media_meta_free (GstCoreMediaMeta * meta, GstBuffer * buf)
|
||||||
CFRelease (meta->sample_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
|
GType
|
||||||
gst_core_media_meta_api_get_type (void)
|
gst_core_media_meta_api_get_type (void)
|
||||||
{
|
{
|
||||||
|
@ -59,7 +101,7 @@ gst_core_media_meta_get_info (void)
|
||||||
"GstCoreMediaMeta", sizeof (GstCoreMediaMeta),
|
"GstCoreMediaMeta", sizeof (GstCoreMediaMeta),
|
||||||
(GstMetaInitFunction) NULL,
|
(GstMetaInitFunction) NULL,
|
||||||
(GstMetaFreeFunction) gst_core_media_meta_free,
|
(GstMetaFreeFunction) gst_core_media_meta_free,
|
||||||
(GstMetaTransformFunction) NULL);
|
(GstMetaTransformFunction) gst_core_media_meta_transform);
|
||||||
g_once_init_leave (&core_media_meta_info, meta);
|
g_once_init_leave (&core_media_meta_info, meta);
|
||||||
}
|
}
|
||||||
return core_media_meta_info;
|
return core_media_meta_info;
|
||||||
|
@ -190,7 +232,6 @@ gst_core_media_buffer_new (CMSampleBufferRef sample_buf,
|
||||||
{
|
{
|
||||||
CVImageBufferRef image_buf;
|
CVImageBufferRef image_buf;
|
||||||
CMBlockBufferRef block_buf;
|
CMBlockBufferRef block_buf;
|
||||||
GstCoreMediaMeta *meta;
|
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
|
|
||||||
image_buf = CMSampleBufferGetImageBuffer (sample_buf);
|
image_buf = CMSampleBufferGetImageBuffer (sample_buf);
|
||||||
|
@ -198,29 +239,18 @@ gst_core_media_buffer_new (CMSampleBufferRef sample_buf,
|
||||||
|
|
||||||
buf = gst_buffer_new ();
|
buf = gst_buffer_new ();
|
||||||
|
|
||||||
meta = (GstCoreMediaMeta *) gst_buffer_add_meta (buf,
|
gst_core_media_meta_add (buf, sample_buf, image_buf, block_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;
|
|
||||||
|
|
||||||
if (image_buf != NULL && CFGetTypeID (image_buf) == CVPixelBufferGetTypeID ()) {
|
if (image_buf != NULL && CFGetTypeID (image_buf) == CVPixelBufferGetTypeID ()) {
|
||||||
GstVideoInfo info;
|
GstVideoInfo info;
|
||||||
gboolean has_padding = FALSE;
|
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, pixel_buf)) {
|
||||||
if (!gst_video_info_init_from_pixel_buffer (&info, meta->pixel_buf)) {
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_core_video_wrap_pixel_buffer (buf, &info, meta->pixel_buf, &has_padding,
|
gst_core_video_wrap_pixel_buffer (buf, &info, pixel_buf, &has_padding, map);
|
||||||
map);
|
|
||||||
|
|
||||||
/* If the video meta API is not supported, remove padding by
|
/* If the video meta API is not supported, remove padding by
|
||||||
* copying the core media buffer to a system memory buffer */
|
* copying the core media buffer to a system memory buffer */
|
||||||
|
|
|
@ -20,12 +20,40 @@
|
||||||
#include "corevideobuffer.h"
|
#include "corevideobuffer.h"
|
||||||
#include "corevideomemory.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
|
static void
|
||||||
gst_core_video_meta_free (GstCoreVideoMeta * meta, GstBuffer * buf)
|
gst_core_video_meta_free (GstCoreVideoMeta * meta, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
CVBufferRelease (meta->cvbuf);
|
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
|
GType
|
||||||
gst_core_video_meta_api_get_type (void)
|
gst_core_video_meta_api_get_type (void)
|
||||||
{
|
{
|
||||||
|
@ -49,7 +77,7 @@ gst_core_video_meta_get_info (void)
|
||||||
"GstCoreVideoMeta", sizeof (GstCoreVideoMeta),
|
"GstCoreVideoMeta", sizeof (GstCoreVideoMeta),
|
||||||
(GstMetaInitFunction) NULL,
|
(GstMetaInitFunction) NULL,
|
||||||
(GstMetaFreeFunction) gst_core_video_meta_free,
|
(GstMetaFreeFunction) gst_core_video_meta_free,
|
||||||
(GstMetaTransformFunction) NULL);
|
(GstMetaTransformFunction) gst_core_video_meta_transform);
|
||||||
g_once_init_leave (&core_video_meta_info, meta);
|
g_once_init_leave (&core_video_meta_info, meta);
|
||||||
}
|
}
|
||||||
return core_video_meta_info;
|
return core_video_meta_info;
|
||||||
|
@ -140,7 +168,7 @@ gst_core_video_buffer_new (CVBufferRef cvbuf, GstVideoInfo * vinfo,
|
||||||
|
|
||||||
buf = gst_buffer_new ();
|
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,
|
meta = (GstCoreVideoMeta *) gst_buffer_add_meta (buf,
|
||||||
gst_core_video_meta_get_info (), NULL);
|
gst_core_video_meta_get_info (), NULL);
|
||||||
meta->cvbuf = CVBufferRetain (cvbuf);
|
meta->cvbuf = CVBufferRetain (cvbuf);
|
||||||
|
|
Loading…
Reference in a new issue