static gboolean gst_irtsp_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * framesize, gint * skipsize) { GstIRTSPParse *IRTSPParse = GST_IRTSP_PARSE (parse); GstBuffer *buf = frame->buffer; GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buf); gint off; if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < 4)) return FALSE; off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffff0000, 0x24000000 + (IRTSPParse->channel_id << 16), 0, GST_BUFFER_SIZE (buf)); GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off); /* didn't find anything that looks like a sync word, skip */ if (off < 0) { *skipsize = GST_BUFFER_SIZE (buf) - 3; return FALSE; } /* possible frame header, but not at offset 0? skip bytes before sync */ if (off > 0) { *skipsize = off; return FALSE; } *framesize = GST_READ_UINT16_BE (GST_BUFFER_DATA (frame->buffer) + 2) + 4; GST_LOG_OBJECT (parse, "got frame size %d", *framesize); return TRUE; }
static GstFlowReturn gst_jp2k_decimator_decimate_jpc (GstJP2kDecimator * self, GstBuffer * inbuf, GstBuffer ** outbuf_) { GstBuffer *outbuf = NULL; GstFlowReturn ret = GST_FLOW_OK; GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (inbuf); GstByteWriter writer; MainHeader main_header; gst_byte_writer_init_with_size (&writer, GST_BUFFER_SIZE (inbuf), FALSE); /* main header */ memset (&main_header, 0, sizeof (MainHeader)); ret = parse_main_header (self, &reader, &main_header); if (ret != GST_FLOW_OK) goto done; ret = decimate_main_header (self, &main_header); if (ret != GST_FLOW_OK) goto done; ret = write_main_header (self, &writer, &main_header); if (ret != GST_FLOW_OK) goto done; outbuf = gst_byte_writer_reset_and_get_buffer (&writer); gst_buffer_copy_metadata (outbuf, inbuf, GST_BUFFER_COPY_ALL); GST_DEBUG_OBJECT (self, "Decimated buffer from %u bytes to %u bytes (%.2lf%%)", GST_BUFFER_SIZE (inbuf), GST_BUFFER_SIZE (outbuf), (100 * GST_BUFFER_SIZE (outbuf)) / ((gdouble) GST_BUFFER_SIZE (inbuf))); done: *outbuf_ = outbuf; reset_main_header (self, &main_header); gst_buffer_unref (inbuf); return ret; }
static gboolean gst_jpeg_parse_read_header (GstJpegParse * parse, GstBuffer * buffer) { GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buffer); guint8 marker = 0; gboolean foundSOF = FALSE; if (!gst_byte_reader_peek_uint8 (&reader, &marker)) goto error; while (marker == 0xff) { if (!gst_byte_reader_skip (&reader, 1)) goto error; if (!gst_byte_reader_get_uint8 (&reader, &marker)) goto error; GST_DEBUG_OBJECT (parse, "marker = %x", marker); switch (marker) { case SOS: /* start of scan (begins compressed data) */ return foundSOF; case SOI: break; case DRI: if (!gst_byte_reader_skip (&reader, 4)) /* fixed size */ goto error; break; case COM: if (!gst_jpeg_parse_com (parse, &reader)) goto error; break; case APP1: if (!gst_jpeg_parse_app1 (parse, &reader)) goto error; break; case DHT: case DQT: /* Ignore these codes */ if (!gst_jpeg_parse_skip_marker (parse, &reader, marker)) goto error; break; case SOF2: parse->priv->interlaced = TRUE; /* fall through */ case SOF0: foundSOF = TRUE; /* parse Start Of Frame */ if (!gst_jpeg_parse_sof (parse, &reader)) goto error; return TRUE; default: if (marker == JPG || (marker >= JPG0 && marker <= JPG13)) { /* we'd like to remove them from the buffer */ if (!gst_jpeg_parse_remove_marker (parse, &reader, marker, buffer)) goto error; } else if (marker >= APP0 && marker <= APP15) { if (!gst_jpeg_parse_skip_marker (parse, &reader, marker)) goto error; } else { GST_WARNING_OBJECT (parse, "unhandled marker %x, leaving", marker); /* Not SOF or SOI. Must not be a JPEG file (or file pointer * is placed wrong). In either case, it's an error. */ return FALSE; } } if (!gst_byte_reader_peek_uint8 (&reader, &marker)) goto error; } return foundSOF; error: GST_WARNING_OBJECT (parse, "Error parsing image header (need more than %u bytes available)", gst_byte_reader_get_remaining (&reader)); return FALSE; }
static gboolean gst_jif_mux_parse_image (GstJifMux * self, GstBuffer * buf) { GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buf); GstJifMuxMarker *m; guint8 marker = 0; guint16 size = 0; const guint8 *data = NULL; GST_LOG_OBJECT (self, "Received buffer of size: %u", GST_BUFFER_SIZE (buf)); if (!gst_byte_reader_peek_uint8 (&reader, &marker)) goto error; while (marker == 0xff) { if (!gst_byte_reader_skip (&reader, 1)) goto error; if (!gst_byte_reader_get_uint8 (&reader, &marker)) goto error; switch (marker) { case RST0: case RST1: case RST2: case RST3: case RST4: case RST5: case RST6: case RST7: case SOI: GST_DEBUG_OBJECT (self, "marker = %x", marker); m = gst_jif_mux_new_marker (marker, 0, NULL, FALSE); self->priv->markers = g_list_prepend (self->priv->markers, m); break; case EOI: GST_DEBUG_OBJECT (self, "marker = %x", marker); m = gst_jif_mux_new_marker (marker, 0, NULL, FALSE); self->priv->markers = g_list_prepend (self->priv->markers, m); goto done; break; default: if (!gst_byte_reader_get_uint16_be (&reader, &size)) goto error; if (!gst_byte_reader_get_data (&reader, size - 2, &data)) goto error; m = gst_jif_mux_new_marker (marker, size - 2, data, FALSE); self->priv->markers = g_list_prepend (self->priv->markers, m); GST_DEBUG_OBJECT (self, "marker = %2x, size = %u", marker, size); break; } if (marker == SOS) { gint eoi_pos = -1; gint i; /* search the last 5 bytes for the EOI marker */ g_assert (GST_BUFFER_SIZE (buf) >= 5); for (i = 5; i >= 2; i--) { if (GST_BUFFER_DATA (buf)[GST_BUFFER_SIZE (buf) - i] == 0xFF && GST_BUFFER_DATA (buf)[GST_BUFFER_SIZE (buf) - i + 1] == EOI) { eoi_pos = GST_BUFFER_SIZE (buf) - i; break; } } if (eoi_pos == -1) { GST_WARNING_OBJECT (self, "Couldn't find an EOI marker"); eoi_pos = GST_BUFFER_SIZE (buf); } /* remaining size except EOI is scan data */ self->priv->scan_size = eoi_pos - gst_byte_reader_get_pos (&reader); if (!gst_byte_reader_get_data (&reader, self->priv->scan_size, &self->priv->scan_data)) goto error; GST_DEBUG_OBJECT (self, "scan data, size = %u", self->priv->scan_size); } if (!gst_byte_reader_peek_uint8 (&reader, &marker)) goto error; } GST_INFO_OBJECT (self, "done parsing at 0x%x / 0x%x", gst_byte_reader_get_pos (&reader), GST_BUFFER_SIZE (buf)); done: self->priv->markers = g_list_reverse (self->priv->markers); return TRUE; error: GST_WARNING_OBJECT (self, "Error parsing image header (need more that %u bytes available)", gst_byte_reader_get_remaining (&reader)); return FALSE; }
static gboolean gst_dirac_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * framesize, gint * skipsize) { GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (frame->buffer); GstDiracParse *diracparse = GST_DIRAC_PARSE (parse); int off; guint32 next_header; gboolean sync; gboolean drain; if (G_UNLIKELY (GST_BUFFER_SIZE (frame->buffer) < 13)) return FALSE; off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff, 0x42424344, 0, GST_BUFFER_SIZE (frame->buffer)); if (off < 0) { *skipsize = GST_BUFFER_SIZE (frame->buffer) - 3; return FALSE; } GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off); if (off > 0) { GST_ERROR ("skipping %d", off); *skipsize = off; return FALSE; } if (!gst_dirac_parse_frame_header (diracparse, frame->buffer, framesize)) { GST_ERROR ("bad header"); *skipsize = 3; return FALSE; } GST_LOG ("framesize %d", *framesize); sync = GST_BASE_PARSE_FRAME_SYNC (frame); drain = GST_BASE_PARSE_FRAME_DRAIN (frame); if (!sync && !drain) { guint32 next_sync_word = 0; next_header = GST_READ_UINT32_BE (GST_BUFFER_DATA (frame->buffer) + 5); GST_LOG ("next header %d", next_header); if (!gst_byte_reader_skip (&reader, next_header) || !gst_byte_reader_get_uint32_be (&reader, &next_sync_word)) { gst_base_parse_set_min_frame_size (parse, next_header + 4); *skipsize = 0; return FALSE; } else { if (next_sync_word != 0x42424344) { *skipsize = 3; return FALSE; } else { gst_base_parse_set_min_frame_size (parse, next_header); } } } return TRUE; }
static gboolean gst_ac3_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * framesize, gint * skipsize) { GstAc3Parse *ac3parse = GST_AC3_PARSE (parse); GstBuffer *buf = frame->buffer; GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buf); gint off; gboolean lost_sync, draining, eac, more = FALSE; guint frmsiz, blocks, sid; gint have_blocks = 0; if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < 6)) return FALSE; off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffff0000, 0x0b770000, 0, GST_BUFFER_SIZE (buf)); GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off); /* didn't find anything that looks like a sync word, skip */ if (off < 0) { *skipsize = GST_BUFFER_SIZE (buf) - 3; return FALSE; } /* possible frame header, but not at offset 0? skip bytes before sync */ if (off > 0) { *skipsize = off; return FALSE; } /* make sure the values in the frame header look sane */ if (!gst_ac3_parse_frame_header (ac3parse, buf, 0, &frmsiz, NULL, NULL, &blocks, &sid, &eac)) { *skipsize = off + 2; return FALSE; } *framesize = frmsiz; if (G_UNLIKELY (g_atomic_int_get (&ac3parse->align) == GST_AC3_PARSE_ALIGN_NONE)) gst_ac3_parse_set_alignment (ac3parse, eac); GST_LOG_OBJECT (parse, "got frame"); lost_sync = GST_BASE_PARSE_LOST_SYNC (parse); draining = GST_BASE_PARSE_DRAINING (parse); if (g_atomic_int_get (&ac3parse->align) == GST_AC3_PARSE_ALIGN_IEC61937) { /* We need 6 audio blocks from each substream, so we keep going forwards * till we have it */ g_assert (blocks > 0); GST_LOG_OBJECT (ac3parse, "Need %d frames before pushing", 6 / blocks); if (sid != 0) { /* We need the first substream to be the one with id 0 */ GST_LOG_OBJECT (ac3parse, "Skipping till we find sid 0"); *skipsize = off + 2; return FALSE; } *framesize = 0; /* Loop till we have 6 blocks per substream */ for (have_blocks = 0; !more && have_blocks < 6; have_blocks += blocks) { /* Loop till we get one frame from each substream */ do { *framesize += frmsiz; if (!gst_byte_reader_skip (&reader, frmsiz) || GST_BUFFER_SIZE (buf) < (*framesize + 6)) { more = TRUE; break; } if (!gst_ac3_parse_frame_header (ac3parse, buf, *framesize, &frmsiz, NULL, NULL, NULL, &sid, &eac)) { *skipsize = off + 2; return FALSE; } } while (sid); } /* We're now at the next frame, so no need to skip if resyncing */ frmsiz = 0; } if (lost_sync && !draining) { guint16 word = 0; GST_DEBUG_OBJECT (ac3parse, "resyncing; checking next frame syncword"); if (more || !gst_byte_reader_skip (&reader, frmsiz) || !gst_byte_reader_get_uint16_be (&reader, &word)) { GST_DEBUG_OBJECT (ac3parse, "... but not sufficient data"); gst_base_parse_set_min_frame_size (parse, *framesize + 6); *skipsize = 0; return FALSE; } else { if (word != 0x0b77) { GST_DEBUG_OBJECT (ac3parse, "0x%x not OK", word); *skipsize = off + 2; return FALSE; } else { /* ok, got sync now, let's assume constant frame size */ gst_base_parse_set_min_frame_size (parse, *framesize); } } } return TRUE; }