正在显示
10 个修改的文件
包含
114 行增加
和
381 行删除
| @@ -527,6 +527,7 @@ Supported operating systems and hardware: | @@ -527,6 +527,7 @@ Supported operating systems and hardware: | ||
| 527 | 527 | ||
| 528 | ### SRS 2.0 history | 528 | ### SRS 2.0 history |
| 529 | 529 | ||
| 530 | +* v2.0, 2015-02-15, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), support config default acodec/vcodec. 2.0.118. | ||
| 530 | * v2.0, 2015-02-15, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), rewrite hls/ts code, support h.264+mp3 for hls. 2.0.117. | 531 | * v2.0, 2015-02-15, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), rewrite hls/ts code, support h.264+mp3 for hls. 2.0.117. |
| 531 | * v2.0, 2015-02-12, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), use stringstream to generate m3u8, add hls_td_ratio. 2.0.116. | 532 | * v2.0, 2015-02-12, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), use stringstream to generate m3u8, add hls_td_ratio. 2.0.116. |
| 532 | * v2.0, 2015-02-11, dev code ZhouGuowen for 2.0.115. | 533 | * v2.0, 2015-02-11, dev code ZhouGuowen for 2.0.115. |
| @@ -495,10 +495,19 @@ vhost with-hls.srs.com { | @@ -495,10 +495,19 @@ vhost with-hls.srs.com { | ||
| 495 | # the default audio codec of hls. | 495 | # the default audio codec of hls. |
| 496 | # when codec changed, write the PAT/PMT table, but maybe ok util next ts. | 496 | # when codec changed, write the PAT/PMT table, but maybe ok util next ts. |
| 497 | # so user can set the default codec for mp3. | 497 | # so user can set the default codec for mp3. |
| 498 | - # the available audio codec: aac, mp3 | 498 | + # the available audio codec: |
| 499 | + # aac, mp3 | ||
| 499 | # default: aac | 500 | # default: aac |
| 500 | # TODO: FIXME: update wiki for it. | 501 | # TODO: FIXME: update wiki for it. |
| 501 | hls_acodec aac; | 502 | hls_acodec aac; |
| 503 | + # the default video codec of hls. | ||
| 504 | + # when codec changed, write the PAT/PMT table, but maybe ok util next ts. | ||
| 505 | + # so user can set the default codec for pure audio(without video) to vn. | ||
| 506 | + # the available video codec: | ||
| 507 | + # h264, vn | ||
| 508 | + # default: h264 | ||
| 509 | + # TODO: FIXME: update wiki for it. | ||
| 510 | + hls_vcodec h264; | ||
| 502 | } | 511 | } |
| 503 | } | 512 | } |
| 504 | # the vhost with hls disabled. | 513 | # the vhost with hls disabled. |
| @@ -713,9 +722,9 @@ vhost example.transcode.srs.com { | @@ -713,9 +722,9 @@ vhost example.transcode.srs.com { | ||
| 713 | filter_complex 'overlay=10:10'; | 722 | filter_complex 'overlay=10:10'; |
| 714 | } | 723 | } |
| 715 | # video encoder name. can be: | 724 | # video encoder name. can be: |
| 716 | - # libx264: use h.264(libx264) video encoder. | ||
| 717 | - # copy: donot encoder the video stream, copy it. | ||
| 718 | - # vn: disable video output. | 725 | + # libx264: use h.264(libx264) video encoder. |
| 726 | + # copy: donot encoder the video stream, copy it. | ||
| 727 | + # vn: disable video output. | ||
| 719 | vcodec libx264; | 728 | vcodec libx264; |
| 720 | # video bitrate, in kbps | 729 | # video bitrate, in kbps |
| 721 | vbitrate 1500; | 730 | vbitrate 1500; |
| @@ -731,8 +740,8 @@ vhost example.transcode.srs.com { | @@ -731,8 +740,8 @@ vhost example.transcode.srs.com { | ||
| 731 | # high,main,baseline | 740 | # high,main,baseline |
| 732 | vprofile main; | 741 | vprofile main; |
| 733 | # x264 preset, @see x264 -help, can be: | 742 | # x264 preset, @see x264 -help, can be: |
| 734 | - # ultrafast,superfast,veryfast,faster,fast | ||
| 735 | - # medium,slow,slower,veryslow,placebo | 743 | + # ultrafast,superfast,veryfast,faster,fast |
| 744 | + # medium,slow,slower,veryslow,placebo | ||
| 736 | vpreset medium; | 745 | vpreset medium; |
| 737 | # other x264 or ffmpeg video params | 746 | # other x264 or ffmpeg video params |
| 738 | vparams { | 747 | vparams { |
| @@ -745,14 +754,15 @@ vhost example.transcode.srs.com { | @@ -745,14 +754,15 @@ vhost example.transcode.srs.com { | ||
| 745 | refs 10; | 754 | refs 10; |
| 746 | } | 755 | } |
| 747 | # audio encoder name. can be: | 756 | # audio encoder name. can be: |
| 748 | - # libaacplus: use aac(libaacplus) audio encoder. | ||
| 749 | - # copy: donot encoder the audio stream, copy it. | ||
| 750 | - # an: disable audio output. | 757 | + # libaacplus: use aac(libaacplus) audio encoder. |
| 758 | + # libfdk_aac: use aac(libfdk_aac) audio encoder. | ||
| 759 | + # copy: donot encoder the audio stream, copy it. | ||
| 760 | + # an: disable audio output. | ||
| 751 | acodec libaacplus; | 761 | acodec libaacplus; |
| 752 | # audio bitrate, in kbps. [16, 72] for libaacplus. | 762 | # audio bitrate, in kbps. [16, 72] for libaacplus. |
| 753 | abitrate 70; | 763 | abitrate 70; |
| 754 | # audio sample rate. for flv/rtmp, it must be: | 764 | # audio sample rate. for flv/rtmp, it must be: |
| 755 | - # 44100,22050,11025,5512 | 765 | + # 44100,22050,11025,5512 |
| 756 | asample_rate 44100; | 766 | asample_rate 44100; |
| 757 | # audio channel, 1 for mono, 2 for stereo. | 767 | # audio channel, 1 for mono, 2 for stereo. |
| 758 | achannels 2; | 768 | achannels 2; |
| @@ -762,17 +772,17 @@ vhost example.transcode.srs.com { | @@ -762,17 +772,17 @@ vhost example.transcode.srs.com { | ||
| 762 | profile:a aac_low; | 772 | profile:a aac_low; |
| 763 | } | 773 | } |
| 764 | # output format, can be: | 774 | # output format, can be: |
| 765 | - # off, do not specifies the format, ffmpeg will guess it. | ||
| 766 | - # flv, for flv or RTMP stream. | ||
| 767 | - # other format, for example, mp4/aac whatever. | 775 | + # off, do not specifies the format, ffmpeg will guess it. |
| 776 | + # flv, for flv or RTMP stream. | ||
| 777 | + # other format, for example, mp4/aac whatever. | ||
| 768 | # default: flv | 778 | # default: flv |
| 769 | oformat flv; | 779 | oformat flv; |
| 770 | # output stream. variables: | 780 | # output stream. variables: |
| 771 | - # [vhost] the input stream vhost. | ||
| 772 | - # [port] the intput stream port. | ||
| 773 | - # [app] the input stream app. | ||
| 774 | - # [stream] the input stream name. | ||
| 775 | - # [engine] the tanscode engine name. | 781 | + # [vhost] the input stream vhost. |
| 782 | + # [port] the intput stream port. | ||
| 783 | + # [app] the input stream app. | ||
| 784 | + # [stream] the input stream name. | ||
| 785 | + # [engine] the tanscode engine name. | ||
| 776 | output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; | 786 | output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; |
| 777 | } | 787 | } |
| 778 | } | 788 | } |
| @@ -1480,7 +1480,7 @@ int SrsConfig::check_config() | @@ -1480,7 +1480,7 @@ int SrsConfig::check_config() | ||
| 1480 | for (int j = 0; j < (int)conf->directives.size(); j++) { | 1480 | for (int j = 0; j < (int)conf->directives.size(); j++) { |
| 1481 | string m = conf->at(j)->name.c_str(); | 1481 | string m = conf->at(j)->name.c_str(); |
| 1482 | if (m != "enabled" && m != "hls_path" && m != "hls_fragment" && m != "hls_window" && m != "hls_on_error" | 1482 | if (m != "enabled" && m != "hls_path" && m != "hls_fragment" && m != "hls_window" && m != "hls_on_error" |
| 1483 | - && m != "hls_storage" && m != "hls_mount" && m != "hls_td_ratio" && m != "hls_acodec" | 1483 | + && m != "hls_storage" && m != "hls_mount" && m != "hls_td_ratio" && m != "hls_acodec" && m != "hls_vcodec" |
| 1484 | ) { | 1484 | ) { |
| 1485 | ret = ERROR_SYSTEM_CONFIG_INVALID; | 1485 | ret = ERROR_SYSTEM_CONFIG_INVALID; |
| 1486 | srs_error("unsupported vhost hls directive %s, ret=%d", m.c_str(), ret); | 1486 | srs_error("unsupported vhost hls directive %s, ret=%d", m.c_str(), ret); |
| @@ -3349,6 +3349,23 @@ string SrsConfig::get_hls_acodec(string vhost) | @@ -3349,6 +3349,23 @@ string SrsConfig::get_hls_acodec(string vhost) | ||
| 3349 | return conf->arg0(); | 3349 | return conf->arg0(); |
| 3350 | } | 3350 | } |
| 3351 | 3351 | ||
| 3352 | +string SrsConfig::get_hls_vcodec(string vhost) | ||
| 3353 | +{ | ||
| 3354 | + SrsConfDirective* hls = get_hls(vhost); | ||
| 3355 | + | ||
| 3356 | + if (!hls) { | ||
| 3357 | + return SRS_CONF_DEFAULT_HLS_VCODEC; | ||
| 3358 | + } | ||
| 3359 | + | ||
| 3360 | + SrsConfDirective* conf = hls->get("hls_vcodec"); | ||
| 3361 | + | ||
| 3362 | + if (!conf) { | ||
| 3363 | + return SRS_CONF_DEFAULT_HLS_VCODEC; | ||
| 3364 | + } | ||
| 3365 | + | ||
| 3366 | + return conf->arg0(); | ||
| 3367 | +} | ||
| 3368 | + | ||
| 3352 | SrsConfDirective* SrsConfig::get_dvr(string vhost) | 3369 | SrsConfDirective* SrsConfig::get_dvr(string vhost) |
| 3353 | { | 3370 | { |
| 3354 | SrsConfDirective* conf = get_vhost(vhost); | 3371 | SrsConfDirective* conf = get_vhost(vhost); |
| @@ -56,6 +56,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -56,6 +56,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 56 | #define SRS_CONF_DEFAULT_HLS_STORAGE "disk" | 56 | #define SRS_CONF_DEFAULT_HLS_STORAGE "disk" |
| 57 | #define SRS_CONF_DEFAULT_HLS_MOUNT "[vhost]/[app]/[stream].m3u8" | 57 | #define SRS_CONF_DEFAULT_HLS_MOUNT "[vhost]/[app]/[stream].m3u8" |
| 58 | #define SRS_CONF_DEFAULT_HLS_ACODEC "aac" | 58 | #define SRS_CONF_DEFAULT_HLS_ACODEC "aac" |
| 59 | +#define SRS_CONF_DEFAULT_HLS_VCODEC "h264" | ||
| 59 | #define SRS_CONF_DEFAULT_DVR_PATH "./objs/nginx/html" | 60 | #define SRS_CONF_DEFAULT_DVR_PATH "./objs/nginx/html" |
| 60 | #define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session" | 61 | #define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session" |
| 61 | #define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment" | 62 | #define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment" |
| @@ -927,6 +928,10 @@ public: | @@ -927,6 +928,10 @@ public: | ||
| 927 | * get the HLS default audio codec. | 928 | * get the HLS default audio codec. |
| 928 | */ | 929 | */ |
| 929 | virtual std::string get_hls_acodec(std::string vhost); | 930 | virtual std::string get_hls_acodec(std::string vhost); |
| 931 | + /** | ||
| 932 | + * get the HLS default video codec. | ||
| 933 | + */ | ||
| 934 | + virtual std::string get_hls_vcodec(std::string vhost); | ||
| 930 | // dvr section | 935 | // dvr section |
| 931 | private: | 936 | private: |
| 932 | /** | 937 | /** |
| @@ -131,14 +131,14 @@ string SrsHlsCacheWriter::cache() | @@ -131,14 +131,14 @@ string SrsHlsCacheWriter::cache() | ||
| 131 | return data; | 131 | return data; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | -SrsHlsSegment::SrsHlsSegment(bool write_cache, bool write_file, SrsCodecAudio ac) | 134 | +SrsHlsSegment::SrsHlsSegment(bool write_cache, bool write_file, SrsCodecAudio ac, SrsCodecVideo vc) |
| 135 | { | 135 | { |
| 136 | duration = 0; | 136 | duration = 0; |
| 137 | sequence_no = 0; | 137 | sequence_no = 0; |
| 138 | segment_start_dts = 0; | 138 | segment_start_dts = 0; |
| 139 | is_sequence_header = false; | 139 | is_sequence_header = false; |
| 140 | writer = new SrsHlsCacheWriter(write_cache, write_file); | 140 | writer = new SrsHlsCacheWriter(write_cache, write_file); |
| 141 | - muxer = new SrsTSMuxer(writer, ac); | 141 | + muxer = new SrsTSMuxer(writer, ac, vc); |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | SrsHlsSegment::~SrsHlsSegment() | 144 | SrsHlsSegment::~SrsHlsSegment() |
| @@ -246,19 +246,36 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) | @@ -246,19 +246,36 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) | ||
| 246 | 246 | ||
| 247 | // load the default acodec from config. | 247 | // load the default acodec from config. |
| 248 | SrsCodecAudio default_acodec = SrsCodecAudioAAC; | 248 | SrsCodecAudio default_acodec = SrsCodecAudioAAC; |
| 249 | - std::string default_acodec_str = _srs_config->get_hls_acodec(req->vhost); | ||
| 250 | - if (default_acodec_str == "mp3") { | ||
| 251 | - default_acodec = SrsCodecAudioMP3; | ||
| 252 | - srs_info("hls: use default mp3 acodec"); | ||
| 253 | - } else if (default_acodec_str == "aac") { | ||
| 254 | - default_acodec = SrsCodecAudioAAC; | ||
| 255 | - srs_info("hls: use default aac acodec"); | ||
| 256 | - } else { | ||
| 257 | - srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str()); | 249 | + if (true) { |
| 250 | + std::string default_acodec_str = _srs_config->get_hls_acodec(req->vhost); | ||
| 251 | + if (default_acodec_str == "mp3") { | ||
| 252 | + default_acodec = SrsCodecAudioMP3; | ||
| 253 | + srs_info("hls: use default mp3 acodec"); | ||
| 254 | + } else if (default_acodec_str == "aac") { | ||
| 255 | + default_acodec = SrsCodecAudioAAC; | ||
| 256 | + srs_info("hls: use default aac acodec"); | ||
| 257 | + } else { | ||
| 258 | + srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str()); | ||
| 259 | + } | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + // load the default vcodec from config. | ||
| 263 | + SrsCodecVideo default_vcodec = SrsCodecVideoAVC; | ||
| 264 | + if (true) { | ||
| 265 | + std::string default_vcodec_str = _srs_config->get_hls_vcodec(req->vhost); | ||
| 266 | + if (default_vcodec_str == "h264") { | ||
| 267 | + default_vcodec = SrsCodecVideoAVC; | ||
| 268 | + srs_info("hls: use default h264 vcodec"); | ||
| 269 | + } else if (default_vcodec_str == "vn") { | ||
| 270 | + default_vcodec = SrsCodecVideoDisabled; | ||
| 271 | + srs_info("hls: use default vn vcodec for pure audio"); | ||
| 272 | + } else { | ||
| 273 | + srs_warn("hls: use h264 for other codec=%s", default_vcodec_str.c_str()); | ||
| 274 | + } | ||
| 258 | } | 275 | } |
| 259 | 276 | ||
| 260 | // new segment. | 277 | // new segment. |
| 261 | - current = new SrsHlsSegment(should_write_cache, should_write_file, default_acodec); | 278 | + current = new SrsHlsSegment(should_write_cache, should_write_file, default_acodec, default_vcodec); |
| 262 | current->sequence_no = _sequence_no++; | 279 | current->sequence_no = _sequence_no++; |
| 263 | current->segment_start_dts = segment_start_dts; | 280 | current->segment_start_dts = segment_start_dts; |
| 264 | 281 |
| @@ -144,7 +144,7 @@ public: | @@ -144,7 +144,7 @@ public: | ||
| 144 | // whether current segement is sequence header. | 144 | // whether current segement is sequence header. |
| 145 | bool is_sequence_header; | 145 | bool is_sequence_header; |
| 146 | public: | 146 | public: |
| 147 | - SrsHlsSegment(bool write_cache, bool write_file, SrsCodecAudio ac); | 147 | + SrsHlsSegment(bool write_cache, bool write_file, SrsCodecAudio ac, SrsCodecVideo vc); |
| 148 | virtual ~SrsHlsSegment(); | 148 | virtual ~SrsHlsSegment(); |
| 149 | public: | 149 | public: |
| 150 | /** | 150 | /** |
| @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 31 | // current release version | 31 | // current release version |
| 32 | #define VERSION_MAJOR 2 | 32 | #define VERSION_MAJOR 2 |
| 33 | #define VERSION_MINOR 0 | 33 | #define VERSION_MINOR 0 |
| 34 | -#define VERSION_REVISION 117 | 34 | +#define VERSION_REVISION 118 |
| 35 | 35 | ||
| 36 | // server info. | 36 | // server info. |
| 37 | #define RTMP_SIG_SRS_KEY "SRS" | 37 | #define RTMP_SIG_SRS_KEY "SRS" |
| @@ -98,7 +98,10 @@ enum SrsCodecVideo | @@ -98,7 +98,10 @@ enum SrsCodecVideo | ||
| 98 | // set to the zero to reserved, for array map. | 98 | // set to the zero to reserved, for array map. |
| 99 | SrsCodecVideoReserved = 0, | 99 | SrsCodecVideoReserved = 0, |
| 100 | SrsCodecVideoReserved1 = 1, | 100 | SrsCodecVideoReserved1 = 1, |
| 101 | - SrsCodecVideoReserved2 = 8, | 101 | + SrsCodecVideoReserved2 = 9, |
| 102 | + | ||
| 103 | + // for user to disable video, for example, use pure audio hls. | ||
| 104 | + SrsCodecVideoDisabled = 8, | ||
| 102 | 105 | ||
| 103 | SrsCodecVideoSorensonH263 = 2, | 106 | SrsCodecVideoSorensonH263 = 2, |
| 104 | SrsCodecVideoScreenVideo = 3, | 107 | SrsCodecVideoScreenVideo = 3, |
| @@ -75,327 +75,6 @@ int aac_sample_rates[] = | @@ -75,327 +75,6 @@ int aac_sample_rates[] = | ||
| 75 | 7350, 0, 0, 0 | 75 | 7350, 0, 0, 0 |
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| 78 | -// @see: ngx_rtmp_mpegts_header | ||
| 79 | -u_int8_t mpegts_header[] = { | ||
| 80 | - /* TS */ | ||
| 81 | - 0x47, 0x40, 0x00, 0x10, 0x00, | ||
| 82 | - /* PSI */ | ||
| 83 | - 0x00, 0xb0, 0x0d, 0x00, 0x01, 0xc1, 0x00, 0x00, | ||
| 84 | - /* PAT */ | ||
| 85 | - 0x00, 0x01, 0xf0, 0x01, | ||
| 86 | - /* CRC */ | ||
| 87 | - 0x2e, 0x70, 0x19, 0x05, | ||
| 88 | - /* stuffing 167 bytes */ | ||
| 89 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 90 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 91 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 92 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 93 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 94 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 95 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 96 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 97 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 98 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 99 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 100 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 101 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 102 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 103 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 104 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 105 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 106 | - | ||
| 107 | - /* TS */ | ||
| 108 | - 0x47, 0x50, 0x01, 0x10, 0x00, | ||
| 109 | - /* PSI */ | ||
| 110 | - 0x02, 0xb0, 0x17, 0x00, 0x01, 0xc1, 0x00, 0x00, | ||
| 111 | - /* PMT */ | ||
| 112 | - 0xe1, 0x00, | ||
| 113 | - 0xf0, 0x00, | ||
| 114 | - // must generate header with/without video, @see: | ||
| 115 | - // https://github.com/winlinvip/simple-rtmp-server/issues/40 | ||
| 116 | - 0x1b, 0xe1, 0x00, 0xf0, 0x00, /* h264, pid=0x100=256 */ | ||
| 117 | -}; | ||
| 118 | -u_int8_t mpegts_header_aac[] = { | ||
| 119 | - 0x0f, 0xe1, 0x01, 0xf0, 0x00, /* aac, pid=0x101=257 */ | ||
| 120 | - /* CRC */ | ||
| 121 | - 0x2f, 0x44, 0xb9, 0x9b, /* crc for aac */ | ||
| 122 | -}; | ||
| 123 | -u_int8_t mpegts_header_mp3[] = { | ||
| 124 | - 0x03, 0xe1, 0x01, 0xf0, 0x00, /* mp3 */ | ||
| 125 | - /* CRC */ | ||
| 126 | - 0x4e, 0x59, 0x3d, 0x1e, /* crc for mp3 */ | ||
| 127 | -}; | ||
| 128 | -u_int8_t mpegts_header_padding[] = { | ||
| 129 | - /* stuffing 157 bytes */ | ||
| 130 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 131 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 132 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 133 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 134 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 135 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 136 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 137 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 138 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 139 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 140 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 141 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 142 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 143 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 144 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 145 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | ||
| 146 | -}; | ||
| 147 | - | ||
| 148 | -// @see: ngx_rtmp_mpegts.c | ||
| 149 | -// TODO: support full mpegts feature in future. | ||
| 150 | -class SrsMpegtsWriter | ||
| 151 | -{ | ||
| 152 | -public: | ||
| 153 | - static int write_header(SrsFileWriter* writer, SrsCodecAudio acodec) | ||
| 154 | - { | ||
| 155 | - int ret = ERROR_SUCCESS; | ||
| 156 | - | ||
| 157 | - if ((ret = writer->write(mpegts_header, sizeof(mpegts_header), NULL)) != ERROR_SUCCESS) { | ||
| 158 | - ret = ERROR_HLS_WRITE_FAILED; | ||
| 159 | - srs_error("write ts file header failed. ret=%d", ret); | ||
| 160 | - return ret; | ||
| 161 | - } | ||
| 162 | - | ||
| 163 | - if (acodec == SrsCodecAudioAAC) { | ||
| 164 | - if ((ret = writer->write(mpegts_header_aac, sizeof(mpegts_header_aac), NULL)) != ERROR_SUCCESS) { | ||
| 165 | - ret = ERROR_HLS_WRITE_FAILED; | ||
| 166 | - srs_error("write ts file aac header failed. ret=%d", ret); | ||
| 167 | - return ret; | ||
| 168 | - } | ||
| 169 | - } else { | ||
| 170 | - if ((ret = writer->write(mpegts_header_mp3, sizeof(mpegts_header_mp3), NULL)) != ERROR_SUCCESS) { | ||
| 171 | - ret = ERROR_HLS_WRITE_FAILED; | ||
| 172 | - srs_error("write ts file mp3 header failed. ret=%d", ret); | ||
| 173 | - return ret; | ||
| 174 | - } | ||
| 175 | - } | ||
| 176 | - | ||
| 177 | - if ((ret = writer->write(mpegts_header_padding, sizeof(mpegts_header_padding), NULL)) != ERROR_SUCCESS) { | ||
| 178 | - ret = ERROR_HLS_WRITE_FAILED; | ||
| 179 | - srs_error("write ts file padding header failed. ret=%d", ret); | ||
| 180 | - return ret; | ||
| 181 | - } | ||
| 182 | - | ||
| 183 | - return ret; | ||
| 184 | - } | ||
| 185 | - static int write_frame(SrsFileWriter* writer, SrsMpegtsFrame* frame, SrsSimpleBuffer* buffer) | ||
| 186 | - { | ||
| 187 | - int ret = ERROR_SUCCESS; | ||
| 188 | - | ||
| 189 | - if (!buffer->bytes() || buffer->length() <= 0) { | ||
| 190 | - return ret; | ||
| 191 | - } | ||
| 192 | - | ||
| 193 | - char* last = buffer->bytes() + buffer->length(); | ||
| 194 | - char* pos = buffer->bytes(); | ||
| 195 | - | ||
| 196 | - bool first = true; | ||
| 197 | - while (pos < last) { | ||
| 198 | - static char packet[188]; | ||
| 199 | - char* p = packet; | ||
| 200 | - | ||
| 201 | - frame->cc++; | ||
| 202 | - | ||
| 203 | - // sync_byte; //8bits | ||
| 204 | - *p++ = 0x47; | ||
| 205 | - // pid; //13bits | ||
| 206 | - *p++ = (frame->pid >> 8) & 0x1f; | ||
| 207 | - // payload_unit_start_indicator; //1bit | ||
| 208 | - if (first) { | ||
| 209 | - p[-1] |= 0x40; | ||
| 210 | - } | ||
| 211 | - *p++ = frame->pid; | ||
| 212 | - | ||
| 213 | - // transport_scrambling_control; //2bits | ||
| 214 | - // adaption_field_control; //2bits, 0x01: PayloadOnly | ||
| 215 | - // continuity_counter; //4bits | ||
| 216 | - *p++ = 0x10 | (frame->cc & 0x0f); | ||
| 217 | - | ||
| 218 | - if (first) { | ||
| 219 | - first = false; | ||
| 220 | - if (frame->write_pcr) { | ||
| 221 | - p[-1] |= 0x20; // Both Adaption and Payload | ||
| 222 | - *p++ = 7; // size | ||
| 223 | - *p++ = 0x50; // random access + PCR | ||
| 224 | - // @see https://github.com/winlinvip/simple-rtmp-server/issues/311 | ||
| 225 | - p = write_pcr(p, frame->dts); | ||
| 226 | - } | ||
| 227 | - | ||
| 228 | - // PES header | ||
| 229 | - // packet_start_code_prefix; //24bits, '00 00 01' | ||
| 230 | - *p++ = 0x00; | ||
| 231 | - *p++ = 0x00; | ||
| 232 | - *p++ = 0x01; | ||
| 233 | - //8bits | ||
| 234 | - *p++ = frame->sid; | ||
| 235 | - | ||
| 236 | - // pts(33bits) need 5bytes. | ||
| 237 | - u_int8_t header_size = 5; | ||
| 238 | - u_int8_t flags = 0x80; // pts | ||
| 239 | - | ||
| 240 | - // dts(33bits) need 5bytes also | ||
| 241 | - if (frame->dts != frame->pts) { | ||
| 242 | - header_size += 5; | ||
| 243 | - flags |= 0x40; // dts | ||
| 244 | - } | ||
| 245 | - | ||
| 246 | - // 3bytes: flag fields from PES_packet_length to PES_header_data_length | ||
| 247 | - int pes_size = (last - pos) + header_size + 3; | ||
| 248 | - if (pes_size > 0xffff) { | ||
| 249 | - /** | ||
| 250 | - * when actual packet length > 0xffff(65535), | ||
| 251 | - * which exceed the max u_int16_t packet length, | ||
| 252 | - * use 0 packet length, the next unit start indicates the end of packet. | ||
| 253 | - */ | ||
| 254 | - pes_size = 0; | ||
| 255 | - } | ||
| 256 | - | ||
| 257 | - // PES_packet_length; //16bits | ||
| 258 | - *p++ = (pes_size >> 8); | ||
| 259 | - *p++ = pes_size; | ||
| 260 | - | ||
| 261 | - // PES_scrambling_control; //2bits, '10' | ||
| 262 | - // PES_priority; //1bit | ||
| 263 | - // data_alignment_indicator; //1bit | ||
| 264 | - // copyright; //1bit | ||
| 265 | - // original_or_copy; //1bit | ||
| 266 | - *p++ = 0x80; /* H222 */ | ||
| 267 | - | ||
| 268 | - // PTS_DTS_flags; //2bits | ||
| 269 | - // ESCR_flag; //1bit | ||
| 270 | - // ES_rate_flag; //1bit | ||
| 271 | - // DSM_trick_mode_flag; //1bit | ||
| 272 | - // additional_copy_info_flag; //1bit | ||
| 273 | - // PES_CRC_flag; //1bit | ||
| 274 | - // PES_extension_flag; //1bit | ||
| 275 | - *p++ = flags; | ||
| 276 | - | ||
| 277 | - // PES_header_data_length; //8bits | ||
| 278 | - *p++ = header_size; | ||
| 279 | - | ||
| 280 | - // pts; // 33bits | ||
| 281 | - p = write_dts_pts(p, flags >> 6, frame->pts); | ||
| 282 | - | ||
| 283 | - // dts; // 33bits | ||
| 284 | - if (frame->dts != frame->pts) { | ||
| 285 | - p = write_dts_pts(p, 1, frame->dts); | ||
| 286 | - } | ||
| 287 | - } | ||
| 288 | - | ||
| 289 | - int body_size = sizeof(packet) - (p - packet); | ||
| 290 | - int in_size = last - pos; | ||
| 291 | - | ||
| 292 | - if (body_size <= in_size) { | ||
| 293 | - memcpy(p, pos, body_size); | ||
| 294 | - pos += body_size; | ||
| 295 | - } else { | ||
| 296 | - p = fill_stuff(p, packet, body_size, in_size); | ||
| 297 | - memcpy(p, pos, in_size); | ||
| 298 | - pos = last; | ||
| 299 | - } | ||
| 300 | - | ||
| 301 | - // write ts packet | ||
| 302 | - if ((ret = writer->write(packet, sizeof(packet), NULL)) != ERROR_SUCCESS) { | ||
| 303 | - if (!srs_is_client_gracefully_close(ret)) { | ||
| 304 | - srs_error("write ts file failed. ret=%d", ret); | ||
| 305 | - } | ||
| 306 | - return ret; | ||
| 307 | - } | ||
| 308 | - } | ||
| 309 | - | ||
| 310 | - return ret; | ||
| 311 | - } | ||
| 312 | -private: | ||
| 313 | - static char* fill_stuff(char* pes_body_end, char* packet, int body_size, int in_size) | ||
| 314 | - { | ||
| 315 | - char* p = pes_body_end; | ||
| 316 | - | ||
| 317 | - // insert the stuff bytes before PES body | ||
| 318 | - int stuff_size = (body_size - in_size); | ||
| 319 | - | ||
| 320 | - // adaption_field_control; //2bits | ||
| 321 | - if (packet[3] & 0x20) { | ||
| 322 | - // has adaptation | ||
| 323 | - // packet[4]: adaption_field_length | ||
| 324 | - // packet[5]: adaption field data | ||
| 325 | - // base: start of PES body | ||
| 326 | - char* base = &packet[5] + packet[4]; | ||
| 327 | - int len = p - base; | ||
| 328 | - p = (char*)memmove(base + stuff_size, base, len) + len; | ||
| 329 | - // increase the adaption field size. | ||
| 330 | - packet[4] += stuff_size; | ||
| 331 | - | ||
| 332 | - return p; | ||
| 333 | - } | ||
| 334 | - | ||
| 335 | - // create adaption field. | ||
| 336 | - // adaption_field_control; //2bits | ||
| 337 | - packet[3] |= 0x20; | ||
| 338 | - // base: start of PES body | ||
| 339 | - char* base = &packet[4]; | ||
| 340 | - int len = p - base; | ||
| 341 | - p = (char*)memmove(base + stuff_size, base, len) + len; | ||
| 342 | - // adaption_field_length; //8bits | ||
| 343 | - packet[4] = (stuff_size - 1); | ||
| 344 | - if (stuff_size >= 2) { | ||
| 345 | - // adaption field flags. | ||
| 346 | - packet[5] = 0; | ||
| 347 | - // adaption data. | ||
| 348 | - if (stuff_size > 2) { | ||
| 349 | - memset(&packet[6], 0xff, stuff_size - 2); | ||
| 350 | - } | ||
| 351 | - } | ||
| 352 | - | ||
| 353 | - return p; | ||
| 354 | - } | ||
| 355 | - static char* write_pcr(char* p, int64_t pcr) | ||
| 356 | - { | ||
| 357 | - // the pcr=dts-delay, where dts = frame->dts + delay | ||
| 358 | - // and the pcr should never be negative | ||
| 359 | - // @see https://github.com/winlinvip/simple-rtmp-server/issues/268 | ||
| 360 | - srs_assert(pcr >= 0); | ||
| 361 | - | ||
| 362 | - int64_t v = pcr; | ||
| 363 | - | ||
| 364 | - *p++ = (char) (v >> 25); | ||
| 365 | - *p++ = (char) (v >> 17); | ||
| 366 | - *p++ = (char) (v >> 9); | ||
| 367 | - *p++ = (char) (v >> 1); | ||
| 368 | - *p++ = (char) (v << 7 | 0x7e); | ||
| 369 | - *p++ = 0; | ||
| 370 | - | ||
| 371 | - return p; | ||
| 372 | - } | ||
| 373 | - static char* write_dts_pts(char* p, u_int8_t fb, int64_t pts) | ||
| 374 | - { | ||
| 375 | - int32_t val; | ||
| 376 | - | ||
| 377 | - val = fb << 4 | (((pts >> 30) & 0x07) << 1) | 1; | ||
| 378 | - *p++ = val; | ||
| 379 | - | ||
| 380 | - val = (((pts >> 15) & 0x7fff) << 1) | 1; | ||
| 381 | - *p++ = (val >> 8); | ||
| 382 | - *p++ = val; | ||
| 383 | - | ||
| 384 | - val = (((pts) & 0x7fff) << 1) | 1; | ||
| 385 | - *p++ = (val >> 8); | ||
| 386 | - *p++ = val; | ||
| 387 | - | ||
| 388 | - return p; | ||
| 389 | - } | ||
| 390 | -}; | ||
| 391 | - | ||
| 392 | -SrsMpegtsFrame::SrsMpegtsFrame() | ||
| 393 | -{ | ||
| 394 | - pts = dts = 0; | ||
| 395 | - pid = sid = cc = 0; | ||
| 396 | - write_pcr = false; | ||
| 397 | -} | ||
| 398 | - | ||
| 399 | string srs_ts_stream2string(SrsTsStream stream) | 78 | string srs_ts_stream2string(SrsTsStream stream) |
| 400 | { | 79 | { |
| 401 | switch (stream) { | 80 | switch (stream) { |
| @@ -600,6 +279,7 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo | @@ -600,6 +279,7 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo | ||
| 600 | case SrsCodecVideoReserved: | 279 | case SrsCodecVideoReserved: |
| 601 | case SrsCodecVideoReserved1: | 280 | case SrsCodecVideoReserved1: |
| 602 | case SrsCodecVideoReserved2: | 281 | case SrsCodecVideoReserved2: |
| 282 | + case SrsCodecVideoDisabled: | ||
| 603 | case SrsCodecVideoSorensonH263: | 283 | case SrsCodecVideoSorensonH263: |
| 604 | case SrsCodecVideoScreenVideo: | 284 | case SrsCodecVideoScreenVideo: |
| 605 | case SrsCodecVideoOn2VP6: | 285 | case SrsCodecVideoOn2VP6: |
| @@ -645,9 +325,9 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo | @@ -645,9 +325,9 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo | ||
| 645 | 325 | ||
| 646 | // encode the media frame to PES packets over TS. | 326 | // encode the media frame to PES packets over TS. |
| 647 | if (msg->is_audio()) { | 327 | if (msg->is_audio()) { |
| 648 | - return encode_pes(writer, msg, audio_pid, as); | 328 | + return encode_pes(writer, msg, audio_pid, as, vs == SrsTsStreamReserved); |
| 649 | } else { | 329 | } else { |
| 650 | - return encode_pes(writer, msg, video_pid, vs); | 330 | + return encode_pes(writer, msg, video_pid, vs, vs == SrsTsStreamReserved); |
| 651 | } | 331 | } |
| 652 | } | 332 | } |
| 653 | 333 | ||
| @@ -711,7 +391,7 @@ int SrsTsContext::encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStrea | @@ -711,7 +391,7 @@ int SrsTsContext::encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStrea | ||
| 711 | return ret; | 391 | return ret; |
| 712 | } | 392 | } |
| 713 | 393 | ||
| 714 | -int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid) | 394 | +int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio) |
| 715 | { | 395 | { |
| 716 | int ret = ERROR_SUCCESS; | 396 | int ret = ERROR_SUCCESS; |
| 717 | 397 | ||
| @@ -719,6 +399,11 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p | @@ -719,6 +399,11 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p | ||
| 719 | return ret; | 399 | return ret; |
| 720 | } | 400 | } |
| 721 | 401 | ||
| 402 | + if (sid != SrsTsStreamVideoH264 && sid != SrsTsStreamAudioMp3 && sid != SrsTsStreamAudioAAC) { | ||
| 403 | + srs_info("ts: ignore the unknown stream, sid=%d", sid); | ||
| 404 | + return ret; | ||
| 405 | + } | ||
| 406 | + | ||
| 722 | SrsTsChannel* channel = get(pid); | 407 | SrsTsChannel* channel = get(pid); |
| 723 | srs_assert(channel); | 408 | srs_assert(channel); |
| 724 | 409 | ||
| @@ -729,9 +414,15 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p | @@ -729,9 +414,15 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p | ||
| 729 | while (p < end) { | 414 | while (p < end) { |
| 730 | SrsTsPacket* pkt = NULL; | 415 | SrsTsPacket* pkt = NULL; |
| 731 | if (p == start) { | 416 | if (p == start) { |
| 417 | + // for pure audio stream, always write pcr. | ||
| 418 | + bool write_pcr = msg->write_pcr; | ||
| 419 | + if (pure_audio && msg->is_audio()) { | ||
| 420 | + write_pcr = true; | ||
| 421 | + } | ||
| 422 | + | ||
| 732 | pkt = SrsTsPacket::create_pes_first(this, | 423 | pkt = SrsTsPacket::create_pes_first(this, |
| 733 | pid, msg->sid, channel->continuity_counter++, msg->discontinuity, | 424 | pid, msg->sid, channel->continuity_counter++, msg->discontinuity, |
| 734 | - msg->write_pcr? msg->dts:-1, msg->dts, msg->pts, msg->payload->length() | 425 | + write_pcr? msg->dts:-1, msg->dts, msg->pts, msg->payload->length() |
| 735 | ); | 426 | ); |
| 736 | } else { | 427 | } else { |
| 737 | pkt = SrsTsPacket::create_pes_continue(this, | 428 | pkt = SrsTsPacket::create_pes_continue(this, |
| @@ -1030,9 +721,13 @@ SrsTsPacket* SrsTsPacket::create_pmt(SrsTsContext* context, int16_t pmt_number, | @@ -1030,9 +721,13 @@ SrsTsPacket* SrsTsPacket::create_pmt(SrsTsContext* context, int16_t pmt_number, | ||
| 1030 | pmt->current_next_indicator = 1; | 721 | pmt->current_next_indicator = 1; |
| 1031 | pmt->section_number = 0; | 722 | pmt->section_number = 0; |
| 1032 | pmt->last_section_number = 0; | 723 | pmt->last_section_number = 0; |
| 1033 | - pmt->PCR_PID = vpid; | ||
| 1034 | pmt->program_info_length = 0; | 724 | pmt->program_info_length = 0; |
| 1035 | - pmt->infos.push_back(new SrsTsPayloadPMTESInfo(vs, vpid)); | 725 | + if (vs == SrsTsStreamVideoH264) { |
| 726 | + pmt->PCR_PID = vpid; | ||
| 727 | + pmt->infos.push_back(new SrsTsPayloadPMTESInfo(vs, vpid)); | ||
| 728 | + } else { | ||
| 729 | + pmt->PCR_PID = apid; | ||
| 730 | + } | ||
| 1036 | pmt->infos.push_back(new SrsTsPayloadPMTESInfo(as, apid)); | 731 | pmt->infos.push_back(new SrsTsPayloadPMTESInfo(as, apid)); |
| 1037 | pmt->CRC_32 = 0; // calc in encode. | 732 | pmt->CRC_32 = 0; // calc in encode. |
| 1038 | return pkt; | 733 | return pkt; |
| @@ -2916,14 +2611,13 @@ int SrsTsPayloadPMT::psi_encode(SrsStream* stream) | @@ -2916,14 +2611,13 @@ int SrsTsPayloadPMT::psi_encode(SrsStream* stream) | ||
| 2916 | return ret; | 2611 | return ret; |
| 2917 | } | 2612 | } |
| 2918 | 2613 | ||
| 2919 | -SrsTSMuxer::SrsTSMuxer(SrsFileWriter* w, SrsCodecAudio ac) | 2614 | +SrsTSMuxer::SrsTSMuxer(SrsFileWriter* w, SrsCodecAudio ac, SrsCodecVideo vc) |
| 2920 | { | 2615 | { |
| 2921 | writer = w; | 2616 | writer = w; |
| 2922 | context = NULL; | 2617 | context = NULL; |
| 2923 | 2618 | ||
| 2924 | acodec = ac; | 2619 | acodec = ac; |
| 2925 | - // default to avc(h.264) | ||
| 2926 | - vcodec = SrsCodecVideoAVC; | 2620 | + vcodec = vc; |
| 2927 | } | 2621 | } |
| 2928 | 2622 | ||
| 2929 | SrsTSMuxer::~SrsTSMuxer() | 2623 | SrsTSMuxer::~SrsTSMuxer() |
| @@ -3295,7 +2989,7 @@ int SrsTsEncoder::initialize(SrsFileWriter* fs) | @@ -3295,7 +2989,7 @@ int SrsTsEncoder::initialize(SrsFileWriter* fs) | ||
| 3295 | _fs = fs; | 2989 | _fs = fs; |
| 3296 | 2990 | ||
| 3297 | srs_freep(muxer); | 2991 | srs_freep(muxer); |
| 3298 | - muxer = new SrsTSMuxer(fs, SrsCodecAudioAAC); | 2992 | + muxer = new SrsTSMuxer(fs, SrsCodecAudioAAC, SrsCodecVideoAVC); |
| 3299 | 2993 | ||
| 3300 | if ((ret = muxer->open("")) != ERROR_SUCCESS) { | 2994 | if ((ret = muxer->open("")) != ERROR_SUCCESS) { |
| 3301 | return ret; | 2995 | return ret; |
| @@ -51,20 +51,6 @@ class SrsTsPacket; | @@ -51,20 +51,6 @@ class SrsTsPacket; | ||
| 51 | // Transport Stream packets are 188 bytes in length. | 51 | // Transport Stream packets are 188 bytes in length. |
| 52 | #define SRS_TS_PACKET_SIZE 188 | 52 | #define SRS_TS_PACKET_SIZE 188 |
| 53 | 53 | ||
| 54 | -// @see: ngx_rtmp_SrsMpegtsFrame_t | ||
| 55 | -class SrsMpegtsFrame | ||
| 56 | -{ | ||
| 57 | -public: | ||
| 58 | - int64_t pts; | ||
| 59 | - int64_t dts; | ||
| 60 | - int pid; | ||
| 61 | - int sid; | ||
| 62 | - int cc; // continuity_counter | ||
| 63 | - bool write_pcr; | ||
| 64 | - | ||
| 65 | - SrsMpegtsFrame(); | ||
| 66 | -}; | ||
| 67 | - | ||
| 68 | /** | 54 | /** |
| 69 | * the pid of ts packet, | 55 | * the pid of ts packet, |
| 70 | * Table 2-3 - PID table, hls-mpeg-ts-iso13818-1.pdf, page 37 | 56 | * Table 2-3 - PID table, hls-mpeg-ts-iso13818-1.pdf, page 37 |
| @@ -387,7 +373,7 @@ public: | @@ -387,7 +373,7 @@ public: | ||
| 387 | virtual int encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo vc, SrsCodecAudio ac); | 373 | virtual int encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo vc, SrsCodecAudio ac); |
| 388 | private: | 374 | private: |
| 389 | virtual int encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as); | 375 | virtual int encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as); |
| 390 | - virtual int encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid); | 376 | + virtual int encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio); |
| 391 | }; | 377 | }; |
| 392 | 378 | ||
| 393 | /** | 379 | /** |
| @@ -1547,7 +1533,7 @@ private: | @@ -1547,7 +1533,7 @@ private: | ||
| 1547 | SrsFileWriter* writer; | 1533 | SrsFileWriter* writer; |
| 1548 | std::string path; | 1534 | std::string path; |
| 1549 | public: | 1535 | public: |
| 1550 | - SrsTSMuxer(SrsFileWriter* w, SrsCodecAudio ac); | 1536 | + SrsTSMuxer(SrsFileWriter* w, SrsCodecAudio ac, SrsCodecVideo vc); |
| 1551 | virtual ~SrsTSMuxer(); | 1537 | virtual ~SrsTSMuxer(); |
| 1552 | public: | 1538 | public: |
| 1553 | /** | 1539 | /** |
-
请 注册 或 登录 后发表评论