Ejemplo n.º 1
0
static void
gst_deinterleave_set_pads_caps (GstDeinterleave * self, GstCaps * caps)
{
  GList *l;

  GstStructure *s;

  gint i;

  for (l = self->srcpads, i = 0; l; l = l->next, i++) {
    GstPad *pad = GST_PAD (l->data);

    GstCaps *srccaps;

    /* Set channel position if we know it */
    if (self->keep_positions) {
      GstAudioChannelPosition pos[1] = { GST_AUDIO_CHANNEL_POSITION_NONE };

      srccaps = gst_caps_copy (caps);
      s = gst_caps_get_structure (srccaps, 0);
      if (self->pos)
        gst_audio_set_channel_positions (s, &self->pos[i]);
      else
        gst_audio_set_channel_positions (s, pos);
    } else {
      srccaps = caps;
    }

    gst_pad_set_caps (pad, srccaps);

    if (self->keep_positions)
      gst_caps_unref (srccaps);
  }
}
Ejemplo n.º 2
0
static gboolean
gst_a52dec_reneg (GstA52Dec * a52dec, GstPad * pad)
{
  GstAudioChannelPosition *pos;
  gint channels = gst_a52dec_channels (a52dec->using_channels, &pos);
  GstCaps *caps = NULL;
  gboolean result = FALSE;

  if (!channels)
    goto done;

  GST_INFO_OBJECT (a52dec, "reneg channels:%d rate:%d",
      channels, a52dec->sample_rate);

  caps = gst_caps_new_simple ("audio/x-raw-float",
      "endianness", G_TYPE_INT, G_BYTE_ORDER,
      "width", G_TYPE_INT, SAMPLE_WIDTH,
      "channels", G_TYPE_INT, channels,
      "rate", G_TYPE_INT, a52dec->sample_rate, NULL);
  gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
  g_free (pos);

  if (!gst_pad_set_caps (pad, caps))
    goto done;

  result = TRUE;

done:
  if (caps)
    gst_caps_unref (caps);
  return result;
}
Ejemplo n.º 3
0
gint
main (gint argc, gchar * argv[])
{
  gchar *str;
  GstCaps *caps;
  GstAudioChannelPosition pos[2] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
    GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
  };

  /* register multichannel type */
  gst_init (&argc, &argv);
  gst_audio_channel_position_get_type ();

  /* test some caps-string conversions */
  caps = gst_caps_new_simple ("audio/x-raw-int",
      "channels", G_TYPE_INT, 2, NULL);
  str = gst_caps_to_string (caps);
  g_print ("Test caps #1: %s\n", str);
  g_free (str);
  gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
  str = gst_caps_to_string (caps);
  g_print ("Test caps #2: %s\n", str);
  g_free (str);
  gst_caps_unref (caps);

  return 0;
}
Ejemplo n.º 4
0
static gboolean
gst_dtsdec_renegotiate (GstDtsDec * dts)
{
  GstAudioChannelPosition *pos;
  GstCaps *caps = gst_caps_from_string (DTS_CAPS);
  gint channels = gst_dtsdec_channels (dts->using_channels, &pos);
  gboolean result = FALSE;

  if (!channels)
    goto done;

  GST_INFO ("dtsdec renegotiate, channels=%d, rate=%d",
      channels, dts->sample_rate);

  gst_caps_set_simple (caps,
      "channels", G_TYPE_INT, channels,
      "rate", G_TYPE_INT, (gint) dts->sample_rate, NULL);
  gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
  g_free (pos);

  if (!gst_pad_set_caps (dts->srcpad, caps))
    goto done;

  result = TRUE;

done:
  if (caps) {
    gst_caps_unref (caps);
  }
  return result;
}
Ejemplo n.º 5
0
/* if channels are less than or equal to 8, we set a default layout,
 * otherwise set layout to an array of GST_AUDIO_CHANNEL_POSITION_NONE */
