arduino-audio-tools
Loading...
Searching...
No Matches
RTSPFormat.h
Go to the documentation of this file.
1/*
2 * Author: Phil Schatzmann
3 *
4 * Based on Micro-RTSP library:
5 * https://github.com/geeksville/Micro-RTSP
6 * https://github.com/Tomp0801/Micro-RTSP-Audio
7 *
8 */
9#pragma once
13#include "VideoInfo.h"
14#include "RTSPPlatform.h"
15#include "stdint.h"
16
17#define DEFAULT_PCM_FRAGMENT_SIZE 640
18
19namespace audio_tools {
20
28
58 public:
59 // Provides the format information: see see
60 // https://en.wikipedia.org/wiki/RTP_payload_formats
61 virtual const char *format(char *buffer, int len) = 0;
62
63 // Data convertsion e.g. to network format. len is in samples
64 virtual int convert(void *data, int sampleCount) { return sampleCount; }
65
66 // Initialize with AudioInfo like data
67 virtual void begin(AudioInfo info) { cfg = info; }
68
69 // Initialize with RTSPVideoInfo data
70 virtual void begin(RTSPVideoInfo info) { video_cfg = info; }
71
72 // Provide a default config (must be overridden by concrete subclass)
73 virtual AudioInfo defaultConfig() = 0;
74
75 // Provide default video config (override for video formats)
77 return RTSPVideoInfo(640, 480, 30.0f, RTSPVideoFormat::MJPEG, 24);
78 }
79
80 // Access current AudioInfo
81 virtual AudioInfo audioInfo() { return cfg; }
82
83 // Access current RTSPVideoInfo
84 virtual RTSPVideoInfo videoInfo() { return video_cfg; }
85
86 // Get media type (audio or video)
87 virtual MediaType mediaType() { return MEDIA_AUDIO; }
88
89 // Name accessors
90 virtual const char *name() { return name_str; }
92 void setName(const char *name) { name_str = name; }
93
96
98 virtual int fragmentSize() { return fragment_size; }
99
101 virtual int timestampIncrement() {
102 if (mediaType() == MEDIA_VIDEO) {
104 }
105 int sample_size_bytes = cfg.bits_per_sample / 8;
106 int samples_per_fragment =
107 fragmentSize() / (sample_size_bytes * cfg.channels);
108 return samples_per_fragment;
109 }
110
112 void setTimerPeriodUs(int period) { timer_period_us = period; }
113
115 virtual int timerPeriodUs() {
116 if (mediaType() == MEDIA_VIDEO) {
117 return video_cfg.framePeriodUs();
118 }
119 return timer_period_us;
120 }
121
123 virtual int rtpPayloadType() { return 96; }
124
126 virtual int readHeader(uint8_t *data) { return 0; }
127
129 virtual void setUseRfc2250Header(bool /*enable*/) {}
130 virtual bool useRfc2250Header() const { return false; }
131
137 virtual void setSpropParameterSets(const char * /*base64Sps*/,
138 const char * /*base64Pps*/) {}
139
143 virtual void setProfileLevelId(const char * /*hex6*/) {}
144
145 protected:
146 const char *STD_URL_PRE_SUFFIX = "trackID";
147 // for sample rate 16000
149 int timer_period_us = 10000;
150 AudioInfo cfg{16000, 1, 16};
152 const char *name_str = "RTSPAudioTools";
153};
154
169class RTSPFormatPCM : public RTSPFormat {
170 public:
176
178 AudioInfo tmp(16000, 1, 16); // Default: 16kHz mono 16-bit
179 cfg = tmp;
182 }
183
185 this->cfg = info;
187 }
188
196 const char *format(char *buffer, int len) override {
197 int pt = rtpPayloadType();
198 snprintf(buffer, len,
199 "s=Microphone\r\n"
200 "c=IN IP4 0.0.0.0\r\n"
201 "t=0 0\r\n"
202 "m=audio 0 RTP/AVP %d\r\n"
203 "a=rtpmap:%d L16/%d/%d\r\n",
204 pt, pt, sampleRate(), channels());
205 LOGI("ftsp format: %s", buffer);
206 return (const char *)buffer;
207 }
208
215 int convert(void *data, int samples) {
216 // convert to network format (big endian)
217 int16_t *pt_16 = (int16_t *)data;
218 for (int j = 0; j < samples / 2; j++) {
219 pt_16[j] = htons(pt_16[j]);
220 }
221 return samples;
222 }
223
224 AudioInfo info() { return cfg; }
225
226 AudioInfo defaultConfig() override { return AudioInfo(16000, 1, 16); }
227
228 int rtpPayloadType() override {
229 // Static assignments per RFC 3551 only valid for 44100Hz mono/stereo
230 if (cfg.sample_rate == 44100) {
231 if (channels() == 1) return 11; // L16 mono 44.1kHz
232 if (channels() == 2) return 10; // L16 stereo 44.1kHz
233 }
234 return 96; // dynamic otherwise
235 }
236
237protected:
238
239 int sampleRate() { return cfg.sample_rate; }
240 int channels() { return cfg.channels; }
241 int bytesPerSample() { return cfg.bits_per_sample / 8; }
242
248 // Calculate how many samples are in the fragment
249 int samples_per_fragment = timestampIncrement();
250 // Calculate how long it takes to play these samples at the given sample
251 // rate
252 int timer_period =
253 (samples_per_fragment * 1000000) / cfg.sample_rate; // microseconds
254 return timer_period;
255 }
256
257
258};
259
267 public:
269 setTimerPeriodUs(20000); // 20ms standard for Opus
270 }
271
274 p_encoder = &encoder;
275 setTimerPeriodUs(encoder.frameDurationUs()); // Convert ms to us
276 }
277
278 // Provides the Opus format information:
279 // m=audio 54312 RTP/AVP 101
280 // a=rtpmap:101 opus/48000/2
281 // a=fmtp:101 stereo=1; sprop-stereo=1
282 const char *format(char *buffer, int len) override {
283 TRACEI();
284 snprintf(buffer, len,
285 "s=%s\r\n" // Stream Name
286 "c=IN IP4 0.0.0.0\r\n" // Connection Information
287 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
288 "m=audio 0 RTP/AVP 101\r\n" // UDP sessions with format 101=opus
289 "a=rtpmap:101 opus/%d/2\r\n"
290 "a=fmtp:101 stereo=1; sprop-stereo=%d\r\n",
291 name(), cfg.sample_rate, cfg.channels == 2);
292 return (const char *)buffer;
293 }
295 AudioInfo cfg(48000, 2, 16);
296 return cfg;
297 }
298
299 void begin(AudioInfo info) override {
300 RTSPFormat::begin(info);
301 // Update timer period based on encoder configuration if available
302 if (p_encoder != nullptr) {
303 // p_encoder->setAudioInfo(info);
304 setTimerPeriodUs(p_encoder->frameDurationUs()); // Convert ms to us
305 }
306 }
307
308 protected:
310};
311
319 public:
321 setTimerPeriodUs(20000); // Default 20ms, will be recalculated in begin()
322 }
323
324 // Provides the SBC format information:
325 // m=audio 5004 RTP/AVP 98
326 // a=rtpmap:98 aptx/44100/2
327 // a=fmtp:98 variant=standard; bitresolution=16;
328 const char *format(char *buffer, int len) override {
329 TRACEI();
330 snprintf(buffer, len,
331 "s=%s\r\n" // Stream Name
332 "c=IN IP4 0.0.0.0\r\n" // Connection Information
333 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
334 "m=audio 0 RTP/AVP 98\r\n" // UDP sessions with format 98=aptx
335 "a=rtpmap:98 aptx/%d/%d\r\n"
336 "a=fmtp:98 variant=standard; bitresolution=%d\r\n",
338 return (const char *)buffer;
339 }
341 AudioInfo cfg(44100, 2, 16);
342 return cfg;
343 }
344
345 void begin(AudioInfo info) override {
346 RTSPFormat::begin(info);
347 // Calculate fragment-based timing for AptX
348 if (fragmentSize() > 0 && cfg.sample_rate > 0 && cfg.channels > 0) {
349 int bytesPerSample = (cfg.bits_per_sample + 7) / 8;
350 int samplesPerFragment = fragmentSize() / (cfg.channels * bytesPerSample);
351 int period = (samplesPerFragment * 1000000) / cfg.sample_rate;
352 setTimerPeriodUs(period);
353 }
354 }
355};
356
363class RTSPFormatGSM : public RTSPFormat {
364 public:
366 setTimerPeriodUs(20000); // 20ms standard for GSM (160 samples at 8kHz)
367 }
368
370 const char *format(char *buffer, int len) override {
371 TRACEI();
372 assert(cfg.sample_rate == 8000);
373 assert(cfg.channels == 1);
374
375 snprintf(buffer, len,
376 "s=%s\r\n" // Stream Name
377 "c=IN IP4 0.0.0.0\r\n" // Connection Information
378 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
379 "m=audio 0 RTP/AVP 3\r\n" // UDP sessions with format 3=GSM
380 ,
381 name());
382 return (const char *)buffer;
383 }
384
386 AudioInfo cfg(8000, 1, 16);
387 return cfg;
388 }
389};
390
399 public:
400 RTSPFormatG711(bool isUlaw = true) {
401 setTimerPeriodUs(20000); // 20ms standard for G.711 (160 samples at 8kHz)
402 setIsULaw(isUlaw);
403 }
404
406 const char *format(char *buffer, int len) override {
407 TRACEI();
408 assert(cfg.sample_rate == 8000);
409 assert(cfg.channels == 1);
410
411 snprintf(
412 buffer, len,
413 "s=%s\r\n" // Stream Name
414 "c=IN IP4 0.0.0.0\r\n" // Connection Information
415 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
416 "m=audio 0 RTP/AVP %d\r\n" // UDP sessions with format 0=G711 μ-Law
417 ,
418 name(), getFormat());
419 return (const char *)buffer;
420 }
421
423 void setIsULaw(bool flag) { is_ulaw = flag; }
424
426 AudioInfo cfg(8000, 1, 16);
427 return cfg;
428 }
429
430 protected:
431 bool is_ulaw = true;
432 uint8_t getFormat() { return is_ulaw ? 0 : 8; }
433};
434
442 public:
444 setTimerPeriodUs(20000); // Default 20ms, will be recalculated in begin()
445 }
446
447 const char *format(char *buffer, int len) override {
448 TRACEI();
449 snprintf(buffer, len,
450 "s=%s\r\n" // Stream Name
451 "c=IN IP4 0.0.0.0\r\n" // Connection Information
452 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
453 "m=audio 0 RTP/AVP 96\r\n" // UDP sessions with format 96=dynamic
454 "a=rtpmap:96 l8/%d/%d\r\n",
456 return (const char *)buffer;
457 }
459 AudioInfo cfg(16000, 2, 8);
460 return cfg;
461 }
462
463 void begin(AudioInfo info) override {
464 RTSPFormat::begin(info);
465 // Calculate fragment-based timing for L8 (8-bit PCM)
466 if (fragmentSize() > 0 && cfg.sample_rate > 0 && cfg.channels > 0) {
467 int bytesPerSample = 1; // 8-bit = 1 byte per sample
468 int samplesPerFragment = fragmentSize() / cfg.channels;
469 int period = (samplesPerFragment * 1000000) / cfg.sample_rate;
470 setTimerPeriodUs(period);
471 }
472 }
473};
474
495template <class AudioEncoder>
497 public:
499 setTimerPeriodUs(20000); // Default 20ms, will be recalculated in begin()
500 }
501
503 p_encoder = &encoder;
504 encoder.begin();
505 setTimerPeriodUs(encoder.frameDurationUs()); // Convert ms to us
506 setFragmentSize(encoder.blockSize());
507 }
508
510 if (p_encoder != nullptr) return p_encoder->frameDurationUs();
512 }
513
514 // Provides the IMA ADPCM format information
515 // See RFC 3551 for details
516 const char *format(char *buffer, int len) override {
517 TRACEI();
518 // Only certain sample rates are valid for DVI4 (IMA ADPCM)
519 int sr = cfg.sample_rate;
520 int payload_type = 5; // default to 8000 Hz
521 switch (sr) {
522 case 8000:
523 payload_type = 5;
524 break;
525 case 16000:
526 payload_type = 6;
527 break;
528 case 11025:
529 payload_type = 16;
530 break;
531 case 22050:
532 payload_type = 17;
533 break;
534 default:
535 LOGE("Unsupported sample rate for IMA ADPCM: %d", sr);
536 sr = 8000;
537 payload_type = 5;
538 break;
539 }
540 snprintf(buffer, len,
541 "s=%s\r\n"
542 "c=IN IP4 0.0.0.0\r\n"
543 "t=0 0\r\n"
544 "m=audio 0 RTP/AVP %d\r\n"
545 "a=rtpmap:%d DVI4/%d\r\n",
546 name(), payload_type, payload_type, sr);
547 return (const char *)buffer;
548 }
550 AudioInfo cfg(22050, 1, 16); // 4 bits per sample for IMA ADPCM
551 return cfg;
552 }
553
554 void begin(AudioInfo info) override {
555 RTSPFormat::begin(info);
556 if (p_encoder != nullptr) {
557 ((AudioInfoSupport *)p_encoder)->setAudioInfo(info);
558 setTimerPeriodUs(p_encoder->frameDurationUs()); // Convert ms to us
559 } else {
560 // Calculate timing for ADPCM (4 bits per sample = 0.5 bytes per sample)
561 if (fragmentSize() > 0 && cfg.sample_rate > 0) {
562 int samplesPerFragment =
563 fragmentSize() * 2; // 2 samples per byte for 4-bit ADPCM
564 int period = (samplesPerFragment * 1000000) / cfg.sample_rate;
565 setTimerPeriodUs(period);
566 }
567 }
568 }
569
570 AudioInfo audioInfo() override {
571 if (p_encoder != nullptr)
572 return ((AudioInfoSupport *)p_encoder)->audioInfo();
573 return RTSPFormat::audioInfo();
574 }
575
576 protected:
578};
579
586class RTSPFormatMP3 : public RTSPFormat {
587 public:
589 setTimerPeriodUs(26122); // ~26ms for MP3 frames (1152 samples at 44.1kHz)
590 setFragmentSize(2884); // Trigger read that is big enough
591 }
592
595 setEncoder(encoder);
596 setFragmentSize(2884); // Trigger read that is big enough
597 setTimerPeriodUs(encoder.frameDurationUs()); // Convert ms to us
598 }
599
600 void setEncoder(AudioEncoder &encoder) { p_encoder = &encoder; }
601
603 if (p_encoder != nullptr) return p_encoder->frameDurationUs();
605 }
606
613 int fragmentSize() override {
614 if (p_encoder != nullptr) {
615 int actual = p_encoder->frameSize();
616 if (actual > 0) return actual;
617 }
619 }
620
621 virtual int timestampIncrement() {
622 if (p_encoder != nullptr) return p_encoder->samplesPerFrame();
623 // MP3 frame size is typically 1152 samples
624 return 1152;
625 }
626
629 if (p_encoder != nullptr)
630 return ((AudioInfoSupport *)p_encoder)->audioInfo();
631 return RTSPFormat::audioInfo();
632 }
633
634 // Provides the MP3 format information:
635 // m=audio 0 RTP/AVP 14
636 // a=rtpmap:14 MPA/90000[/ch]
637 // See RFC 3551 for details: MP3 RTP clock is always 90kHz
638 const char *format(char *buffer, int len) override {
639 TRACEI();
640 int payload_type = rtpPayloadType(); // RTP/AVP 14 = MPEG audio (MP3)
641 int ch = cfg.channels;
642 if (ch <= 0) ch = 1;
643 // Include channels when not mono for clarity
644 int ptime_ms =
645 (cfg.sample_rate > 0) ? (int)((1152 * 1000) / cfg.sample_rate) : 26;
646 if (ptime_ms < 10) ptime_ms = 10; // clamp to a reasonable minimum
647 if (ch == 1) {
648 snprintf(buffer, len,
649 "m=audio 0 RTP/AVP %d\r\n"
650 "a=rtpmap:%d MPA/90000\r\n"
651 "a=fmtp:%d layer=3\r\n"
652 "a=ptime:%d\r\n",
653 payload_type, payload_type, payload_type, ptime_ms);
654 } else {
655 snprintf(buffer, len,
656 "m=audio 0 RTP/AVP %d\r\n"
657 "a=rtpmap:%d MPA/90000/%d\r\n"
658 "a=fmtp:%d layer=3\r\n"
659 "a=ptime:%d\r\n",
660 payload_type, payload_type, ch, payload_type, ptime_ms);
661 }
662 return (const char *)buffer;
663 }
664
665 int rtpPayloadType() override { return 14; }
666
668 AudioInfo cfg(44100, 2, 16); // Typical MP3 config
669 return cfg;
670 }
671
672 void begin(AudioInfo info) override {
673 RTSPFormat::begin(info);
674 // MP3 frame size is typically 1152 samples
675 int samplesPerFrame = 1152;
676 if (cfg.sample_rate > 0) {
677 int period = (samplesPerFrame * 1000000) / cfg.sample_rate;
678 setTimerPeriodUs(period);
679 }
680 }
681
683 int readHeader(unsigned char *buffer) override {
684 // Some clients (e.g., FFmpeg/ffplay) expect the optional RFC2250 4-byte
685 // MPEG audio header for payload type 14, while others (e.g., VLC) expect
686 // raw frames. Make this behavior configurable.
688 memset(buffer, 0, 4);
689 return 4;
690 }
691 (void)buffer;
692 return 0;
693 }
694
695 protected:
698
699 public:
700 // Enable/disable RFC2250 4-byte MPEG audio header in RTP payload
701 void setUseRfc2250Header(bool enable) { use_rfc2250_header_ = enable; }
702 bool useRfc2250Header() const override { return use_rfc2250_header_; }
703};
704
712class RTSPFormatAAC : public RTSPFormat {
713 public:
715 setTimerPeriodUs(23219); // ~23ms for AAC frames (1024 samples at 44.1kHz)
716 }
717
718 // Provides the AAC format information:
719 // m=audio 0 RTP/AVP 96
720 // a=rtpmap:96 MPEG4-GENERIC/44100/2
721 // a=fmtp:96 streamtype=5; profile-level-id=1; mode=AAC-hbr; ...
722 // For simplicity, only basic SDP lines are provided here
723 const char *format(char *buffer, int len) override {
724 TRACEI();
725 int payload_type = 96; // Dynamic payload type for AAC
726 int sr = cfg.sample_rate;
727 int ch = cfg.channels;
728 snprintf(buffer, len,
729 "s=%s\r\n"
730 "c=IN IP4 0.0.0.0\r\n"
731 "t=0 0\r\n"
732 "m=audio 0 RTP/AVP %d\r\n"
733 "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n"
734 "a=fmtp:%d streamtype=5; profile-level-id=1; mode=AAC-hbr;\r\n",
735 name(), payload_type, payload_type, sr, ch, payload_type);
736 return (const char *)buffer;
737 }
739 AudioInfo cfg(44100, 2, 16); // Typical AAC config
740 return cfg;
741 }
742
743 void begin(AudioInfo info) override {
744 RTSPFormat::begin(info);
745 // AAC frame size is typically 1024 samples
746 int samplesPerFrame = 1024;
747 if (cfg.sample_rate > 0) {
748 int period = (samplesPerFrame * 1000000) / cfg.sample_rate;
749 setTimerPeriodUs(period);
750 }
751 }
752};
753
772 public:
773 RTSPFormatMJPEG(int width = 640, int height = 480, float framerate = 30.0f) {
774 video_width = width;
775 video_height = height;
776 video_framerate = framerate;
777 video_cfg = RTSPVideoInfo(width, height, framerate, RTSPVideoFormat::MJPEG, 24);
778 // Calculate timer period based on framerate
779 setTimerPeriodUs((int)(1000000.0f / framerate));
780 }
781
783 MediaType mediaType() override { return MEDIA_VIDEO; }
784
785 const char *format(char *buffer, int len) override {
786 TRACEI();
787 int payload_type = 26; // Static payload type for JPEG per RFC 3551
788 snprintf(buffer, len,
789 "s=%s\r\n"
790 "c=IN IP4 0.0.0.0\r\n"
791 "t=0 0\r\n"
792 "m=video 0 RTP/AVP %d\r\n"
793 "a=rtpmap:%d JPEG/90000\r\n"
794 "a=framerate:%.1f\r\n"
795 "a=framesize:%d %d-%d\r\n",
796 name(), payload_type, payload_type, video_framerate,
797 payload_type, video_width, video_height);
798 return (const char *)buffer;
799 }
800
802 AudioInfo cfg(0, 0, 0);
803 return cfg;
804 }
805
809
810 int rtpPayloadType() override { return 26; }
811
813 int timestampIncrement() override {
814 // Video RTP clock is 90kHz, so timestamp increment per frame is:
815 return (int)(90000.0f / video_framerate);
816 }
817
819 void setVideoDimensions(int width, int height) {
820 video_width = width;
821 video_height = height;
823 }
824
826 void setFramerate(float fps) {
827 video_framerate = fps;
829 setTimerPeriodUs((int)(1000000.0f / fps));
830 }
831
833 int getWidth() const { return video_width; }
834
836 int getHeight() const { return video_height; }
837
839 float getFramerate() const { return video_framerate; }
840
841 // Note: the RFC 2435 JPEG/RTP header (fragment offset, Q value,
842 // width/height, quantization-table sub-header) is built by
843 // JPEGRtpEncoder, which is a packetized IMediaSource and therefore
844 // bypasses RTSPFormat::readHeader() entirely. Keeping a second
845 // implementation here previously caused the two to drift apart and
846 // produce duplicated, inconsistent headers on the wire.
847
848 protected:
849 int video_width = 640;
850 int video_height = 480;
851 float video_framerate = 30.0f;
852};
853
880 public:
881 RTSPFormatH264(int width = 1280, int height = 720, float framerate = 15.0f) {
882 video_width = width;
883 video_height = height;
884 video_framerate = framerate;
885 video_cfg = RTSPVideoInfo(width, height, framerate, RTSPVideoFormat::H264, 24);
886 setTimerPeriodUs((int)(1000000.0f / framerate));
887 }
888
890 MediaType mediaType() override { return MEDIA_VIDEO; }
891
892 const char *format(char *buffer, int len) override {
893 TRACEI();
894 int payload_type = 96; // Dynamic payload type (RFC 3551: 96-127)
895 if (sprop_parameter_sets.length() > 0) {
896 snprintf(buffer, len,
897 "s=%s\r\n"
898 "c=IN IP4 0.0.0.0\r\n"
899 "t=0 0\r\n"
900 "m=video 0 RTP/AVP %d\r\n"
901 "a=rtpmap:%d H264/90000\r\n"
902 "a=framerate:%.1f\r\n"
903 "a=fmtp:%d packetization-mode=1;profile-level-id=%s;"
904 "sprop-parameter-sets=%s\r\n",
905 name(), payload_type, payload_type, video_framerate,
906 payload_type, profile_level_id.c_str(),
907 sprop_parameter_sets.c_str());
908 } else {
909 // SPS/PPS not captured yet (no frame encoded so far): rely on
910 // in-band parameter sets instead - H264RtpEncoder re-sends SPS/PPS
911 // before every IDR frame.
912 snprintf(buffer, len,
913 "s=%s\r\n"
914 "c=IN IP4 0.0.0.0\r\n"
915 "t=0 0\r\n"
916 "m=video 0 RTP/AVP %d\r\n"
917 "a=rtpmap:%d H264/90000\r\n"
918 "a=framerate:%.1f\r\n"
919 "a=fmtp:%d packetization-mode=1\r\n",
920 name(), payload_type, payload_type, video_framerate,
921 payload_type);
922 }
923 return (const char *)buffer;
924 }
925
927 AudioInfo cfg(0, 0, 0);
928 return cfg;
929 }
930
934
935 int rtpPayloadType() override { return 96; }
936
938 int timestampIncrement() override {
939 return (int)(90000.0f / video_framerate);
940 }
941
943 void setVideoDimensions(int width, int height) {
944 video_width = width;
945 video_height = height;
947 }
948
950 void setFramerate(float fps) {
951 video_framerate = fps;
953 setTimerPeriodUs((int)(1000000.0f / fps));
954 }
955
957 int getWidth() const { return video_width; }
958
960 int getHeight() const { return video_height; }
961
963 float getFramerate() const { return video_framerate; }
964
967 void setSpropParameterSets(const char *base64Sps, const char *base64Pps) override {
968 sprop_parameter_sets = base64Sps;
970 sprop_parameter_sets += base64Pps;
971 }
972
975 void setProfileLevelId(const char *hex6) override { profile_level_id = hex6; }
976
977 protected:
978 int video_width = 1280;
979 int video_height = 720;
980 float video_framerate = 15.0f;
982 // Conservative default (Constrained Baseline, level 3.0) used only until
983 // the real value parsed from the stream's SPS is available.
984 String profile_level_id = "42E01E";
985};
986
1014 public:
1018 RTSPFormatMTS(float framerate = 25.0f) { setFramerate(framerate); }
1019
1021 MediaType mediaType() override { return MEDIA_VIDEO; }
1022
1023 const char *format(char *buffer, int len) override {
1024 TRACEI();
1025 snprintf(buffer, len,
1026 "s=%s\r\n"
1027 "c=IN IP4 0.0.0.0\r\n"
1028 "t=0 0\r\n"
1029 "m=video 0 RTP/AVP %d\r\n",
1030 name(), rtpPayloadType());
1031 return (const char *)buffer;
1032 }
1033
1034 AudioInfo defaultConfig() override { return AudioInfo(0, 0, 0); }
1035
1036 int rtpPayloadType() override { return 33; }
1037
1038 int timerPeriodUs() override { return (int)(1000000.0f / video_framerate); }
1039
1041 void setFramerate(float fps) { video_framerate = fps; }
1042
1043 protected:
1044 float video_framerate = 25.0f;
1045};
1046
1047} // namespace audio_tools
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define htons(x)
Definition Net.h:15
#define DEFAULT_PCM_FRAGMENT_SIZE
Definition RTSPFormat.h:17
#define assert(T)
Definition avr.h:10
Encoding of PCM data.
Definition AudioCodecsBase.h:101
virtual uint16_t samplesPerFrame()
Optional rtsp function: provide samples per the frame.
Definition AudioCodecsBase.h:117
virtual uint32_t frameDurationUs()
Optional rtsp function: provide the frame duration in microseconds.
Definition AudioCodecsBase.h:115
virtual int frameSize()
Definition AudioCodecsBase.h:126
Supports changes to the sampling rate, bits and channels.
Definition AudioTypes.h:137
virtual bool begin()=0
AAC format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats See RFC 3640 for details.
Definition RTSPFormat.h:712
RTSPFormatAAC()
Definition RTSPFormat.h:714
AudioInfo defaultConfig()
Definition RTSPFormat.h:738
const char * format(char *buffer, int len) override
Definition RTSPFormat.h:723
void begin(AudioInfo info) override
Definition RTSPFormat.h:743
RTSP/RTP formatter for mono IMA ADPCM (DVI4)
Definition RTSPFormat.h:496
RTSPFormatADPCM(AudioEncoder &encoder)
Definition RTSPFormat.h:502
RTSPFormatADPCM()
Definition RTSPFormat.h:498
int timerPeriodUs()
Timer period in microseconds.
Definition RTSPFormat.h:509
AudioInfo defaultConfig()
Definition RTSPFormat.h:549
const char * format(char *buffer, int len) override
Definition RTSPFormat.h:516
void begin(AudioInfo info) override
Definition RTSPFormat.h:554
AudioEncoder * p_encoder
Definition RTSPFormat.h:577
AudioInfo audioInfo() override
Definition RTSPFormat.h:570
abtX format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats
Definition RTSPFormat.h:318
AudioInfo defaultConfig()
Definition RTSPFormat.h:340
const char * format(char *buffer, int len) override
Definition RTSPFormat.h:328
RTSPFormatAbtX()
Definition RTSPFormat.h:320
void begin(AudioInfo info) override
Definition RTSPFormat.h:345
G711 μ-Law format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats Packet intervall: 20,...
Definition RTSPFormat.h:398
bool is_ulaw
Definition RTSPFormat.h:431
uint8_t getFormat()
Definition RTSPFormat.h:432
void setIsULaw(bool flag)
Defines if we use ulow ar alow; by default we use ulaw!
Definition RTSPFormat.h:423
AudioInfo defaultConfig()
Definition RTSPFormat.h:425
RTSPFormatG711(bool isUlaw=true)
Definition RTSPFormat.h:400
const char * format(char *buffer, int len) override
Provides the G711 format information.
Definition RTSPFormat.h:406
GSM format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats.
Definition RTSPFormat.h:363
RTSPFormatGSM()
Definition RTSPFormat.h:365
AudioInfo defaultConfig()
Definition RTSPFormat.h:385
const char * format(char *buffer, int len) override
Provides the GSM format information.
Definition RTSPFormat.h:370
H.264 (AVC) format for RTSP video streaming, per RFC 6184.
Definition RTSPFormat.h:879
RTSPVideoInfo defaultVideoConfig() override
Definition RTSPFormat.h:931
String sprop_parameter_sets
Definition RTSPFormat.h:981
int timestampIncrement() override
Override timestamp increment for video (90kHz clock)
Definition RTSPFormat.h:938
RTSPFormatH264(int width=1280, int height=720, float framerate=15.0f)
Definition RTSPFormat.h:881
String profile_level_id
Definition RTSPFormat.h:984
int video_height
Definition RTSPFormat.h:979
int getHeight() const
Get video height.
Definition RTSPFormat.h:960
AudioInfo defaultConfig() override
Definition RTSPFormat.h:926
const char * format(char *buffer, int len) override
Definition RTSPFormat.h:892
void setSpropParameterSets(const char *base64Sps, const char *base64Pps) override
Definition RTSPFormat.h:967
int video_width
Definition RTSPFormat.h:978
MediaType mediaType() override
Override media type for video.
Definition RTSPFormat.h:890
void setVideoDimensions(int width, int height)
Set video dimensions.
Definition RTSPFormat.h:943
void setProfileLevelId(const char *hex6) override
Definition RTSPFormat.h:975
void setFramerate(float fps)
Set video framerate.
Definition RTSPFormat.h:950
float video_framerate
Definition RTSPFormat.h:980
int getWidth() const
Get video width.
Definition RTSPFormat.h:957
int rtpPayloadType() override
default dynamic
Definition RTSPFormat.h:935
float getFramerate() const
Get framerate.
Definition RTSPFormat.h:963
Audio Format Definition - Base class for RTSP audio formats.
Definition RTSPFormat.h:57
int timer_period_us
Definition RTSPFormat.h:149
AudioInfo cfg
Definition RTSPFormat.h:150
virtual const char * format(char *buffer, int len)=0
const char * STD_URL_PRE_SUFFIX
Definition RTSPFormat.h:146
virtual int timerPeriodUs()
Timer period in microseconds.
Definition RTSPFormat.h:115
virtual int readHeader(uint8_t *data)
Optional header: e.g. rfc2250.
Definition RTSPFormat.h:126
const char * name_str
Definition RTSPFormat.h:152
virtual RTSPVideoInfo videoInfo()
Definition RTSPFormat.h:84
void setTimerPeriodUs(int period)
Defines the timer period in microseconds.
Definition RTSPFormat.h:112
virtual int convert(void *data, int sampleCount)
Definition RTSPFormat.h:64
RTSPVideoInfo video_cfg
Definition RTSPFormat.h:151
virtual void begin(RTSPVideoInfo info)
Definition RTSPFormat.h:70
virtual MediaType mediaType()
Definition RTSPFormat.h:87
virtual const char * name()
Definition RTSPFormat.h:90
virtual int timestampIncrement()
Fragment size in samples (for audio) or timestamp increment (for video)
Definition RTSPFormat.h:101
virtual void begin(AudioInfo info)
Definition RTSPFormat.h:67
virtual bool useRfc2250Header() const
Definition RTSPFormat.h:130
void setFragmentSize(int fragmentSize)
Defines the fragment size in bytes.
Definition RTSPFormat.h:95
virtual void setSpropParameterSets(const char *, const char *)
Definition RTSPFormat.h:137
virtual int fragmentSize()
Fragment (=write) size in bytes.
Definition RTSPFormat.h:98
virtual int rtpPayloadType()
default dynamic
Definition RTSPFormat.h:123
void setName(const char *name)
Defines the name of the stream.
Definition RTSPFormat.h:92
virtual void setProfileLevelId(const char *)
Definition RTSPFormat.h:143
virtual AudioInfo defaultConfig()=0
virtual AudioInfo audioInfo()
Definition RTSPFormat.h:81
int fragment_size
Definition RTSPFormat.h:148
virtual void setUseRfc2250Header(bool)
Optional: Configure RFC2250 header usage (default: no-op)
Definition RTSPFormat.h:129
virtual RTSPVideoInfo defaultVideoConfig()
Definition RTSPFormat.h:76
MJPEG (Motion JPEG) format for RTSP video streaming.
Definition RTSPFormat.h:771
RTSPVideoInfo defaultVideoConfig() override
Definition RTSPFormat.h:806
RTSPFormatMJPEG(int width=640, int height=480, float framerate=30.0f)
Definition RTSPFormat.h:773
int timestampIncrement() override
Override timestamp increment for video (90kHz clock)
Definition RTSPFormat.h:813
int video_height
Definition RTSPFormat.h:850
int getHeight() const
Get video height
Definition RTSPFormat.h:836
AudioInfo defaultConfig() override
Definition RTSPFormat.h:801
const char * format(char *buffer, int len) override
Definition RTSPFormat.h:785
int video_width
Definition RTSPFormat.h:849
MediaType mediaType() override
Override media type for video.
Definition RTSPFormat.h:783
void setVideoDimensions(int width, int height)
Set video dimensions.
Definition RTSPFormat.h:819
void setFramerate(float fps)
Set video framerate.
Definition RTSPFormat.h:826
float video_framerate
Definition RTSPFormat.h:851
int getWidth() const
Get video width.
Definition RTSPFormat.h:833
int rtpPayloadType() override
default dynamic
Definition RTSPFormat.h:810
float getFramerate() const
Get framerate.
Definition RTSPFormat.h:839
MP3 format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats.
Definition RTSPFormat.h:586
bool use_rfc2250_header_
Definition RTSPFormat.h:697
RTSPFormatMP3()
Definition RTSPFormat.h:588
void setEncoder(AudioEncoder &encoder)
Definition RTSPFormat.h:600
bool useRfc2250Header() const override
Definition RTSPFormat.h:702
int timerPeriodUs()
Timer period in microseconds.
Definition RTSPFormat.h:602
int fragmentSize() override
Definition RTSPFormat.h:613
virtual int timestampIncrement()
Fragment size in samples (for audio) or timestamp increment (for video)
Definition RTSPFormat.h:621
AudioInfo audioInfo()
Provides the AudioInfo.
Definition RTSPFormat.h:628
RTSPFormatMP3(AudioEncoder &encoder)
Provide dynamic frame duration if encoder is available.
Definition RTSPFormat.h:594
AudioInfo defaultConfig()
Definition RTSPFormat.h:667
int readHeader(unsigned char *buffer) override
rfc2250 header before the playload
Definition RTSPFormat.h:683
const char * format(char *buffer, int len) override
Definition RTSPFormat.h:638
void setUseRfc2250Header(bool enable)
Optional: Configure RFC2250 header usage (default: no-op)
Definition RTSPFormat.h:701
void begin(AudioInfo info) override
Definition RTSPFormat.h:672
AudioEncoder * p_encoder
Definition RTSPFormat.h:696
int rtpPayloadType() override
default dynamic
Definition RTSPFormat.h:665
MPEG-2 Transport Stream (MP2T) format for RTSP streaming of a pre-muxed audio+video container,...
Definition RTSPFormat.h:1013
int timerPeriodUs() override
Timer period in microseconds.
Definition RTSPFormat.h:1038
RTSPFormatMTS(float framerate=25.0f)
Definition RTSPFormat.h:1018
AudioInfo defaultConfig() override
Definition RTSPFormat.h:1034
const char * format(char *buffer, int len) override
Definition RTSPFormat.h:1023
MediaType mediaType() override
Override media type for video.
Definition RTSPFormat.h:1021
void setFramerate(float fps)
Set the fragment pacing rate (see constructor note)
Definition RTSPFormat.h:1041
float video_framerate
Definition RTSPFormat.h:1044
int rtpPayloadType() override
default dynamic
Definition RTSPFormat.h:1036
Opus format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats.
Definition RTSPFormat.h:266
RTSPFormatOpus()
Definition RTSPFormat.h:268
AudioInfo defaultConfig()
Definition RTSPFormat.h:294
const char * format(char *buffer, int len) override
Definition RTSPFormat.h:282
void begin(AudioInfo info) override
Definition RTSPFormat.h:299
RTSPFormatOpus(AudioEncoder &encoder)
Determine timer duration from opus configuration.
Definition RTSPFormat.h:273
AudioEncoder * p_encoder
Definition RTSPFormat.h:309
L8 format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats.
Definition RTSPFormat.h:441
RTSPFormatPCM8()
Definition RTSPFormat.h:443
AudioInfo defaultConfig()
Definition RTSPFormat.h:458
const char * format(char *buffer, int len) override
Definition RTSPFormat.h:447
void begin(AudioInfo info) override
Definition RTSPFormat.h:463
Linear PCM Format for RTSP Streaming.
Definition RTSPFormat.h:169
int convert(void *data, int samples)
Convert to network format.
Definition RTSPFormat.h:215
RTSPFormatPCM()
Definition RTSPFormat.h:177
int sampleRate()
Definition RTSPFormat.h:239
int channels()
Definition RTSPFormat.h:240
void begin(AudioInfo info)
Definition RTSPFormat.h:184
AudioInfo defaultConfig() override
Definition RTSPFormat.h:226
int bytesPerSample()
Definition RTSPFormat.h:241
AudioInfo info()
Definition RTSPFormat.h:224
const char * format(char *buffer, int len) override
Provide format 10 or 11.
Definition RTSPFormat.h:196
int getTimerPeriod(int fragmentSize)
Get the timer period for streaming.
Definition RTSPFormat.h:247
int rtpPayloadType() override
default dynamic
Definition RTSPFormat.h:228
RTSPFormatPCM(AudioInfo info, int fragmentSize=640)
Definition RTSPFormat.h:171
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
MediaType
Media type enumeration for RTSP streams.
Definition RTSPFormat.h:24
@ MEDIA_VIDEO
Video stream.
Definition RTSPFormat.h:26
@ MEDIA_AUDIO
Audio stream.
Definition RTSPFormat.h:25
@ MJPEG
Motion JPEG format.
@ H264
H.264/AVC compressed format.
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:56
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:58
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:60
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:62
Video Information Structure.
Definition VideoInfo.h:43
uint32_t framePeriodUs() const
Calculate frame period in microseconds.
Definition VideoInfo.h:87
uint32_t timestampIncrement() const
Calculate RTP timestamp increment per frame.
Definition VideoInfo.h:82