1 /* GStreamer mplex (mjpegtools) wrapper
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 *
4 * gstmplexjob.hh: gstreamer/mplex multiplex-job wrapper
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "gstmplexjob.hh"
27 #include <gst/gst.h>
28
29 enum
30 {
31 ARG_0,
32 ARG_FORMAT,
33 ARG_MUX_BITRATE,
34 ARG_VBR,
35 ARG_SYSTEM_HEADERS,
36 ARG_SPLIT_SEQUENCE,
37 ARG_SEGMENT_SIZE,
38 ARG_PACKETS_PER_PACK,
39 ARG_SECTOR_SIZE,
40 ARG_BUFSIZE
41 /* FILL ME */
42 };
43
44 #define DEFAULT_FORMAT MPEG_FORMAT_DVD
45 /*
46 * Property enumeration types.
47 */
48
49 #define GST_TYPE_MPLEX_FORMAT \
50 (gst_mplex_format_get_type ())
51
52 static GType
gst_mplex_format_get_type(void)53 gst_mplex_format_get_type (void)
54 {
55 static GType mplex_format_type = 0;
56
57 if (!mplex_format_type) {
58 static const GEnumValue mplex_formats[] = {
59 {MPEG_FORMAT_MPEG1, "Generic MPEG-1", "mpeg-1"},
60 {MPEG_FORMAT_VCD, "Standard VCD", "vcd"},
61 {MPEG_FORMAT_VCD_NSR, "User VCD", "vcd-nsr"},
62 {MPEG_FORMAT_MPEG2, "Generic MPEG-2", "mpeg-2"},
63 {MPEG_FORMAT_SVCD, "Standard SVCD", "svcd"},
64 {MPEG_FORMAT_SVCD_NSR, "User SVCD", "svcd-nsr"},
65 {MPEG_FORMAT_VCD_STILL, "VCD Stills sequences", "vcd-still"},
66 {MPEG_FORMAT_SVCD_STILL, "SVCD Stills sequences", "svcd-still"},
67 {MPEG_FORMAT_DVD_NAV, "DVD MPEG-2 for dvdauthor", "dvd-nav"},
68 {MPEG_FORMAT_DVD, "DVD MPEG-2", "dvd"},
69 {MPEG_FORMAT_ATSC480i, "ATSC 480i", "atsc-480i"},
70 {MPEG_FORMAT_ATSC480p, "ATSC 480p", "atsc-480p"},
71 {MPEG_FORMAT_ATSC720p, "ATSC 720p", "atsc-720p"},
72 {MPEG_FORMAT_ATSC1080i, "ATSC 1080i", "atsc-1080i"},
73 {0, NULL, NULL},
74 };
75
76 mplex_format_type =
77 g_enum_register_static ("GstMplexFormat", mplex_formats);
78 }
79
80 return mplex_format_type;
81 }
82
83 /*
84 * Class init functions.
85 */
86
GstMplexJob(void)87 GstMplexJob::GstMplexJob (void):
88 MultiplexJob ()
89 {
90 /* blabla */
91 bufsize = 0;
92 }
93
94 /*
95 * GObject properties.
96 */
97
98 void
initProperties(GObjectClass * klass)99 GstMplexJob::initProperties (GObjectClass * klass)
100 {
101 /* encoding profile */
102 g_object_class_install_property (klass, ARG_FORMAT,
103 g_param_spec_enum ("format", "Format", "Encoding profile format",
104 GST_TYPE_MPLEX_FORMAT, DEFAULT_FORMAT,
105 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
106
107 /* total stream datarate. Normally, this shouldn't be needed, but
108 * some DVD/VCD/SVCD players really need strict values to handle
109 * the created files correctly. */
110 g_object_class_install_property (klass, ARG_MUX_BITRATE,
111 g_param_spec_int ("mux-bitrate", "Mux. bitrate",
112 "Bitrate of output stream in kbps (0 = autodetect)",
113 0, 15 * 1024, 0,
114 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
115
116 /* override decode buffer size otherwise determined by format */
117 g_object_class_install_property (klass, ARG_BUFSIZE,
118 g_param_spec_int ("bufsize", "Decoder buf. size",
119 "Target decoders video buffer size (kB) "
120 "[default determined by format if not explicitly set]",
121 20, 4000, 46,
122 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
123
124 /* some boolean stuff for headers */
125 g_object_class_install_property (klass, ARG_VBR,
126 g_param_spec_boolean ("vbr", "VBR",
127 "Whether the input video stream is variable bitrate",
128 FALSE,
129 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
130 g_object_class_install_property (klass, ARG_SYSTEM_HEADERS,
131 g_param_spec_boolean ("system-headers", "System headers",
132 "Create system header in every pack for generic formats",
133 FALSE,
134 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
135 #if 0 /* not supported */
136 g_object_class_install_property (klass, ARG_SPLIT_SEQUENCE,
137 g_param_spec_boolean ("split-sequence", "Split sequence",
138 "Simply split a sequence across files "
139 "(rather than building run-out/run-in)",
140 FALSE,
141 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
142
143 /* size of a segment */
144 g_object_class_install_property (klass, ARG_SEGMENT_SIZE,
145 g_param_spec_int ("max-segment-size", "Max. segment size",
146 "Max. size per segment/file in MB (0 = unlimited)",
147 0, 10 * 1024, 0,
148 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
149 #endif
150
151 /* packets per pack (generic formats) */
152 g_object_class_install_property (klass, ARG_PACKETS_PER_PACK,
153 g_param_spec_int ("packets-per-pack", "Packets per pack",
154 "Number of packets per pack for generic formats",
155 1, 100, 1,
156 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
157
158 /* size of one sector */
159 g_object_class_install_property (klass, ARG_SECTOR_SIZE,
160 g_param_spec_int ("sector-size", "Sector size",
161 "Specify sector size in bytes for generic formats",
162 256, 16384, 2048,
163 (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
164
165 gst_type_mark_as_plugin_api (GST_TYPE_MPLEX_FORMAT, (GstPluginAPIFlags) 0);
166 }
167
168 /*
169 * set/get gobject properties.
170 */
171
172 void
getProperty(guint prop_id,GValue * value)173 GstMplexJob::getProperty (guint prop_id, GValue * value)
174 {
175 switch (prop_id) {
176 case ARG_FORMAT:
177 g_value_set_enum (value, mux_format);
178 break;
179 case ARG_MUX_BITRATE:
180 /* convert from bytes back to bits */
181 g_value_set_int (value, (data_rate * 8) / 1000);
182 break;
183 case ARG_VBR:
184 g_value_set_boolean (value, VBR);
185 break;
186 case ARG_SYSTEM_HEADERS:
187 g_value_set_boolean (value, always_system_headers);
188 break;
189 case ARG_SPLIT_SEQUENCE:
190 g_value_set_boolean (value, multifile_segment);
191 break;
192 case ARG_SEGMENT_SIZE:
193 g_value_set_int (value, max_segment_size);
194 break;
195 case ARG_PACKETS_PER_PACK:
196 g_value_set_int (value, packets_per_pack);
197 break;
198 case ARG_SECTOR_SIZE:
199 g_value_set_int (value, sector_size);
200 break;
201 case ARG_BUFSIZE:
202 g_value_set_int (value, bufsize);
203 break;
204 default:
205 break;
206 }
207 }
208
209 void
setProperty(guint prop_id,const GValue * value)210 GstMplexJob::setProperty (guint prop_id, const GValue * value)
211 {
212 switch (prop_id) {
213 case ARG_FORMAT:
214 mux_format = g_value_get_enum (value);
215 break;
216 case ARG_MUX_BITRATE:
217 /* data_rate expects bytes (don't ask me why the property itself is
218 * in bits, I'm just staying compatible to mjpegtools options), and
219 * rounded up to 50-bytes. */
220 data_rate = ((g_value_get_int (value) * 1000 / 8 + 49) / 50) * 50;
221 break;
222 case ARG_VBR:
223 VBR = g_value_get_boolean (value);
224 break;
225 case ARG_SYSTEM_HEADERS:
226 always_system_headers = g_value_get_boolean (value);
227 break;
228 case ARG_SPLIT_SEQUENCE:
229 multifile_segment = g_value_get_boolean (value);
230 break;
231 case ARG_SEGMENT_SIZE:
232 max_segment_size = g_value_get_int (value);
233 break;
234 case ARG_PACKETS_PER_PACK:
235 packets_per_pack = g_value_get_int (value);
236 break;
237 case ARG_SECTOR_SIZE:
238 sector_size = g_value_get_int (value);
239 break;
240 case ARG_BUFSIZE:
241 bufsize = g_value_get_int (value);
242 break;
243 default:
244 break;
245 }
246 }
247