94
90
static GstFlowReturn
95
gst_real_video_dec_alloc_buffer (GstRealVideoDec * dec, GstClockTime timestamp,
91
gst_real_video_dec_chain (GstPad * pad, GstBuffer * in)
102
GstClockTime ts = timestamp;
104
GST_LOG_OBJECT (dec, "timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (ts));
107
b = gst_adapter_peek (dec->adapter, 4);
108
switch (dec->version) {
109
case GST_REAL_VIDEO_DEC_VERSION_2:
113
* Bit 1- 2: frame type
115
* Bit 10-22: sequence number
118
frame_type = (b[0] >> 6) & 0x03;
119
seq = ((b[1] & 0x7f) << 6) + ((b[2] & 0xfc) >> 2);
122
case GST_REAL_VIDEO_DEC_VERSION_3:
126
* Bit 3: skip packet if 1
127
* Bit 4- 5: frame type
129
* Bit 13-25: sequence number
132
frame_type = (b[0] >> 3) & 0x03;
133
seq = ((b[1] & 0x0f) << 9) + (b[2] << 1) + ((b[3] & 0x80) >> 7);
136
case GST_REAL_VIDEO_DEC_VERSION_4:
139
* Bit 1: skip packet if 1
140
* Bit 2- 3: frame type
142
* Bit 14-26: sequence number
145
frame_type = (b[0] >> 5) & 0x03;
146
seq = ((b[1] & 0x07) << 10) + (b[2] << 2) + ((b[3] & 0xc0) >> 6);
150
goto unknown_version;
153
GST_LOG_OBJECT (dec, "frame_type:%d", frame_type);
155
switch (frame_type) {
160
timestamp = dec->next_ts;
161
dec->last_ts = dec->next_ts;
163
dec->last_seq = dec->next_seq;
171
timestamp = dec->last_ts = dec->next_ts;
172
if (seq < dec->next_seq)
173
dec->next_ts += (seq + 0x2000 - dec->next_seq) * GST_MSECOND;
175
dec->next_ts += (seq - dec->next_seq) * GST_MSECOND;
176
dec->last_seq = dec->next_seq;
183
if (seq < dec->last_seq) {
184
timestamp = (seq + 0x2000 - dec->last_seq) * GST_MSECOND + dec->last_ts;
186
timestamp = (seq - dec->last_seq) * GST_MSECOND + dec->last_ts;
192
goto unknown_frame_type;
195
ret = gst_pad_alloc_buffer (dec->src, GST_BUFFER_OFFSET_NONE,
196
dec->width * dec->height * 3 / 2, GST_PAD_CAPS (dec->src), buf);
198
if (ret == GST_FLOW_OK)
199
GST_BUFFER_TIMESTAMP (*buf) = timestamp;
206
GST_ELEMENT_ERROR (dec, STREAM, DECODE,
207
("Unknown version: %i.", dec->version), (NULL));
208
return GST_FLOW_ERROR;
213
GST_ELEMENT_ERROR (dec, STREAM, DECODE, ("Unknown frame type."), (NULL));
214
return GST_FLOW_ERROR;
219
gst_real_video_dec_decode (GstRealVideoDec * dec, GstBuffer * in, guint offset)
99
GstClockTime timestamp, duration;
222
GstBuffer *out = NULL;
224
guint8 *data, hdr_subseq, hdr_seqnum;
225
guint32 hdr_offset, hdr_length;
228
guint8 *buf = GST_BUFFER_DATA (in) + offset;
229
guint len = GST_BUFFER_SIZE (in) - offset;
230
GstClockTime timestamp = GST_BUFFER_TIMESTAMP (in);
233
"Got buffer %p with timestamp %" GST_TIME_FORMAT " offset %d", in,
234
GST_TIME_ARGS (timestamp), offset);
238
goto not_enough_data;
239
if (*buf != 0x40 && *buf != 0x41 && *buf != 0x42 &&
240
*buf != 0x43 && *buf != 0x44 && *buf != 0x45) {
241
hdr_subseq = *buf & 0x7f;
244
if (hdr_subseq == 64)
252
goto not_enough_data;
253
hdr_length = GST_READ_UINT16_BE (buf);
254
if (!(hdr_length & 0xc000)) {
256
goto not_enough_data;
257
hdr_length = GST_READ_UINT32_BE (buf);
261
hdr_length &= 0x3fff;
268
goto not_enough_data;
269
hdr_offset = GST_READ_UINT16_BE (buf);
270
if (!(hdr_offset & 0xc000)) {
272
goto not_enough_data;
273
hdr_offset = GST_READ_UINT32_BE (buf);
277
hdr_offset &= 0x3fff;
282
/* Sequence number */
284
goto not_enough_data;
289
goto not_enough_data;
291
/* Verify the sequence numbers. */
292
if (hdr_subseq == 1) {
293
n = gst_adapter_available_fast (dec->adapter);
295
GST_DEBUG_OBJECT (dec, "Dropping data for sequence %i "
296
"because we are already receiving data for sequence %i.",
297
dec->seqnum, hdr_seqnum);
298
gst_adapter_clear (dec->adapter);
300
dec->seqnum = hdr_seqnum;
301
dec->length = hdr_length;
302
dec->fragment_count = 1;
304
if (dec->seqnum != hdr_seqnum) {
305
GST_DEBUG_OBJECT (dec, "Expected sequence %i, got sequence %i "
306
"(subseq=%i). Dropping packet.", dec->seqnum, hdr_seqnum, hdr_subseq);
308
} else if (dec->subseq + 1 != hdr_subseq) {
309
GST_DEBUG_OBJECT (dec, "Expected subsequence %i, got subseqence %i. "
310
"Dropping packet.", dec->subseq + 1, hdr_subseq);
313
dec->fragment_count++;
315
dec->subseq = hdr_subseq;
317
/* Remember the offset */
318
if (sizeof (dec->fragments) < 2 * (dec->fragment_count - 1) + 1)
319
goto too_many_fragments;
320
dec->fragments[2 * (dec->fragment_count - 1)] = 1;
321
dec->fragments[2 * (dec->fragment_count - 1) + 1] =
322
gst_adapter_available (dec->adapter);
324
/* Some buffers need to be skipped. */
325
if (((dec->version == GST_REAL_VIDEO_DEC_VERSION_3) && (*buf & 0x20)) ||
326
((dec->version == GST_REAL_VIDEO_DEC_VERSION_4) && (*buf & 0x80))) {
327
dec->fragment_count--;
330
gst_adapter_push (dec->adapter,
331
gst_buffer_create_sub (in, GST_BUFFER_SIZE (in) - len, len));
334
/* All bytes received? */
335
n = gst_adapter_available (dec->adapter);
336
GST_LOG_OBJECT (dec, "We know have %d bytes, and we need %d", n, dec->length);
337
if (dec->length <= n) {
342
gst_real_video_dec_alloc_buffer (dec, timestamp,
343
&out)) != GST_FLOW_OK)
347
tin.datalen = dec->length;
349
tin.nfragments = dec->fragment_count - 1;
350
tin.fragments = dec->fragments;
352
tin.timestamp = GST_BUFFER_TIMESTAMP (out);
353
data = gst_adapter_take (dec->adapter, dec->length);
355
result = dec->hooks.transform (
357
(gchar *) GST_BUFFER_DATA (out), &tin, &tout, dec->hooks.context);
361
goto could_not_transform;
363
/* Check for new dimensions */
364
if (tout.frames && ((dec->width != tout.width)
365
|| (dec->height != tout.height))) {
366
GstCaps *caps = gst_caps_copy (GST_PAD_CAPS (dec->src));
367
GstStructure *s = gst_caps_get_structure (caps, 0);
369
GST_DEBUG_OBJECT (dec, "New dimensions: %"
370
G_GUINT32_FORMAT " x %" G_GUINT32_FORMAT, tout.width, tout.height);
371
gst_structure_set (s, "width", G_TYPE_LONG, tout.width,
372
"height", G_TYPE_LONG, tout.height, NULL);
373
bres = gst_pad_set_caps (dec->src, caps);
374
gst_caps_unref (caps);
376
goto new_dimensions_failed;
377
dec->width = tout.width;
378
dec->height = tout.height;
381
GST_DEBUG_OBJECT (dec,
382
"Pushing out buffer with timestamp %" GST_TIME_FORMAT,
383
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (out)));
385
if ((ret = gst_pad_push (dec->src, out)) != GST_FLOW_OK)
388
n = gst_adapter_available (dec->adapter);
390
GST_LOG_OBJECT (dec, "Data left in the adapter: %d", n);
391
in = gst_adapter_take_buffer (dec->adapter, n);
392
ret = gst_real_video_dec_decode (dec, in, 0);
393
gst_buffer_unref (in);
394
if (ret != GST_FLOW_OK)
404
GST_ELEMENT_ERROR (dec, STREAM, DECODE, ("Not enough data."), (NULL));
405
return GST_FLOW_ERROR;
410
gst_buffer_unref (in);
411
GST_ELEMENT_ERROR (dec, STREAM, DECODE,
412
("Got more fragments (%u) than can be handled (%u)",
413
dec->fragment_count, (guint) G_N_ELEMENTS (dec->fragments)),
415
return GST_FLOW_ERROR;
420
gst_buffer_unref (out);
421
GST_ELEMENT_ERROR (dec, STREAM, DECODE,
422
("Could not decode buffer: %" G_GUINT32_FORMAT, result), (NULL));
423
return GST_FLOW_ERROR;
426
new_dimensions_failed:
428
gst_buffer_unref (out);
429
GST_ELEMENT_ERROR (dec, STREAM, DECODE,
430
("Could not set new dimensions."), (NULL));
431
return GST_FLOW_ERROR;
436
GST_DEBUG_OBJECT (dec, "Could not push buffer: %s",
437
gst_flow_get_name (ret));
443
gst_real_video_dec_chain (GstPad * pad, GstBuffer * in)
445
GstRealVideoDec *dec = GST_REAL_VIDEO_DEC (GST_PAD_PARENT (pad));
446
guint8 flags, *buf = GST_BUFFER_DATA (in);
447
guint len = GST_BUFFER_SIZE (in);
102
guint frag_count, frag_size;
104
dec = GST_REAL_VIDEO_DEC (GST_PAD_PARENT (pad));
450
106
if (G_UNLIKELY (dec->hooks.transform == NULL || dec->hooks.module == NULL))
451
107
goto not_negotiated;
455
goto not_enough_data;
461
GST_DEBUG_OBJECT (dec, "Don't know how to handle buffer of type 0x40 "
466
ret = gst_real_video_dec_decode (dec, in, 1);
109
data = GST_BUFFER_DATA (in);
110
size = GST_BUFFER_SIZE (in);
111
timestamp = GST_BUFFER_TIMESTAMP (in);
112
duration = GST_BUFFER_DURATION (in);
114
GST_DEBUG_OBJECT (dec, "got buffer of size %u, timestamp %" GST_TIME_FORMAT,
115
size, GST_TIME_ARGS (timestamp));
117
/* alloc output buffer */
118
ret = gst_pad_alloc_buffer (dec->src, GST_BUFFER_OFFSET_NONE,
119
dec->width * dec->height * 3 / 2, GST_PAD_CAPS (dec->src), &out);
120
if (ret != GST_FLOW_OK)
123
GST_BUFFER_TIMESTAMP (out) = timestamp;
124
GST_BUFFER_DURATION (out) = duration;
126
frag_count = *data++;
127
frag_size = (frag_count + 1) * 8;
128
size -= (frag_size + 1);
130
GST_DEBUG_OBJECT (dec, "frag_count %u, frag_size %u, data size %u",
131
frag_count, frag_size, size);
135
* The Buffers contain
138
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
139
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
140
* | nfragments | fragment1 ... |
141
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
143
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
144
* | ... | fragment2 ... |
145
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
147
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
148
* | ... | fragment data |
149
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
151
* nfragments: number of fragments
152
* fragmentN: 8 bytes of fragment data (nfragements + 1) of them
153
* fragment data: the data of the fragments.
157
tin.nfragments = frag_count;
158
tin.fragments = data;
160
tin.timestamp = timestamp;
162
/* jump over the frag table to the fragments */
165
result = dec->hooks.transform (
167
(gchar *) GST_BUFFER_DATA (out), &tin, &tout, dec->hooks.context);
169
goto could_not_transform;
171
/* When we decoded a frame, reset the error counter. We only fail after N
172
* consecutive decoding errors. */
173
dec->error_count = 0;
467
175
gst_buffer_unref (in);
468
if (ret != GST_FLOW_OK)
177
/* Check for new dimensions */
178
if (tout.frames && ((dec->width != tout.width)
179
|| (dec->height != tout.height))) {
180
GstCaps *caps = gst_caps_copy (GST_PAD_CAPS (dec->src));
181
GstStructure *s = gst_caps_get_structure (caps, 0);
183
GST_DEBUG_OBJECT (dec, "New dimensions: %"
184
G_GUINT32_FORMAT " x %" G_GUINT32_FORMAT, tout.width, tout.height);
186
gst_structure_set (s, "width", G_TYPE_INT, (gint) tout.width,
187
"height", G_TYPE_INT, (gint) tout.height, NULL);
189
gst_pad_set_caps (dec->src, caps);
190
gst_buffer_set_caps (out, caps);
191
gst_caps_unref (caps);
193
dec->width = tout.width;
194
dec->height = tout.height;
195
GST_BUFFER_SIZE (out) = dec->width * dec->height * 3 / 2;
198
GST_DEBUG_OBJECT (dec,
199
"Pushing out buffer with timestamp %" GST_TIME_FORMAT,
200
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (out)));
202
if ((ret = gst_pad_push (dec->src, out)) != GST_FLOW_OK)
475
GST_ELEMENT_ERROR (dec, STREAM, DECODE, ("Not enough data."), (NULL));
476
gst_buffer_unref (in);
477
return GST_FLOW_ERROR;
481
210
GST_WARNING_OBJECT (dec, "decoder not open, probably no input caps set "
637
400
GstRealVideoDecVersion version)
639
402
gpointer rv_custom_msg, rv_free, rv_init, rv_transform;
403
GModule *module = NULL;
405
gchar **split_names, **split_path;
643
408
GST_DEBUG_OBJECT (dec,
644
409
"Attempting to open shared library for real video version %d", version);
646
/* FIXME : Search for the correct library in various places if dec->path_rv20
647
* isn't set explicitely !
648
* Library names can also be different (ex : drv30.so vs drvc.so)
411
path = dec->real_codecs_path ? dec->real_codecs_path :
412
DEFAULT_REAL_CODECS_PATH;
651
414
switch (version) {
652
415
case GST_REAL_VIDEO_DEC_VERSION_2:
655
path = dec->path_rv20;
656
else if (g_file_test (DEFAULT_PATH_RV20, G_FILE_TEST_EXISTS))
657
path = DEFAULT_PATH_RV20;
658
else if (g_file_test ("/usr/lib/drv2.so.6.0", G_FILE_TEST_EXISTS))
659
path = "/usr/lib/drv2.so.6.0";
661
goto no_known_libraries;
416
names = dec->rv20_names ? dec->rv20_names : DEFAULT_RV20_NAMES;
664
418
case GST_REAL_VIDEO_DEC_VERSION_3:
667
path = dec->path_rv30;
668
else if (g_file_test (DEFAULT_PATH_RV30, G_FILE_TEST_EXISTS))
669
path = DEFAULT_PATH_RV30;
670
else if (g_file_test ("/usr/lib/drv3.so.6.0", G_FILE_TEST_EXISTS))
671
path = "/usr/lib/drv3.so.6.0";
673
goto no_known_libraries;
419
names = dec->rv30_names ? dec->rv30_names : DEFAULT_RV30_NAMES;
676
421
case GST_REAL_VIDEO_DEC_VERSION_4:
679
path = dec->path_rv40;
680
else if (g_file_test (DEFAULT_PATH_RV40, G_FILE_TEST_EXISTS))
681
path = DEFAULT_PATH_RV40;
682
else if (g_file_test ("/usr/lib/drv4.so.6.0", G_FILE_TEST_EXISTS))
683
path = "/usr/lib/drv4.so.6.0";
685
goto no_known_libraries;
422
names = dec->rv40_names ? dec->rv40_names : DEFAULT_RV40_NAMES;
689
425
goto unknown_version;
692
GST_LOG_OBJECT (dec, "Trying to open '%s'", path);
693
hooks->module = g_module_open (path, G_MODULE_BIND_LAZY);
695
if (hooks->module == NULL)
428
split_path = g_strsplit (path, ":", 0);
429
split_names = g_strsplit (names, ":", 0);
431
for (i = 0; split_path[i]; i++) {
432
for (j = 0; split_names[j]; j++) {
433
gchar *codec = g_strconcat (split_path[i], "/", split_names[j], NULL);
435
module = g_module_open (codec, G_MODULE_BIND_LAZY);
438
goto codec_search_done;
443
g_strfreev (split_path);
444
g_strfreev (split_names);
696
447
goto could_not_open;
698
module = hooks->module;
700
449
/* First try opening legacy symbols, if that fails try loading new symbols */
701
450
if (g_module_symbol (module, "RV20toYUV420Init", &rv_init) &&
702
451
g_module_symbol (module, "RV20toYUV420Free", &rv_free) &&
884
643
object_class->get_property = gst_real_video_dec_get_property;
885
644
object_class->finalize = gst_real_video_dec_finalize;
887
g_object_class_install_property (object_class, PROP_PATH_RV20,
888
g_param_spec_string ("path_rv20", "Path to rv20 driver",
889
"Path to rv20 driver", DEFAULT_PATH_RV20, G_PARAM_READWRITE));
890
g_object_class_install_property (object_class, PROP_PATH_RV30,
891
g_param_spec_string ("path_rv30", "Path to rv30 driver",
892
"Path to rv30 driver", DEFAULT_PATH_RV30, G_PARAM_READWRITE));
893
g_object_class_install_property (object_class, PROP_PATH_RV40,
894
g_param_spec_string ("path_rv40", "Path to rv40 driver",
895
"Path to rv40 driver", DEFAULT_PATH_RV40, G_PARAM_READWRITE));
646
g_object_class_install_property (object_class, PROP_REAL_CODECS_PATH,
647
g_param_spec_string ("real-codecs-path",
648
"Path where to search for RealPlayer codecs",
649
"Path where to search for RealPlayer codecs",
650
DEFAULT_REAL_CODECS_PATH, G_PARAM_READWRITE));
651
g_object_class_install_property (object_class, PROP_RV20_NAMES,
652
g_param_spec_string ("rv20-names", "Names of rv20 driver",
653
"Names of rv20 driver", DEFAULT_RV20_NAMES, G_PARAM_READWRITE));
654
g_object_class_install_property (object_class, PROP_RV30_NAMES,
655
g_param_spec_string ("rv30-names", "Names of rv30 driver",
656
"Names of rv30 driver", DEFAULT_RV30_NAMES, G_PARAM_READWRITE));
657
g_object_class_install_property (object_class, PROP_RV40_NAMES,
658
g_param_spec_string ("rv40-names", "Names of rv40 driver",
659
"Names of rv40 driver", DEFAULT_RV40_NAMES, G_PARAM_READWRITE));
660
g_object_class_install_property (object_class, PROP_MAX_ERRORS,
661
g_param_spec_int ("max-errors", "Max errors",
662
"Maximum number of consecutive errors (0 = unlimited)",
663
0, G_MAXINT, DEFAULT_MAX_ERRORS, G_PARAM_READWRITE));
897
665
GST_DEBUG_CATEGORY_INIT (realvideode_debug, "realvideodec", 0,
898
666
"RealVideo decoder");