Esempio n. 1
0
static GstFlowReturn
gst_png_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
{
  GstPngParse *pngparse = GST_PNG_PARSE (parse);

  if (!pngparse->sent_codec_tag) {
    GstTagList *taglist;
    GstCaps *caps;

    /* codec tag */
    caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
    if (G_UNLIKELY (caps == NULL)) {
      if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
        GST_INFO_OBJECT (parse, "Src pad is flushing");
        return GST_FLOW_FLUSHING;
      } else {
        GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
        return GST_FLOW_NOT_NEGOTIATED;
      }
    }

    taglist = gst_tag_list_new_empty ();
    gst_pb_utils_add_codec_description_to_tag_list (taglist,
        GST_TAG_VIDEO_CODEC, caps);
    gst_caps_unref (caps);

    gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
    gst_tag_list_unref (taglist);

    /* also signals the end of first-frame processing */
    pngparse->sent_codec_tag = TRUE;
  }

  return GST_FLOW_OK;
}
Esempio n. 2
0
static GstFlowReturn
gst_png_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
{
  GstPngParse *pngparse = GST_PNG_PARSE (parse);

  if (!pngparse->sent_codec_tag) {
    GstTagList *taglist;
    GstCaps *caps;

    taglist = gst_tag_list_new_empty ();

    /* codec tag */
    caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
    gst_pb_utils_add_codec_description_to_tag_list (taglist,
        GST_TAG_VIDEO_CODEC, caps);
    gst_caps_unref (caps);

    gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
    gst_tag_list_unref (taglist);

    /* also signals the end of first-frame processing */
    pngparse->sent_codec_tag = TRUE;
  }

  return GST_FLOW_OK;
}
Esempio n. 3
0
static gboolean
gst_png_parse_start (GstBaseParse * parse)
{
    GstPngParse *pngparse = GST_PNG_PARSE (parse);

    GST_DEBUG_OBJECT (pngparse, "start");

    /* the start code and at least 2 empty frames (IHDR and IEND) */
    gst_base_parse_set_min_frame_size (parse, 8 + 12 + 12);

    pngparse->width = 0;
    pngparse->height = 0;

    return TRUE;
}
Esempio n. 4
0
static GstFlowReturn
gst_png_parse_handle_frame (GstBaseParse * parse,
    GstBaseParseFrame * frame, gint * skipsize)
{
  GstPngParse *pngparse = GST_PNG_PARSE (parse);
  GstMapInfo map;
  GstByteReader reader;
  GstFlowReturn ret = GST_FLOW_OK;
  guint64 signature;
  guint width = 0, height = 0;

  gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
  gst_byte_reader_init (&reader, map.data, map.size);

  if (!gst_byte_reader_peek_uint64_be (&reader, &signature))
    goto beach;

  if (signature != PNG_SIGNATURE) {
    for (;;) {
      guint offset;

      offset = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
          0x89504E47, 0, gst_byte_reader_get_remaining (&reader));

      if (offset == -1) {
        *skipsize = gst_byte_reader_get_remaining (&reader) - 4;
        goto beach;
      }

      gst_byte_reader_skip (&reader, offset);

      if (!gst_byte_reader_peek_uint64_be (&reader, &signature))
        goto beach;

      if (signature == PNG_SIGNATURE) {
        /* We're skipping, go out, we'll be back */
        *skipsize = gst_byte_reader_get_pos (&reader);
        goto beach;
      }
      gst_byte_reader_skip (&reader, 4);
    }
  }

  gst_byte_reader_skip (&reader, 8);

  for (;;) {
    guint32 length;
    guint32 code;

    if (!gst_byte_reader_get_uint32_be (&reader, &length))
      goto beach;
    if (!gst_byte_reader_get_uint32_le (&reader, &code))
      goto beach;

    GST_TRACE_OBJECT (parse, "%" GST_FOURCC_FORMAT " chunk, %u bytes",
        GST_FOURCC_ARGS (code), length);

    if (code == GST_MAKE_FOURCC ('I', 'H', 'D', 'R')) {
      if (!gst_byte_reader_get_uint32_be (&reader, &width))
        goto beach;
      if (!gst_byte_reader_get_uint32_be (&reader, &height))
        goto beach;
      length -= 8;
    } else if (code == GST_MAKE_FOURCC ('I', 'D', 'A', 'T')) {
      gst_base_parse_set_min_frame_size (parse,
          gst_byte_reader_get_pos (&reader) + 4 + length + 12);
    }

    if (!gst_byte_reader_skip (&reader, length + 4))
      goto beach;

    if (code == GST_MAKE_FOURCC ('I', 'E', 'N', 'D')) {
      /* the start code and at least 2 empty frames (IHDR and IEND) */
      gst_base_parse_set_min_frame_size (parse, 8 + 12 + 12);

      if (pngparse->width != width || pngparse->height != height) {
        GstCaps *caps, *sink_caps;

        pngparse->height = height;
        pngparse->width = width;

        caps = gst_caps_new_simple ("image/png",
            "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL);

        sink_caps =
            gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (pngparse));

        if (sink_caps) {
          GstStructure *st;
          gint fr_num, fr_denom;

          st = gst_caps_get_structure (sink_caps, 0);
          if (st
              && gst_structure_get_fraction (st, "framerate", &fr_num,
                  &fr_denom)) {
            gst_caps_set_simple (caps,
                "framerate", GST_TYPE_FRACTION, fr_num, fr_denom, NULL);
          } else {
            GST_WARNING_OBJECT (pngparse, "No framerate set");
          }

          gst_caps_unref (sink_caps);
        }

        if (!gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps))
          ret = GST_FLOW_NOT_NEGOTIATED;

        gst_caps_unref (caps);

        if (ret != GST_FLOW_OK)
          goto beach;
      }


      gst_buffer_unmap (frame->buffer, &map);
      return gst_base_parse_finish_frame (parse, frame,
          gst_byte_reader_get_pos (&reader));
    }
  }

