コード例 #1
0
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;
}
コード例 #2
0
ファイル: gstdiracparse.c プロジェクト: c-a/gst-plugins-bad
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);
}
コード例 #3
0
ファイル: gstdiracparse.c プロジェクト: c-a/gst-plugins-bad
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);
}
コード例 #4
0
ファイル: gstdiracparse.c プロジェクト: c-a/gst-plugins-bad
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;
  }
}
コード例 #5
0
ファイル: gstdiracparse.c プロジェクト: c-a/gst-plugins-bad
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;
}
コード例 #6
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;
}