Branch data Line data Source code
1 : : /* GStreamer Jasper based j2k image encoder
2 : : * Copyright (C) 2008 Mark Nauwelaerts <mnauw@users.sf.net>
3 : : *
4 : : * This library is free software; you can redistribute it and/or
5 : : * modify it under the terms of the GNU Library General Public
6 : : * License as published by the Free Software Foundation; either
7 : : * version 2 of the License, or (at your option) any later version.
8 : : *
9 : : * This library is distributed in the hope that it will be useful,
10 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : : * Library General Public License for more details.
13 : : *
14 : : * You should have received a copy of the GNU Library General Public
15 : : * License along with this library; if not, write to the
16 : : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 : : * Boston, MA 02111-1307, USA.
18 : : */
19 : :
20 : : /**
21 : : * SECTION:element-jasperenc
22 : : *
23 : : * Encodes video to jpeg2000 images.
24 : : */
25 : :
26 : : #ifdef HAVE_CONFIG_H
27 : : #include "config.h"
28 : : #endif
29 : : #include <gst/gst.h>
30 : : #include <gst/video/video.h>
31 : : #include <string.h>
32 : :
33 : : #include <jasper/jasper.h>
34 : :
35 : : #include "gstjasperenc.h"
36 : :
37 : : GST_DEBUG_CATEGORY_STATIC (gst_jasper_enc_debug);
38 : : #define GST_CAT_DEFAULT gst_jasper_enc_debug
39 : :
40 : : enum
41 : : {
42 : : ARG_0,
43 : : };
44 : :
45 : : static GstStaticPadTemplate gst_jasper_enc_sink_template =
46 : : GST_STATIC_PAD_TEMPLATE ("sink",
47 : : GST_PAD_SINK,
48 : : GST_PAD_ALWAYS,
49 : : GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB "; " GST_VIDEO_CAPS_BGR "; "
50 : : GST_VIDEO_CAPS_RGBx "; " GST_VIDEO_CAPS_xRGB "; "
51 : : GST_VIDEO_CAPS_BGRx "; " GST_VIDEO_CAPS_xBGR "; "
52 : : GST_VIDEO_CAPS_YUV ("{ I420, YV12, v308 }"))
53 : : );
54 : :
55 : : static GstStaticPadTemplate gst_jasper_enc_src_template =
56 : : GST_STATIC_PAD_TEMPLATE ("src",
57 : : GST_PAD_SRC,
58 : : GST_PAD_ALWAYS,
59 : : GST_STATIC_CAPS ("image/x-j2c, width = " GST_VIDEO_SIZE_RANGE ", height = "
60 : : GST_VIDEO_SIZE_RANGE ", fourcc = (GstFourcc) { sRGB, sYUV },"
61 : : "framerate = " GST_VIDEO_FPS_RANGE ", " "fields = (int) 1; "
62 : : "image/x-jpc, width = " GST_VIDEO_SIZE_RANGE ", height = "
63 : : GST_VIDEO_SIZE_RANGE ", fourcc = (GstFourcc) { sRGB, sYUV },"
64 : : "framerate = " GST_VIDEO_FPS_RANGE ", " "fields = (int) 1; "
65 : : "image/jp2")
66 : : );
67 : :
68 : : static void gst_jasper_enc_set_property (GObject * object, guint prop_id,
69 : : const GValue * value, GParamSpec * pspec);
70 : : static void gst_jasper_enc_get_property (GObject * object, guint prop_id,
71 : : GValue * value, GParamSpec * pspec);
72 : :
73 : : static void gst_jasper_enc_reset (GstJasperEnc * enc);
74 : : static GstStateChangeReturn gst_jasper_enc_change_state (GstElement * element,
75 : : GstStateChange transition);
76 : : static gboolean gst_jasper_enc_sink_setcaps (GstPad * pad, GstCaps * caps);
77 : : static GstFlowReturn gst_jasper_enc_chain (GstPad * pad, GstBuffer * buffer);
78 : :
79 : : /* minor trick:
80 : : * keep original naming but use unique name here for a happy type system
81 : : */
82 : :
83 : : typedef GstJasperEnc GstJp2kEnc;
84 : : typedef GstJasperEncClass GstJp2kEncClass;
85 : :
86 : : static void
87 : 0 : _do_init (GType object_type)
88 : : {
89 : 0 : const GInterfaceInfo preset_interface_info = {
90 : : NULL, /* interface_init */
91 : : NULL, /* interface_finalize */
92 : : NULL /* interface_data */
93 : : };
94 : :
95 : 0 : g_type_add_interface_static (object_type, GST_TYPE_PRESET,
96 : : &preset_interface_info);
97 : 0 : }
98 : :
99 [ # # ]: 0 : GST_BOILERPLATE_FULL (GstJp2kEnc, gst_jasper_enc, GstElement, GST_TYPE_ELEMENT,
100 : 0 : _do_init);
101 : :
102 : : static void
103 : 0 : gst_jasper_enc_base_init (gpointer g_class)
104 : : {
105 : 0 : GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
106 : :
107 : 0 : gst_element_class_add_pad_template (element_class,
108 : : gst_static_pad_template_get (&gst_jasper_enc_src_template));
109 : 0 : gst_element_class_add_pad_template (element_class,
110 : : gst_static_pad_template_get (&gst_jasper_enc_sink_template));
111 : 0 : gst_element_class_set_details_simple (element_class,
112 : : "Jasper JPEG2000 image encoder", "Codec/Encoder/Image",
113 : : "Encodes video to JPEG2000 using jasper",
114 : : "Mark Nauwelaerts <mnauw@users.sf.net>");
115 : 0 : }
116 : :
117 : : /* initialize the plugin's class */
118 : : static void
119 : 0 : gst_jasper_enc_class_init (GstJasperEncClass * klass)
120 : : {
121 : : GObjectClass *gobject_class;
122 : : GstElementClass *gstelement_class;
123 : :
124 : 0 : gobject_class = (GObjectClass *) klass;
125 : 0 : gstelement_class = (GstElementClass *) klass;
126 : :
127 [ # # ]: 0 : GST_DEBUG_CATEGORY_INIT (gst_jasper_enc_debug, "jp2kenc", 0,
128 : : "Jasper JPEG2000 encoder");
129 : :
130 : 0 : gobject_class->set_property = gst_jasper_enc_set_property;
131 : 0 : gobject_class->get_property = gst_jasper_enc_get_property;
132 : :
133 : : /* FIXME add some encoder properties */
134 : :
135 : 0 : gstelement_class->change_state =
136 : 0 : GST_DEBUG_FUNCPTR (gst_jasper_enc_change_state);
137 : 0 : }
138 : :
139 : : static void
140 : 0 : gst_jasper_enc_init (GstJasperEnc * enc, GstJasperEncClass * klass)
141 : : {
142 : 0 : enc->sinkpad =
143 : 0 : gst_pad_new_from_static_template (&gst_jasper_enc_sink_template, "sink");
144 : 0 : gst_pad_set_setcaps_function (enc->sinkpad,
145 : 0 : GST_DEBUG_FUNCPTR (gst_jasper_enc_sink_setcaps));
146 : 0 : gst_pad_set_chain_function (enc->sinkpad,
147 : 0 : GST_DEBUG_FUNCPTR (gst_jasper_enc_chain));
148 : 0 : gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad);
149 : :
150 : 0 : enc->srcpad =
151 : 0 : gst_pad_new_from_static_template (&gst_jasper_enc_src_template, "src");
152 : 0 : gst_pad_use_fixed_caps (enc->srcpad);
153 : 0 : gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad);
154 : :
155 : 0 : enc->buf = NULL;
156 : 0 : gst_jasper_enc_reset (enc);
157 : 0 : }
158 : :
159 : : static void
160 : 0 : gst_jasper_enc_reset (GstJasperEnc * enc)
161 : : {
162 [ # # ]: 0 : if (enc->buf)
163 : 0 : g_free (enc->buf);
164 : 0 : enc->buf = NULL;
165 [ # # ]: 0 : if (enc->image)
166 : 0 : jas_image_destroy (enc->image);
167 : 0 : enc->image = NULL;
168 : 0 : enc->fmt = -1;
169 : 0 : enc->mode = GST_JP2ENC_MODE_J2C;
170 : 0 : enc->clrspc = JAS_CLRSPC_UNKNOWN;
171 : 0 : enc->format = GST_VIDEO_FORMAT_UNKNOWN;
172 : 0 : }
173 : :
174 : : static gboolean
175 : 0 : gst_jasper_enc_set_src_caps (GstJasperEnc * enc)
176 : : {
177 : : GstCaps *caps;
178 : : guint32 fourcc;
179 : : gboolean ret;
180 : : GstCaps *peercaps;
181 : :
182 : 0 : peercaps = gst_pad_peer_get_caps (enc->srcpad);
183 [ # # ]: 0 : if (peercaps) {
184 : : guint i, n;
185 : :
186 : 0 : n = gst_caps_get_size (peercaps);
187 [ # # ]: 0 : for (i = 0; i < n; i++) {
188 : 0 : GstStructure *s = gst_caps_get_structure (peercaps, i);
189 : 0 : const gchar *name = gst_structure_get_name (s);
190 : :
191 [ # # ]: 0 : if (!strcmp (name, "image/x-j2c")) {
192 : 0 : enc->mode = GST_JP2ENC_MODE_J2C;
193 : 0 : break;
194 [ # # ]: 0 : } else if (!strcmp (name, "image/x-jpc")) {
195 : 0 : enc->mode = GST_JP2ENC_MODE_JPC;
196 : 0 : break;
197 [ # # ]: 0 : } else if (!strcmp (name, "image/jp2")) {
198 : 0 : enc->mode = GST_JP2ENC_MODE_JP2;
199 : 0 : break;
200 : : }
201 : : }
202 : 0 : gst_caps_unref (peercaps);
203 : : }
204 : :
205 : : /* enumerated colourspace */
206 [ # # ]: 0 : if (gst_video_format_is_rgb (enc->format)) {
207 : 0 : fourcc = GST_MAKE_FOURCC ('s', 'R', 'G', 'B');
208 : : } else {
209 : 0 : fourcc = GST_MAKE_FOURCC ('s', 'Y', 'U', 'V');
210 : : }
211 : :
212 [ # # # # ]: 0 : switch (enc->mode) {
213 : : case GST_JP2ENC_MODE_J2C:
214 : 0 : caps =
215 : 0 : gst_caps_new_simple ("image/x-j2c", "width", G_TYPE_INT, enc->width,
216 : : "height", G_TYPE_INT, enc->height, "fourcc", GST_TYPE_FOURCC, fourcc,
217 : : NULL);
218 : 0 : break;
219 : : case GST_JP2ENC_MODE_JPC:
220 : 0 : caps =
221 : 0 : gst_caps_new_simple ("image/x-jpc", "width", G_TYPE_INT, enc->width,
222 : : "height", G_TYPE_INT, enc->height, "fourcc", GST_TYPE_FOURCC, fourcc,
223 : : NULL);
224 : 0 : break;
225 : : case GST_JP2ENC_MODE_JP2:
226 : 0 : caps = gst_caps_new_simple ("image/jp2", "width", G_TYPE_INT, enc->width,
227 : : "height", G_TYPE_INT, enc->height, "fourcc", GST_TYPE_FOURCC, fourcc,
228 : : NULL);
229 : 0 : break;
230 : : default:
231 : 0 : g_assert_not_reached ();
232 : : }
233 : :
234 : :
235 [ # # ]: 0 : if (enc->fps_den > 0)
236 : 0 : gst_caps_set_simple (caps,
237 : : "framerate", GST_TYPE_FRACTION, enc->fps_num, enc->fps_den, NULL);
238 [ # # ]: 0 : if (enc->par_den > 0)
239 : 0 : gst_caps_set_simple (caps,
240 : : "pixel-aspect-ratio", GST_TYPE_FRACTION, enc->par_num, enc->par_den,
241 : : NULL);
242 : :
243 : 0 : ret = gst_pad_set_caps (enc->srcpad, caps);
244 : 0 : gst_caps_unref (caps);
245 : :
246 : 0 : return ret;
247 : : }
248 : :
249 : : static gboolean
250 : 0 : gst_jasper_enc_init_encoder (GstJasperEnc * enc)
251 : : {
252 : : jas_image_cmptparm_t param[GST_JASPER_ENC_MAX_COMPONENT];
253 : : gint i;
254 : :
255 [ # # # ]: 0 : switch (enc->mode) {
256 : : case GST_JP2ENC_MODE_J2C:
257 : : case GST_JP2ENC_MODE_JPC:
258 : 0 : enc->fmt = jas_image_strtofmt ((char *) "jpc");
259 : 0 : break;
260 : : case GST_JP2ENC_MODE_JP2:
261 : 0 : enc->fmt = jas_image_strtofmt ((char *) "jp2");
262 : 0 : break;
263 : : }
264 : :
265 [ # # ]: 0 : if (gst_video_format_is_rgb (enc->format))
266 : 0 : enc->clrspc = JAS_CLRSPC_SRGB;
267 : : else
268 : 0 : enc->clrspc = JAS_CLRSPC_SYCBCR;
269 : :
270 [ # # ]: 0 : if (enc->buf) {
271 : 0 : g_free (enc->buf);
272 : 0 : enc->buf = NULL;
273 : : }
274 : 0 : enc->buf = g_new0 (glong, enc->width);
275 : :
276 [ # # ]: 0 : if (enc->image) {
277 : 0 : jas_image_destroy (enc->image);
278 : 0 : enc->image = NULL;
279 : : }
280 : :
281 [ # # ]: 0 : for (i = 0; i < enc->channels; ++i) {
282 : 0 : param[i].tlx = 0;
283 : 0 : param[i].tly = 0;
284 : 0 : param[i].prec = 8;
285 : 0 : param[i].sgnd = 0;
286 : 0 : param[i].height = enc->cheight[i];
287 : 0 : param[i].width = enc->cwidth[i];
288 : 0 : param[i].hstep = enc->height / param[i].height;
289 : 0 : param[i].vstep = enc->width / param[i].width;
290 : : }
291 : :
292 [ # # ]: 0 : if (!(enc->image = jas_image_create (enc->channels, param, enc->clrspc)))
293 : 0 : return FALSE;
294 : :
295 : 0 : return TRUE;
296 : : }
297 : :
298 : : static gboolean
299 : 0 : gst_jasper_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
300 : : {
301 : : GstJasperEnc *enc;
302 : : GstStructure *s;
303 : : const gchar *mimetype;
304 : : GstVideoFormat format;
305 : : gint width, height;
306 : : gint fps_num, fps_den;
307 : : gint par_num, par_den;
308 : : gint i;
309 : :
310 : 0 : enc = GST_JASPER_ENC (GST_PAD_PARENT (pad));
311 : 0 : s = gst_caps_get_structure (caps, 0);
312 : 0 : mimetype = gst_structure_get_name (s);
313 : :
314 : : /* get info from caps */
315 [ # # ]: 0 : if (!gst_video_format_parse_caps (caps, &format, &width, &height))
316 : 0 : goto refuse_caps;
317 : : /* optional; pass along if present */
318 : 0 : fps_num = fps_den = -1;
319 : 0 : par_num = par_den = -1;
320 : 0 : gst_video_parse_caps_framerate (caps, &fps_num, &fps_den);
321 : 0 : gst_video_parse_caps_pixel_aspect_ratio (caps, &par_num, &par_den);
322 : :
323 [ # # ][ # # ]: 0 : if (width == enc->width && height == enc->height && enc->format == format
[ # # ]
324 [ # # ][ # # ]: 0 : && fps_num == enc->fps_num && fps_den == enc->fps_den
325 [ # # ][ # # ]: 0 : && par_num == enc->par_num && par_den == enc->par_den)
326 : 0 : return TRUE;
327 : :
328 : : /* store input description */
329 : 0 : enc->format = format;
330 : 0 : enc->width = width;
331 : 0 : enc->height = height;
332 : 0 : enc->fps_num = fps_num;
333 : 0 : enc->fps_den = fps_den;
334 : 0 : enc->par_num = par_num;
335 : 0 : enc->par_den = par_den;
336 : :
337 : : /* prepare a cached image description */
338 [ # # ]: 0 : enc->channels = 3 + (gst_video_format_has_alpha (format) ? 1 : 0);
339 [ # # ]: 0 : for (i = 0; i < enc->channels; ++i) {
340 : 0 : enc->cwidth[i] = gst_video_format_get_component_width (format, i, width);
341 : 0 : enc->cheight[i] = gst_video_format_get_component_height (format, i, height);
342 : 0 : enc->offset[i] = gst_video_format_get_component_offset (format, i, width,
343 : : height);
344 : 0 : enc->stride[i] = gst_video_format_get_row_stride (format, i, width);
345 : 0 : enc->inc[i] = gst_video_format_get_pixel_stride (format, i);
346 : : }
347 : :
348 [ # # ]: 0 : if (!gst_jasper_enc_set_src_caps (enc))
349 : 0 : goto setcaps_failed;
350 [ # # ]: 0 : if (!gst_jasper_enc_init_encoder (enc))
351 : 0 : goto setup_failed;
352 : :
353 : 0 : return TRUE;
354 : :
355 : : /* ERRORS */
356 : : setup_failed:
357 : : {
358 [ # # ][ # # ]: 0 : GST_ELEMENT_ERROR (enc, LIBRARY, SETTINGS, (NULL), (NULL));
[ # # ][ # # ]
359 : 0 : return FALSE;
360 : : }
361 : : setcaps_failed:
362 : : {
363 [ # # ]: 0 : GST_WARNING_OBJECT (enc, "Setting src caps failed");
364 [ # # ][ # # ]: 0 : GST_ELEMENT_ERROR (enc, LIBRARY, SETTINGS, (NULL), (NULL));
[ # # ][ # # ]
365 : 0 : return FALSE;
366 : : }
367 : : refuse_caps:
368 : : {
369 [ # # ]: 0 : GST_WARNING_OBJECT (enc, "refused caps %" GST_PTR_FORMAT, caps);
370 : 0 : gst_object_unref (enc);
371 : 0 : return FALSE;
372 : : }
373 : : }
374 : :
375 : : static GstFlowReturn
376 : 0 : gst_jasper_enc_get_data (GstJasperEnc * enc, guint8 * data, GstBuffer ** outbuf)
377 : : {
378 : 0 : GstFlowReturn ret = GST_FLOW_OK;
379 : 0 : jas_stream_t *stream = NULL;
380 : : gint i;
381 : : guint size, boxsize;
382 : :
383 [ # # ]: 0 : g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR);
384 : :
385 : 0 : *outbuf = NULL;
386 : :
387 [ # # ]: 0 : boxsize = (enc->mode == GST_JP2ENC_MODE_J2C) ? 8 : 0;
388 : :
389 [ # # ]: 0 : if (!(stream = jas_stream_memopen (NULL, 0)))
390 : 0 : goto fail_stream;
391 : :
392 [ # # ]: 0 : for (i = 0; i < enc->channels; ++i) {
393 : : gint x, y, cwidth, cheight, inc, stride, cmpt;
394 : : guint8 *row_pix, *in_pix;
395 : : glong *tb;
396 : :
397 : 0 : cmpt = i;
398 : 0 : inc = enc->inc[i];
399 : 0 : stride = enc->stride[i];
400 : 0 : cheight = enc->cheight[cmpt];
401 : 0 : cwidth = enc->cwidth[cmpt];
402 : :
403 [ # # ]: 0 : GST_LOG_OBJECT (enc,
404 : : "write component %d<=%d, size %dx%d, offset %d, inc %d, stride %d",
405 : : i, cmpt, cwidth, cheight, enc->offset[i], inc, stride);
406 : :
407 : 0 : row_pix = data + enc->offset[i];
408 : :
409 [ # # ]: 0 : for (y = 0; y < cheight; y++) {
410 : 0 : in_pix = row_pix;
411 : 0 : tb = enc->buf;
412 [ # # ]: 0 : for (x = 0; x < cwidth; x++) {
413 : 0 : *tb = *in_pix;
414 : 0 : in_pix += inc;
415 : 0 : tb++;
416 : : }
417 [ # # ]: 0 : if (jas_image_writecmpt2 (enc->image, cmpt, 0, y, cwidth, 1, enc->buf))
418 : 0 : goto fail_image;
419 : 0 : row_pix += stride;
420 : : }
421 : : }
422 : :
423 [ # # ]: 0 : GST_LOG_OBJECT (enc, "all components written");
424 : :
425 [ # # ]: 0 : if (jas_image_encode (enc->image, stream, enc->fmt, (char *) "sop"))
426 : 0 : goto fail_encode;
427 : :
428 [ # # ]: 0 : GST_LOG_OBJECT (enc, "image encoded");
429 : :
430 : 0 : size = jas_stream_length (stream);
431 : 0 : ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad,
432 : 0 : GST_BUFFER_OFFSET_NONE, size + boxsize, GST_PAD_CAPS (enc->srcpad),
433 : : outbuf);
434 : :
435 [ # # ]: 0 : if (ret != GST_FLOW_OK)
436 : 0 : goto no_buffer;
437 : :
438 : 0 : data = GST_BUFFER_DATA (*outbuf);
439 [ # # # # ]: 0 : if (jas_stream_flush (stream) ||
440 [ # # ]: 0 : jas_stream_rewind (stream) < 0 ||
441 : 0 : jas_stream_read (stream, data + boxsize, size) < size)
442 : : goto fail_image_out;
443 : :
444 [ # # ]: 0 : if (boxsize) {
445 : : /* write atom prefix */
446 : 0 : GST_WRITE_UINT32_BE (data, size + 8);
447 : 0 : GST_WRITE_UINT32_LE (data + 4, GST_MAKE_FOURCC ('j', 'p', '2', 'c'));
448 : : }
449 : :
450 : : done:
451 [ # # ]: 0 : if (stream)
452 : 0 : jas_stream_close (stream);
453 : :
454 : 0 : return ret;
455 : :
456 : : /* ERRORS */
457 : : fail_stream:
458 : : {
459 [ # # ]: 0 : GST_DEBUG_OBJECT (enc, "Failed to create inputstream.");
460 : 0 : goto fail;
461 : : }
462 : : fail_encode:
463 : : {
464 [ # # ]: 0 : GST_DEBUG_OBJECT (enc, "Failed to encode image.");
465 : 0 : goto fail;
466 : : }
467 : : fail_image:
468 : : {
469 [ # # ]: 0 : GST_DEBUG_OBJECT (enc, "Failed to process input image.");
470 : 0 : goto fail;
471 : : }
472 : : fail_image_out:
473 : : {
474 [ # # ]: 0 : GST_DEBUG_OBJECT (enc, "Failed to process encoded image.");
475 : 0 : goto fail;
476 : : }
477 : : fail:
478 : : {
479 [ # # ]: 0 : if (*outbuf)
480 : 0 : gst_buffer_unref (*outbuf);
481 : 0 : *outbuf = NULL;
482 [ # # ][ # # ]: 0 : GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), (NULL));
[ # # ][ # # ]
483 : 0 : ret = GST_FLOW_ERROR;
484 : 0 : goto done;
485 : : }
486 : : no_buffer:
487 : : {
488 [ # # ]: 0 : GST_DEBUG_OBJECT (enc, "Failed to create outbuffer - %s",
489 : : gst_flow_get_name (ret));
490 : 0 : goto done;
491 : : }
492 : : }
493 : :
494 : : static GstFlowReturn
495 : 0 : gst_jasper_enc_chain (GstPad * pad, GstBuffer * buf)
496 : : {
497 : : GstJasperEnc *enc;
498 : 0 : GstFlowReturn ret = GST_FLOW_OK;
499 : 0 : GstBuffer *outbuf = NULL;
500 : : guint8 *data;
501 : 0 : gboolean discont = FALSE;
502 : :
503 : 0 : enc = GST_JASPER_ENC (gst_pad_get_parent (pad));
504 : :
505 [ # # ]: 0 : if (enc->fmt < 0)
506 : 0 : goto not_negotiated;
507 : :
508 [ # # ][ # # ]: 0 : GST_LOG_OBJECT (enc, "buffer with ts: %" GST_TIME_FORMAT,
[ # # ][ # # ]
[ # # ]
509 : : GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
510 : :
511 : 0 : discont = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT);
512 : :
513 : : /* now really feed the data to encoder */
514 : 0 : data = GST_BUFFER_DATA (buf);
515 : 0 : ret = gst_jasper_enc_get_data (enc, data, &outbuf);
516 : :
517 [ # # ]: 0 : if (outbuf) {
518 : 0 : gst_buffer_copy_metadata (outbuf, buf, GST_BUFFER_COPY_TIMESTAMPS);
519 [ # # ]: 0 : if (discont)
520 : 0 : GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
521 : : }
522 : :
523 [ # # ][ # # ]: 0 : if (ret == GST_FLOW_OK && outbuf)
524 : 0 : ret = gst_pad_push (enc->srcpad, outbuf);
525 : :
526 : : done:
527 : 0 : gst_buffer_unref (buf);
528 : 0 : gst_object_unref (enc);
529 : :
530 : 0 : return ret;
531 : :
532 : : /* ERRORS */
533 : : not_negotiated:
534 : : {
535 [ # # ][ # # ]: 0 : GST_ELEMENT_ERROR (enc, CORE, NEGOTIATION, (NULL),
[ # # ][ # # ]
536 : : ("format wasn't negotiated before chain function"));
537 : 0 : ret = GST_FLOW_NOT_NEGOTIATED;
538 : 0 : goto done;
539 : : }
540 : : }
541 : :
542 : : static void
543 : 0 : gst_jasper_enc_set_property (GObject * object, guint prop_id,
544 : : const GValue * value, GParamSpec * pspec)
545 : : {
546 : : GstJasperEnc *filter;
547 : :
548 : 0 : filter = GST_JASPER_ENC (object);
549 : :
550 : : switch (prop_id) {
551 : : default:
552 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
553 : 0 : break;
554 : : }
555 : 0 : }
556 : :
557 : : static void
558 : 0 : gst_jasper_enc_get_property (GObject * object, guint prop_id,
559 : : GValue * value, GParamSpec * pspec)
560 : : {
561 : : GstJasperEnc *filter;
562 : :
563 : 0 : filter = GST_JASPER_ENC (object);
564 : :
565 : : switch (prop_id) {
566 : : default:
567 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
568 : 0 : break;
569 : : }
570 : 0 : }
571 : :
572 : : static GstStateChangeReturn
573 : 0 : gst_jasper_enc_change_state (GstElement * element, GstStateChange transition)
574 : : {
575 : 0 : GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
576 : 0 : GstJasperEnc *enc = GST_JASPER_ENC (element);
577 : :
578 [ # # # ]: 0 : switch (transition) {
579 : : case GST_STATE_CHANGE_NULL_TO_READY:
580 [ # # ]: 0 : if (jas_init ())
581 : 0 : goto fail_init;
582 : 0 : break;
583 : : case GST_STATE_CHANGE_READY_TO_PAUSED:
584 : 0 : break;
585 : : default:
586 : 0 : break;
587 : : }
588 : :
589 : 0 : ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
590 [ # # ]: 0 : if (ret == GST_STATE_CHANGE_FAILURE)
591 : 0 : return ret;
592 : :
593 [ # # # ]: 0 : switch (transition) {
594 : : case GST_STATE_CHANGE_PAUSED_TO_READY:
595 : 0 : gst_jasper_enc_reset (enc);
596 : 0 : break;
597 : : case GST_STATE_CHANGE_READY_TO_NULL:
598 : 0 : jas_cleanup ();
599 : 0 : break;
600 : : default:
601 : 0 : break;
602 : : }
603 : :
604 : 0 : return ret;
605 : :
606 : : /* ERRORS */
607 : : fail_init:
608 : : {
609 [ # # ][ # # ]: 0 : GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL), (NULL));
[ # # ][ # # ]
610 : 0 : return GST_STATE_CHANGE_FAILURE;
611 : : }
612 : : }
|