beach:

  gst_buffer_unmap (frame->buffer, &map);

  return ret;
}
Esempio n. 5
0
static GstFlowReturn
gst_png_parse_handle_frame (GstBaseParse * parse,
                            GstBaseParseFrame * frame, gint * skipsize)
{
    GstPngParse *pngparse = GST_PNG_PARSE (parse);
    GstMapInfo map;
    GstByteReader reader;
    GstFlowReturn ret = GST_FLOW_OK;
    guint64 signature;
    guint width = 0, height = 0;

    gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
    gst_byte_reader_init (&reader, map.data, map.size);

    if (!gst_byte_reader_peek_uint64_be (&reader, &signature))
        goto beach;

    if (signature != PNG_SIGNATURE) {
        for (;;) {
            guint offset;

            offset = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
                     0x89504E47, 0, gst_byte_reader_get_remaining (&reader));

            if (offset == -1) {
                *skipsize = gst_byte_reader_get_remaining (&reader) - 4;
                goto beach;
            }

            gst_byte_reader_skip (&reader, offset);

            if (!gst_byte_reader_peek_uint64_be (&reader, &signature))
                goto beach;

            if (signature == PNG_SIGNATURE) {
                /* We're skipping, go out, we'll be back */
                *skipsize = gst_byte_reader_get_pos (&reader);
                goto beach;
            }
            gst_byte_reader_skip (&reader, 4);
        }
    }

    gst_byte_reader_skip (&reader, 8);

    for (;;) {
        guint32 length;
        guint32 code;

        if (!gst_byte_reader_get_uint32_be (&reader, &length))
            goto beach;
        if (!gst_byte_reader_get_uint32_le (&reader, &code))
            goto beach;

        if (code == GST_MAKE_FOURCC ('I', 'H', 'D', 'R')) {
            if (!gst_byte_reader_get_uint32_be (&reader, &width))
                goto beach;
            if (!gst_byte_reader_get_uint32_be (&reader, &height))
                goto beach;
            length -= 8;
        }

        if (!gst_byte_reader_skip (&reader, length + 4))
            goto beach;

        if (code == GST_MAKE_FOURCC ('I', 'E', 'N', 'D')) {
            if (pngparse->width != width || pngparse->height != height) {
                GstCaps *caps;

                pngparse->height = height;
                pngparse->width = width;

                caps = gst_caps_new_simple ("image/png",
                                            "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL);
                if (!gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps)) {
                    ret = GST_FLOW_NOT_NEGOTIATED;
                }
                gst_caps_unref (caps);

                if (ret != GST_FLOW_OK)
                    goto beach;
            }


            gst_buffer_unmap (frame->buffer, &map);
            return gst_base_parse_finish_frame (parse, frame,
                                                gst_byte_reader_get_pos (&reader));
        }
    }

