| /* |
| * GStreamer |
| * Copyright (C) 2012 Edward Hervey <edward@collabora.com> |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with this library; if not, write to the |
| * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| * Boston, MA 02111-1307, USA. |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #include "gstmpegvideometa.h" |
| |
| GST_DEBUG_CATEGORY_STATIC (mpegv_meta_debug); |
| #define GST_CAT_DEFAULT mpegv_meta_debug |
| |
| static gboolean |
| gst_mpeg_video_meta_init (GstMpegVideoMeta * mpeg_video_meta, |
| gpointer params, GstBuffer * buffer) |
| { |
| mpeg_video_meta->sequencehdr = NULL; |
| mpeg_video_meta->sequenceext = NULL; |
| mpeg_video_meta->sequencedispext = NULL; |
| mpeg_video_meta->pichdr = NULL; |
| mpeg_video_meta->picext = NULL; |
| mpeg_video_meta->quantext = NULL; |
| mpeg_video_meta->num_slices = mpeg_video_meta->slice_offset = 0; |
| |
| return TRUE; |
| } |
| |
| static void |
| gst_mpeg_video_meta_free (GstMpegVideoMeta * mpeg_video_meta, |
| GstBuffer * buffer) |
| { |
| if (mpeg_video_meta->sequencehdr) |
| g_slice_free (GstMpegVideoSequenceHdr, mpeg_video_meta->sequencehdr); |
| if (mpeg_video_meta->sequenceext) |
| g_slice_free (GstMpegVideoSequenceExt, mpeg_video_meta->sequenceext); |
| if (mpeg_video_meta->sequencedispext) |
| g_slice_free (GstMpegVideoSequenceDisplayExt, |
| mpeg_video_meta->sequencedispext); |
| if (mpeg_video_meta->pichdr) |
| g_slice_free (GstMpegVideoPictureHdr, mpeg_video_meta->pichdr); |
| if (mpeg_video_meta->picext) |
| g_slice_free (GstMpegVideoPictureExt, mpeg_video_meta->picext); |
| if (mpeg_video_meta->quantext) |
| g_slice_free (GstMpegVideoQuantMatrixExt, mpeg_video_meta->quantext); |
| } |
| |
| static gboolean |
| gst_mpeg_video_meta_transform (GstBuffer * dest, GstMeta * meta, |
| GstBuffer * buffer, GQuark type, gpointer data) |
| { |
| GstMpegVideoMeta *smeta, *dmeta; |
| |
| smeta = (GstMpegVideoMeta *) meta; |
| |
| if (GST_META_TRANSFORM_IS_COPY (type)) { |
| GstMetaTransformCopy *copy = data; |
| |
| if (!copy->region) { |
| /* only copy if the complete data is copied as well */ |
| dmeta = |
| gst_buffer_add_mpeg_video_meta (dest, smeta->sequencehdr, |
| smeta->sequenceext, smeta->sequencedispext, smeta->pichdr, |
| smeta->picext, smeta->quantext); |
| |
| if (!dmeta) |
| return FALSE; |
| |
| dmeta->num_slices = smeta->num_slices; |
| dmeta->slice_offset = smeta->slice_offset; |
| } |
| } else { |
| /* return FALSE, if transform type is not supported */ |
| return FALSE; |
| } |
| |
| return TRUE; |
| } |
| |
| GType |
| gst_mpeg_video_meta_api_get_type (void) |
| { |
| static volatile GType type; |
| static const gchar *tags[] = { "memory", NULL }; /* don't know what to set here */ |
| |
| if (g_once_init_enter (&type)) { |
| GType _type = gst_meta_api_type_register ("GstMpegVideoMetaAPI", tags); |
| GST_DEBUG_CATEGORY_INIT (mpegv_meta_debug, "mpegvideometa", 0, |
| "MPEG-1/2 video GstMeta"); |
| |
| g_once_init_leave (&type, _type); |
| } |
| return type; |
| } |
| |
| const GstMetaInfo * |
| gst_mpeg_video_meta_get_info (void) |
| { |
| static const GstMetaInfo *mpeg_video_meta_info = NULL; |
| |
| if (g_once_init_enter ((GstMetaInfo **) & mpeg_video_meta_info)) { |
| const GstMetaInfo *meta = gst_meta_register (GST_MPEG_VIDEO_META_API_TYPE, |
| "GstMpegVideoMeta", sizeof (GstMpegVideoMeta), |
| (GstMetaInitFunction) gst_mpeg_video_meta_init, |
| (GstMetaFreeFunction) gst_mpeg_video_meta_free, |
| (GstMetaTransformFunction) gst_mpeg_video_meta_transform); |
| g_once_init_leave ((GstMetaInfo **) & mpeg_video_meta_info, |
| (GstMetaInfo *) meta); |
| } |
| |
| return mpeg_video_meta_info; |
| } |
| |
| /** |
| * gst_buffer_add_mpeg_video_meta: |
| * @buffer: a #GstBuffer |
| * |
| * Creates and adds a #GstMpegVideoMeta to a @buffer. |
| * |
| * Provided structures must either be %NULL or GSlice-allocated. |
| * |
| * Returns: (transfer full): a newly created #GstMpegVideoMeta |
| * |
| * Since: 1.2 |
| */ |
| GstMpegVideoMeta * |
| gst_buffer_add_mpeg_video_meta (GstBuffer * buffer, |
| const GstMpegVideoSequenceHdr * seq_hdr, |
| const GstMpegVideoSequenceExt * seq_ext, |
| const GstMpegVideoSequenceDisplayExt * disp_ext, |
| const GstMpegVideoPictureHdr * pic_hdr, |
| const GstMpegVideoPictureExt * pic_ext, |
| const GstMpegVideoQuantMatrixExt * quant_ext) |
| { |
| GstMpegVideoMeta *mpeg_video_meta; |
| |
| mpeg_video_meta = |
| (GstMpegVideoMeta *) gst_buffer_add_meta (buffer, |
| GST_MPEG_VIDEO_META_INFO, NULL); |
| |
| GST_DEBUG |
| ("seq_hdr:%p, seq_ext:%p, disp_ext:%p, pic_hdr:%p, pic_ext:%p, quant_ext:%p", |
| seq_hdr, seq_ext, disp_ext, pic_hdr, pic_ext, quant_ext); |
| |
| if (seq_hdr) |
| mpeg_video_meta->sequencehdr = |
| g_slice_dup (GstMpegVideoSequenceHdr, seq_hdr); |
| if (seq_ext) |
| mpeg_video_meta->sequenceext = |
| g_slice_dup (GstMpegVideoSequenceExt, seq_ext); |
| if (disp_ext) |
| mpeg_video_meta->sequencedispext = |
| g_slice_dup (GstMpegVideoSequenceDisplayExt, disp_ext); |
| mpeg_video_meta->pichdr = g_slice_dup (GstMpegVideoPictureHdr, pic_hdr); |
| if (pic_ext) |
| mpeg_video_meta->picext = g_slice_dup (GstMpegVideoPictureExt, pic_ext); |
| if (quant_ext) |
| mpeg_video_meta->quantext = |
| g_slice_dup (GstMpegVideoQuantMatrixExt, quant_ext); |
| |
| return mpeg_video_meta; |
| } |