Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}