gst_plugins_base/gst/audioconvert/gstaudioconvert.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
    22  */
    22  */
    23 
    23 
    24 /**
    24 /**
    25  * SECTION:element-audioconvert
    25  * SECTION:element-audioconvert
    26  *
    26  *
       
    27  * <refsect2>
       
    28  * <para>
    27  * Audioconvert converts raw audio buffers between various possible formats.
    29  * Audioconvert converts raw audio buffers between various possible formats.
    28  * It supports integer to float conversion, width/depth conversion,
    30  * It supports integer to float conversion, width/depth conversion,
    29  * signedness and endianness conversion and channel transformations.
    31  * signedness and endianness conversion.
    30  *
    32  * </para>
    31  * <refsect2>
    33  * <para>
       
    34  * Some format conversion are not carried out in an optimal way right now.
       
    35  * E.g. converting from double to float would cause a loss of precision.
       
    36  * </para>
    32  * <title>Example launch line</title>
    37  * <title>Example launch line</title>
    33  * |[
    38  * <para>
       
    39  * <programlisting>
    34  * gst-launch -v -m audiotestsrc ! audioconvert ! audio/x-raw-int,channels=2,width=8,depth=8 ! level ! fakesink silent=TRUE
    40  * gst-launch -v -m audiotestsrc ! audioconvert ! audio/x-raw-int,channels=2,width=8,depth=8 ! level ! fakesink silent=TRUE
    35  * ]| This pipeline converts audio to 8-bit.  The level element shows that
    41  * </programlisting>
       
    42  * This pipeline converts audio to 8-bit.  The level element shows that
    36  * the output levels still match the one for a sine wave.
    43  * the output levels still match the one for a sine wave.
    37  * |[
    44  * </para>
       
    45  * <para>
       
    46  * <programlisting>
    38  * gst-launch -v -m audiotestsrc ! audioconvert ! vorbisenc ! fakesink silent=TRUE
    47  * gst-launch -v -m audiotestsrc ! audioconvert ! vorbisenc ! fakesink silent=TRUE
    39  * ]| The vorbis encoder takes float audio data instead of the integer data
    48  * </programlisting>
       
    49  * The vorbis encoder takes float audio data instead of the integer data
    40  * generated by audiotestsrc.
    50  * generated by audiotestsrc.
       
    51  * </para>
    41  * </refsect2>
    52  * </refsect2>
    42  *
    53  *
    43  * Last reviewed on 2006-03-02 (0.10.4)
    54  * Last reviewed on 2006-03-02 (0.10.4)
    44  */
    55  */
    45 
    56 
    94     GstBuffer * buf);
   105     GstBuffer * buf);
    95 static void gst_audio_convert_set_property (GObject * object, guint prop_id,
   106 static void gst_audio_convert_set_property (GObject * object, guint prop_id,
    96     const GValue * value, GParamSpec * pspec);
   107     const GValue * value, GParamSpec * pspec);
    97 static void gst_audio_convert_get_property (GObject * object, guint prop_id,
   108 static void gst_audio_convert_get_property (GObject * object, guint prop_id,
    98     GValue * value, GParamSpec * pspec);
   109     GValue * value, GParamSpec * pspec);
    99 static gboolean structure_has_fixed_channel_positions (GstStructure * s,
   110 
   100     gboolean * unpositioned_layout);
       
   101 
   111 
   102 /* AudioConvert signals and args */
   112 /* AudioConvert signals and args */
   103 enum
   113 enum
   104 {
   114 {
   105   /* FILL ME */
   115   /* FILL ME */
   123 
   133 
   124 #define STATIC_CAPS \
   134 #define STATIC_CAPS \
   125 GST_STATIC_CAPS ( \
   135 GST_STATIC_CAPS ( \
   126   "audio/x-raw-float, " \
   136   "audio/x-raw-float, " \
   127     "rate = (int) [ 1, MAX ], " \
   137     "rate = (int) [ 1, MAX ], " \
   128     "channels = (int) [ 1, MAX ], " \
   138     "channels = (int) [ 1, 8 ], " \
   129     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
   139     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
   130     "width = (int) 64;" \
   140     "width = (int) 64;" \
   131   "audio/x-raw-float, " \
   141   "audio/x-raw-float, " \
   132     "rate = (int) [ 1, MAX ], " \
   142     "rate = (int) [ 1, MAX ], " \
   133     "channels = (int) [ 1, MAX ], " \
   143     "channels = (int) [ 1, 8 ], " \
   134     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
   144     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
   135     "width = (int) 32;" \
   145     "width = (int) 32;" \
   136   "audio/x-raw-int, " \
   146   "audio/x-raw-int, " \
   137     "rate = (int) [ 1, MAX ], " \
   147     "rate = (int) [ 1, MAX ], " \
   138     "channels = (int) [ 1, MAX ], " \
   148     "channels = (int) [ 1, 8 ], " \
   139     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
   149     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
   140     "width = (int) 32, " \
   150     "width = (int) 32, " \
   141     "depth = (int) [ 1, 32 ], " \
   151     "depth = (int) [ 1, 32 ], " \
   142     "signed = (boolean) { true, false }; " \
   152     "signed = (boolean) { true, false }; " \
   143   "audio/x-raw-int, "   \
   153   "audio/x-raw-int, "   \
   144     "rate = (int) [ 1, MAX ], " \
   154     "rate = (int) [ 1, MAX ], " \
   145     "channels = (int) [ 1, MAX ], "       \
   155     "channels = (int) [ 1, 8 ], "       \
   146     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, "        \
   156     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, "        \
   147     "width = (int) 24, "        \
   157     "width = (int) 24, "        \
   148     "depth = (int) [ 1, 24 ], " "signed = (boolean) { true, false }; "  \
   158     "depth = (int) [ 1, 24 ], " "signed = (boolean) { true, false }; "  \
   149   "audio/x-raw-int, " \
   159   "audio/x-raw-int, " \
   150     "rate = (int) [ 1, MAX ], " \
   160     "rate = (int) [ 1, MAX ], " \
   151     "channels = (int) [ 1, MAX ], " \
   161     "channels = (int) [ 1, 8 ], " \
   152     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
   162     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
   153     "width = (int) 16, " \
   163     "width = (int) 16, " \
   154     "depth = (int) [ 1, 16 ], " \
   164     "depth = (int) [ 1, 16 ], " \
   155     "signed = (boolean) { true, false }; " \
   165     "signed = (boolean) { true, false }; " \
   156   "audio/x-raw-int, " \
   166   "audio/x-raw-int, " \
   157     "rate = (int) [ 1, MAX ], " \
   167     "rate = (int) [ 1, MAX ], " \
   158     "channels = (int) [ 1, MAX ], " \
   168     "channels = (int) [ 1, 8 ], " \
   159     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
   169     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
   160     "width = (int) 8, " \
   170     "width = (int) 8, " \
   161     "depth = (int) [ 1, 8 ], " \
   171     "depth = (int) [ 1, 8 ], " \
   162     "signed = (boolean) { true, false } " \
   172     "signed = (boolean) { true, false } " \
   163 )
   173 )
   251     supported_positions[i] = i;
   261     supported_positions[i] = i;
   252 
   262 
   253   g_object_class_install_property (gobject_class, ARG_DITHERING,
   263   g_object_class_install_property (gobject_class, ARG_DITHERING,
   254       g_param_spec_enum ("dithering", "Dithering",
   264       g_param_spec_enum ("dithering", "Dithering",
   255           "Selects between different dithering methods.",
   265           "Selects between different dithering methods.",
   256           GST_TYPE_AUDIO_CONVERT_DITHERING, DITHER_TPDF,
   266           GST_TYPE_AUDIO_CONVERT_DITHERING, DITHER_TPDF, G_PARAM_READWRITE));
   257           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   258 
   267 
   259   g_object_class_install_property (gobject_class, ARG_NOISE_SHAPING,
   268   g_object_class_install_property (gobject_class, ARG_NOISE_SHAPING,
   260       g_param_spec_enum ("noise-shaping", "Noise shaping",
   269       g_param_spec_enum ("noise-shaping", "Noise shaping",
   261           "Selects between different noise shaping methods.",
   270           "Selects between different noise shaping methods.",
   262           GST_TYPE_AUDIO_CONVERT_NOISE_SHAPING, NOISE_SHAPING_NONE,
   271           GST_TYPE_AUDIO_CONVERT_NOISE_SHAPING, NOISE_SHAPING_NONE,
   263           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   272           G_PARAM_READWRITE));
   264 
   273 
   265   basetransform_class->get_unit_size =
   274   basetransform_class->get_unit_size =
   266       GST_DEBUG_FUNCPTR (gst_audio_convert_get_unit_size);
   275       GST_DEBUG_FUNCPTR (gst_audio_convert_get_unit_size);
   267   basetransform_class->transform_caps =
   276   basetransform_class->transform_caps =
   268       GST_DEBUG_FUNCPTR (gst_audio_convert_transform_caps);
   277       GST_DEBUG_FUNCPTR (gst_audio_convert_transform_caps);
   282 gst_audio_convert_init (GstAudioConvert * this, GstAudioConvertClass * g_class)
   291 gst_audio_convert_init (GstAudioConvert * this, GstAudioConvertClass * g_class)
   283 {
   292 {
   284   this->dither = DITHER_TPDF;
   293   this->dither = DITHER_TPDF;
   285   this->ns = NOISE_SHAPING_NONE;
   294   this->ns = NOISE_SHAPING_NONE;
   286   memset (&this->ctx, 0, sizeof (AudioConvertCtx));
   295   memset (&this->ctx, 0, sizeof (AudioConvertCtx));
   287 
       
   288   gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (this), TRUE);
       
   289 }
   296 }
   290 
   297 
   291 static void
   298 static void
   292 gst_audio_convert_dispose (GObject * obj)
   299 gst_audio_convert_dispose (GObject * obj)
   293 {
   300 {
   321   /* parse common fields */
   328   /* parse common fields */
   322   if (!gst_structure_get_int (structure, "channels", &fmt->channels))
   329   if (!gst_structure_get_int (structure, "channels", &fmt->channels))
   323     goto no_values;
   330     goto no_values;
   324   if (!(fmt->pos = gst_audio_get_channel_positions (structure)))
   331   if (!(fmt->pos = gst_audio_get_channel_positions (structure)))
   325     goto no_values;
   332     goto no_values;
   326 
       
   327   fmt->unpositioned_layout = FALSE;
       
   328   structure_has_fixed_channel_positions (structure, &fmt->unpositioned_layout);
       
   329 
       
   330   if (!gst_structure_get_int (structure, "width", &fmt->width))
   333   if (!gst_structure_get_int (structure, "width", &fmt->width))
   331     goto no_values;
   334     goto no_values;
   332   if (!gst_structure_get_int (structure, "rate", &fmt->rate))
   335   if (!gst_structure_get_int (structure, "rate", &fmt->rate))
   333     goto no_values;
   336     goto no_values;
   334   /* width != 8 needs an endianness field */
   337   /* width != 8 needs an endianness field */
   522     s2 = gst_structure_copy (s);
   525     s2 = gst_structure_copy (s);
   523     gst_structure_set_name (s2, "audio/x-raw-float");
   526     gst_structure_set_name (s2, "audio/x-raw-float");
   524     s = make_lossless_changes (s2, TRUE);
   527     s = make_lossless_changes (s2, TRUE);
   525     gst_caps_append_structure (caps, s2);
   528     gst_caps_append_structure (caps, s2);
   526   }
   529   }
   527 }
       
   528 
       
   529 static gboolean
       
   530 structure_has_fixed_channel_positions (GstStructure * s,
       
   531     gboolean * unpositioned_layout)
       
   532 {
       
   533   GstAudioChannelPosition *pos;
       
   534   const GValue *val;
       
   535   gint channels = 0;
       
   536 
       
   537   if (!gst_structure_get_int (s, "channels", &channels))
       
   538     return FALSE;               /* probably a range */
       
   539 
       
   540   val = gst_structure_get_value (s, "channel-positions");
       
   541   if ((val == NULL || !gst_value_is_fixed (val)) && channels <= 8) {
       
   542     GST_LOG ("no or unfixed channel-positions in %" GST_PTR_FORMAT, s);
       
   543     return FALSE;
       
   544   } else if (val == NULL || !gst_value_is_fixed (val)) {
       
   545     GST_LOG ("implicit undefined channel-positions");
       
   546     *unpositioned_layout = TRUE;
       
   547     return TRUE;
       
   548   }
       
   549 
       
   550   pos = gst_audio_get_channel_positions (s);
       
   551   if (pos && pos[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
       
   552     GST_LOG ("fixed undefined channel-positions in %" GST_PTR_FORMAT, s);
       
   553     *unpositioned_layout = TRUE;
       
   554   } else {
       
   555     GST_LOG ("fixed defined channel-positions in %" GST_PTR_FORMAT, s);
       
   556     *unpositioned_layout = FALSE;
       
   557   }
       
   558   g_free (pos);
       
   559 
       
   560   return TRUE;
       
   561 }
   530 }
   562 
   531 
   563 /* Audioconvert can perform all conversions on audio except for resampling. 
   532 /* Audioconvert can perform all conversions on audio except for resampling. 
   564  * However, there are some conversions we _prefer_ not to do. For example, it's
   533  * However, there are some conversions we _prefer_ not to do. For example, it's
   565  * better to convert format (float<->int, endianness, etc) than the number of
   534  * better to convert format (float<->int, endianness, etc) than the number of
   575 gst_audio_convert_transform_caps (GstBaseTransform * base,
   544 gst_audio_convert_transform_caps (GstBaseTransform * base,
   576     GstPadDirection direction, GstCaps * caps)
   545     GstPadDirection direction, GstCaps * caps)
   577 {
   546 {
   578   GstCaps *ret;
   547   GstCaps *ret;
   579   GstStructure *s, *structure;
   548   GstStructure *s, *structure;
   580   gboolean isfloat, allow_mixing;
   549   gboolean isfloat;
   581   gint width, depth, channels = 0;
   550   gint width, depth, channels;
   582   const gchar *fields_used[] = {
   551   const gchar *fields_used[] = {
   583     "width", "depth", "rate", "channels", "endianness", "signed"
   552     "width", "depth", "rate", "channels", "endianness", "signed"
   584   };
   553   };
   585   const gchar *structure_name;
   554   const gchar *structure_name;
   586   int i;
   555   int i;
   632       else
   601       else
   633         gst_structure_set (s, "depth", GST_TYPE_INT_RANGE, depth, 32, NULL);
   602         gst_structure_set (s, "depth", GST_TYPE_INT_RANGE, depth, 32, NULL);
   634     }
   603     }
   635   }
   604   }
   636 
   605 
   637   allow_mixing = TRUE;
       
   638   if (gst_structure_get_int (structure, "channels", &channels)) {
   606   if (gst_structure_get_int (structure, "channels", &channels)) {
   639     gboolean unpositioned;
   607     if (channels == 8)
   640 
   608       gst_structure_set (s, "channels", G_TYPE_INT, 8, NULL);
   641     /* we don't support mixing for channels without channel positions */
       
   642     if (structure_has_fixed_channel_positions (structure, &unpositioned))
       
   643       allow_mixing = (unpositioned == FALSE);
       
   644   }
       
   645 
       
   646   if (!allow_mixing) {
       
   647     gst_structure_set (s, "channels", G_TYPE_INT, channels, NULL);
       
   648     if (gst_structure_has_field (structure, "channel-positions"))
       
   649       gst_structure_set_value (s, "channel-positions",
       
   650           gst_structure_get_value (structure, "channel-positions"));
       
   651   } else {
       
   652     if (channels == 0)
       
   653       gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 11, NULL);
       
   654     else if (channels == 11)
       
   655       gst_structure_set (s, "channels", G_TYPE_INT, 11, NULL);
       
   656     else
   609     else
   657       gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, channels, 11, NULL);
   610       gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, channels, 8, NULL);
   658     gst_structure_remove_field (s, "channel-positions");
       
   659   }
   611   }
   660   gst_caps_append_structure (ret, s);
   612   gst_caps_append_structure (ret, s);
   661 
   613 
   662   /* Same, plus a float<->int conversion */
   614   /* Same, plus a float<->int conversion */
   663   append_with_other_format (ret, s, isfloat);
   615   append_with_other_format (ret, s, isfloat);
   682 
   634 
   683   /* Channel conversions to fewer channels is only done if needed - generally
   635   /* Channel conversions to fewer channels is only done if needed - generally
   684    * it's very bad to drop channels entirely.
   636    * it's very bad to drop channels entirely.
   685    */
   637    */
   686   s = gst_structure_copy (s);
   638   s = gst_structure_copy (s);
   687   if (allow_mixing) {
   639   gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 8, NULL);
   688     gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 11, NULL);
       
   689     gst_structure_remove_field (s, "channel-positions");
       
   690   } else {
       
   691     /* allow_mixing can only be FALSE if we got a fixed number of channels */
       
   692     gst_structure_set (s, "channels", G_TYPE_INT, channels, NULL);
       
   693     if (gst_structure_has_field (structure, "channel-positions"))
       
   694       gst_structure_set_value (s, "channel-positions",
       
   695           gst_structure_get_value (structure, "channel-positions"));
       
   696   }
       
   697   gst_caps_append_structure (ret, s);
   640   gst_caps_append_structure (ret, s);
   698 
   641 
   699   /* Same, plus a float<->int conversion */
   642   /* Same, plus a float<->int conversion */
   700   append_with_other_format (ret, s, isfloat);
   643   append_with_other_format (ret, s, isfloat);
   701 
   644 
   806 
   749 
   807 static void
   750 static void
   808 gst_audio_convert_fixate_channels (GstBaseTransform * base, GstStructure * ins,
   751 gst_audio_convert_fixate_channels (GstBaseTransform * base, GstStructure * ins,
   809     GstStructure * outs)
   752     GstStructure * outs)
   810 {
   753 {
   811   const GValue *in_layout, *out_layout;
   754   const GValue *out_layout;
   812   gint in_chans, out_chans;
   755   gint in_chans, out_chans;
   813 
   756 
   814   if (!gst_structure_get_int (ins, "channels", &in_chans))
   757   if (!gst_structure_get_int (ins, "channels", &in_chans))
   815     return;                     /* this shouldn't really happen, should it? */
   758     return;                     /* this shouldn't really happen, should it? */
   816 
   759 
   831   }
   774   }
   832 
   775 
   833   /* check if the output has a channel layout (or a list of layouts) */
   776   /* check if the output has a channel layout (or a list of layouts) */
   834   out_layout = gst_structure_get_value (outs, "channel-positions");
   777   out_layout = gst_structure_get_value (outs, "channel-positions");
   835 
   778 
   836   /* get the channel layout of the input if any */
       
   837   in_layout = gst_structure_get_value (ins, "channel-positions");
       
   838 
       
   839   if (out_layout == NULL) {
   779   if (out_layout == NULL) {
   840     if (out_chans <= 2 && (in_chans != out_chans || in_layout == NULL))
   780     if (out_chans <= 2)
   841       return;                   /* nothing to do, default layout will be assumed */
   781       return;                   /* nothing to do, default layout will be assumed */
   842     GST_WARNING_OBJECT (base, "downstream caps contain no channel layout");
   782     GST_WARNING_OBJECT (base, "downstream caps contain no channel layout");
   843   }
   783   }
   844 
   784 
   845   if (in_chans == out_chans && in_layout != NULL) {
   785   if (in_chans == out_chans) {
       
   786     const GValue *in_layout;
   846     GValue res = { 0, };
   787     GValue res = { 0, };
       
   788 
       
   789     in_layout = gst_structure_get_value (ins, "channel-positions");
       
   790     g_return_if_fail (in_layout != NULL);
   847 
   791 
   848     /* same number of channels and no output layout: just use input layout */
   792     /* same number of channels and no output layout: just use input layout */
   849     if (out_layout == NULL) {
   793     if (out_layout == NULL) {
   850       gst_structure_set_value (outs, "channel-positions", in_layout);
   794       gst_structure_set_value (outs, "channel-positions", in_layout);
   851       return;
   795       return;
   900   /* missing or invalid output layout and we can't use the input layout for
   844   /* missing or invalid output layout and we can't use the input layout for
   901    * one reason or another, so just pick a default layout (we could be smarter
   845    * one reason or another, so just pick a default layout (we could be smarter
   902    * and try to add/remove channels from the input layout, or pick a default
   846    * and try to add/remove channels from the input layout, or pick a default
   903    * layout based on LFE-presence in input layout, but let's save that for
   847    * layout based on LFE-presence in input layout, but let's save that for
   904    * another day) */
   848    * another day) */
   905   if (out_chans > 0 && out_chans <= G_N_ELEMENTS (default_positions[0])) {
   849   if (out_chans > 0 && out_chans < G_N_ELEMENTS (default_positions[0])) {
   906     GST_DEBUG_OBJECT (base, "using default channel layout as fallback");
   850     GST_DEBUG_OBJECT (base, "using default channel layout as fallback");
   907     gst_audio_set_channel_positions (outs, default_positions[out_chans - 1]);
   851     gst_audio_set_channel_positions (outs, default_positions[out_chans - 1]);
   908   }
   852   }
   909 }
   853 }
   910 
   854 
   998 static GstFlowReturn
   942 static GstFlowReturn
   999 gst_audio_convert_transform_ip (GstBaseTransform * base, GstBuffer * buf)
   943 gst_audio_convert_transform_ip (GstBaseTransform * base, GstBuffer * buf)
  1000 {
   944 {
  1001   /* nothing to do here */
   945   /* nothing to do here */
  1002   return GST_FLOW_OK;
   946   return GST_FLOW_OK;
  1003 }
       
  1004 
       
  1005 static void
       
  1006 gst_audio_convert_create_silence_buffer (GstAudioConvert * this, gpointer dst,
       
  1007     gint size)
       
  1008 {
       
  1009   if (this->ctx.out.is_int && !this->ctx.out.sign) {
       
  1010     gint i;
       
  1011 
       
  1012     switch (this->ctx.out.width) {
       
  1013       case 8:{
       
  1014         guint8 zero = 0x80 >> (8 - this->ctx.out.depth);
       
  1015 
       
  1016         memset (dst, zero, size);
       
  1017         break;
       
  1018       }
       
  1019       case 16:{
       
  1020         guint16 *data = (guint16 *) dst;
       
  1021         guint16 zero = 0x8000 >> (16 - this->ctx.out.depth);
       
  1022 
       
  1023         if (this->ctx.out.endianness == G_LITTLE_ENDIAN)
       
  1024           zero = GUINT16_TO_LE (zero);
       
  1025         else
       
  1026           zero = GUINT16_TO_BE (zero);
       
  1027 
       
  1028         size /= 2;
       
  1029 
       
  1030         for (i = 0; i < size; i++)
       
  1031           data[i] = zero;
       
  1032         break;
       
  1033       }
       
  1034       case 24:{
       
  1035         guint32 zero = 0x800000 >> (24 - this->ctx.out.depth);
       
  1036         guint8 *data = (guint8 *) dst;
       
  1037 
       
  1038         if (this->ctx.out.endianness == G_LITTLE_ENDIAN) {
       
  1039           for (i = 0; i < size; i += 3) {
       
  1040             data[i] = zero & 0xff;
       
  1041             data[i + 1] = (zero >> 8) & 0xff;
       
  1042             data[i + 2] = (zero >> 16) & 0xff;
       
  1043           }
       
  1044         } else {
       
  1045           for (i = 0; i < size; i += 3) {
       
  1046             data[i + 2] = zero & 0xff;
       
  1047             data[i + 1] = (zero >> 8) & 0xff;
       
  1048             data[i] = (zero >> 16) & 0xff;
       
  1049           }
       
  1050         }
       
  1051         break;
       
  1052       }
       
  1053       case 32:{
       
  1054         guint32 *data = (guint32 *) dst;
       
  1055         guint32 zero = (0x80000000 >> (32 - this->ctx.out.depth));
       
  1056 
       
  1057         if (this->ctx.out.endianness == G_LITTLE_ENDIAN)
       
  1058           zero = GUINT32_TO_LE (zero);
       
  1059         else
       
  1060           zero = GUINT32_TO_BE (zero);
       
  1061 
       
  1062         size /= 4;
       
  1063 
       
  1064         for (i = 0; i < size; i++)
       
  1065           data[i] = zero;
       
  1066         break;
       
  1067       }
       
  1068       default:
       
  1069         memset (dst, 0, size);
       
  1070         g_return_if_reached ();
       
  1071         break;
       
  1072     }
       
  1073   } else {
       
  1074     memset (dst, 0, size);
       
  1075   }
       
  1076 }
   947 }
  1077 
   948 
  1078 static GstFlowReturn
   949 static GstFlowReturn
  1079 gst_audio_convert_transform (GstBaseTransform * base, GstBuffer * inbuf,
   950 gst_audio_convert_transform (GstBaseTransform * base, GstBuffer * inbuf,
  1080     GstBuffer * outbuf)
   951     GstBuffer * outbuf)
  1105   /* get src and dst data */
   976   /* get src and dst data */
  1106   src = GST_BUFFER_DATA (inbuf);
   977   src = GST_BUFFER_DATA (inbuf);
  1107   dst = GST_BUFFER_DATA (outbuf);
   978   dst = GST_BUFFER_DATA (outbuf);
  1108 
   979 
  1109   /* and convert the samples */
   980   /* and convert the samples */
  1110   if (!GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) {
   981   if (!(res = audio_convert_convert (&this->ctx, src, dst,
  1111     if (!(res = audio_convert_convert (&this->ctx, src, dst,
   982               samples, gst_buffer_is_writable (inbuf))))
  1112                 samples, gst_buffer_is_writable (inbuf))))
   983     goto convert_error;
  1113       goto convert_error;
       
  1114   } else {
       
  1115     /* Create silence buffer */
       
  1116     gst_audio_convert_create_silence_buffer (this, dst, outsize);
       
  1117   }
       
  1118 
   984 
  1119   GST_BUFFER_SIZE (outbuf) = outsize;
   985   GST_BUFFER_SIZE (outbuf) = outsize;
  1120 
   986 
  1121   return GST_FLOW_OK;
   987   return GST_FLOW_OK;
  1122 
   988