Imported Upstream version 0.10.23
[profile/ivi/gst-plugins-bad.git] / gst / rawparse / gstvideoparse.c
1 /* GStreamer
2  * Copyright (C) 2006 David A. Schleef <ds@schleef.org>
3  * Copyright (C) 2007,2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
4  *
5  * gstvideoparse.c:
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22 /**
23  * SECTION:element-videoparse
24  *
25  * Converts a byte stream into video frames.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 #  include "config.h"
30 #endif
31
32 #include "gstvideoparse.h"
33
34 static void gst_video_parse_set_property (GObject * object, guint prop_id,
35     const GValue * value, GParamSpec * pspec);
36 static void gst_video_parse_get_property (GObject * object, guint prop_id,
37     GValue * value, GParamSpec * pspec);
38
39 static GstCaps *gst_video_parse_get_caps (GstRawParse * rp);
40 static void gst_video_parse_set_buffer_flags (GstRawParse * rp,
41     GstBuffer * buffer);
42
43 static void gst_video_parse_update_frame_size (GstVideoParse * vp);
44
45 GST_DEBUG_CATEGORY_STATIC (gst_video_parse_debug);
46 #define GST_CAT_DEFAULT gst_video_parse_debug
47
48 enum
49 {
50   PROP_0,
51   PROP_FORMAT,
52   PROP_WIDTH,
53   PROP_HEIGHT,
54   PROP_PAR,
55   PROP_FRAMERATE,
56   PROP_INTERLACED,
57   PROP_TOP_FIELD_FIRST
58 };
59
60 GST_BOILERPLATE (GstVideoParse, gst_video_parse, GstRawParse,
61     GST_TYPE_RAW_PARSE);
62
63 static void
64 gst_video_parse_base_init (gpointer g_class)
65 {
66   GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (g_class);
67   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
68   GstCaps *caps;
69
70   GST_DEBUG_CATEGORY_INIT (gst_video_parse_debug, "videoparse", 0,
71       "videoparse element");
72
73   gst_element_class_set_details_simple (gstelement_class, "Video Parse",
74       "Filter/Video",
75       "Converts stream into video frames",
76       "David Schleef <ds@schleef.org>, "
77       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
78
79   caps =
80       gst_caps_from_string
81       ("video/x-raw-rgb; video/x-raw-yuv; video/x-raw-gray; video/x-raw-bayer");
82
83   gst_raw_parse_class_set_src_pad_template (rp_class, caps);
84   gst_raw_parse_class_set_multiple_frames_per_buffer (rp_class, FALSE);
85   gst_caps_unref (caps);
86 }
87
88 static void
89 gst_video_parse_class_init (GstVideoParseClass * klass)
90 {
91   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
92   GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (klass);
93
94   gobject_class->set_property = gst_video_parse_set_property;
95   gobject_class->get_property = gst_video_parse_get_property;
96
97   rp_class->get_caps = gst_video_parse_get_caps;
98   rp_class->set_buffer_flags = gst_video_parse_set_buffer_flags;
99
100   g_object_class_install_property (gobject_class, PROP_FORMAT,
101       g_param_spec_enum ("format", "Format", "Format of images in raw stream",
102           GST_TYPE_VIDEO_FORMAT, GST_VIDEO_FORMAT_I420,
103           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
104   g_object_class_install_property (gobject_class, PROP_WIDTH,
105       g_param_spec_int ("width", "Width", "Width of images in raw stream",
106           0, INT_MAX, 320, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
107   g_object_class_install_property (gobject_class, PROP_HEIGHT,
108       g_param_spec_int ("height", "Height", "Height of images in raw stream",
109           0, INT_MAX, 240, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
110   g_object_class_install_property (gobject_class, PROP_FRAMERATE,
111       gst_param_spec_fraction ("framerate", "Frame Rate",
112           "Frame rate of images in raw stream", 0, 1, 100, 1, 25, 1,
113           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
114   g_object_class_install_property (gobject_class, PROP_PAR,
115       gst_param_spec_fraction ("pixel-aspect-ratio", "Pixel Aspect Ratio",
116           "Pixel aspect ratio of images in raw stream", 1, 100, 100, 1, 1, 1,
117           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
118   g_object_class_install_property (gobject_class, PROP_INTERLACED,
119       g_param_spec_boolean ("interlaced", "Interlaced flag",
120           "True if video is interlaced", FALSE,
121           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
122   g_object_class_install_property (gobject_class, PROP_TOP_FIELD_FIRST,
123       g_param_spec_boolean ("top-field-first", "Top field first",
124           "True if top field is earlier than bottom field", TRUE,
125           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
126 }
127
128 static void
129 gst_video_parse_init (GstVideoParse * vp, GstVideoParseClass * g_class)
130 {
131   vp->width = 320;
132   vp->height = 240;
133   vp->format = GST_VIDEO_FORMAT_I420;
134   vp->par_n = 1;
135   vp->par_d = 1;
136
137   gst_video_parse_update_frame_size (vp);
138   gst_raw_parse_set_fps (GST_RAW_PARSE (vp), 25, 1);
139 }
140
141 static void
142 gst_video_parse_set_property (GObject * object, guint prop_id,
143     const GValue * value, GParamSpec * pspec)
144 {
145   GstVideoParse *vp = GST_VIDEO_PARSE (object);
146
147   g_return_if_fail (!gst_raw_parse_is_negotiated (GST_RAW_PARSE (vp)));
148
149   switch (prop_id) {
150     case PROP_FORMAT:
151       vp->format = g_value_get_enum (value);
152       break;
153     case PROP_WIDTH:
154       vp->width = g_value_get_int (value);
155       break;
156     case PROP_HEIGHT:
157       vp->height = g_value_get_int (value);
158       break;
159     case PROP_FRAMERATE:
160       gst_raw_parse_set_fps (GST_RAW_PARSE (vp),
161           gst_value_get_fraction_numerator (value),
162           gst_value_get_fraction_denominator (value));
163       break;
164     case PROP_PAR:
165       vp->par_n = gst_value_get_fraction_numerator (value);
166       vp->par_d = gst_value_get_fraction_denominator (value);
167       break;
168     case PROP_INTERLACED:
169       vp->interlaced = g_value_get_boolean (value);
170       break;
171     case PROP_TOP_FIELD_FIRST:
172       vp->top_field_first = g_value_get_boolean (value);
173       break;
174     default:
175       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
176       break;
177   }
178
179   gst_video_parse_update_frame_size (vp);
180 }
181
182 static void
183 gst_video_parse_get_property (GObject * object, guint prop_id, GValue * value,
184     GParamSpec * pspec)
185 {
186   GstVideoParse *vp = GST_VIDEO_PARSE (object);
187
188   switch (prop_id) {
189     case PROP_FORMAT:
190       g_value_set_enum (value, vp->format);
191       break;
192     case PROP_WIDTH:
193       g_value_set_int (value, vp->width);
194       break;
195     case PROP_HEIGHT:
196       g_value_set_int (value, vp->height);
197       break;
198     case PROP_FRAMERATE:{
199       gint fps_n, fps_d;
200
201       gst_raw_parse_get_fps (GST_RAW_PARSE (vp), &fps_n, &fps_d);
202       gst_value_set_fraction (value, fps_n, fps_d);
203       break;
204     }
205     case PROP_PAR:
206       gst_value_set_fraction (value, vp->par_n, vp->par_d);
207       break;
208     case PROP_INTERLACED:
209       g_value_set_boolean (value, vp->interlaced);
210       break;
211     case PROP_TOP_FIELD_FIRST:
212       g_value_set_boolean (value, vp->top_field_first);
213       break;
214     default:
215       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
216       break;
217   }
218 }
219
220 void
221 gst_video_parse_update_frame_size (GstVideoParse * vp)
222 {
223   gint framesize;
224
225   framesize = gst_video_format_get_size (vp->format, vp->width, vp->height);
226
227   gst_raw_parse_set_framesize (GST_RAW_PARSE (vp), framesize);
228 }
229
230 static GstCaps *
231 gst_video_parse_get_caps (GstRawParse * rp)
232 {
233   GstVideoParse *vp = GST_VIDEO_PARSE (rp);
234   GstCaps *caps;
235
236   gint fps_n, fps_d;
237
238   gst_raw_parse_get_fps (rp, &fps_n, &fps_d);
239
240   caps =
241       gst_video_format_new_caps_interlaced (vp->format, vp->width, vp->height,
242       fps_n, fps_d, vp->par_n, vp->par_d, vp->interlaced);
243
244   return caps;
245 }
246
247 static void
248 gst_video_parse_set_buffer_flags (GstRawParse * rp, GstBuffer * buffer)
249 {
250   GstVideoParse *vp = GST_VIDEO_PARSE (rp);
251
252   if (vp->interlaced) {
253     if (vp->top_field_first) {
254       GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_TFF);
255     } else {
256       GST_BUFFER_FLAG_UNSET (buffer, GST_VIDEO_BUFFER_TFF);
257     }
258   }
259 }