Browse code

lavu/opt: add AV_OPT_TYPE_CHANNEL_LAYOUT and handler functions

The new type is compatible with AV_OPT_TYPE_INT64, but allows to specify
channel layouts using the format accepted by av_get_channel_layout().

Stefano Sabatini authored on 2013/10/04 19:07:55
Showing 4 changed files
... ...
@@ -15,6 +15,11 @@ libavutil:     2012-10-22
15 15
 
16 16
 API changes, most recent first:
17 17
 
18
+libavutil 52.47.100
19
+2013-10-17 - xxxxxxx - lavu 52.47.100 - opt.h
20
+  Add AV_OPT_TYPE_CHANNEL_LAYOUT and channel layout option handlers
21
+  av_opt_get_channel_layout() and av_opt_set_channel_layout().
22
+
18 23
 2013-10-xx - xxxxxxx -libswscale 2.5.101 - options.c
19 24
   Change default scaler to bicubic
20 25
 
... ...
@@ -27,6 +27,7 @@
27 27
 
28 28
 #include "avutil.h"
29 29
 #include "avstring.h"
30
+#include "channel_layout.h"
30 31
 #include "common.h"
31 32
 #include "opt.h"
32 33
 #include "eval.h"
... ...
@@ -77,6 +78,7 @@ static int read_number(const AVOption *o, void *dst, double *num, int *den, int6
77 77
     case AV_OPT_TYPE_PIXEL_FMT:
78 78
     case AV_OPT_TYPE_SAMPLE_FMT:
79 79
     case AV_OPT_TYPE_INT:       *intnum = *(int         *)dst;return 0;
80
+    case AV_OPT_TYPE_CHANNEL_LAYOUT:
80 81
     case AV_OPT_TYPE_DURATION:
81 82
     case AV_OPT_TYPE_INT64:     *intnum = *(int64_t     *)dst;return 0;
82 83
     case AV_OPT_TYPE_FLOAT:     *num    = *(float       *)dst;return 0;
... ...
@@ -103,6 +105,7 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int
103 103
     case AV_OPT_TYPE_SAMPLE_FMT:
104 104
     case AV_OPT_TYPE_INT:   *(int       *)dst= llrint(num/den)*intnum; break;
105 105
     case AV_OPT_TYPE_DURATION:
106
+    case AV_OPT_TYPE_CHANNEL_LAYOUT:
106 107
     case AV_OPT_TYPE_INT64: *(int64_t   *)dst= llrint(num/den)*intnum; break;
107 108
     case AV_OPT_TYPE_FLOAT: *(float     *)dst= num*intnum/den;         break;
108 109
     case AV_OPT_TYPE_DOUBLE:*(double    *)dst= num*intnum/den;         break;
... ...
@@ -259,7 +262,8 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
259 259
     if (!val && (o->type != AV_OPT_TYPE_STRING &&
260 260
                  o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
261 261
                  o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE &&
262
-                 o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR))
262
+                 o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
263
+                 o->type != AV_OPT_TYPE_CHANNEL_LAYOUT))
263 264
         return AVERROR(EINVAL);
264 265
 
265 266
     dst = ((uint8_t*)target_obj) + o->offset;
... ...
@@ -341,6 +345,24 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
341 341
                 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val);
342 342
             return ret;
343 343
         }
344
+        break;
345
+    case AV_OPT_TYPE_CHANNEL_LAYOUT:
346
+        if (!val || !strcmp(val, "none")) {
347
+            *(int64_t *)dst = 0;
348
+        } else {
349
+#if FF_API_GET_CHANNEL_LAYOUT_COMPAT
350
+            int64_t cl = ff_get_channel_layout(val, 0);
351
+#else
352
+            int64_t cl = av_get_channel_layout(val);
353
+#endif
354
+            if (!cl) {
355
+                av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
356
+                ret = AVERROR(EINVAL);
357
+            }
358
+            *(int64_t *)dst = cl;
359
+            return ret;
360
+        }
361
+        break;
344 362
     }
345 363
 
346 364
     av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
... ...
@@ -532,6 +554,22 @@ int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt,
532 532
     return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
533 533
 }
534 534
 
535
+int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags)
536
+{
537
+    void *target_obj;
538
+    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
539
+
540
+    if (!o || !target_obj)
541
+        return AVERROR_OPTION_NOT_FOUND;
542
+    if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
543
+        av_log(obj, AV_LOG_ERROR,
544
+               "The value set by option '%s' is not a channel layout.\n", o->name);
545
+        return AVERROR(EINVAL);
546
+    }
547
+    *(int *)(((int64_t *)target_obj) + o->offset) = cl;
548
+    return 0;
549
+}
550
+
535 551
 #if FF_API_OLD_AVOPTIONS
