static gboolean gst_dirac_parse_start (GstBaseParse * parse) { GstDiracParse *diracparse = GST_DIRAC_PARSE (parse); gst_base_parse_set_min_frame_size (parse, 13); diracparse->sent_codec_tag = FALSE; return TRUE; }
void gst_dirac_parse_finalize (GObject * object) { GstDiracParse *diracparse; g_return_if_fail (GST_IS_DIRAC_PARSE (object)); diracparse = GST_DIRAC_PARSE (object); /* clean up object here */ G_OBJECT_CLASS (parent_class)->finalize (object); }
void gst_dirac_parse_dispose (GObject * object) { GstDiracParse *diracparse; g_return_if_fail (GST_IS_DIRAC_PARSE (object)); diracparse = GST_DIRAC_PARSE (object); /* clean up as possible. may be called multiple times */ G_OBJECT_CLASS (parent_class)->dispose (object); }
void gst_dirac_parse_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { GstDiracParse *diracparse; g_return_if_fail (GST_IS_DIRAC_PARSE (object)); diracparse = GST_DIRAC_PARSE (object); switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
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 GstFlowReturn gst_dirac_parse_handle_frame (GstBaseParse * parse, GstBaseParseFrame * frame, gint * skipsize) { int off; guint32 next_header; GstMapInfo map; guint8 *data; gsize size; gboolean have_picture = FALSE; int offset; guint framesize = 0; gst_buffer_map (frame->buffer, &map, GST_MAP_READ); data = map.data; size = map.size; if (G_UNLIKELY (size < 13)) { *skipsize = 1; goto out; } GST_DEBUG ("%" G_GSIZE_FORMAT ": %02x %02x %02x %02x", size, data[0], data[1], data[2], data[3]); if (GST_READ_UINT32_BE (data) != 0x42424344) { GstByteReader reader; gst_byte_reader_init (&reader, data, size); off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff, 0x42424344, 0, size); if (off < 0) { *skipsize = size - 3; goto out; } GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off); GST_DEBUG ("skipping %d", off); *skipsize = off; goto out; } /* have sync, parse chunks */ offset = 0; while (!have_picture) { GST_DEBUG ("offset %d:", offset); if (offset + 13 >= size) { framesize = offset + 13; goto out; } GST_DEBUG ("chunk type %02x", data[offset + 4]); if (GST_READ_UINT32_BE (data + offset) != 0x42424344) { GST_DEBUG ("bad header"); *skipsize = 3; goto out; } next_header = GST_READ_UINT32_BE (data + offset + 5); GST_DEBUG ("next_header %d", next_header); if (next_header == 0) next_header = 13; if (SCHRO_PARSE_CODE_IS_PICTURE (data[offset + 4])) { have_picture = TRUE; } offset += next_header; if (offset >= size) { framesize = offset; goto out; } } gst_buffer_unmap (frame->buffer, &map); framesize = offset; GST_DEBUG ("framesize %d", framesize); g_assert (framesize <= size); if (data[4] == SCHRO_PARSE_CODE_SEQUENCE_HEADER) { GstCaps *caps; GstDiracParse *diracparse = GST_DIRAC_PARSE (parse); DiracSequenceHeader sequence_header; int ret; ret = dirac_sequence_header_parse (&sequence_header, data + 13, size - 13); if (ret) { memcpy (&diracparse->sequence_header, &sequence_header, sizeof (sequence_header)); caps = gst_caps_new_simple ("video/x-dirac", "width", G_TYPE_INT, sequence_header.width, "height", G_TYPE_INT, sequence_header.height, "framerate", GST_TYPE_FRACTION, sequence_header.frame_rate_numerator, sequence_header.frame_rate_denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, sequence_header.aspect_ratio_numerator, sequence_header.aspect_ratio_denominator, "interlace-mode", G_TYPE_STRING, sequence_header.interlaced ? "interleaved" : "progressive", "profile", G_TYPE_STRING, get_profile_name (sequence_header.profile), "level", G_TYPE_STRING, get_level_name (sequence_header.level), NULL); gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps); gst_caps_unref (caps); gst_base_parse_set_frame_rate (parse, sequence_header.frame_rate_numerator, sequence_header.frame_rate_denominator, 0, 0); } } gst_base_parse_set_min_frame_size (parse, 13); return gst_base_parse_finish_frame (parse, frame, framesize); out: gst_buffer_unmap (frame->buffer, &map); if (framesize) gst_base_parse_set_min_frame_size (parse, framesize); return GST_FLOW_OK; }