1 /*
2  * GStreamer
3  * Copyright (C) 2012 Edward Hervey <edward@collabora.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include "gstmpegvideometa.h"
26 
27 GST_DEBUG_CATEGORY_STATIC (mpegv_meta_debug);
28 #define GST_CAT_DEFAULT mpegv_meta_debug
29 
30 static gboolean
gst_mpeg_video_meta_init(GstMpegVideoMeta * mpeg_video_meta,gpointer params,GstBuffer * buffer)31 gst_mpeg_video_meta_init (GstMpegVideoMeta * mpeg_video_meta,
32     gpointer params, GstBuffer * buffer)
33 {
34   mpeg_video_meta->sequencehdr = NULL;
35   mpeg_video_meta->sequenceext = NULL;
36   mpeg_video_meta->sequencedispext = NULL;
37   mpeg_video_meta->pichdr = NULL;
38   mpeg_video_meta->picext = NULL;
39   mpeg_video_meta->quantext = NULL;
40   mpeg_video_meta->num_slices = mpeg_video_meta->slice_offset = 0;
41 
42   return TRUE;
43 }
44 
45 static void
gst_mpeg_video_meta_free(GstMpegVideoMeta * mpeg_video_meta,GstBuffer * buffer)46 gst_mpeg_video_meta_free (GstMpegVideoMeta * mpeg_video_meta,
47     GstBuffer * buffer)
48 {
49   if (mpeg_video_meta->sequencehdr)
50     g_slice_free (GstMpegVideoSequenceHdr, mpeg_video_meta->sequencehdr);
51   if (mpeg_video_meta->sequenceext)
52     g_slice_free (GstMpegVideoSequenceExt, mpeg_video_meta->sequenceext);
53   if (mpeg_video_meta->sequencedispext)
54     g_slice_free (GstMpegVideoSequenceDisplayExt,
55         mpeg_video_meta->sequencedispext);
56   if (mpeg_video_meta->pichdr)
57     g_slice_free (GstMpegVideoPictureHdr, mpeg_video_meta->pichdr);
58   if (mpeg_video_meta->picext)
59     g_slice_free (GstMpegVideoPictureExt, mpeg_video_meta->picext);
60   if (mpeg_video_meta->quantext)
61     g_slice_free (GstMpegVideoQuantMatrixExt, mpeg_video_meta->quantext);
62 }
63 
64 static gboolean
gst_mpeg_video_meta_transform(GstBuffer * dest,GstMeta * meta,GstBuffer * buffer,GQuark type,gpointer data)65 gst_mpeg_video_meta_transform (GstBuffer * dest, GstMeta * meta,
66     GstBuffer * buffer, GQuark type, gpointer data)
67 {
68   GstMpegVideoMeta *smeta, *dmeta;
69 
70   smeta = (GstMpegVideoMeta *) meta;
71 
72   if (GST_META_TRANSFORM_IS_COPY (type)) {
73     GstMetaTransformCopy *copy = data;
74 
75     if (!copy->region) {
76       /* only copy if the complete data is copied as well */
77       dmeta =
78           gst_buffer_add_mpeg_video_meta (dest, smeta->sequencehdr,
79           smeta->sequenceext, smeta->sequencedispext, smeta->pichdr,
80           smeta->picext, smeta->quantext);
81 
82       if (!dmeta)
83         return FALSE;
84 
85       dmeta->num_slices = smeta->num_slices;
86       dmeta->slice_offset = smeta->slice_offset;
87     }
88   } else {
89     /* return FALSE, if transform type is not supported */
90     return FALSE;
91   }
92 
93   return TRUE;
94 }
95 
96 GType
gst_mpeg_video_meta_api_get_type(void)97 gst_mpeg_video_meta_api_get_type (void)
98 {
99   static volatile GType type;
100   static const gchar *tags[] = { "memory", NULL };      /* don't know what to set here */
101 
102   if (g_once_init_enter (&type)) {
103     GType _type = gst_meta_api_type_register ("GstMpegVideoMetaAPI", tags);
104     GST_DEBUG_CATEGORY_INIT (mpegv_meta_debug, "mpegvideometa", 0,
105         "MPEG-1/2 video GstMeta");
106 
107     g_once_init_leave (&type, _type);
108   }
109   return type;
110 }
111 
112 const GstMetaInfo *
gst_mpeg_video_meta_get_info(void)113 gst_mpeg_video_meta_get_info (void)
114 {
115   static const GstMetaInfo *mpeg_video_meta_info = NULL;
116 
117   if (g_once_init_enter ((GstMetaInfo **) & mpeg_video_meta_info)) {
118     const GstMetaInfo *meta = gst_meta_register (GST_MPEG_VIDEO_META_API_TYPE,
119         "GstMpegVideoMeta", sizeof (GstMpegVideoMeta),
120         (GstMetaInitFunction) gst_mpeg_video_meta_init,
121         (GstMetaFreeFunction) gst_mpeg_video_meta_free,
122         (GstMetaTransformFunction) gst_mpeg_video_meta_transform);
123     g_once_init_leave ((GstMetaInfo **) & mpeg_video_meta_info,
124         (GstMetaInfo *) meta);
125   }
126 
127   return mpeg_video_meta_info;
128 }
129 
130 /**
131  * gst_buffer_add_mpeg_video_meta:
132  * @buffer: a #GstBuffer
133  *
134  * Creates and adds a #GstMpegVideoMeta to a @buffer.
135  *
136  * Provided structures must either be %NULL or GSlice-allocated.
137  *
138  * Returns: (transfer full): a newly created #GstMpegVideoMeta
139  *
140  * Since: 1.2
141  */
142 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)143 gst_buffer_add_mpeg_video_meta (GstBuffer * buffer,
144     const GstMpegVideoSequenceHdr * seq_hdr,
145     const GstMpegVideoSequenceExt * seq_ext,
146     const GstMpegVideoSequenceDisplayExt * disp_ext,
147     const GstMpegVideoPictureHdr * pic_hdr,
148     const GstMpegVideoPictureExt * pic_ext,
149     const GstMpegVideoQuantMatrixExt * quant_ext)
150 {
151   GstMpegVideoMeta *mpeg_video_meta;
152 
153   mpeg_video_meta =
154       (GstMpegVideoMeta *) gst_buffer_add_meta (buffer,
155       GST_MPEG_VIDEO_META_INFO, NULL);
156 
157   GST_DEBUG
158       ("seq_hdr:%p, seq_ext:%p, disp_ext:%p, pic_hdr:%p, pic_ext:%p, quant_ext:%p",
159       seq_hdr, seq_ext, disp_ext, pic_hdr, pic_ext, quant_ext);
160 
161   if (seq_hdr)
162     mpeg_video_meta->sequencehdr =
163         g_slice_dup (GstMpegVideoSequenceHdr, seq_hdr);
164   if (seq_ext)
165     mpeg_video_meta->sequenceext =
166         g_slice_dup (GstMpegVideoSequenceExt, seq_ext);
167   if (disp_ext)
168     mpeg_video_meta->sequencedispext =
169         g_slice_dup (GstMpegVideoSequenceDisplayExt, disp_ext);
170   mpeg_video_meta->pichdr = g_slice_dup (GstMpegVideoPictureHdr, pic_hdr);
171   if (pic_ext)
172     mpeg_video_meta->picext = g_slice_dup (GstMpegVideoPictureExt, pic_ext);
173   if (quant_ext)
174     mpeg_video_meta->quantext =
175         g_slice_dup (GstMpegVideoQuantMatrixExt, quant_ext);
176 
177   return mpeg_video_meta;
178 }
179