res_format_attr_celt.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2011, Digium, Inc.
  5. *
  6. * David Vossel <dvossel@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*!
  19. * \file
  20. * \brief CELT format attribute interface
  21. *
  22. * \author David Vossel <dvossel@digium.com>
  23. */
  24. /*** MODULEINFO
  25. <support_level>core</support_level>
  26. ***/
  27. #include "asterisk.h"
  28. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  29. #include "asterisk/module.h"
  30. #include "asterisk/format.h"
  31. /*!
  32. * \brief CELT attribute structure.
  33. *
  34. * \note The only attribute that affects compatibility here is the sample rate.
  35. */
  36. struct celt_attr {
  37. unsigned int samplerate;
  38. unsigned int maxbitrate;
  39. unsigned int framesize;
  40. };
  41. static void celt_destroy(struct ast_format *format)
  42. {
  43. struct celt_attr *attr = ast_format_get_attribute_data(format);
  44. ast_free(attr);
  45. }
  46. static int celt_clone(const struct ast_format *src, struct ast_format *dst)
  47. {
  48. struct celt_attr *original = ast_format_get_attribute_data(src);
  49. struct celt_attr *attr = ast_calloc(1, sizeof(*attr));
  50. if (!attr) {
  51. return -1;
  52. }
  53. if (original) {
  54. *attr = *original;
  55. }
  56. ast_format_set_attribute_data(dst, attr);
  57. return 0;
  58. }
  59. static struct ast_format *celt_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
  60. {
  61. struct ast_format *cloned;
  62. struct celt_attr *attr;
  63. unsigned int val;
  64. cloned = ast_format_clone(format);
  65. if (!cloned) {
  66. return NULL;
  67. }
  68. attr = ast_format_get_attribute_data(cloned);
  69. if (sscanf(attributes, "framesize=%30u", &val) == 1) {
  70. attr->framesize = val;
  71. }
  72. return cloned;
  73. }
  74. static void celt_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str)
  75. {
  76. struct celt_attr *attr = ast_format_get_attribute_data(format);
  77. if (!attr || !attr->framesize) {
  78. return;
  79. }
  80. ast_str_append(str, 0, "a=fmtp:%u framesize=%u\r\n", payload, attr->framesize);
  81. }
  82. static enum ast_format_cmp_res celt_cmp(const struct ast_format *format1, const struct ast_format *format2)
  83. {
  84. struct celt_attr *attr1 = ast_format_get_attribute_data(format1);
  85. struct celt_attr *attr2 = ast_format_get_attribute_data(format2);
  86. if (((!attr1 || !attr1->samplerate) && (!attr2 || !attr2->samplerate)) ||
  87. (attr1->samplerate == attr2->samplerate)) {
  88. return AST_FORMAT_CMP_EQUAL;
  89. }
  90. return AST_FORMAT_CMP_NOT_EQUAL;
  91. }
  92. static struct ast_format *celt_getjoint(const struct ast_format *format1, const struct ast_format *format2)
  93. {
  94. struct celt_attr *attr1 = ast_format_get_attribute_data(format1);
  95. struct celt_attr *attr2 = ast_format_get_attribute_data(format2);
  96. struct ast_format *jointformat;
  97. struct celt_attr *jointattr;
  98. if (attr1 && attr2 && (attr1->samplerate != attr2->samplerate)) {
  99. return NULL;
  100. }
  101. jointformat = ast_format_clone(format1);
  102. if (!jointformat) {
  103. return NULL;
  104. }
  105. jointattr = ast_format_get_attribute_data(jointformat);
  106. /* either would work, they are guaranteed the same at this point. */
  107. jointattr->samplerate = attr1->samplerate;
  108. /* Take the lowest max bitrate */
  109. jointattr->maxbitrate = MIN(attr1->maxbitrate, attr2->maxbitrate);
  110. jointattr->framesize = attr2->framesize; /* TODO figure out what joint framesize means */
  111. return jointformat;
  112. }
  113. static struct ast_format *celt_set(const struct ast_format *format, const char *name, const char *value)
  114. {
  115. struct ast_format *cloned;
  116. struct celt_attr *attr;
  117. unsigned int val;
  118. cloned = ast_format_clone(format);
  119. if (!cloned) {
  120. return NULL;
  121. }
  122. attr = ast_format_get_attribute_data(cloned);
  123. if (sscanf(value, "%30u", &val) != 1) {
  124. ast_log(LOG_WARNING, "Unknown value '%s' for attribute type '%s'\n",
  125. value, name);
  126. ao2_ref(cloned, -1);
  127. return NULL;
  128. }
  129. if (!strcasecmp(name, "sample_rate")) {
  130. attr->samplerate = val;
  131. } else if (!strcasecmp(name, "max_bitrate")) {
  132. attr->maxbitrate = val;
  133. } else if (!strcasecmp(name, "frame_size")) {
  134. attr->framesize = val;
  135. } else {
  136. ast_log(LOG_WARNING, "Unknown attribute type '%s'\n", name);
  137. ao2_ref(cloned, -1);
  138. return NULL;
  139. }
  140. return cloned;
  141. }
  142. static struct ast_format_interface celt_interface = {
  143. .format_destroy = celt_destroy,
  144. .format_clone = celt_clone,
  145. .format_cmp = celt_cmp,
  146. .format_get_joint = celt_getjoint,
  147. .format_attribute_set = celt_set,
  148. .format_parse_sdp_fmtp = celt_parse_sdp_fmtp,
  149. .format_generate_sdp_fmtp = celt_generate_sdp_fmtp,
  150. };
  151. static int load_module(void)
  152. {
  153. if (ast_format_interface_register("celt", &celt_interface)) {
  154. return AST_MODULE_LOAD_DECLINE;
  155. }
  156. return AST_MODULE_LOAD_SUCCESS;
  157. }
  158. static int unload_module(void)
  159. {
  160. return 0;
  161. }
  162. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "CELT Format Attribute Module",
  163. .support_level = AST_MODULE_SUPPORT_CORE,
  164. .load = load_module,
  165. .unload = unload_module,
  166. .load_pri = AST_MODPRI_CHANNEL_DEPEND,
  167. );