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; }
int main (int argc, char *argv[]) { FILE *file; int ret; DiracSequenceHeader header = {0}; int size; unsigned char *packet; int n; int i; if (argc < 2) { fprintf(stderr, "parse_header infile.drc\n"); return 1; } file = fopen (argv[1], "r"); if (file == NULL) { printf("cannot open %s for reading: %s\n", argv[1], strerror(errno)); return 1; } n = fread (data, 1, 4096, file); if (n < 13) { printf("file too short\n"); exit(1); } for(i=0;i<=n - 13;i++){ packet = data + i; if (packet[0] == 'B' && packet[1] == 'B' && packet[2] == 'C' && packet[3] == 'D') { size = (packet[5]<<24) | (packet[6]<<16) | (packet[7]<<8) | (packet[8]); if (size == 0) { size = 13; } if (i + size > n) { continue; } if (SCHRO_PARSE_CODE_IS_SEQ_HEADER(packet[4])) { ret = dirac_sequence_header_parse (&header, packet + 13, size - 13); if (!ret) { printf("bad header\n"); exit(1); } #define PRINT(ack) printf( #ack ": %d\n", header. ack ); PRINT(major_version); PRINT(minor_version); PRINT(profile); PRINT(level); PRINT(index); PRINT(width); PRINT(height); PRINT(chroma_format); PRINT(interlaced); PRINT(top_field_first); PRINT(frame_rate_numerator); PRINT(frame_rate_denominator); PRINT(aspect_ratio_numerator); PRINT(aspect_ratio_denominator); PRINT(clean_width); PRINT(clean_height); PRINT(left_offset); PRINT(top_offset); PRINT(luma_offset); PRINT(luma_excursion); PRINT(chroma_offset); PRINT(chroma_excursion); PRINT(colour_primaries); PRINT(colour_matrix); PRINT(transfer_function); PRINT(interlaced_coding); return 0; } } } return 0; }