Exemplo n.º 1
0
static GstStateChangeReturn
opus_dec_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstOpusDec *dec = GST_OPUS_DEC (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
    case GST_STATE_CHANGE_READY_TO_PAUSED:
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
    default:
      break;
  }

  ret = parent_class->change_state (element, transition);
  if (ret != GST_STATE_CHANGE_SUCCESS)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_opus_dec_reset (dec);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;
}
Exemplo n.º 2
0
static void
gst_opus_dec_init (GstOpusDec * dec, GstOpusDecClass * g_class)
{
  dec->sinkpad =
      gst_pad_new_from_static_template (&opus_dec_sink_factory, "sink");
  gst_pad_set_chain_function (dec->sinkpad, GST_DEBUG_FUNCPTR (opus_dec_chain));
  gst_pad_set_event_function (dec->sinkpad,
      GST_DEBUG_FUNCPTR (opus_dec_sink_event));
  gst_pad_set_query_type_function (dec->sinkpad,
      GST_DEBUG_FUNCPTR (opus_get_sink_query_types));
  gst_pad_set_query_function (dec->sinkpad,
      GST_DEBUG_FUNCPTR (opus_dec_sink_query));
  gst_pad_set_setcaps_function (dec->sinkpad,
      GST_DEBUG_FUNCPTR (opus_dec_sink_setcaps));
  gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);

  dec->srcpad = gst_pad_new_from_static_template (&opus_dec_src_factory, "src");
  gst_pad_use_fixed_caps (dec->srcpad);
  gst_pad_set_event_function (dec->srcpad,
      GST_DEBUG_FUNCPTR (opus_dec_src_event));
  gst_pad_set_query_type_function (dec->srcpad,
      GST_DEBUG_FUNCPTR (opus_get_src_query_types));
  gst_pad_set_query_function (dec->srcpad,
      GST_DEBUG_FUNCPTR (opus_dec_src_query));
  gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);

  dec->sample_rate = 48000;
  dec->n_channels = 2;

  gst_opus_dec_reset (dec);
}
Exemplo n.º 3
0
static gboolean
gst_opus_dec_stop (GstAudioDecoder * dec)
{
  GstOpusDec *odec = GST_OPUS_DEC (dec);

  gst_opus_dec_reset (odec);

  return TRUE;
}
Exemplo n.º 4
0
static void
gst_opus_dec_init (GstOpusDec * dec)
{
  dec->use_inband_fec = FALSE;
  dec->apply_gain = DEFAULT_APPLY_GAIN;

  gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (dec), TRUE);

  gst_opus_dec_reset (dec);
}
Exemplo n.º 5
0
static void
gst_opus_dec_init (GstOpusDec * dec)
{
  dec->sample_rate = 0;
  dec->n_channels = 0;
  dec->use_inband_fec = FALSE;
  dec->apply_gain = DEFAULT_APPLY_GAIN;

  gst_opus_dec_reset (dec);
}
static void
gst_opus_dec_init (GstOpusDec * dec)
{
  dec->use_inband_fec = FALSE;
  dec->apply_gain = DEFAULT_APPLY_GAIN;

  gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (dec), TRUE);
  gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
      (dec), TRUE);
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (dec));

  gst_opus_dec_reset (dec);
}
Exemplo n.º 7
0
static gboolean
gst_opus_dec_start (GstAudioDecoder * dec)
{
  GstOpusDec *odec = GST_OPUS_DEC (dec);

  gst_opus_dec_reset (odec);

  /* we know about concealment */
  gst_audio_decoder_set_plc_aware (dec, TRUE);

  if (odec->use_inband_fec) {
    gst_audio_decoder_set_latency (dec, 2 * GST_MSECOND + GST_MSECOND / 2,
        120 * GST_MSECOND);
  }

  return TRUE;
}
Exemplo n.º 8
0
static gboolean
gst_opus_dec_start (GstAudioDecoder * dec)
{
  GstOpusDec *odec = GST_OPUS_DEC (dec);

  gst_opus_dec_reset (odec);

  /* we know about concealment */
  gst_audio_decoder_set_plc_aware (dec, TRUE);

  if (odec->use_inband_fec) {
    /* opusdec outputs samples directly from an input buffer, except if
     * FEC is on, in which case it buffers one buffer in case one buffer
     * goes missing.
     */
    gst_audio_decoder_set_latency (dec, 120 * GST_MSECOND, 120 * GST_MSECOND);
  }

  return TRUE;
}
Exemplo n.º 9
0
static gboolean
gst_opus_dec_set_format (GstAudioDecoder * bdec, GstCaps * caps)
{
  GstOpusDec *dec = GST_OPUS_DEC (bdec);
  gboolean ret = TRUE;
  GstStructure *s;
  const GValue *streamheader;
  GstCaps *old_caps;

  GST_DEBUG_OBJECT (dec, "set_format: %" GST_PTR_FORMAT, caps);

  if ((old_caps = gst_pad_get_current_caps (GST_AUDIO_DECODER_SINK_PAD (bdec)))) {
    if (gst_caps_is_equal (caps, old_caps)) {
      gst_caps_unref (old_caps);
      GST_DEBUG_OBJECT (dec, "caps didn't change");
      goto done;
    }

    GST_DEBUG_OBJECT (dec, "caps have changed, resetting decoder");
    gst_opus_dec_reset (dec);
    gst_caps_unref (old_caps);
  }

  s = gst_caps_get_structure (caps, 0);
  if ((streamheader = gst_structure_get_value (s, "streamheader")) &&
      G_VALUE_HOLDS (streamheader, GST_TYPE_ARRAY) &&
      gst_value_array_get_size (streamheader) >= 2) {
    const GValue *header, *vorbiscomment;
    GstBuffer *buf;
    GstFlowReturn res = GST_FLOW_OK;

    header = gst_value_array_get_value (streamheader, 0);
    if (header && G_VALUE_HOLDS (header, GST_TYPE_BUFFER)) {
      buf = gst_value_get_buffer (header);
      res = gst_opus_dec_parse_header (dec, buf);
      if (res != GST_FLOW_OK)
        goto done;
      gst_buffer_replace (&dec->streamheader, buf);
    }

    vorbiscomment = gst_value_array_get_value (streamheader, 1);
    if (vorbiscomment && G_VALUE_HOLDS (vorbiscomment, GST_TYPE_BUFFER)) {
      buf = gst_value_get_buffer (vorbiscomment);
      res = gst_opus_dec_parse_comments (dec, buf);
      if (res != GST_FLOW_OK)
        goto done;
      gst_buffer_replace (&dec->vorbiscomment, buf);
    }
  } else {
    /* defaults if not in the caps */
    dec->n_channels = 2;
    dec->sample_rate = 48000;

    gst_structure_get_int (s, "channels", &dec->n_channels);
    gst_structure_get_int (s, "rate", &dec->sample_rate);

    /* default stereo mapping */
    dec->channel_mapping_family = 0;
    dec->channel_mapping[0] = 0;
    dec->channel_mapping[1] = 1;
    dec->n_streams = 1;
    dec->n_stereo_streams = 1;

    gst_opus_dec_negotiate (dec, NULL);
  }

done:
  return ret;
}
static gboolean
gst_opus_dec_set_format (GstAudioDecoder * bdec, GstCaps * caps)
{
  GstOpusDec *dec = GST_OPUS_DEC (bdec);
  gboolean ret = TRUE;
  GstStructure *s;
  const GValue *streamheader;
  GstCaps *old_caps;

  GST_DEBUG_OBJECT (dec, "set_format: %" GST_PTR_FORMAT, caps);

  if ((old_caps = gst_pad_get_current_caps (GST_AUDIO_DECODER_SINK_PAD (bdec)))) {
    if (gst_caps_is_equal (caps, old_caps)) {
      gst_caps_unref (old_caps);
      GST_DEBUG_OBJECT (dec, "caps didn't change");
      goto done;
    }

    GST_DEBUG_OBJECT (dec, "caps have changed, resetting decoder");
    gst_opus_dec_reset (dec);
    gst_caps_unref (old_caps);
  }

  s = gst_caps_get_structure (caps, 0);
  if ((streamheader = gst_structure_get_value (s, "streamheader")) &&
      G_VALUE_HOLDS (streamheader, GST_TYPE_ARRAY) &&
      gst_value_array_get_size (streamheader) >= 2) {
    const GValue *header, *vorbiscomment;
    GstBuffer *buf;
    GstFlowReturn res = GST_FLOW_OK;

    header = gst_value_array_get_value (streamheader, 0);
    if (header && G_VALUE_HOLDS (header, GST_TYPE_BUFFER)) {
      buf = gst_value_get_buffer (header);
      res = gst_opus_dec_parse_header (dec, buf);
      if (res != GST_FLOW_OK) {
        ret = FALSE;
        goto done;
      }
      gst_buffer_replace (&dec->streamheader, buf);
    }

    vorbiscomment = gst_value_array_get_value (streamheader, 1);
    if (vorbiscomment && G_VALUE_HOLDS (vorbiscomment, GST_TYPE_BUFFER)) {
      buf = gst_value_get_buffer (vorbiscomment);
      res = gst_opus_dec_parse_comments (dec, buf);
      if (res != GST_FLOW_OK) {
        ret = FALSE;
        goto done;
      }
      gst_buffer_replace (&dec->vorbiscomment, buf);
    }
  } else {
    const GstAudioChannelPosition *posn = NULL;

    if (!gst_codec_utils_opus_parse_caps (caps, &dec->sample_rate,
            &dec->n_channels, &dec->channel_mapping_family, &dec->n_streams,
            &dec->n_stereo_streams, dec->channel_mapping)) {
      ret = FALSE;
      goto done;
    }

    if (dec->channel_mapping_family == 1 && dec->n_channels <= 8)
      posn = gst_opus_channel_positions[dec->n_channels - 1];

    if (!gst_opus_dec_negotiate (dec, posn))
      return FALSE;
  }

done:
  return ret;
}