正在显示
5 个修改的文件
包含
143 行增加
和
19 行删除
| @@ -585,6 +585,7 @@ public: | @@ -585,6 +585,7 @@ public: | ||
| 585 | 585 | ||
| 586 | int64_t pts; // 33bits | 586 | int64_t pts; // 33bits |
| 587 | int64_t dts; // 33bits | 587 | int64_t dts; // 33bits |
| 588 | + int64_t pcr; | ||
| 588 | 589 | ||
| 589 | // header size. | 590 | // header size. |
| 590 | int packet_header_size; | 591 | int packet_header_size; |
| @@ -596,6 +597,10 @@ public: | @@ -596,6 +597,10 @@ public: | ||
| 596 | int packet_data_size; | 597 | int packet_data_size; |
| 597 | char* packet_data; | 598 | char* packet_data; |
| 598 | 599 | ||
| 600 | + // for avc. | ||
| 601 | + u_int8_t nal_ref_idc; | ||
| 602 | + u_int8_t nal_unit_type; | ||
| 603 | + | ||
| 599 | TSMessage(); | 604 | TSMessage(); |
| 600 | virtual ~TSMessage(); | 605 | virtual ~TSMessage(); |
| 601 | 606 | ||
| @@ -709,12 +714,15 @@ TSMessage::TSMessage() | @@ -709,12 +714,15 @@ TSMessage::TSMessage() | ||
| 709 | stream_type = TSStreamTypeReserved; | 714 | stream_type = TSStreamTypeReserved; |
| 710 | stream_id = 0; | 715 | stream_id = 0; |
| 711 | packet_start_code_prefix = 0; | 716 | packet_start_code_prefix = 0; |
| 712 | - pts = dts = 0; | 717 | + pts = dts = pcr = 0; |
| 713 | PES_packet_length = 0; | 718 | PES_packet_length = 0; |
| 714 | packet_header_size = 0; | 719 | packet_header_size = 0; |
| 715 | parsed_packet_size = 0; | 720 | parsed_packet_size = 0; |
| 716 | packet_data_size = 0; | 721 | packet_data_size = 0; |
| 717 | packet_data = NULL; | 722 | packet_data = NULL; |
| 723 | + | ||
| 724 | + nal_ref_idc = 0; | ||
| 725 | + nal_unit_type = 0; | ||
| 718 | } | 726 | } |
| 719 | 727 | ||
| 720 | TSMessage::~TSMessage() | 728 | TSMessage::~TSMessage() |
| @@ -1596,6 +1604,10 @@ int TSPayload::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* l | @@ -1596,6 +1604,10 @@ int TSPayload::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* l | ||
| 1596 | } | 1604 | } |
| 1597 | if (pid && (pid->type == TSPidTypeVideo || pid->type == TSPidTypeAudio)) { | 1605 | if (pid && (pid->type == TSPidTypeVideo || pid->type == TSPidTypeAudio)) { |
| 1598 | TSMessage* msg = ctx->get_msg(pkt->header->pid); | 1606 | TSMessage* msg = ctx->get_msg(pkt->header->pid); |
| 1607 | + | ||
| 1608 | + if (pkt->adaption_field->pcr > 0) { | ||
| 1609 | + msg->pcr = pkt->adaption_field->pcr; | ||
| 1610 | + } | ||
| 1599 | 1611 | ||
| 1600 | // flush previous PES_packet_length(0) packets. | 1612 | // flush previous PES_packet_length(0) packets. |
| 1601 | if (msg->packet_start_code_prefix == 0x01 | 1613 | if (msg->packet_start_code_prefix == 0x01 |
| @@ -2135,6 +2147,10 @@ int consume(TSMessage* msg, AacMuxer* aac_muxer) | @@ -2135,6 +2147,10 @@ int consume(TSMessage* msg, AacMuxer* aac_muxer) | ||
| 2135 | int8_t nal_unit_type = *pp++; | 2147 | int8_t nal_unit_type = *pp++; |
| 2136 | int8_t nal_ref_idc = (nal_unit_type >> 5) & 0x03; | 2148 | int8_t nal_ref_idc = (nal_unit_type >> 5) & 0x03; |
| 2137 | nal_unit_type &= 0x1f; | 2149 | nal_unit_type &= 0x1f; |
| 2150 | + | ||
| 2151 | + msg->nal_ref_idc = nal_ref_idc; | ||
| 2152 | + msg->nal_unit_type = nal_unit_type; | ||
| 2153 | + | ||
| 2138 | if (nal_ref_idc != 0) { | 2154 | if (nal_ref_idc != 0) { |
| 2139 | trace("ts+h264 got an SPS or PPS."); | 2155 | trace("ts+h264 got an SPS or PPS."); |
| 2140 | } | 2156 | } |
| @@ -2235,6 +2251,18 @@ int main(int argc, char** argv) | @@ -2235,6 +2251,18 @@ int main(int argc, char** argv) | ||
| 2235 | return -1; | 2251 | return -1; |
| 2236 | } | 2252 | } |
| 2237 | 2253 | ||
| 2254 | + int64_t pts = msg->pts; | ||
| 2255 | + int64_t dts = (msg->dts == 0)? msg->pts : msg->dts; | ||
| 2256 | + int64_t pcr = msg->pcr; | ||
| 2257 | + static int64_t last_pcr_dts = 0; | ||
| 2258 | + trace("demuxer+report id=%d, type=%s, size=%d, dts=%d, pts=%d, cts=%d, pcr=%d, dts-pcr=%d, ref=%d, unit=%d, dts(diff-pcr)=%d", | ||
| 2259 | + ctx.ts_packet_count, (msg->type == TSPidTypeVideo)? "video":"audio", | ||
| 2260 | + msg->parsed_packet_size, dts, pts, pts - dts, pcr, pcr? dts - pcr : 0, | ||
| 2261 | + msg->nal_ref_idc, msg->nal_unit_type, pcr? dts - last_pcr_dts: 0); | ||
| 2262 | + if (pcr > 0) { | ||
| 2263 | + last_pcr_dts = dts; | ||
| 2264 | + } | ||
| 2265 | + | ||
| 2238 | srs_freep(msg); | 2266 | srs_freep(msg); |
| 2239 | } | 2267 | } |
| 2240 | } | 2268 | } |
| @@ -115,6 +115,10 @@ SrsCodec::SrsCodec() | @@ -115,6 +115,10 @@ SrsCodec::SrsCodec() | ||
| 115 | avc_extra_data = NULL; | 115 | avc_extra_data = NULL; |
| 116 | aac_extra_size = 0; | 116 | aac_extra_size = 0; |
| 117 | aac_extra_data = NULL; | 117 | aac_extra_data = NULL; |
| 118 | + sequenceParameterSetLength = 0; | ||
| 119 | + sequenceParameterSetNALUnit = NULL; | ||
| 120 | + pictureParameterSetLength = 0; | ||
| 121 | + pictureParameterSetNALUnit = NULL; | ||
| 118 | 122 | ||
| 119 | stream = new SrsStream(); | 123 | stream = new SrsStream(); |
| 120 | } | 124 | } |
| @@ -125,6 +129,8 @@ SrsCodec::~SrsCodec() | @@ -125,6 +129,8 @@ SrsCodec::~SrsCodec() | ||
| 125 | srs_freepa(aac_extra_data); | 129 | srs_freepa(aac_extra_data); |
| 126 | 130 | ||
| 127 | srs_freep(stream); | 131 | srs_freep(stream); |
| 132 | + srs_freepa(sequenceParameterSetNALUnit); | ||
| 133 | + srs_freepa(pictureParameterSetNALUnit); | ||
| 128 | } | 134 | } |
| 129 | 135 | ||
| 130 | int SrsCodec::audio_aac_demux(int8_t* data, int size, SrsCodecSample* sample) | 136 | int SrsCodec::audio_aac_demux(int8_t* data, int size, SrsCodecSample* sample) |
| @@ -315,16 +321,67 @@ int SrsCodec::video_avc_demux(int8_t* data, int size, SrsCodecSample* sample) | @@ -315,16 +321,67 @@ int SrsCodec::video_avc_demux(int8_t* data, int size, SrsCodecSample* sample) | ||
| 315 | int8_t lengthSizeMinusOne = stream->read_1bytes(); | 321 | int8_t lengthSizeMinusOne = stream->read_1bytes(); |
| 316 | lengthSizeMinusOne &= 0x03; | 322 | lengthSizeMinusOne &= 0x03; |
| 317 | NAL_unit_length = lengthSizeMinusOne; | 323 | NAL_unit_length = lengthSizeMinusOne; |
| 318 | - /** | ||
| 319 | - * skip the following: | ||
| 320 | - * numOfSequenceParameterSets | ||
| 321 | - * donot parse the following: | ||
| 322 | - * sequenceParameterSetLength | ||
| 323 | - * sequenceParameterSetNALUnit | ||
| 324 | - * numOfPictureParameterSets | ||
| 325 | - * pictureParameterSetLength | ||
| 326 | - * pictureParameterSetNALUnit | ||
| 327 | - */ | 324 | + |
| 325 | + // 1 sps | ||
| 326 | + if (!stream->require(1)) { | ||
| 327 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 328 | + srs_error("hls decode video avc sequenc header sps failed. ret=%d", ret); | ||
| 329 | + return ret; | ||
| 330 | + } | ||
| 331 | + int8_t numOfSequenceParameterSets = stream->read_1bytes(); | ||
| 332 | + numOfSequenceParameterSets &= 0x1f; | ||
| 333 | + if (numOfSequenceParameterSets != 1) { | ||
| 334 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 335 | + srs_error("hls decode video avc sequenc header sps failed. ret=%d", ret); | ||
| 336 | + return ret; | ||
| 337 | + } | ||
| 338 | + if (!stream->require(2)) { | ||
| 339 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 340 | + srs_error("hls decode video avc sequenc header sps size failed. ret=%d", ret); | ||
| 341 | + return ret; | ||
| 342 | + } | ||
| 343 | + sequenceParameterSetLength = stream->read_2bytes(); | ||
| 344 | + if (!stream->require(sequenceParameterSetLength)) { | ||
| 345 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 346 | + srs_error("hls decode video avc sequenc header sps data failed. ret=%d", ret); | ||
| 347 | + return ret; | ||
| 348 | + } | ||
| 349 | + if (sequenceParameterSetLength > 0) { | ||
| 350 | + srs_freepa(sequenceParameterSetNALUnit); | ||
| 351 | + sequenceParameterSetNALUnit = new char[sequenceParameterSetLength]; | ||
| 352 | + memcpy(sequenceParameterSetNALUnit, stream->current(), sequenceParameterSetLength); | ||
| 353 | + stream->skip(sequenceParameterSetLength); | ||
| 354 | + } | ||
| 355 | + // 1 pps | ||
| 356 | + if (!stream->require(1)) { | ||
| 357 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 358 | + srs_error("hls decode video avc sequenc header pps failed. ret=%d", ret); | ||
| 359 | + return ret; | ||
| 360 | + } | ||
| 361 | + int8_t numOfPictureParameterSets = stream->read_1bytes(); | ||
| 362 | + numOfPictureParameterSets &= 0x1f; | ||
| 363 | + if (numOfPictureParameterSets != 1) { | ||
| 364 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 365 | + srs_error("hls decode video avc sequenc header pps failed. ret=%d", ret); | ||
| 366 | + return ret; | ||
| 367 | + } | ||
| 368 | + if (!stream->require(2)) { | ||
| 369 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 370 | + srs_error("hls decode video avc sequenc header pps size failed. ret=%d", ret); | ||
| 371 | + return ret; | ||
| 372 | + } | ||
| 373 | + pictureParameterSetLength = stream->read_2bytes(); | ||
| 374 | + if (!stream->require(pictureParameterSetLength)) { | ||
| 375 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 376 | + srs_error("hls decode video avc sequenc header pps data failed. ret=%d", ret); | ||
| 377 | + return ret; | ||
| 378 | + } | ||
| 379 | + if (pictureParameterSetLength > 0) { | ||
| 380 | + srs_freepa(pictureParameterSetNALUnit); | ||
| 381 | + pictureParameterSetNALUnit = new char[pictureParameterSetLength]; | ||
| 382 | + memcpy(pictureParameterSetNALUnit, stream->current(), pictureParameterSetLength); | ||
| 383 | + stream->skip(pictureParameterSetLength); | ||
| 384 | + } | ||
| 328 | } else if (avc_packet_type == SrsCodecVideoAVCTypeNALU){ | 385 | } else if (avc_packet_type == SrsCodecVideoAVCTypeNALU){ |
| 329 | // ensure the sequence header demuxed | 386 | // ensure the sequence header demuxed |
| 330 | if (avc_extra_size <= 0 || !avc_extra_data) { | 387 | if (avc_extra_size <= 0 || !avc_extra_data) { |
| @@ -250,6 +250,10 @@ public: | @@ -250,6 +250,10 @@ public: | ||
| 250 | int duration; | 250 | int duration; |
| 251 | // lengthSizeMinusOne, H.264-AVC-ISO_IEC_14496-15.pdf, page 16 | 251 | // lengthSizeMinusOne, H.264-AVC-ISO_IEC_14496-15.pdf, page 16 |
| 252 | int8_t NAL_unit_length; | 252 | int8_t NAL_unit_length; |
| 253 | + u_int16_t sequenceParameterSetLength; | ||
| 254 | + char* sequenceParameterSetNALUnit; | ||
| 255 | + u_int16_t pictureParameterSetLength; | ||
| 256 | + char* pictureParameterSetNALUnit; | ||
| 253 | /** | 257 | /** |
| 254 | * audio specified | 258 | * audio specified |
| 255 | */ | 259 | */ |
| @@ -512,8 +512,13 @@ SrsTSMuxer::SrsTSMuxer() | @@ -512,8 +512,13 @@ SrsTSMuxer::SrsTSMuxer() | ||
| 512 | { | 512 | { |
| 513 | fd = -1; | 513 | fd = -1; |
| 514 | 514 | ||
| 515 | + // ffmpeg set the start time to the delay time. | ||
| 516 | + base_dts = SRS_HLS_DELAY; | ||
| 517 | + | ||
| 515 | audio_buffer = new SrsCodecBuffer(); | 518 | audio_buffer = new SrsCodecBuffer(); |
| 516 | video_buffer = new SrsCodecBuffer(); | 519 | video_buffer = new SrsCodecBuffer(); |
| 520 | + | ||
| 521 | + got_iframe = false; | ||
| 517 | } | 522 | } |
| 518 | 523 | ||
| 519 | SrsTSMuxer::~SrsTSMuxer() | 524 | SrsTSMuxer::~SrsTSMuxer() |
| @@ -555,7 +560,7 @@ int SrsTSMuxer::write_audio(u_int32_t time, SrsCodec* codec, SrsCodecSample* sam | @@ -555,7 +560,7 @@ int SrsTSMuxer::write_audio(u_int32_t time, SrsCodec* codec, SrsCodecSample* sam | ||
| 555 | { | 560 | { |
| 556 | int ret = ERROR_SUCCESS; | 561 | int ret = ERROR_SUCCESS; |
| 557 | 562 | ||
| 558 | - audio_frame.dts = audio_frame.pts = time * 90; | 563 | + audio_frame.dts = audio_frame.pts = base_dts + time * 90; |
| 559 | audio_frame.pid = TS_AUDIO_PID; | 564 | audio_frame.pid = TS_AUDIO_PID; |
| 560 | audio_frame.sid = TS_AUDIO_AAC; | 565 | audio_frame.sid = TS_AUDIO_AAC; |
| 561 | 566 | ||
| @@ -626,12 +631,19 @@ int SrsTSMuxer::write_video(u_int32_t time, SrsCodec* codec, SrsCodecSample* sam | @@ -626,12 +631,19 @@ int SrsTSMuxer::write_video(u_int32_t time, SrsCodec* codec, SrsCodecSample* sam | ||
| 626 | { | 631 | { |
| 627 | int ret = ERROR_SUCCESS; | 632 | int ret = ERROR_SUCCESS; |
| 628 | 633 | ||
| 629 | - video_frame.dts = time * 90; | 634 | + video_frame.dts = base_dts + time * 90; |
| 630 | video_frame.pts = video_frame.dts + sample->cts * 90; | 635 | video_frame.pts = video_frame.dts + sample->cts * 90; |
| 631 | video_frame.pid = TS_VIDEO_PID; | 636 | video_frame.pid = TS_VIDEO_PID; |
| 632 | video_frame.sid = TS_VIDEO_AVC; | 637 | video_frame.sid = TS_VIDEO_AVC; |
| 633 | video_frame.key = sample->frame_type == SrsCodecVideoAVCFrameKeyFrame; | 638 | video_frame.key = sample->frame_type == SrsCodecVideoAVCFrameKeyFrame; |
| 634 | 639 | ||
| 640 | + if (video_frame.key) { | ||
| 641 | + got_iframe = true; | ||
| 642 | + } | ||
| 643 | + if (!got_iframe) { | ||
| 644 | + return ret; | ||
| 645 | + } | ||
| 646 | + | ||
| 635 | static u_int8_t aud_nal[] = { 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0 }; | 647 | static u_int8_t aud_nal[] = { 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0 }; |
| 636 | video_buffer->append(aud_nal, sizeof(aud_nal)); | 648 | video_buffer->append(aud_nal, sizeof(aud_nal)); |
| 637 | 649 | ||
| @@ -646,12 +658,33 @@ int SrsTSMuxer::write_video(u_int32_t time, SrsCodec* codec, SrsCodecSample* sam | @@ -646,12 +658,33 @@ int SrsTSMuxer::write_video(u_int32_t time, SrsCodec* codec, SrsCodecSample* sam | ||
| 646 | return ret; | 658 | return ret; |
| 647 | } | 659 | } |
| 648 | 660 | ||
| 649 | - if (false && video_frame.key && !sps_pps_sent) { | ||
| 650 | - // sample start prefix | ||
| 651 | - video_buffer->append(aud_nal, 4); | ||
| 652 | - // sps and pps | ||
| 653 | - // TODO: do in right way. | ||
| 654 | - video_buffer->append(codec->avc_extra_data, codec->avc_extra_size); | 661 | + // 5bits, 7.3.1 NAL unit syntax, |
| 662 | + // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. | ||
| 663 | + u_int8_t nal_unit_type; | ||
| 664 | + nal_unit_type = *buf->bytes; | ||
| 665 | + nal_unit_type &= 0x1f; | ||
| 666 | + | ||
| 667 | + // Table 7-1 – NAL unit type codes, page 61 | ||
| 668 | + // 1: Coded slice | ||
| 669 | + if (nal_unit_type == 1) { | ||
| 670 | + sps_pps_sent = false; | ||
| 671 | + } | ||
| 672 | + // 5: Coded slice of an IDR picture | ||
| 673 | + if (nal_unit_type == 5 && !sps_pps_sent) { | ||
| 674 | + // ngx_rtmp_hls_append_sps_pps | ||
| 675 | + if (codec->sequenceParameterSetLength > 0) { | ||
| 676 | + // AnnexB prefix | ||
| 677 | + video_buffer->append(aud_nal, 4); | ||
| 678 | + // sps | ||
| 679 | + video_buffer->append(codec->sequenceParameterSetNALUnit, codec->sequenceParameterSetLength); | ||
| 680 | + } | ||
| 681 | + if (codec->pictureParameterSetLength > 0) { | ||
| 682 | + // AnnexB prefix | ||
| 683 | + video_buffer->append(aud_nal, 4); | ||
| 684 | + // pps | ||
| 685 | + video_buffer->append(codec->pictureParameterSetNALUnit, codec->pictureParameterSetLength); | ||
| 686 | + } | ||
| 687 | + | ||
| 655 | } | 688 | } |
| 656 | 689 | ||
| 657 | // sample start prefix, '00 00 00 01' or '00 00 01' | 690 | // sample start prefix, '00 00 00 01' or '00 00 01' |
| @@ -81,6 +81,8 @@ private: | @@ -81,6 +81,8 @@ private: | ||
| 81 | int fd; | 81 | int fd; |
| 82 | std::string path; | 82 | std::string path; |
| 83 | private: | 83 | private: |
| 84 | + bool got_iframe; | ||
| 85 | + int64_t base_dts; | ||
| 84 | mpegts_frame audio_frame; | 86 | mpegts_frame audio_frame; |
| 85 | SrsCodecBuffer* audio_buffer; | 87 | SrsCodecBuffer* audio_buffer; |
| 86 | mpegts_frame video_frame; | 88 | mpegts_frame video_frame; |
-
请 注册 或 登录 后发表评论