beach:

    gst_buffer_unmap (frame->buffer, &map);

    return ret;
}
Esempio n. 6
0
static GstFlowReturn
gst_png_parse_handle_frame (GstBaseParse * parse,
    GstBaseParseFrame * frame, gint * skipsize)
{
  GstPngParse *pngparse = GST_PNG_PARSE (parse);
  GstMapInfo map;
  GstByteReader reader;
  GstFlowReturn ret = GST_FLOW_OK;
  guint64 signature;
  guint width = 0, height = 0;

  gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
  gst_byte_reader_init (&reader, map.data, map.size);

  if (!gst_byte_reader_peek_uint64_be (&reader, &signature))
    goto beach;

  if (signature != PNG_SIGNATURE) {
    for (;;) {
      guint offset;

      offset = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
          0x89504E47, 0, gst_byte_reader_get_remaining (&reader));

      if (offset == -1) {
        *skipsize = gst_byte_reader_get_remaining (&reader) - 4;
        goto beach;
      }

      gst_byte_reader_skip (&reader, offset);

      if (!gst_byte_reader_peek_uint64_be (&reader, &signature))
        goto beach;

      if (signature == PNG_SIGNATURE) {
        /* We're skipping, go out, we'll be back */
        *skipsize = gst_byte_reader_get_pos (&reader);
        goto beach;
      }
      gst_byte_reader_skip (&reader, 4);
    }
  }

  gst_byte_reader_skip (&reader, 8);

  for (;;) {
    guint32 length;
    guint32 code;

    if (!gst_byte_reader_get_uint32_be (&reader, &length))
      goto beach;
    if (!gst_byte_reader_get_uint32_le (&reader, &code))
      goto beach;

    if (code == GST_MAKE_FOURCC ('I', 'H', 'D', 'R')) {
      if (!gst_byte_reader_get_uint32_be (&reader, &width))
        goto beach;
      if (!gst_byte_reader_get_uint32_be (&reader, &height))
        goto beach;
      length -= 8;
    }

    if (!gst_byte_reader_skip (&reader, length + 4))
      goto beach;

    if (code == GST_MAKE_FOURCC ('I', 'E', 'N', 'D')) {
      if (pngparse->width != width || pngparse->height != height) {
        GstStructure *st = NULL;
        GstCaps *caps, *sink_caps;
        gint fr_num, fr_denom;

        pngparse->height = height;
        pngparse->width = width;

        sink_caps =
            gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (pngparse));
        if (sink_caps && (st = gst_caps_get_structure (sink_caps, 0))
            && gst_structure_get_fraction (st, "framerate", &fr_num, &fr_denom)) {
          /* Got it in caps - nothing more to do */
          GST_DEBUG_OBJECT (pngparse,
              "sink caps override framerate from headers");
        } else {
          GST_INFO_OBJECT (pngparse, "No framerate set");
        }

        caps = gst_caps_new_simple ("image/png",
            "width", G_TYPE_INT, width, "height", G_TYPE_INT, height,
            "framerate", GST_TYPE_FRACTION, fr_num, fr_denom, NULL);

        if (!gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps)) {
          ret = GST_FLOW_NOT_NEGOTIATED;
        }
        gst_caps_unref (caps);

        if (ret != GST_FLOW_OK)
          goto beach;
      }


      gst_buffer_unmap (frame->buffer, &map);
      return gst_base_parse_finish_frame (parse, frame,
          gst_byte_reader_get_pos (&reader));
    }
  }

beach:

  gst_buffer_unmap (frame->buffer, &map);

  return ret;
}