536 552
 /**
537 553
  *
... ...
@@ -630,6 +668,10 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
630 630
     case AV_OPT_TYPE_COLOR:
631 631
         ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", ((int *)dst)[0], ((int *)dst)[1], ((int *)dst)[2], ((int *)dst)[3]);
632 632
         break;
633
+    case AV_OPT_TYPE_CHANNEL_LAYOUT:
634
+        i64 = *(int64_t *)dst;
635
+        ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
636
+        break;
633 637
     default:
634 638
         return AVERROR(EINVAL);
635 639
     }
... ...
@@ -799,6 +841,23 @@ int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AV
799 799
     return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
800 800
 }
801 801
 
802
+int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl)
803
+{
804
+    void *dst, *target_obj;
805
+    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
806
+    if (!o || !target_obj)
807
+        return AVERROR_OPTION_NOT_FOUND;
808
+    if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
809
+        av_log(obj, AV_LOG_ERROR,
810
+               "The value for option '%s' is not a channel layout.\n", name);
811
+        return AVERROR(EINVAL);
812
+    }
813
+
814
+    dst = ((uint8_t*)target_obj) + o->offset;
815
+    *cl = *(int64_t *)dst;
816
+    return 0;
817
+}
818
+
802 819
 int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
803 820
 {
804 821
     const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
... ...
@@ -902,6 +961,9 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
902 902
             case AV_OPT_TYPE_COLOR:
903 903
                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>");
904 904
                 break;
905
+            case AV_OPT_TYPE_CHANNEL_LAYOUT:
906
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>");
907
+                break;
905 908
             case AV_OPT_TYPE_CONST:
906 909
             default:
907 910
                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
... ...
@@ -972,6 +1034,10 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
972 972
             case AV_OPT_TYPE_STRING:
973 973
             case AV_OPT_TYPE_VIDEO_RATE:
974 974
                 av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
975
+                break;
976
+            case AV_OPT_TYPE_CHANNEL_LAYOUT:
977
+                av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64);
978
+                break;
975 979
             }
976 980
             av_log(av_log_obj, AV_LOG_INFO, ")");
977 981
         }
... ...
@@ -1019,6 +1085,7 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
1019 1019
             case AV_OPT_TYPE_INT:
1020 1020
             case AV_OPT_TYPE_INT64:
1021 1021
             case AV_OPT_TYPE_DURATION:
1022
+            case AV_OPT_TYPE_CHANNEL_LAYOUT:
1022 1023
                 av_opt_set_int(s, opt->name, opt->default_val.i64, 0);
1023 1024
             break;
1024 1025
             case AV_OPT_TYPE_DOUBLE:
... ...
@@ -1395,6 +1462,7 @@ int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const ch
1395 1395
     case AV_OPT_TYPE_DOUBLE:
1396 1396
     case AV_OPT_TYPE_DURATION:
1397 1397
     case AV_OPT_TYPE_COLOR:
1398
+    case AV_OPT_TYPE_CHANNEL_LAYOUT:
1398 1399
         break;
1399 1400
     case AV_OPT_TYPE_STRING:
1400 1401
         range->component_min = 0;
... ...
@@ -1462,6 +1530,7 @@ typedef struct TestContext
1462 1462
     enum AVSampleFormat sample_fmt;
1463 1463
     int64_t duration;
1464 1464
     uint8_t color[4];
1465
+    int64_t channel_layout;
1465 1466
 } TestContext;
1466 1467
 
1467 1468
 #define OFFSET(x) offsetof(TestContext, x)
... ...
@@ -1485,6 +1554,7 @@ static const AVOption test_options[]= {
1485 1485
 {"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE,  {.str = "25"}, 0,     0                   },
1486 1486
 {"duration", "set duration",   OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX},
1487 1487
 {"color", "set color",   OFFSET(color), AV_OPT_TYPE_COLOR, {.str = "pink"}, 0, 0},
1488
+{"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = AV_CH_LAYOUT_HEXAGONAL}, 0, INT64_MAX},
1488 1489
 {NULL},
1489 1490
 };
1490 1491
 
... ...
@@ -1546,6 +1616,8 @@ int main(void)
1546 1546
             "color=blue",
1547 1547
             "color=0x223300",
1548 1548
             "color=0x42FF07AA",
1549
+            "cl=stereo+downmix",
1550
+            "cl=foo",
1549 1551
         };
1550 1552
 
1551 1553
         test_ctx.class = &test_class;
... ...
@@ -233,6 +233,7 @@ enum AVOptionType{
233 233
     AV_OPT_TYPE_VIDEO_RATE = MKBETAG('V','R','A','T'), ///< offset must point to AVRational
234 234
     AV_OPT_TYPE_DURATION   = MKBETAG('D','U','R',' '),
235 235
     AV_OPT_TYPE_COLOR      = MKBETAG('C','O','L','R'),
236
+    AV_OPT_TYPE_CHANNEL_LAYOUT = MKBETAG('C','H','L','A'),
236 237
 #if FF_API_OLD_AVOPTIONS
237 238
     FF_OPT_TYPE_FLAGS = 0,
238 239
     FF_OPT_TYPE_INT,
... ...
@@ -657,6 +658,7 @@ int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_
657 657
 int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags);
658 658
 int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags);
659 659
 int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags);
660
+int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags);
660 661
 
661 662
 /**
662 663
  * Set a binary option to an integer list.
... ...
@@ -700,6 +702,7 @@ int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_
700 700
 int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt);
701 701
 int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt);
702 702
 int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val);
703
+int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout);
703 704
 /**
704 705
  * @}
705 706
  */
... ...
@@ -75,8 +75,8 @@
75 75
  */
76 76
 
77 77
 #define LIBAVUTIL_VERSION_MAJOR  52
78
-#define LIBAVUTIL_VERSION_MINOR  46
79
-#define LIBAVUTIL_VERSION_MICRO 101
78
+#define LIBAVUTIL_VERSION_MINOR  47
79
+#define LIBAVUTIL_VERSION_MICRO 100
80 80
 
81 81
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
82 82
                                                LIBAVUTIL_VERSION_MINOR, \