You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
6.3KB

  1. // RFC6184 RTP Payload Format for H.264 Video
  2. #include "mpeg4-aac.h"
  3. #include "sdp-payload.h"
  4. #include "base64.h"
  5. #include <stdio.h>
  6. #include <stdint.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <assert.h>
  10. #include <errno.h>
  11. // RFC6416 RTP Payload Format for MPEG-4 Audio/Visual Streams
  12. int sdp_aac_latm(uint8_t *data, int bytes, const char* proto, unsigned short port, int payload, int sample_rate, int channel_count, const void* extra, int extra_size)
  13. {
  14. // In the presence of SBR, the sampling rates for the core encoder/
  15. // decoder and the SBR tool are different in most cases. Therefore,
  16. // this parameter SHALL NOT be considered as the definitive sampling rate.
  17. // profile-level-id --> ISO/IEC 14496-3:2009 audioProfileLevelIndication values
  18. static const char* pattern =
  19. "m=audio %hu %s %d\n"
  20. "a=rtpmap:%d MP4A-LATM/%d/%d\n"
  21. "a=fmtp:%d profile-level-id=%d;object=%d;cpresent=0;config=";
  22. int r, n;
  23. uint8_t config[6];
  24. struct mpeg4_aac_t aac;
  25. //aac.profile = MPEG4_AAC_LC;
  26. //aac.channel_configuration = (uint8_t)channel_count;
  27. //aac.sampling_frequency_index = (uint8_t)mpeg4_aac_audio_frequency_from(sample_rate);
  28. r = mpeg4_aac_audio_specific_config_load((const uint8_t*)extra, extra_size, &aac);
  29. if (r < 0) return r;
  30. sample_rate = 0 == sample_rate ? mpeg4_aac_audio_frequency_to(aac.sampling_frequency_index) : sample_rate;
  31. channel_count = 0 == channel_count ? aac.channel_configuration : channel_count;
  32. assert(aac.sampling_frequency_index == (uint8_t)mpeg4_aac_audio_frequency_from(sample_rate));
  33. assert(aac.channel_configuration == channel_count);
  34. r = mpeg4_aac_stream_mux_config_save(&aac, config, sizeof(config));
  35. if (r < 0) return r;
  36. // the "rate" parameter indicates the RTP timestamp "clock rate".
  37. // The default value is 90000. Other rates MAY be indicated
  38. // only if they are set to the same value as the audio sampling rate
  39. sample_rate = 0 == sample_rate ? 90000 : sample_rate;
  40. n = snprintf((char*)data, bytes, pattern, port,
  41. proto && *proto ? proto : "RTP/AVP",
  42. payload, payload, sample_rate, channel_count,
  43. payload, mpeg4_aac_profile_level(&aac), aac.profile);
  44. if (n + r * 2 + 1 > bytes)
  45. return -ENOMEM; // don't have enough memory
  46. n += (int)base16_encode((char*)data + n, config, r);
  47. if (n < bytes)
  48. data[n++] = '\n';
  49. return n;
  50. }
  51. // RFC 3640 3.3.1. General (p21)
  52. int sdp_aac_generic(uint8_t *data, int bytes, const char* proto, unsigned short port, int payload, int sample_rate, int channel_count, const void* extra, int extra_size)
  53. {
  54. // a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding parameters > ]
  55. // For audio streams, <encoding parameters> specifies the number of audio channels, default value is 1.
  56. // streamType: AudioStream --> ISO/IEC 14496-1:2010 streamType Values
  57. // profile-level-id --> ISO/IEC 14496-3:2009 audioProfileLevelIndication values
  58. // When using SDP, the clock rate of the RTP time stamp MUST be expressed using the "rtpmap" attribute.
  59. // If an MPEG-4 audio stream is transported, the rate SHOULD be set to the same value as the sampling rate of the audio stream.
  60. // If an MPEG-4 video stream transported, it is RECOMMENDED that the rate be set to 90 kHz.
  61. static const char* pattern =
  62. "m=audio %hu %s %d\n"
  63. "a=rtpmap:%d mpeg4-generic/%d/%d\n"
  64. "a=fmtp:%d streamtype=5;profile-level-id=%d;mode=AAC-hbr;sizeLength=13;indexLength=3;indexDeltaLength=3;config=";
  65. int r, n;
  66. struct mpeg4_aac_t aac;
  67. r = mpeg4_aac_audio_specific_config_load((const uint8_t*)extra, extra_size, &aac);
  68. if (r < 0) return r;
  69. sample_rate = 0 == sample_rate ? mpeg4_aac_audio_frequency_to(aac.sampling_frequency_index) : sample_rate;
  70. channel_count = 0 == channel_count ? aac.channel_configuration : channel_count;
  71. assert(aac.sampling_frequency_index == (uint8_t)mpeg4_aac_audio_frequency_from(sample_rate));
  72. assert(aac.channel_configuration == channel_count);
  73. n = snprintf((char*)data, bytes, pattern, port, proto && *proto ? proto : "RTP/AVP", payload, payload, sample_rate, channel_count, payload, mpeg4_aac_profile_level(&aac));
  74. if (n + extra_size * 2 + 1 > bytes)
  75. return -ENOMEM; // don't have enough memory
  76. // For MPEG-4 Audio streams, config is the audio object type specific
  77. // decoder configuration data AudioSpecificConfig()
  78. n += (int)base16_encode((char*)data + n, extra, extra_size);
  79. if (n < bytes)
  80. data[n++] = '\n';
  81. return n;
  82. }
  83. /// @return >0-ok, <=0-error
  84. int sdp_aac_latm_load(uint8_t* data, int bytes, const char* config)
  85. {
  86. int n;
  87. uint8_t buf[128];
  88. struct mpeg4_aac_t aac;
  89. n = (int)strlen(config);
  90. if (n / 2 > sizeof(buf))
  91. return -E2BIG;
  92. n = (int)base16_decode(buf, config, n);
  93. n = mpeg4_aac_stream_mux_config_load(buf, n, &aac);
  94. return n <= 0 ? n : mpeg4_aac_audio_specific_config_save(&aac, data, bytes);
  95. }
  96. /// @return >0-ok, <=0-error
  97. int sdp_aac_mpeg4_load(uint8_t* data, int bytes, const char* config)
  98. {
  99. int n;
  100. n = (int)strlen(config);
  101. if (n / 2 > bytes)
  102. return -E2BIG;
  103. return (int)base16_decode(data, config, n);
  104. }
  105. #if defined(_DEBUG) || defined(DEBUG)
  106. void sdp_aac_test(void)
  107. {
  108. // rfc3640
  109. //const unsigned char celpcbr[] = { "440E00" }; // 16000/1 streamtype=5; profile-level-id=14
  110. //const unsigned char celpvbr[] = { "440F20" }; // 16000/1 streamtype=5; profile-level-id=14
  111. //const unsigned char aaclbr[] = { "1388" }; // 22050/1 streamtype=5; profile-level-id=14
  112. //const unsigned char aachbr[] = { "11B0" }; // 48000/6 streamtype=5; profile-level-id=16
  113. const uint8_t config[] = { 0x11, 0x90, };
  114. //const char* mpeg4_generic_sdp = "m=audio 0 RTP/AVP 96\na=rtpmap:96 mpeg4-generic/48000/2\na=fmtp:96 streamtype=5; profile-level-id=15; mode=AAC-hbr; config=1190; SizeLength=13; IndexLength=3; IndexDeltaLength=3; Profile=1\n";
  115. const char* mpeg4_generic_sdp = "m=audio 0 RTP/AVP 96\na=rtpmap:96 mpeg4-generic/48000/2\na=fmtp:96 streamtype=5;profile-level-id=41;mode=AAC-hbr;sizeLength=13;indexLength=3;indexDeltaLength=3;config=1190\n";
  116. //const char* mp4a_latm_sdp = "m=audio 0 RTP/AVP 96\na=rtpmap:96 MP4A-LATM/48000/2\na=fmtp:96 profile-level-id=9;object=8;cpresent=0;config=9128B1071070\n";
  117. uint8_t buffer[256];
  118. //struct mpeg4_aac_t aac;
  119. //int n;
  120. assert((int)strlen(mpeg4_generic_sdp) == sdp_aac_generic(buffer, sizeof(buffer), "RTP/AVP", 0, 96, 48000, 2, config, sizeof(config)));
  121. assert(0 == memcmp(mpeg4_generic_sdp, buffer, strlen(mpeg4_generic_sdp)));
  122. assert(sizeof(config) == sdp_aac_mpeg4_load(buffer, sizeof(buffer), "1190"));
  123. assert(0 == memcmp(config, buffer, sizeof(config)));
  124. }
  125. #endif