void
gst_jack_set_layout_on_caps (GstCaps ** caps, gint channels)
{
  int c;
  GValue pos = { 0 };
  GValue chanpos = { 0 };
  gst_caps_unref (*caps);

  if (channels <= 8) {
    g_assert (channels >= 1);
    gst_audio_set_channel_positions (gst_caps_get_structure (*caps, 0),
        default_positions[channels - 1]);
  } else {
    g_value_init (&chanpos, GST_TYPE_ARRAY);
    g_value_init (&pos, GST_TYPE_AUDIO_CHANNEL_POSITION);
    for (c = 0; c < channels; c++) {
      g_value_set_enum (&pos, GST_AUDIO_CHANNEL_POSITION_NONE);
      gst_value_array_append_value (&chanpos, &pos);
    }
    g_value_unset (&pos);
    gst_structure_set_value (gst_caps_get_structure (*caps, 0),
        "channel-positions", &chanpos);
    g_value_unset (&chanpos);
  }
  gst_caps_ref (*caps);
}
Ejemplo n.º 6
0
static void
sink_handoff_float32 (GstElement * element, GstBuffer * buffer, GstPad * pad,
    gpointer user_data)
{
  gint i;
  gfloat *data;
  GstCaps *caps;
  gint n = GPOINTER_TO_INT (user_data);

  fail_unless (GST_IS_BUFFER (buffer));
  fail_unless_equals_int (GST_BUFFER_SIZE (buffer),
      48000 * 2 * sizeof (gfloat));
  fail_unless_equals_int (GST_BUFFER_DURATION (buffer), GST_SECOND);

  caps = gst_caps_new_simple ("audio/x-raw-float",
      "width", G_TYPE_INT, 32,
      "channels", G_TYPE_INT, 2,
      "rate", G_TYPE_INT, 48000, "endianness", G_TYPE_INT, G_BYTE_ORDER, NULL);

  if (n == 0) {
    GstAudioChannelPosition pos[2] =
        { GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE };
    gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
  } else if (n == 1) {
    GstAudioChannelPosition pos[2] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
      GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
    };
    gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
  } else if (n == 2) {
    GstAudioChannelPosition pos[2] = { GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
      GST_AUDIO_CHANNEL_POSITION_REAR_CENTER
    };
    gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
  }

  fail_unless (gst_caps_is_equal (caps, GST_BUFFER_CAPS (buffer)));
  gst_caps_unref (caps);

  data = (gfloat *) GST_BUFFER_DATA (buffer);

  for (i = 0; i < 48000 * 2; i += 2) {
    fail_unless_equals_float (data[i], -1.0);
    fail_unless_equals_float (data[i + 1], 1.0);
  }

  have_data++;
}
Ejemplo n.º 7
0
static void
gst_deinterleave_add_new_pads (GstDeinterleave * self, GstCaps * caps)
{
  GstPad *pad;

  guint i;

  for (i = 0; i < self->channels; i++) {
    gchar *name = g_strdup_printf ("src%d", i);

    GstCaps *srccaps;

    GstStructure *s;

    pad = gst_pad_new_from_static_template (&src_template, name);
    g_free (name);

    /* Set channel position if we know it */
    if (self->keep_positions) {
      GstAudioChannelPosition pos[1] = { GST_AUDIO_CHANNEL_POSITION_NONE };

      srccaps = gst_caps_copy (caps);
      s = gst_caps_get_structure (srccaps, 0);
      if (self->pos)
        gst_audio_set_channel_positions (s, &self->pos[i]);
      else
        gst_audio_set_channel_positions (s, pos);
    } else {
      srccaps = caps;
    }

    gst_pad_set_caps (pad, srccaps);
    gst_pad_use_fixed_caps (pad);
    gst_pad_set_query_function (pad,
        GST_DEBUG_FUNCPTR (gst_deinterleave_src_query));
    gst_pad_set_active (pad, TRUE);
    gst_element_add_pad (GST_ELEMENT (self), pad);
    self->srcpads = g_list_prepend (self->srcpads, gst_object_ref (pad));

    if (self->keep_positions)
      gst_caps_unref (srccaps);
  }

  gst_element_no_more_pads (GST_ELEMENT (self));
  self->srcpads = g_list_reverse (self->srcpads);
}
Ejemplo n.º 8
0
static void
src_handoff_float32 (GstElement * element, GstBuffer * buffer, GstPad * pad,
    gpointer user_data)
{
  gint n = GPOINTER_TO_INT (user_data);
  GstCaps *caps;
  gfloat *data;
  gint i;

  if (GST_PAD_CAPS (pad))
    caps = gst_caps_ref (GST_PAD_CAPS (pad));
  else {
    caps = gst_caps_new_simple ("audio/x-raw-float",
        "width", G_TYPE_INT, 32,
        "channels", G_TYPE_INT, 1,
        "rate", G_TYPE_INT, 48000, "endianness", G_TYPE_INT, G_BYTE_ORDER,
        NULL);

    if (n == 2) {
      GstAudioChannelPosition pos[1] =
          { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT };
      gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
    } else if (n == 3) {
      GstAudioChannelPosition pos[1] =
          { GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT };
      gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
    }
  }

  data = g_new (gfloat, 48000);
  GST_BUFFER_MALLOCDATA (buffer) = (guint8 *) data;
  GST_BUFFER_DATA (buffer) = (guint8 *) data;
  GST_BUFFER_SIZE (buffer) = 48000 * sizeof (gfloat);

  GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
  GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
  GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET_NONE;
  GST_BUFFER_DURATION (buffer) = GST_SECOND;

  GST_BUFFER_CAPS (buffer) = caps;

  for (i = 0; i < 48000; i++)
    data[i] = (n % 2 == 0) ? -1.0 : 1.0;
}
Ejemplo n.º 9
0
static gboolean
gst_wavpack_dec_sink_set_caps (GstPad * pad, GstCaps * caps)
{
    GstWavpackDec *dec = GST_WAVPACK_DEC (gst_pad_get_parent (pad));
    GstStructure *structure = gst_caps_get_structure (caps, 0);

    /* Check if we can set the caps here already */
    if (gst_structure_get_int (structure, "channels", &dec->channels) &&
            gst_structure_get_int (structure, "rate", &dec->sample_rate) &&
            gst_structure_get_int (structure, "width", &dec->depth)) {
        GstCaps *caps;
        GstAudioChannelPosition *pos;

        caps = gst_caps_new_simple ("audio/x-raw-int",
                                    "rate", G_TYPE_INT, dec->sample_rate,
                                    "channels", G_TYPE_INT, dec->channels,
                                    "depth", G_TYPE_INT, dec->depth,
                                    "width", G_TYPE_INT, 32,
                                    "endianness", G_TYPE_INT, G_BYTE_ORDER,
                                    "signed", G_TYPE_BOOLEAN, TRUE, NULL);

        /* If we already have the channel layout set from upstream
         * take this */
        if (gst_structure_has_field (structure, "channel-positions")) {
            pos = gst_audio_get_channel_positions (structure);
            if (pos != NULL && dec->channels > 2) {
                GstStructure *new_str = gst_caps_get_structure (caps, 0);

                gst_audio_set_channel_positions (new_str, pos);
                dec->channel_mask =
                    gst_wavpack_get_channel_mask_from_positions (pos, dec->channels);
            }

            if (pos != NULL)
                g_free (pos);
        }

        GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);

        /* should always succeed */
        gst_pad_set_caps (dec->srcpad, caps);
        gst_caps_unref (caps);

        /* send GST_TAG_AUDIO_CODEC and GST_TAG_BITRATE tags before something
         * is decoded or after the format has changed */
        gst_wavpack_dec_post_tags (dec);
    }

    gst_object_unref (dec);

    return TRUE;
}
Ejemplo n.º 10
0
static gboolean
gst_dvdlpcmdec_set_outcaps (GstDvdLpcmDec * dvdlpcmdec)
{
  gboolean res = TRUE;
  GstCaps *src_caps;
  GstAudioChannelPosition *pos;

  /* Build caps to set on the src pad, which we know from the incoming caps */
  src_caps = gst_caps_new_simple ("audio/x-raw-int",
      "rate", G_TYPE_INT, dvdlpcmdec->rate,
      "channels", G_TYPE_INT, dvdlpcmdec->channels,
      "endianness", G_TYPE_INT, G_BIG_ENDIAN,
      "depth", G_TYPE_INT, dvdlpcmdec->out_width,
      "width", G_TYPE_INT, dvdlpcmdec->out_width,
      "signed", G_TYPE_BOOLEAN, TRUE, NULL);

  pos = get_audio_channel_positions (dvdlpcmdec);
  if (pos) {
    gst_audio_set_channel_positions (gst_caps_get_structure (src_caps, 0), pos);
    g_free (pos);
  }

  GST_DEBUG_OBJECT (dvdlpcmdec, "Set rate %d, channels %d, width %d (out %d)",
      dvdlpcmdec->rate, dvdlpcmdec->channels, dvdlpcmdec->width,
      dvdlpcmdec->out_width);

  res = gst_pad_set_caps (dvdlpcmdec->srcpad, src_caps);
  if (res) {
    GST_DEBUG_OBJECT (dvdlpcmdec, "Successfully set output caps: %"
        GST_PTR_FORMAT, src_caps);

    gst_dvdlpcmdec_send_tags (dvdlpcmdec);
  } else {
    GST_DEBUG_OBJECT (dvdlpcmdec, "Failed to set output caps: %"
        GST_PTR_FORMAT, src_caps);
  }

  gst_caps_unref (src_caps);

  return res;
}
Ejemplo n.º 11
0
GstRingBufferSpec *
gst_pulse_channel_map_to_gst (const pa_channel_map * map,
    GstRingBufferSpec * spec)
{
  int i;
  GstAudioChannelPosition *pos;
  gboolean invalid = FALSE;

  g_return_val_if_fail (map->channels == spec->channels, NULL);

  pos = g_new0 (GstAudioChannelPosition, spec->channels + 1);

  for (i = 0; i < spec->channels; i++) {
    if (map->map[i] == PA_CHANNEL_POSITION_INVALID) {
      invalid = TRUE;
      break;
    } else if ((int) map->map[i] < (int) GST_AUDIO_CHANNEL_POSITION_NUM) {
      pos[i] = pa_to_gst_pos[map->map[i] + 1];
    } else {
      invalid = TRUE;
      break;
    }
  }

  if (!invalid && !gst_audio_check_channel_positions (pos, spec->channels))
    invalid = TRUE;

  if (invalid) {
    for (i = 0; i < spec->channels; i++)
      pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
  }

  gst_audio_set_channel_positions (gst_caps_get_structure (spec->caps, 0), pos);

  g_free (pos);

  return spec;
}
Ejemplo n.º 12
0
static GstFlowReturn
vorbis_handle_identification_packet (GstVorbisDec * vd)
{
  GstCaps *caps;
  const GstAudioChannelPosition *pos = NULL;
  gint width = GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH;

  switch (vd->vi.channels) {
    case 1:
    case 2:
      /* nothing */
      break;
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      pos = gst_vorbis_channel_positions[vd->vi.channels - 1];
      break;
    default:{
      gint i;
      GstAudioChannelPosition *posn =
          g_new (GstAudioChannelPosition, vd->vi.channels);

      GST_ELEMENT_WARNING (GST_ELEMENT (vd), STREAM, DECODE,
          (NULL), ("Using NONE channel layout for more than 8 channels"));

      for (i = 0; i < vd->vi.channels; i++)
        posn[i] = GST_AUDIO_CHANNEL_POSITION_NONE;

      pos = posn;
    }
  }

  /* negotiate width with downstream */
  caps = gst_pad_get_allowed_caps (vd->srcpad);
  if (caps) {
    if (!gst_caps_is_empty (caps)) {
      GstStructure *s;

      s = gst_caps_get_structure (caps, 0);
      /* template ensures 16 or 32 */
      gst_structure_get_int (s, "width", &width);

      GST_INFO_OBJECT (vd, "using %s with %d channels and %d bit audio depth",
          gst_structure_get_name (s), vd->vi.channels, width);
    }
    gst_caps_unref (caps);
  }
  vd->width = width >> 3;

  /* select a copy_samples function, this way we can have specialized versions
   * for mono/stereo and avoid the depth switch in tremor case */
  vd->copy_samples = get_copy_sample_func (vd->vi.channels, vd->width);

  caps = gst_caps_copy (gst_pad_get_pad_template_caps (vd->srcpad));
  gst_caps_set_simple (caps, "rate", G_TYPE_INT, vd->vi.rate,
      "channels", G_TYPE_INT, vd->vi.channels,
      "width", G_TYPE_INT, width, NULL);

  if (pos) {
    gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
  }

  if (vd->vi.channels > 8) {
    g_free ((GstAudioChannelPosition *) pos);
  }

  gst_pad_set_caps (vd->srcpad, caps);
  gst_caps_unref (caps);

  return GST_FLOW_OK;
}
Ejemplo n.º 13
0
static gboolean
gst_rtp_g722_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
{
  GstStructure *structure;
  GstRtpG722Depay *rtpg722depay;
  gint clock_rate, payload, samplerate;
  gint channels;
  GstCaps *srccaps;
  gboolean res;
  const gchar *channel_order;
  const GstRTPChannelOrder *order;

  rtpg722depay = GST_RTP_G722_DEPAY (depayload);

  structure = gst_caps_get_structure (caps, 0);

  payload = 96;
  gst_structure_get_int (structure, "payload", &payload);
  switch (payload) {
    case GST_RTP_PAYLOAD_G722:
      channels = 1;
      clock_rate = 8000;
      samplerate = 16000;
      break;
    default:
      /* no fixed mapping, we need clock-rate */
      channels = 0;
      clock_rate = 0;
      samplerate = 0;
      break;
  }

  /* caps can overwrite defaults */
  clock_rate =
      gst_rtp_g722_depay_parse_int (structure, "clock-rate", clock_rate);
  if (clock_rate == 0)
    goto no_clockrate;

  if (clock_rate == 8000)
    samplerate = 16000;

  if (samplerate == 0)
    samplerate = clock_rate;

  channels =
      gst_rtp_g722_depay_parse_int (structure, "encoding-params", channels);
  if (channels == 0) {
    channels = gst_rtp_g722_depay_parse_int (structure, "channels", channels);
    if (channels == 0) {
      /* channels defaults to 1 otherwise */
      channels = 1;
    }
  }

  depayload->clock_rate = clock_rate;
  rtpg722depay->rate = samplerate;
  rtpg722depay->channels = channels;

  srccaps = gst_caps_new_simple ("audio/G722",
      "rate", G_TYPE_INT, samplerate, "channels", G_TYPE_INT, channels, NULL);

  /* add channel positions */
  channel_order = gst_structure_get_string (structure, "channel-order");

  order = gst_rtp_channels_get_by_order (channels, channel_order);
  if (order) {
    gst_audio_set_channel_positions (gst_caps_get_structure (srccaps, 0),
        order->pos);
  } else {
    GstAudioChannelPosition *pos;

    GST_ELEMENT_WARNING (rtpg722depay, STREAM, DECODE,
        (NULL), ("Unknown channel order '%s' for %d channels",
            GST_STR_NULL (channel_order), channels));
    /* create default NONE layout */
    pos = gst_rtp_channels_create_default (channels);
    gst_audio_set_channel_positions (gst_caps_get_structure (srccaps, 0), pos);
    g_free (pos);
  }

  res = gst_pad_set_caps (depayload->srcpad, srccaps);
  gst_caps_unref (srccaps);

  return res;

  /* ERRORS */
no_clockrate:
  {
    GST_ERROR_OBJECT (depayload, "no clock-rate specified");
    return FALSE;
  }
}
Ejemplo n.º 14
0
static gboolean
gst_lv2_filter_setup (GstAudioFilter * gsp, const GstAudioInfo * info)
{
    GstLV2Filter *self;
    GstLV2FilterClass *oclass;
    GstAudioFilterClass *audiofilter_class;
    gint i;

    audiofilter_class = GST_AUDIO_FILTER_GET_CLASS (gsp);
    self = (GstLV2Filter *) gsp;
    oclass = (GstLV2FilterClass *) audiofilter_class;

    g_return_val_if_fail (self->activated == FALSE, FALSE);

    GST_DEBUG_OBJECT (self, "instantiating the plugin at %d Hz",
                      GST_AUDIO_INFO_RATE (info));

    if (self->instance)
        lilv_instance_free (self->instance);

    if (!(self->instance =
                lilv_plugin_instantiate (oclass->plugin, GST_AUDIO_INFO_RATE (info),
                                         NULL)))
        goto no_instance;

    /* connect the control ports */
    for (i = 0; i < oclass->control_in_ports->len; i++)
        lilv_instance_connect_port (self->instance,
                                    g_array_index (oclass->control_in_ports, GstLV2FilterPort, i).index,
                                    &(self->ports.control.in[i]));

    for (i = 0; i < oclass->control_out_ports->len; i++)
        lilv_instance_connect_port (self->instance,
                                    g_array_index (oclass->control_out_ports, GstLV2FilterPort, i).index,
                                    &(self->ports.control.out[i]));

    /* FIXME Handle audio channel positionning while negotiating CAPS */
#if 0
    /* set input group pad audio channel position */
    for (i = 0; i < oclass->in_groups->len; ++i) {
        group = &g_array_index (oclass->in_groups, GstLV2FilterGroup, i);
        if (group->has_roles) {
            if ((positions = gst_lv2_filter_build_positions (group))) {
                if ((pad = gst_element_get_static_pad (GST_ELEMENT (gsp),
                                                       lilv_node_as_string (group->symbol)))) {
                    GST_INFO_OBJECT (self, "set audio channel positions on sink pad %s",
                                     lilv_node_as_string (group->symbol));
                    s = gst_caps_get_structure (caps, 0);
                    gst_audio_set_channel_positions (s, positions);
                    gst_object_unref (pad);
                }
                g_free (positions);
                positions = NULL;
            }
        }
    }
    /* set output group pad audio channel position */
    for (i = 0; i < oclass->out_groups->len; ++i) {
        group = &g_array_index (oclass->out_groups, GstLV2FilterGroup, i);
        if (group->has_roles) {
            if ((positions = gst_lv2_filter_build_positions (group))) {
                if ((pad = gst_element_get_static_pad (GST_ELEMENT (gsp),
                                                       lilv_node_as_string (group->symbol)))) {
                    GST_INFO_OBJECT (self, "set audio channel positions on src pad %s",
                                     lilv_node_as_string (group->symbol));
                    s = gst_caps_get_structure (caps, 0);
                    gst_audio_set_channel_positions (s, positions);
                    gst_object_unref (pad);
                }
                g_free (positions);
                positions = NULL;
            }
        }
    }
#endif

    lilv_instance_activate (self->instance);
    self->activated = TRUE;

    return TRUE;

no_instance:
    {
        GST_ERROR_OBJECT (gsp, "could not create instance");
        return FALSE;
    }
}
Ejemplo n.º 15
0
void test_multichannel_checks()
{
  GstAudioChannelPosition pos_2_mixed[2] = {
    GST_AUDIO_CHANNEL_POSITION_FRONT_MONO,
    GST_AUDIO_CHANNEL_POSITION_NONE
  };
  GstAudioChannelPosition pos_2_none[2] = {
    GST_AUDIO_CHANNEL_POSITION_NONE,
    GST_AUDIO_CHANNEL_POSITION_NONE
  };
  GstAudioChannelPosition pos_2_flr[2] = {
    GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
    GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
  };
  GstAudioChannelPosition pos_2_frr[2] = {
    GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
    GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
  };
  GstStructure *s;
  
    	xmlfile = "test_multichannel_checks";
  std_log(LOG_FILENAME_LINE, "Test Started test_multichannel_checks");

  s = gst_structure_new ("audio/x-raw-int", "channels", G_TYPE_INT, 2, NULL);

  /* this should not work and issue a warning: FRONT_MONO + NONE */
//  _gst_check_expecting_log = TRUE;
//  gst_audio_set_channel_positions (s, pos_2_mixed);
//  _gst_check_expecting_log = FALSE;
//  fail_if (structure_contains_channel_positions (s));

  /* this should work: NONE + NONE */
  gst_audio_set_channel_positions (s, pos_2_none);
  fail_unless (structure_contains_channel_positions (s));
  gst_structure_remove_field (s, "channel-positions");

  /* this should also work: FRONT_LEFT + FRONT_RIGHT */
  gst_audio_set_channel_positions (s, pos_2_flr);
  fail_unless (structure_contains_channel_positions (s));
  gst_structure_remove_field (s, "channel-positions");

  /* this should not work and issue a warning: FRONT_RIGHT twice */
//  _gst_check_expecting_log = TRUE;
//  gst_audio_set_channel_positions (s, pos_2_frr);
//  _gst_check_expecting_log = FALSE;

/* FIXME: did I misunderstand _set_structure_channel_positions_list? */
#if  0
  /* this should not work and issue a warning: FRONT_RIGHT twice */
  _gst_check_expecting_log = TRUE;
  gst_audio_set_structure_channel_positions_list (s, pos_2_frr, 2);
  _gst_check_expecting_log = FALSE;

  /* this should not work and issue a warning: FRONT_MONO + NONE */
  _gst_check_expecting_log = TRUE;
  gst_audio_set_structure_channel_positions_list (s, pos_2_mixed, 2);
  _gst_check_expecting_log = FALSE;

  /* this should not work either (channel count mismatch) */
  _gst_check_expecting_log = TRUE;
  gst_audio_set_structure_channel_positions_list (s, pos_2_none, 44);
  _gst_check_expecting_log = FALSE;
  fail_if (structure_contains_channel_positions (s));
#endif

  gst_structure_free (s);
  
      std_log(LOG_FILENAME_LINE, "Test Successful");
  create_xml(0);
}
Ejemplo n.º 16
0
static void
caps_add_channel_configuration (GstCaps * caps,
    const GstStructure * in_structure, gint min_chans, gint max_chans)
{
  GstAudioChannelPosition pos[8] = {
    GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
    GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
    GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
    GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
    GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
    GST_AUDIO_CHANNEL_POSITION_LFE,
    GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
    GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT
  };
  GstStructure *s = NULL;
  gint c;

  if (min_chans == max_chans && max_chans <= 2) {
    s = get_channel_free_structure (in_structure);
    gst_structure_set (s, "channels", G_TYPE_INT, max_chans, NULL);
    gst_caps_append_structure (caps, s);
    return;
  }

  g_assert (min_chans >= 1);

  /* mono and stereo don't need channel configurations */
  if (min_chans == 2) {
    s = get_channel_free_structure (in_structure);
    gst_structure_set (s, "channels", G_TYPE_INT, 2, NULL);
    gst_caps_append_structure (caps, s);
  } else if (min_chans == 1 && max_chans >= 2) {
    s = get_channel_free_structure (in_structure);
    gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
    gst_caps_append_structure (caps, s);
  }

  /* don't know whether to use 2.1 or 3.0 here - but I suspect
   * alsa might work around that/fix it somehow. Can we tell alsa
   * what our channel layout is like? */
  if (max_chans >= 3 && min_chans <= 3) {
    GstAudioChannelPosition pos_21[3] = {
      GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
      GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
      GST_AUDIO_CHANNEL_POSITION_LFE
    };

    s = get_channel_free_structure (in_structure);
    gst_structure_set (s, "channels", G_TYPE_INT, 3, NULL);
    gst_audio_set_channel_positions (s, pos_21);
    gst_caps_append_structure (caps, s);
  }

  /* everything else (4, 6, 8 channels) needs a channel layout */
  for (c = MAX (4, min_chans); c <= 8; c += 2) {
    if (max_chans >= c) {
      s = get_channel_free_structure (in_structure);
      gst_structure_set (s, "channels", G_TYPE_INT, c, NULL);
      gst_audio_set_channel_positions (s, pos);
      gst_caps_append_structure (caps, s);
    }
  }

  for (c = MAX (9, min_chans); c <= max_chans; ++c) {
    GstAudioChannelPosition *ch_layout;
    guint i;

    ch_layout = g_new (GstAudioChannelPosition, c);
    for (i = 0; i < c; ++i) {
      ch_layout[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
    }
    s = get_channel_free_structure (in_structure);
    gst_structure_set (s, "channels", G_TYPE_INT, c, NULL);
    gst_audio_set_channel_positions (s, ch_layout);
    gst_caps_append_structure (caps, s);
    g_free (ch_layout);
  }
}
Ejemplo n.º 17
0
static gboolean  
dmo_audiodec_sink_setcaps (GstPad * pad, GstCaps * caps)
{
  DMOAudioDec *dec = (DMOAudioDec *) gst_pad_get_parent (pad);
  DMOAudioDecClass *klass = (DMOAudioDecClass *) G_OBJECT_GET_CLASS (dec);
  GstStructure *s = gst_caps_get_structure (caps, 0);
  gchar *dll;
  gint size;
  WAVEFORMATEX * hdr = NULL;
  const GValue *v;
  GstBuffer *extradata = NULL;
  GstCaps *out;
  gboolean ret = FALSE;
  guint32 fourcc;
  
  GST_DEBUG_OBJECT (dec, "setcaps called with %" GST_PTR_FORMAT, caps);

  Check_FS_Segment ();

  if (dec->ctx) {
    DMO_AudioDecoder_Destroy (dec->ctx);
    dec->ctx = NULL;
  }

  /* read data */
  if (!gst_structure_get_int (s, "bitrate", &dec->bitrate) ||
      !gst_structure_get_int (s, "block_align", &dec->block_align) ||
      !gst_structure_get_int (s, "rate", &dec->rate) ||
      !gst_structure_get_int (s, "channels", &dec->channels) ||
      !gst_structure_get_int (s, "depth", &dec->depth)) {
    goto beach;
  }
  
  if ((v = gst_structure_get_value (s, "codec_data")))
    extradata = gst_value_get_buffer (v);

  if (!gst_structure_get_fourcc (s, "format", &fourcc))
    fourcc = klass->entry->format;

  /* set up dll initialization */
  dll = g_strdup_printf ("%s.dll", klass->entry->dll);
  size = sizeof (WAVEFORMATEX) +
      (extradata ? GST_BUFFER_SIZE (extradata) : 0);
  hdr = g_malloc0 (size);
  if (extradata) { /* Codec data is appended after our header */
    memcpy (((guchar *) hdr) + sizeof (WAVEFORMATEX),
  	        GST_BUFFER_DATA (extradata), GST_BUFFER_SIZE (extradata));
    hdr->cbSize = GST_BUFFER_SIZE (extradata);
  }
  hdr->wFormatTag = fourcc;
  hdr->nChannels = dec->channels;
  hdr->nSamplesPerSec = dec->rate;
  hdr->nAvgBytesPerSec = dec->bitrate / 8;
  hdr->nBlockAlign = dec->block_align;
  hdr->wBitsPerSample = dec->depth;
  GST_DEBUG ("Will now open %s using %d bps %d channels", dll, dec->bitrate,
             dec->channels);
  if (!(dec->ctx = DMO_AudioDecoder_Open (dll, &klass->entry->guid, hdr))) {
    GST_ERROR ("Failed to open DLL %s", dll);
    g_free (dll);
    g_free (hdr);
    goto beach;
  }
  g_free (dll);
  g_free (hdr);
  
  DMO_AudioDecoder_GetOutputInfos (dec->ctx, &dec->out_buffer_size,
                                   &dec->out_align);
  DMO_AudioDecoder_GetInputInfos (dec->ctx, &dec->in_buffer_size,
                                  &dec->in_align, &dec->lookahead);
  
  /* negotiate output */
  out = gst_caps_from_string (klass->entry->srccaps);
  gst_caps_set_simple (out,
      "width", G_TYPE_INT, dec->depth,
      "depth", G_TYPE_INT, dec->depth,
      "rate", G_TYPE_INT, dec->rate,
      "channels", G_TYPE_INT, dec->channels,
      NULL);
  if (dec->channels > 2 && dec->channels <= 11) {
    GstAudioChannelPosition pos[] = {
      GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
      GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
      GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
      GST_AUDIO_CHANNEL_POSITION_LFE,
      GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
      GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
      GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
      GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
      GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
      GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
      GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT
    };
    gst_audio_set_channel_positions (gst_caps_get_structure (out, 0), pos);
  }
  if (!gst_pad_set_caps (dec->srcpad, out)) {
    gst_caps_unref (out);
    GST_ERROR ("Failed to negotiate output");
    goto beach;
  }
  gst_caps_unref (out);
  
  ret = TRUE;

beach:
  gst_object_unref (dec);
  
  return ret;
}
Ejemplo n.º 18
0
static GstCaps *
gst_openal_helper_probe_caps (ALCcontext * ctx)
{
    static const struct
    {
        gint count;
        GstAudioChannelPosition pos[8];
    } chans[] = {
        {
            1, {
                GST_AUDIO_CHANNEL_POSITION_FRONT_MONO
            }
        }, {
            2, {
                GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
                GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
            }
        }, {
            4, {
                GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
                GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
                GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
                GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT
            }
        }, {
            6, {
                GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
                GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
                GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
                GST_AUDIO_CHANNEL_POSITION_LFE,
                GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
                GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT
            }
        }, {
            7, {
                GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
                GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
                GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
                GST_AUDIO_CHANNEL_POSITION_LFE,
                GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
                GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
                GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT
            }
        }, {
            8, {
                GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
                GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
                GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
                GST_AUDIO_CHANNEL_POSITION_LFE,
                GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
                GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
                GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
                GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT
            }
        },
    };
    GstStructure *structure;
    ALCcontext *old;
    GstCaps *caps;

    old = pushContext (ctx);

    caps = gst_caps_new_empty ();
    if (alIsExtensionPresent ("AL_EXT_MCFORMATS")) {
        const char *fmt32[] = {
            "AL_FORMAT_MONO_FLOAT32", "AL_FORMAT_STEREO_FLOAT32",
            "AL_FORMAT_QUAD32", "AL_FORMAT_51CHN32", "AL_FORMAT_61CHN32",
            "AL_FORMAT_71CHN32", NULL
        }, *fmt16[] = {
            "AL_FORMAT_MONO16", "AL_FORMAT_STEREO16", "AL_FORMAT_QUAD16",
            "AL_FORMAT_51CHN16", "AL_FORMAT_61CHN16", "AL_FORMAT_71CHN16", NULL
        },
        *fmt8[] = {
            "AL_FORMAT_MONO8", "AL_FORMAT_STEREO8", "AL_FORMAT_QUAD8",
            "AL_FORMAT_51CHN8", "AL_FORMAT_61CHN8", "AL_FORMAT_71CHN8", NULL
        };
        int i;

        if (alIsExtensionPresent ("AL_EXT_FLOAT32")) {
            for (i = 0; fmt32[i]; i++) {
                ALenum val = alGetEnumValue (fmt32[i]);
                if (checkALError () != AL_NO_ERROR || val == 0 || val == -1)
                    continue;

                structure = gst_structure_new ("audio/x-raw-float",
                                               "endianness", G_TYPE_INT, G_BYTE_ORDER,
                                               "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE,
                                               OPENAL_MAX_RATE, "width", G_TYPE_INT, 32, NULL);
                gst_structure_set (structure, "channels", G_TYPE_INT,
                                   chans[i].count, NULL);
                if (chans[i].count > 2)
                    gst_audio_set_channel_positions (structure, chans[i].pos);
                gst_caps_append_structure (caps, structure);
            }
        }
        for (i = 0; fmt16[i]; i++) {
            ALenum val = alGetEnumValue (fmt16[i]);
            if (checkALError () != AL_NO_ERROR || val == 0 || val == -1)
                continue;

            structure = gst_structure_new ("audio/x-raw-int",
                                           "endianness", G_TYPE_INT, G_BYTE_ORDER,
                                           "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE,
                                           "width", G_TYPE_INT, 16,
                                           "depth", G_TYPE_INT, 16, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
            gst_structure_set (structure, "channels", G_TYPE_INT,
                               chans[i].count, NULL);
            if (chans[i].count > 2)
                gst_audio_set_channel_positions (structure, chans[i].pos);
            gst_caps_append_structure (caps, structure);
        }
        for (i = 0; fmt8[i]; i++) {
            ALenum val = alGetEnumValue (fmt8[i]);
            if (checkALError () != AL_NO_ERROR || val == 0 || val == -1)
                continue;

            structure = gst_structure_new ("audio/x-raw-int",
                                           "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE,
                                           "width", G_TYPE_INT, 8,
                                           "depth", G_TYPE_INT, 8, "signed", G_TYPE_BOOLEAN, FALSE, NULL);
            gst_structure_set (structure, "channels", G_TYPE_INT,
                               chans[i].count, NULL);
            if (chans[i].count > 2)
                gst_audio_set_channel_positions (structure, chans[i].pos);
            gst_caps_append_structure (caps, structure);
        }
    } else {
        if (alIsExtensionPresent ("AL_EXT_FLOAT32")) {
            structure = gst_structure_new ("audio/x-raw-float",
                                           "endianness", G_TYPE_INT, G_BYTE_ORDER,
                                           "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE,
                                           "width", G_TYPE_INT, 32, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
            gst_caps_append_structure (caps, structure);
        }

        structure = gst_structure_new ("audio/x-raw-int",
                                       "endianness", G_TYPE_INT, G_BYTE_ORDER,
                                       "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE,
                                       "width", G_TYPE_INT, 16,
                                       "depth", G_TYPE_INT, 16,
                                       "signed", G_TYPE_BOOLEAN, TRUE,
                                       "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
        gst_caps_append_structure (caps, structure);

        structure = gst_structure_new ("audio/x-raw-int",
                                       "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE,
                                       "width", G_TYPE_INT, 8,
                                       "depth", G_TYPE_INT, 8,
                                       "signed", G_TYPE_BOOLEAN, FALSE,
                                       "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
        gst_caps_append_structure (caps, structure);
    }

    if (alIsExtensionPresent ("AL_EXT_MULAW_MCFORMATS")) {
        const char *fmtmulaw[] = {
            "AL_FORMAT_MONO_MULAW", "AL_FORMAT_STEREO_MULAW",
            "AL_FORMAT_QUAD_MULAW", "AL_FORMAT_51CHN_MULAW",
            "AL_FORMAT_61CHN_MULAW", "AL_FORMAT_71CHN_MULAW", NULL
        };
        int i;

        for (i = 0; fmtmulaw[i]; i++) {
            ALenum val = alGetEnumValue (fmtmulaw[i]);
            if (checkALError () != AL_NO_ERROR || val == 0 || val == -1)
                continue;

            structure = gst_structure_new ("audio/x-mulaw",
                                           "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE, NULL);
            gst_structure_set (structure, "channels", G_TYPE_INT,
                               chans[i].count, NULL);
            if (chans[i].count > 2)
                gst_audio_set_channel_positions (structure, chans[i].pos);
            gst_caps_append_structure (caps, structure);
        }
    } else if (alIsExtensionPresent ("AL_EXT_MULAW")) {
        structure = gst_structure_new ("audio/x-mulaw",
                                       "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE,
                                       "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
        gst_caps_append_structure (caps, structure);
    }

    popContext (old, ctx);
    return caps;
}
static GstFlowReturn
gst_opus_dec_parse_header (GstOpusDec * dec, GstBuffer * buf)
{
  const guint8 *data = GST_BUFFER_DATA (buf);
  GstCaps *caps;
  const GstAudioChannelPosition *pos = NULL;

  if (!gst_opus_header_is_id_header (buf)) {
    GST_ERROR_OBJECT (dec, "Header is not an Opus ID header");
    return GST_FLOW_ERROR;
  }
  if (!(dec->n_channels == 0 || dec->n_channels == data[9])) {
    GST_ERROR_OBJECT (dec, "Opus ID header has invalid channels");
    return GST_FLOW_ERROR;
  }

  dec->n_channels = data[9];
  dec->pre_skip = GST_READ_UINT16_LE (data + 10);
  dec->r128_gain = GST_READ_UINT16_LE (data + 16);
  dec->r128_gain_volume = gst_opus_dec_get_r128_volume (dec->r128_gain);
  GST_INFO_OBJECT (dec,
      "Found pre-skip of %u samples, R128 gain %d (volume %f)",
      dec->pre_skip, dec->r128_gain, dec->r128_gain_volume);

  dec->channel_mapping_family = data[18];
  if (dec->channel_mapping_family == 0) {
    /* implicit mapping */
    GST_INFO_OBJECT (dec, "Channel mapping family 0, implicit mapping");
    dec->n_streams = dec->n_stereo_streams = 1;
    dec->channel_mapping[0] = 0;
    dec->channel_mapping[1] = 1;
  } else {
    dec->n_streams = data[19];
    dec->n_stereo_streams = data[20];
    memcpy (dec->channel_mapping, data + 21, dec->n_channels);

    if (dec->channel_mapping_family == 1) {
      GST_INFO_OBJECT (dec, "Channel mapping family 1, Vorbis mapping");
      switch (dec->n_channels) {
        case 1:
        case 2:
          /* nothing */
          break;
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
          pos = gst_opus_channel_positions[dec->n_channels - 1];
          break;
        default:{
          gint i;
          GstAudioChannelPosition *posn =
              g_new (GstAudioChannelPosition, dec->n_channels);

          GST_ELEMENT_WARNING (GST_ELEMENT (dec), STREAM, DECODE,
              (NULL), ("Using NONE channel layout for more than 8 channels"));

          for (i = 0; i < dec->n_channels; i++)
            posn[i] = GST_AUDIO_CHANNEL_POSITION_NONE;

          pos = posn;
        }
      }
    } else {
      GST_INFO_OBJECT (dec, "Channel mapping family %d",
          dec->channel_mapping_family);
    }
  }

  caps = gst_opus_dec_negotiate (dec);

  if (pos) {
    GST_DEBUG_OBJECT (dec, "Setting channel positions on caps");
    gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
  }

  if (dec->n_channels > 8) {
    g_free ((GstAudioChannelPosition *) pos);
  }

  GST_INFO_OBJECT (dec, "Setting src caps to %" GST_PTR_FORMAT, caps);
  gst_pad_set_caps (GST_AUDIO_DECODER_SRC_PAD (dec), caps);
  gst_caps_unref (caps);

  return GST_FLOW_OK;
}