]> git.sesse.net Git - ffmpeg/blobdiff - libavutil/audioconvert.c
lavfi: remove unnecessary inclusion of libavcodec/avcodec.h in avfilter.h
[ffmpeg] / libavutil / audioconvert.c
index 877027f1f7d40728e84015bb1ade3b30d32b4968..e17f52ee59486eca4b60bda568a4bdb8eece9c0c 100644 (file)
@@ -26,6 +26,7 @@
 #include "avstring.h"
 #include "avutil.h"
 #include "audioconvert.h"
+#include "bprint.h"
 
 static const char * const channel_names[] = {
     [0]  = "FL",        /* front left */
@@ -136,8 +137,8 @@ uint64_t av_get_channel_layout(const char *name)
     return layout;
 }
 
-void av_get_channel_layout_string(char *buf, int buf_size,
-                                  int nb_channels, uint64_t channel_layout)
+void av_bprint_channel_layout(struct AVBPrint *bp,
+                              int nb_channels, uint64_t channel_layout)
 {
     int i;
 
@@ -147,36 +148,41 @@ void av_get_channel_layout_string(char *buf, int buf_size,
     for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
         if (nb_channels    == channel_layout_map[i].nb_channels &&
             channel_layout == channel_layout_map[i].layout) {
-            av_strlcpy(buf, channel_layout_map[i].name, buf_size);
+            av_bprintf(bp, "%s", channel_layout_map[i].name);
             return;
         }
 
-    snprintf(buf, buf_size, "%d channels", nb_channels);
+    av_bprintf(bp, "%d channels", nb_channels);
     if (channel_layout) {
         int i, ch;
-        av_strlcat(buf, " (", buf_size);
+        av_bprintf(bp, " (");
         for (i = 0, ch = 0; i < 64; i++) {
             if ((channel_layout & (UINT64_C(1) << i))) {
                 const char *name = get_channel_name(i);
                 if (name) {
                     if (ch > 0)
-                        av_strlcat(buf, "+", buf_size);
-                    av_strlcat(buf, name, buf_size);
+                        av_bprintf(bp, "+");
+                    av_bprintf(bp, "%s", name);
                 }
                 ch++;
             }
         }
-        av_strlcat(buf, ")", buf_size);
+        av_bprintf(bp, ")");
     }
 }
 
+void av_get_channel_layout_string(char *buf, int buf_size,
+                                  int nb_channels, uint64_t channel_layout)
+{
+    AVBPrint bp;
+
+    av_bprint_init_for_buffer(&bp, buf, buf_size);
+    av_bprint_channel_layout(&bp, nb_channels, channel_layout);
+}
+
 int av_get_channel_layout_nb_channels(uint64_t channel_layout)
 {
-    int count;
-    uint64_t x = channel_layout;
-    for (count = 0; x; count++)
-        x &= x-1; // unset lowest set bit
-    return count;
+    return av_popcount64(channel_layout);
 }
 
 int64_t av_get_default_channel_layout(int nb_channels) {
@@ -186,3 +192,38 @@ int64_t av_get_default_channel_layout(int nb_channels) {
             return channel_layout_map[i].layout;
     return 0;
 }
+
+int av_get_channel_layout_channel_index(uint64_t channel_layout,
+                                        uint64_t channel)
+{
+    if (!(channel_layout & channel) ||
+        av_get_channel_layout_nb_channels(channel) != 1)
+        return AVERROR(EINVAL);
+    channel_layout &= channel - 1;
+    return av_get_channel_layout_nb_channels(channel_layout);
+}
+
+const char *av_get_channel_name(uint64_t channel)
+{
+    int i;
+    if (av_get_channel_layout_nb_channels(channel) != 1)
+        return NULL;
+    for (i = 0; i < 64; i++)
+        if ((1ULL<<i) & channel)
+            return get_channel_name(i);
+    return NULL;
+}
+
+uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
+{
+    int i;
+
+    if (av_get_channel_layout_nb_channels(channel_layout) <= index)
+        return 0;
+
+    for (i = 0; i < 64; i++) {
+        if ((1ULL << i) & channel_layout && !index--)
+            return 1ULL << i;
+    }
+    return 0;
+}