static GstCaps *
gst_ac3_parse_get_sink_caps (GstBaseParse * parse)
{
  GstCaps *peercaps;
  GstCaps *res;

  peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse));
  if (peercaps) {
    guint i, n;

    /* Remove the framed and alignment field. We can convert
     * between different alignments. */
    peercaps = gst_caps_make_writable (peercaps);
    n = gst_caps_get_size (peercaps);
    for (i = 0; i < n; i++) {
      GstStructure *s = gst_caps_get_structure (peercaps, i);

      gst_structure_remove_field (s, "framed");
      gst_structure_remove_field (s, "alignment");
    }

    res =
        gst_caps_intersect_full (peercaps,
        gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse)),
        GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (peercaps);
  } else {
    res =
        gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD
            (parse)));
  }

  return res;
}
Пример #2
0
static GstCaps *
gst_h263_parse_get_sink_caps (GstBaseParse * parse)
{
  GstCaps *peercaps;
  GstCaps *res;

  peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse));
  if (peercaps) {
    guint i, n;

    /* Remove parsed field */
    peercaps = gst_caps_make_writable (peercaps);
    n = gst_caps_get_size (peercaps);
    for (i = 0; i < n; i++) {
      GstStructure *s = gst_caps_get_structure (peercaps, i);
      gst_structure_remove_field (s, "parsed");
    }

    res =
        gst_caps_intersect_full (peercaps,
        gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse)),
        GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (peercaps);
  } else {
    res =
        gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD
            (parse)));
  }

  return res;
}
Пример #3
0
static void
gst_dirac_parse_init (GstDiracParse * diracparse)
{
    gst_base_parse_set_min_frame_size (GST_BASE_PARSE (diracparse), 13);
    gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (diracparse), FALSE);
    GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (diracparse));
    GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (diracparse));
}
/**
 * gst_amr_parse_init:
 * @amrparse: #GstAmrParse
 * @klass: #GstAmrParseClass.
 *
 */
