10#include "AudioTools/AudioCodecs/AudioCodecsBase.h"
11#include "AudioTools/CoreAudio/AudioStreams.h"
12#include "AudioTools/CoreAudio/AudioTypes.h"
13#include "RTSPPlatform.h"
16#define DEFAULT_PCM_FRAGMENT_SIZE 640
52 virtual const char *format(
char *buffer,
int len) = 0;
55 virtual int convert(
void *data,
int sampleCount) {
return sampleCount; }
58 virtual void begin(
AudioInfo info) { cfg = info; }
62 virtual AudioInfo audioInfo() {
return cfg; }
64 virtual const char *name() {
return name_str; }
66 void setName(
const char *name) { name_str = name; }
77 int samples_per_fragment =
79 return samples_per_fragment;
96 virtual bool useRfc2250Header()
const {
return false; }
99 const char *STD_URL_PRE_SUFFIX =
"trackID";
101 int fragment_size = DEFAULT_PCM_FRAGMENT_SIZE;
102 int timer_period_us = 10000;
103 AudioInfo cfg{16000, 1, 16};
104 const char *name_str =
"RTSPAudioTools";
148 const char *
format(
char *buffer,
int len)
override {
150 snprintf(buffer, len,
152 "c=IN IP4 0.0.0.0\r\n"
154 "m=audio 0 RTP/AVP %d\r\n"
155 "a=rtpmap:%d L16/%d/%d\r\n",
156 pt, pt, sampleRate(), channels());
157 LOGI(
"ftsp format: %s", buffer);
158 return (
const char *)buffer;
169 int16_t *pt_16 = (int16_t *)data;
170 for (
int j = 0; j < samples / 2; j++) {
171 pt_16[j] = htons(pt_16[j]);
178 AudioInfo defaultConfig()
override {
return AudioInfo(16000, 1, 16); }
183 if (channels() == 1)
return 11;
184 if (channels() == 2)
return 10;
192 int channels() {
return cfg.
channels; }
205 (samples_per_fragment * 1000000) / cfg.
sample_rate;
226 p_encoder = &encoder;
234 const char *format(
char *buffer,
int len)
override {
236 snprintf(buffer, len,
238 "c=IN IP4 0.0.0.0\r\n"
240 "m=audio 0 RTP/AVP 101\r\n"
241 "a=rtpmap:101 opus/%d/2\r\n"
242 "a=fmtp:101 stereo=1; sprop-stereo=%d\r\n",
244 return (
const char *)buffer;
246 AudioInfo defaultConfig() {
247 AudioInfo cfg(48000, 2, 16);
251 void begin(AudioInfo info)
override {
252 RTSPFormat::begin(info);
254 if (p_encoder !=
nullptr) {
261 AudioEncoder *p_encoder =
nullptr;
280 const char *format(
char *buffer,
int len)
override {
282 snprintf(buffer, len,
284 "c=IN IP4 0.0.0.0\r\n"
286 "m=audio 0 RTP/AVP 98\r\n"
287 "a=rtpmap:98 aptx/%d/%d\r\n"
288 "a=fmtp:98 variant=standard; bitresolution=%d\r\n",
290 return (
const char *)buffer;
298 RTSPFormat::begin(info);
303 int period = (samplesPerFragment * 1000000) / cfg.
sample_rate;
322 const char *
format(
char *buffer,
int len)
override {
327 snprintf(buffer, len,
329 "c=IN IP4 0.0.0.0\r\n"
331 "m=audio 0 RTP/AVP 3\r\n"
334 return (
const char *)buffer;
358 const char *
format(
char *buffer,
int len)
override {
366 "c=IN IP4 0.0.0.0\r\n"
368 "m=audio 0 RTP/AVP %d\r\n"
370 name(), getFormat());
371 return (
const char *)buffer;
384 uint8_t getFormat() {
return is_ulaw ? 0 : 8; }
399 const char *format(
char *buffer,
int len)
override {
401 snprintf(buffer, len,
403 "c=IN IP4 0.0.0.0\r\n"
405 "m=audio 0 RTP/AVP 96\r\n"
406 "a=rtpmap:96 l8/%d/%d\r\n",
408 return (
const char *)buffer;
416 RTSPFormat::begin(info);
419 int bytesPerSample = 1;
421 int period = (samplesPerFragment * 1000000) / cfg.
sample_rate;
447template <
class AudioEncoder>
455 p_encoder = &encoder;
468 const char *format(
char *buffer,
int len)
override {
472 int payload_type = 5;
487 LOGE(
"Unsupported sample rate for IMA ADPCM: %d", sr);
492 snprintf(buffer, len,
494 "c=IN IP4 0.0.0.0\r\n"
496 "m=audio 0 RTP/AVP %d\r\n"
497 "a=rtpmap:%d DVI4/%d\r\n",
498 name(), payload_type, payload_type, sr);
499 return (
const char *)buffer;
501 AudioInfo defaultConfig() {
502 AudioInfo cfg(22050, 1, 16);
506 void begin(AudioInfo info)
override {
507 RTSPFormat::begin(info);
508 if (p_encoder !=
nullptr) {
509 ((AudioInfoSupport *)p_encoder)->setAudioInfo(info);
514 int samplesPerFragment =
516 int period = (samplesPerFragment * 1000000) / cfg.
sample_rate;
522 AudioInfo audioInfo()
override {
523 if (p_encoder !=
nullptr)
524 return ((AudioInfoSupport *)p_encoder)->audioInfo();
525 return RTSPFormat::audioInfo();
529 AudioEncoder *p_encoder =
nullptr;
552 void setEncoder(
AudioEncoder &encoder) { p_encoder = &encoder; }
567 if (p_encoder !=
nullptr)
569 return RTSPFormat::audioInfo();
576 const char *format(
char *buffer,
int len)
override {
584 if (ptime_ms < 10) ptime_ms = 10;
586 snprintf(buffer, len,
587 "m=audio 0 RTP/AVP %d\r\n"
588 "a=rtpmap:%d MPA/90000\r\n"
589 "a=fmtp:%d layer=3\r\n"
591 payload_type, payload_type, payload_type, ptime_ms);
593 snprintf(buffer, len,
594 "m=audio 0 RTP/AVP %d\r\n"
595 "a=rtpmap:%d MPA/90000/%d\r\n"
596 "a=fmtp:%d layer=3\r\n"
598 payload_type, payload_type, ch, payload_type, ptime_ms);
600 return (
const char *)buffer;
610 void begin(AudioInfo info)
override {
611 RTSPFormat::begin(info);
613 int samplesPerFrame = 1152;
615 int period = (samplesPerFrame * 1000000) / cfg.
sample_rate;
625 if (use_rfc2250_header_) {
626 memset(buffer, 0, 4);
635 bool use_rfc2250_header_ =
false;
640 bool useRfc2250Header()
const override {
return use_rfc2250_header_; }
661 const char *format(
char *buffer,
int len)
override {
663 int payload_type = 96;
666 snprintf(buffer, len,
668 "c=IN IP4 0.0.0.0\r\n"
670 "m=audio 0 RTP/AVP %d\r\n"
671 "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n"
672 "a=fmtp:%d streamtype=5; profile-level-id=1; mode=AAC-hbr;\r\n",
673 name(), payload_type, payload_type, sr, ch, payload_type);
674 return (
const char *)buffer;
682 RTSPFormat::begin(info);
684 int samplesPerFrame = 1024;
686 int period = (samplesPerFrame * 1000000) / cfg.
sample_rate;