return dvbsub;
}
-/**
- * dvb_sub_feed:
- * @dvb_sub: a #DvbSub
- * @data: The data to feed to the parser
- * @len: Length of the data
- *
- * Feeds the DvbSub parser with new PES packet data to parse.
- * The data given must be a full PES packet, which must
- * include a PTS field in the headers.
- * Only one packet is handled in one call, so the available data
- * should be fed continously until all is consumed.
- *
- * Return value: a negative value on errors, -4 if simply not enough data for the PES packet;
- * Amount of data consumed (length of handled PES packet on success)
- */
-gint
-dvb_sub_feed (DvbSub * dvb_sub, guint8 * data, gint len)
-{
- guint64 pts = 0;
- unsigned int pos = 0;
- guint16 PES_packet_len;
- guint8 PES_packet_header_len;
- gboolean is_subtitle_packet = TRUE;
- gboolean pts_field_present = FALSE;
- g_warning ("Feeding %d bytes of data to dvbsub!!!!!!!!!!!!\n", len);
- if (len == 0)
- return 0;
-
- if (len <= 8) {
- dvb_log (DVB_LOG_PACKET, G_LOG_LEVEL_WARNING,
- "Length %d too small for further processing", len);
- return -1;
- }
-
- if (data[0] != 0x00 || data[1] != 0x00 || data[2] != 0x01) {
- dvb_log (DVB_LOG_PACKET, G_LOG_LEVEL_WARNING,
- "Data fed to dvb_sub_feed is not a PES packet - does not start with a code_prefix of 0x000001");
- return 1; // FIXME: Probably handle it? - we need to skip PES_packet_len from this elementary stream then and move on
- }
-
- if (data[3] != 0xBD) {
- dvb_log (DVB_LOG_PACKET, G_LOG_LEVEL_INFO,
- "Data fed to dvb_sub_feed is not a PES packet of type private_stream_1, but rather '0x%X', so not a subtitle stream",
- data[3]);
- is_subtitle_packet = FALSE;
- }
-
- PES_packet_len = (data[4] << 8) | data[5];
- dvb_log (DVB_LOG_PACKET, G_LOG_LEVEL_DEBUG,
- "PES packet length is %u", PES_packet_len);
- pos = 6;
-
- /* FIXME: If the packet is cut, we could be feeding data more than we actually have here, which breaks everything. Probably need to buffer up and handle it,
- * FIXME: Or push back in front to the file descriptor buffer (but we are using read, not libc buffered fread, so that idea might not be possible )*/
- if ((len - 5) < PES_packet_len) {
- dvb_log (DVB_LOG_PACKET, G_LOG_LEVEL_WARNING,
- "!!!!!!!!!!! claimed PES packet length was %d, but we only had %d bytes available, falling back and waiting more !!!!!!!!!",
- PES_packet_len, len - 5);
- return -4;
- }
- /* FIXME: Validate sizes inbetween here */
-
- /* If this is a non-subtitle packet, still skip the data, pretending we consumed it (FIXME: Signal up) */
- if (!is_subtitle_packet) {
- return pos + PES_packet_len;
- }
-
- pos++;
-
- if (data[pos++] & 0x80) { /* PTS fields present (possibly also DTS). Technically this must be present per the spec */
- pts_field_present = TRUE;
- }
-
- /* pos should be 8 now anyway */
- pos = 8;
-
- PES_packet_header_len = data[pos++];
-
- if (pts_field_present) {
- /* '001x', PTS[32..30], marker, PTS[29..15], marker, PTS[14..0], marker */
- pts = ((guint64) (data[pos] & 0x0E)) << 29; /* PTS[32..30], ignore marker at rightmost bit */
- pts |= ((guint64) (data[pos + 1])) << 22; /* PTS[29..22], full byte */
- pts |= ((guint64) (data[pos + 2] & 0xFE)) << 14; /* PTS[21..15], ignore marker at rightmost bit */
- pts |= ((guint64) (data[pos + 3])) << 7; /* PTS[14.. 7], full byte */
- pts |= ((guint64) (data[pos + 4] & 0xFE)) >> 1; /* PTS[ 6.. 0], ignore marker at rightmost bit */
- }
-
- pos += PES_packet_header_len; /* FIXME: Currently including all header values with all but PTS ignored */
-
- dvb_sub_feed_with_pts (dvb_sub, pts, data + pos, PES_packet_len - PES_packet_header_len - 3); /* 2 bytes between PES_packet_len and PES_packet_header_len fields, minus header_len itself */
- pos += PES_packet_len - PES_packet_header_len - 3;
- dvb_log (DVB_LOG_PACKET, G_LOG_LEVEL_DEBUG,
- "Finished PES packet - consumed %u bytes of %d", pos, len);
-
- return pos;
-}
-
#define DVB_SUB_SEGMENT_PAGE_COMPOSITION 0x10
#define DVB_SUB_SEGMENT_REGION_COMPOSITION 0x11
#define DVB_SUB_SEGMENT_CLUT_DEFINITION 0x12