static void
gst_amr_parse_init (GstAmrParse * amrparse)
{
  /* init rest */
  gst_base_parse_set_min_frame_size (GST_BASE_PARSE (amrparse), 62);
  GST_DEBUG ("initialized");
  GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (amrparse));
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (amrparse));
}
Пример #5
0
static void
gst_ac3_parse_init (GstAc3Parse * ac3parse)
{
  gst_base_parse_set_min_frame_size (GST_BASE_PARSE (ac3parse), 8);
  gst_ac3_parse_reset (ac3parse);
  ac3parse->baseparse_chainfunc =
      GST_BASE_PARSE_SINK_PAD (GST_BASE_PARSE (ac3parse))->chainfunc;
  GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (ac3parse));
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (ac3parse));
}
Пример #6
0
static void
gst_h264_parse_init (GstH264Parse * h264parse, GstH264ParseClass * g_class)
{
  h264parse->frame_out = gst_adapter_new ();

  /* retrieve and intercept baseparse.
   * Quite HACKish, but fairly OK since it is needed to perform avc packet
   * splitting, which is the penultimate de-parsing */
  h264parse->parse_chain =
      GST_PAD_CHAINFUNC (GST_BASE_PARSE_SINK_PAD (h264parse));
  gst_pad_set_chain_function (GST_BASE_PARSE_SINK_PAD (h264parse),
      gst_h264_parse_chain);
}
static GstCaps *
gst_amr_parse_sink_getcaps (GstBaseParse * parse, GstCaps * filter)
{
  GstCaps *peercaps, *templ;
  GstCaps *res;


  templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
  peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), filter);

  if (peercaps) {
    guint i, n;

    /* Rename structure names */
    peercaps = gst_caps_make_writable (peercaps);
    n = gst_caps_get_size (peercaps);
    for (i = 0; i < n; i++) {
      GstStructure *s = gst_caps_get_structure (peercaps, i);

      if (gst_structure_has_name (s, "audio/AMR"))
        gst_structure_set_name (s, "audio/x-amr-nb-sh");
      else
        gst_structure_set_name (s, "audio/x-amr-wb-sh");
    }

    res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (peercaps);
    res = gst_caps_make_writable (res);
    /* Append the template caps because we still want to accept
     * caps without any fields in the case upstream does not
     * know anything.
     */
    gst_caps_append (res, templ);
  } else {
    res = templ;
  }

  if (filter) {
    GstCaps *intersection;

    intersection =
        gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (res);
    res = intersection;
  }

  return res;
}
Пример #8
0
static GstCaps *
gst_ac3_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
{
  GstCaps *peercaps, *templ;
  GstCaps *res;

  templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
  peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), filter);

  if (peercaps) {
    guint i, n;

    /* Remove the framed and alignment field. We can convert
     * between different alignments. */
    peercaps = gst_caps_make_writable (peercaps);
    n = gst_caps_get_size (peercaps);
    for (i = 0; i < n; i++) {
      GstStructure *s = gst_caps_get_structure (peercaps, i);

      gst_structure_remove_field (s, "framed");
      gst_structure_remove_field (s, "alignment");
    }

    res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (peercaps);
    res = gst_caps_make_writable (res);

    /* Append the template caps because we still want to accept
     * caps without any fields in the case upstream does not
     * know anything.
     */
    gst_caps_append (res, templ);
  } else {
    res = templ;
  }

  if (filter) {
    GstCaps *intersection;

    intersection =
        gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (res);
    res = intersection;
  }

  return res;
}
Пример #9
0
static GstCaps *
gst_ac3_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
{
  GstCaps *peercaps, *templ;
  GstCaps *res;

  templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
  if (filter) {
    GstCaps *fcopy = gst_caps_copy (filter);
    /* Remove the fields we convert */
    remove_fields (fcopy);
    /* we do not ask downstream to handle x-private1-ac3 */
    fcopy = extend_caps (fcopy, FALSE);
    peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
    gst_caps_unref (fcopy);
  } else
    peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);

  if (peercaps) {
    /* Remove the framed and alignment field. We can convert
     * between different alignments. */
    peercaps = gst_caps_make_writable (peercaps);
    remove_fields (peercaps);
    /* also allow for x-private1-ac3 input */
    peercaps = extend_caps (peercaps, TRUE);

    res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (peercaps);
    gst_caps_unref (templ);
  } else {
    res = templ;
  }

  if (filter) {
    GstCaps *intersection;

    intersection =
        gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (res);
    res = intersection;
  }

  return res;
}
Пример #10
0
static GstCaps *
gst_dirac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
{
    GstCaps *peercaps, *templ;
    GstCaps *res;

    templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
    if (filter) {
        GstCaps *fcopy = gst_caps_copy (filter);
        /* Remove the fields we convert */
        remove_fields (fcopy);
        peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
        gst_caps_unref (fcopy);
    } else
        peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);

    if (peercaps) {
        /* Remove the parsed field */
        peercaps = gst_caps_make_writable (peercaps);
        remove_fields (peercaps);

        res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
        gst_caps_unref (peercaps);
        gst_caps_unref (templ);
    } else {
        res = templ;
    }

    if (filter) {
        GstCaps *intersection;

        intersection =
            gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
        gst_caps_unref (res);
        res = intersection;
    }

    return res;
}
Пример #11
0
static void
gst_h264_parse_update_src_caps (GstH264Parse * h264parse)
{
  GstH264ParamsSPS *sps;
  GstCaps *caps = NULL, *sink_caps;
  gboolean modified = FALSE;
  GstBuffer *buf = NULL;

  if (G_UNLIKELY (!GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (h264parse))))
    modified = TRUE;
  else if (G_UNLIKELY (!h264parse->update_caps))
    return;

  /* carry over input caps as much as possible; override with our own stuff */
  sink_caps = GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (h264parse));
  if (sink_caps)
    gst_caps_ref (sink_caps);
  else
    sink_caps = gst_caps_new_simple ("video/x-h264", NULL);

  sps = h264parse->params->sps;
  GST_DEBUG_OBJECT (h264parse, "sps: %p", sps);

  /* only codec-data for nice-and-clean au aligned packetized avc format */
  if (h264parse->format == GST_H264_PARSE_FORMAT_AVC &&
      h264parse->align == GST_H264_PARSE_ALIGN_AU) {
    buf = gst_h264_parse_make_codec_data (h264parse);
    if (buf && h264parse->codec_data) {
      if (GST_BUFFER_SIZE (buf) != GST_BUFFER_SIZE (h264parse->codec_data) ||
          memcmp (GST_BUFFER_DATA (buf),
              GST_BUFFER_DATA (h264parse->codec_data), GST_BUFFER_SIZE (buf)))
        modified = TRUE;
    } else {
      if (h264parse->codec_data)
        buf = gst_buffer_ref (h264parse->codec_data);
      modified = TRUE;
    }
  }

  if (G_UNLIKELY (!sps)) {
    caps = gst_caps_copy (sink_caps);
  } else if (G_UNLIKELY (h264parse->width != sps->width ||
          h264parse->height != sps->height || h264parse->fps_num != sps->fps_num
          || h264parse->fps_den != sps->fps_den || modified)) {
    caps = gst_caps_copy (sink_caps);
    /* sps should give this */
    gst_caps_set_simple (caps, "width", G_TYPE_INT, sps->width,
        "height", G_TYPE_INT, sps->height, NULL);
    h264parse->height = sps->height;
    h264parse->width = sps->width;
    /* but not necessarily or reliably this */
    if ((!h264parse->fps_num || !h264parse->fps_den) &&
        sps->fps_num > 0 && sps->fps_den > 0) {
      gst_caps_set_simple (caps, "framerate",
          GST_TYPE_FRACTION, sps->fps_num, sps->fps_den, NULL);
      h264parse->fps_num = sps->fps_num;
      h264parse->fps_den = sps->fps_den;
      gst_base_parse_set_frame_props (GST_BASE_PARSE (h264parse),
          h264parse->fps_num, h264parse->fps_den, 0, 0);
    }
  }

  if (caps) {
    gst_caps_set_simple (caps, "parsed", G_TYPE_BOOLEAN, TRUE,
        "stream-format", G_TYPE_STRING,
        gst_h264_parse_get_string (h264parse, TRUE, h264parse->format),
        "alignment", G_TYPE_STRING,
        gst_h264_parse_get_string (h264parse, FALSE, h264parse->align), NULL);
    if (buf) {
      gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
      gst_buffer_replace (&h264parse->codec_data, buf);
      gst_buffer_unref (buf);
      buf = NULL;
    } else {
      GstStructure *s;
      /* remove any left-over codec-data hanging around */
      s = gst_caps_get_structure (caps, 0);
      gst_structure_remove_field (s, "codec_data");
    }
    gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (h264parse), caps);
    gst_caps_unref (caps);
  }

  gst_caps_unref (sink_caps);
  if (buf)
    gst_buffer_unref (buf);
}
static void
gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse)
{
  GstCaps *caps = NULL;

  /* only update if no src caps yet or explicitly triggered */
  if (G_LIKELY (gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (mpvparse)) &&
          !mpvparse->update_caps))
    return;

  /* carry over input caps as much as possible; override with our own stuff */
  caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (mpvparse));
  if (caps) {
    caps = gst_caps_make_writable (caps);
  } else {
    caps = gst_caps_new_empty_simple ("video/mpeg");
  }

  /* typically we don't output buffers until we have properly parsed some
   * config data, so we should at least know about version.
   * If not, it means it has been requested not to drop data, and
   * upstream and/or app must know what they are doing ... */
  gst_caps_set_simple (caps,
      "mpegversion", G_TYPE_INT, (mpvparse->config_flags & FLAG_MPEG2) ? 2 : 1,
      NULL);

  gst_caps_set_simple (caps, "systemstream", G_TYPE_BOOLEAN, FALSE,
      "parsed", G_TYPE_BOOLEAN, TRUE, NULL);

  if (mpvparse->sequencehdr.width > 0 && mpvparse->sequencehdr.height > 0) {
    gst_caps_set_simple (caps, "width", G_TYPE_INT, mpvparse->sequencehdr.width,
        "height", G_TYPE_INT, mpvparse->sequencehdr.height, NULL);
  }

  /* perhaps we have  a framerate */
  if (mpvparse->fps_num > 0 && mpvparse->fps_den > 0) {
    gint fps_num = mpvparse->fps_num;
    gint fps_den = mpvparse->fps_den;
    GstClockTime latency = gst_util_uint64_scale (GST_SECOND, fps_den, fps_num);

    gst_caps_set_simple (caps, "framerate",
        GST_TYPE_FRACTION, fps_num, fps_den, NULL);
    gst_base_parse_set_frame_rate (GST_BASE_PARSE (mpvparse),
        fps_num, fps_den, 0, 0);
    gst_base_parse_set_latency (GST_BASE_PARSE (mpvparse), latency, latency);
  }

  /* or pixel-aspect-ratio */
  if (mpvparse->sequencehdr.par_w && mpvparse->sequencehdr.par_h > 0) {
    gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
        mpvparse->sequencehdr.par_w, mpvparse->sequencehdr.par_h, NULL);
  }

  if (mpvparse->config != NULL) {
    gst_caps_set_simple (caps, "codec_data",
        GST_TYPE_BUFFER, mpvparse->config, NULL);
  }

  if (mpvparse->config_flags & FLAG_SEQUENCE_EXT) {
    const guint profile_c = mpvparse->sequenceext.profile;
    const guint level_c = mpvparse->sequenceext.level;
    const gchar *profile = NULL, *level = NULL;
    /*
     * Profile indication - 1 => High, 2 => Spatially Scalable,
     *                      3 => SNR Scalable, 4 => Main, 5 => Simple
     * 4:2:2 and Multi-view have profile = 0, with the escape bit set to 1
     */
    const gchar *const profiles[] =
        { "high", "spatial", "snr", "main", "simple" };
    /*
     * Level indication - 4 => High, 6 => High-1440, 8 => Main, 10 => Low,
     *                    except in the case of profile = 0
     */
    const gchar *const levels[] = { "high", "high-1440", "main", "low" };

    if (profile_c > 0 && profile_c < 6)
      profile = profiles[profile_c - 1];

    if ((level_c > 3) && (level_c < 11) && (level_c % 2 == 0))
      level = levels[(level_c >> 1) - 2];

    if (profile_c == 8) {
      /* Non-hierarchical profile */
      switch (level_c) {
        case 2:
          level = levels[0];
        case 5:
          level = levels[2];
          profile = "4:2:2";
          break;
        case 10:
          level = levels[0];
        case 11:
          level = levels[1];
        case 13:
          level = levels[2];
        case 14:
          level = levels[3];
          profile = "multiview";
          break;
        default:
          break;
      }
    }

    /* FIXME does it make sense to expose profile/level in the caps ? */

    GST_DEBUG_OBJECT (mpvparse, "profile:'%s' level:'%s'", profile, level);

    if (profile)
      gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
    else
      GST_DEBUG_OBJECT (mpvparse, "Invalid profile - %u", profile_c);

    if (level)
      gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
    else
      GST_DEBUG_OBJECT (mpvparse, "Invalid level - %u", level_c);

    gst_caps_set_simple (caps, "interlace-mode",
        G_TYPE_STRING,
        (mpvparse->sequenceext.progressive ? "progressive" : "mixed"), NULL);
  }

  gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (mpvparse), caps);
  gst_caps_unref (caps);

  mpvparse->update_caps = FALSE;
}
Пример #13
0
static void
gst_h263_parse_set_src_caps (GstH263Parse * h263parse,
    const H263Params * params)
{
  GstStructure *st;
  GstCaps *caps, *sink_caps;
  gint fr_num, fr_denom;

  g_assert (h263parse->state == PASSTHROUGH || h263parse->state == GOT_HEADER);

  caps = GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (h263parse));
  if (caps) {
    caps = gst_caps_copy (caps);
  } else {
    caps = gst_caps_new_simple ("video/x-h263",
        "variant", G_TYPE_STRING, "itu", NULL);
  }
  gst_caps_set_simple (caps, "parsed", G_TYPE_BOOLEAN, TRUE, NULL);

  sink_caps = GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (h263parse));
  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 (h263parse, "sink caps override framerate from headers");
  } else {
    /* Caps didn't have the framerate - get it from params */
    gst_h263_parse_get_framerate (params, &fr_num, &fr_denom);
  }
  gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, fr_num, fr_denom,
      NULL);

  if (params->width && params->height)
    gst_caps_set_simple (caps, "width", G_TYPE_INT, params->width,
        "height", G_TYPE_INT, params->height, NULL);

  if (h263parse->state == GOT_HEADER) {
    gst_caps_set_simple (caps,
        "annex-d", G_TYPE_BOOLEAN, (params->features & H263_OPTION_UMV_MODE),
        "annex-e", G_TYPE_BOOLEAN, (params->features & H263_OPTION_SAC_MODE),
        "annex-f", G_TYPE_BOOLEAN, (params->features & H263_OPTION_AP_MODE),
        "annex-g", G_TYPE_BOOLEAN, (params->features & H263_OPTION_PB_MODE),
        "annex-i", G_TYPE_BOOLEAN, (params->features & H263_OPTION_AIC_MODE),
        "annex-j", G_TYPE_BOOLEAN, (params->features & H263_OPTION_DF_MODE),
        "annex-k", G_TYPE_BOOLEAN, (params->features & H263_OPTION_SS_MODE),
        "annex-m", G_TYPE_BOOLEAN, (params->type == PICTURE_IMPROVED_PB),
        "annex-n", G_TYPE_BOOLEAN, (params->features & H263_OPTION_RPS_MODE),
        "annex-q", G_TYPE_BOOLEAN, (params->features & H263_OPTION_RRU_MODE),
        "annex-r", G_TYPE_BOOLEAN, (params->features & H263_OPTION_ISD_MODE),
        "annex-s", G_TYPE_BOOLEAN, (params->features & H263_OPTION_AIV_MODE),
        "annex-t", G_TYPE_BOOLEAN, (params->features & H263_OPTION_MQ_MODE),
        "annex-u", G_TYPE_BOOLEAN, (params->features & H263_OPTION_ERPS_MODE),
        "annex-v", G_TYPE_BOOLEAN, (params->features & H263_OPTION_DPS_MODE),
        NULL);

    h263parse->profile = gst_h263_parse_get_profile (params);
    if (h263parse->profile != -1)
      gst_caps_set_simple (caps, "profile", G_TYPE_UINT, h263parse->profile,
          NULL);

    h263parse->level = gst_h263_parse_get_level (params, h263parse->profile,
        h263parse->bitrate, fr_num, fr_denom);
    if (h263parse->level != -1)
      gst_caps_set_simple (caps, "level", G_TYPE_UINT, h263parse->level, NULL);
  }

  gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (GST_BASE_PARSE (h263parse)), caps);
  gst_caps_unref (caps);
}
Пример #14
0
static GstFlowReturn
gst_opus_parse_parse_frame (GstBaseParse * base, GstBaseParseFrame * frame)
{
  guint64 duration;
  GstOpusParse *parse;
  gboolean is_idheader, is_commentheader;
  GstMapInfo map;
  GstAudioClippingMeta *cmeta =
      gst_buffer_get_audio_clipping_meta (frame->buffer);

  parse = GST_OPUS_PARSE (base);

  g_assert (!cmeta || cmeta->format == GST_FORMAT_DEFAULT);

  is_idheader = gst_opus_header_is_id_header (frame->buffer);
  is_commentheader = gst_opus_header_is_comment_header (frame->buffer);

  if (!parse->got_headers || !parse->header_sent) {
    GstCaps *caps;

    /* Opus streams can decode to 1 or 2 channels, so use the header
       value if we have one, or 2 otherwise */
    if (is_idheader) {
      gst_buffer_replace (&parse->id_header, frame->buffer);
      GST_DEBUG_OBJECT (parse, "Found ID header, keeping");
      return GST_BASE_PARSE_FLOW_DROPPED;
    } else if (is_commentheader) {
      gst_buffer_replace (&parse->comment_header, frame->buffer);
      GST_DEBUG_OBJECT (parse, "Found comment header, keeping");
      return GST_BASE_PARSE_FLOW_DROPPED;
    }

    parse->got_headers = TRUE;

    if (cmeta && cmeta->start) {
      parse->pre_skip += cmeta->start;

      gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
      duration = packet_duration_opus (map.data, map.size);
      gst_buffer_unmap (frame->buffer, &map);

      /* Queue frame for later once we know all initial padding */
      if (duration == cmeta->start) {
        frame->flags |= GST_BASE_PARSE_FRAME_FLAG_QUEUE;
      }
    }

    if (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_QUEUE)) {
      if (FALSE && parse->id_header && parse->comment_header) {
        guint16 pre_skip;

        gst_buffer_map (parse->id_header, &map, GST_MAP_READWRITE);
        pre_skip = GST_READ_UINT16_LE (map.data + 10);
        if (pre_skip != parse->pre_skip) {
          GST_DEBUG_OBJECT (parse,
              "Fixing up pre-skip %u -> %" G_GUINT64_FORMAT, pre_skip,
              parse->pre_skip);
          GST_WRITE_UINT16_LE (map.data + 10, parse->pre_skip);
        }
        gst_buffer_unmap (parse->id_header, &map);

        caps =
            gst_codec_utils_opus_create_caps_from_header (parse->id_header,
            parse->comment_header);
      } else {
        GstCaps *sink_caps;
        guint32 sample_rate = 48000;
        guint8 n_channels, n_streams, n_stereo_streams, channel_mapping_family;
        guint8 channel_mapping[256];
        GstBuffer *id_header;

        sink_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (parse));
        if (!sink_caps
            || !gst_codec_utils_opus_parse_caps (sink_caps, &sample_rate,
                &n_channels, &channel_mapping_family, &n_streams,
                &n_stereo_streams, channel_mapping)) {
          GST_INFO_OBJECT (parse,
              "No headers and no caps, blindly setting up canonical stereo");
          n_channels = 2;
          n_streams = 1;
          n_stereo_streams = 1;
          channel_mapping_family = 0;
          channel_mapping[0] = 0;
          channel_mapping[1] = 1;
        }
        if (sink_caps)
          gst_caps_unref (sink_caps);

        id_header =
            gst_codec_utils_opus_create_header (sample_rate, n_channels,
            channel_mapping_family, n_streams, n_stereo_streams,
            channel_mapping, parse->pre_skip, 0);
        caps = gst_codec_utils_opus_create_caps_from_header (id_header, NULL);
        gst_buffer_unref (id_header);
      }

      gst_buffer_replace (&parse->id_header, NULL);
      gst_buffer_replace (&parse->comment_header, NULL);

      gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
      gst_caps_unref (caps);
      parse->header_sent = TRUE;
    }
  }

  GST_BUFFER_TIMESTAMP (frame->buffer) = parse->next_ts;

  gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
  duration = packet_duration_opus (map.data, map.size);
  gst_buffer_unmap (frame->buffer, &map);
  parse->next_ts += duration;

  GST_BUFFER_DURATION (frame->buffer) = duration;
  GST_BUFFER_OFFSET_END (frame->buffer) =
      gst_util_uint64_scale (parse->next_ts, 48000, GST_SECOND);
  GST_BUFFER_OFFSET (frame->buffer) = parse->next_ts;

  return GST_FLOW_OK;
}
Пример #15
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;
}
Пример #16
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;
}
Пример #17
0
static void
gst_png_parse_init (GstPngParse * pngparse)
{
  GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (pngparse));
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (pngparse));
}
Пример #18
0
static void
gst_h263_parse_init (GstH263Parse * h263parse)
{
  GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h263parse));
}