From 3e8cb3f9d52bf23d0f589ed899694048679fbb94 Mon Sep 17 00:00:00 2001 From: Winlin Date: Mon, 1 Sep 2025 18:06:24 -0400 Subject: [PATCH] AI: Replace SrsSharedPtrMessage with SrsMediaPacket for unified media packet handling. v7.0.74 (#4465) This PR introduces a major refactoring to replace `SrsSharedPtrMessage` with `SrsMediaPacket` throughout the SRS codebase, providing a more unified and cleaner approach to media packet handling. --------- Co-authored-by: OSSRS-AI --- trunk/configure | 2 +- trunk/doc/CHANGELOG.md | 1 + trunk/src/app/srs_app_caster_flv.cpp | 8 +- trunk/src/app/srs_app_dash.cpp | 12 +- trunk/src/app/srs_app_dash.hpp | 14 +- trunk/src/app/srs_app_dvr.cpp | 42 +- trunk/src/app/srs_app_dvr.hpp | 46 +- trunk/src/app/srs_app_edge.cpp | 20 +- trunk/src/app/srs_app_edge.hpp | 8 +- trunk/src/app/srs_app_forward.cpp | 12 +- trunk/src/app/srs_app_forward.hpp | 12 +- trunk/src/app/srs_app_gb28181.cpp | 22 +- trunk/src/app/srs_app_gb28181.hpp | 8 +- trunk/src/app/srs_app_hds.cpp | 36 +- trunk/src/app/srs_app_hds.hpp | 10 +- trunk/src/app/srs_app_hls.cpp | 34 +- trunk/src/app/srs_app_hls.hpp | 30 +- trunk/src/app/srs_app_http_conn.hpp | 2 +- trunk/src/app/srs_app_http_stream.cpp | 12 +- trunk/src/app/srs_app_http_stream.hpp | 4 +- trunk/src/app/srs_app_mpegts_udp.cpp | 23 +- trunk/src/app/srs_app_mpegts_udp.hpp | 8 +- trunk/src/app/srs_app_rtc_codec.cpp | 14 +- trunk/src/app/srs_app_rtc_codec.hpp | 9 +- trunk/src/app/srs_app_rtc_conn.hpp | 2 +- trunk/src/app/srs_app_rtc_source.cpp | 100 +- trunk/src/app/srs_app_rtc_source.hpp | 28 +- trunk/src/app/srs_app_rtmp_conn.cpp | 14 +- trunk/src/app/srs_app_rtmp_conn.hpp | 4 +- trunk/src/app/srs_app_rtsp_source.cpp | 24 +- trunk/src/app/srs_app_rtsp_source.hpp | 18 +- trunk/src/app/srs_app_source.cpp | 140 +- trunk/src/app/srs_app_source.hpp | 72 +- trunk/src/app/srs_app_srt_source.cpp | 42 +- trunk/src/app/srs_app_srt_source.hpp | 6 +- trunk/src/app/srs_app_stream_bridge.cpp | 8 +- trunk/src/app/srs_app_stream_bridge.hpp | 12 +- trunk/src/core/srs_core_version7.hpp | 2 +- trunk/src/kernel/srs_kernel_codec.cpp | 2373 +--------------- trunk/src/kernel/srs_kernel_codec.hpp | 206 +- trunk/src/kernel/srs_kernel_flv.cpp | 178 +- trunk/src/kernel/srs_kernel_flv.hpp | 100 +- trunk/src/kernel/srs_kernel_kbps.cpp | 2 + trunk/src/kernel/srs_kernel_kbps.hpp | 2 + trunk/src/kernel/srs_kernel_mp4.cpp | 1 + trunk/src/kernel/srs_kernel_packet.cpp | 2451 +++++++++++++++++ trunk/src/kernel/srs_kernel_packet.hpp | 260 ++ trunk/src/kernel/srs_kernel_rtc_rtp.cpp | 82 +- trunk/src/kernel/srs_kernel_rtc_rtp.hpp | 27 +- trunk/src/kernel/srs_kernel_ts.cpp | 20 +- trunk/src/kernel/srs_kernel_ts.hpp | 13 +- trunk/src/protocol/srs_protocol_format.cpp | 8 +- trunk/src/protocol/srs_protocol_format.hpp | 7 +- trunk/src/protocol/srs_protocol_raw_avc.cpp | 1 + trunk/src/protocol/srs_protocol_rtmp_conn.cpp | 6 +- trunk/src/protocol/srs_protocol_rtmp_conn.hpp | 10 +- .../protocol/srs_protocol_rtmp_msg_array.cpp | 4 +- .../protocol/srs_protocol_rtmp_msg_array.hpp | 4 +- .../src/protocol/srs_protocol_rtmp_stack.cpp | 225 +- .../src/protocol/srs_protocol_rtmp_stack.hpp | 124 +- trunk/src/protocol/srs_protocol_rtp.cpp | 12 +- trunk/src/protocol/srs_protocol_rtp.hpp | 12 +- .../src/protocol/srs_protocol_rtsp_stack.hpp | 2 +- trunk/src/protocol/srs_protocol_utility.cpp | 24 +- trunk/src/protocol/srs_protocol_utility.hpp | 3 +- trunk/src/utest/srs_utest_fmp4.cpp | 64 +- trunk/src/utest/srs_utest_kernel.cpp | 308 ++- trunk/src/utest/srs_utest_protocol.cpp | 88 +- trunk/src/utest/srs_utest_protocol2.cpp | 2 - trunk/src/utest/srs_utest_rtc.cpp | 24 +- trunk/src/utest/srs_utest_rtc2.cpp | 2 +- trunk/src/utest/srs_utest_rtmp.cpp | 185 +- 72 files changed, 3749 insertions(+), 3942 deletions(-) create mode 100644 trunk/src/kernel/srs_kernel_packet.cpp create mode 100644 trunk/src/kernel/srs_kernel_packet.hpp diff --git a/trunk/configure b/trunk/configure index ddfe19b7b..f9c1b42b4 100755 --- a/trunk/configure +++ b/trunk/configure @@ -251,7 +251,7 @@ MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_buffer" "srs_kernel_utility" "srs_kernel_flv" "srs_kernel_codec" "srs_kernel_io" "srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3" "srs_kernel_ts" "srs_kernel_ps" "srs_kernel_stream" "srs_kernel_balance" "srs_kernel_mp4" "srs_kernel_file" - "srs_kernel_kbps" "srs_kernel_rtc_rtp" "srs_kernel_rtc_rtcp") + "srs_kernel_kbps" "srs_kernel_rtc_rtp" "srs_kernel_rtc_rtcp" "srs_kernel_packet") KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . $SRS_WORKDIR/auto/modules.sh KERNEL_OBJS="${MODULE_OBJS[@]}" # diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 20551f544..f0d1e5324 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,6 +7,7 @@ The changelog for SRS. ## SRS 7.0 Changelog +* v7.0, 2025-09-01, Merge [#4465](https://github.com/ossrs/srs/pull/4465): AI: Replace SrsSharedPtrMessage with SrsMediaPacket for unified media packet handling. v7.0.74 (#4465) * v7.0, 2025-09-01, Merge [#4464](https://github.com/ossrs/srs/pull/4464): AI: Use shared ptr in RTMP message. v7.0.73 (#4464) * v7.0, 2025-09-01, Merge [#4463](https://github.com/ossrs/srs/pull/4463): AI: Use SrsHttpUri for URL parsing and add legacy RTMP URL conversion. v7.0.72 (#4463) * v7.0, 2025-09-01, Merge [#4462](https://github.com/ossrs/srs/pull/4462): HTTP: Rename HTTP hijack to dynamic match for better clarity. v7.0.71 (#4462) diff --git a/trunk/src/app/srs_app_caster_flv.cpp b/trunk/src/app/srs_app_caster_flv.cpp index e479e5735..1b7d5b5fe 100644 --- a/trunk/src/app/srs_app_caster_flv.cpp +++ b/trunk/src/app/srs_app_caster_flv.cpp @@ -279,11 +279,15 @@ srs_error_t SrsDynamicHttpConn::do_proxy(ISrsHttpResponseReader *rr, SrsFlvDecod return srs_error_wrap(err, "read tag data"); } - SrsSharedPtrMessage *msg = NULL; - if ((err = srs_rtmp_create_msg(type, time, data, size, sdk->sid(), &msg)) != srs_success) { + SrsCommonMessage *cmsg = NULL; + if ((err = srs_rtmp_create_msg(type, time, data, size, sdk->sid(), &cmsg)) != srs_success) { return srs_error_wrap(err, "create message"); } + SrsMediaPacket *msg = new SrsMediaPacket(); + cmsg->to_msg(msg); + srs_freep(cmsg); + // TODO: FIXME: for post flv, reconnect when error. if ((err = sdk->send_and_free_message(msg)) != srs_success) { return srs_error_wrap(err, "send message"); diff --git a/trunk/src/app/srs_app_dash.cpp b/trunk/src/app/srs_app_dash.cpp index 1aaab172f..3cec13ada 100644 --- a/trunk/src/app/srs_app_dash.cpp +++ b/trunk/src/app/srs_app_dash.cpp @@ -112,7 +112,7 @@ srs_error_t SrsFragmentedMp4::initialize(ISrsRequest *r, bool video, int64_t tim return err; } -srs_error_t SrsFragmentedMp4::write(SrsSharedPtrMessage *shared_msg, SrsFormat *format) +srs_error_t SrsFragmentedMp4::write(SrsMediaPacket *shared_msg, SrsFormat *format) { srs_error_t err = srs_success; @@ -480,7 +480,7 @@ void SrsDashController::on_unpublish() } } -srs_error_t SrsDashController::on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format) +srs_error_t SrsDashController::on_audio(SrsMediaPacket *shared_audio, SrsFormat *format) { srs_error_t err = srs_success; @@ -552,7 +552,7 @@ srs_error_t SrsDashController::on_audio(SrsSharedPtrMessage *shared_audio, SrsFo return err; } -srs_error_t SrsDashController::on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format) +srs_error_t SrsDashController::on_video(SrsMediaPacket *shared_video, SrsFormat *format) { srs_error_t err = srs_success; @@ -641,7 +641,7 @@ srs_error_t SrsDashController::refresh_mpd(SrsFormat *format) return err; } -srs_error_t SrsDashController::refresh_init_mp4(SrsSharedPtrMessage *msg, SrsFormat *format) +srs_error_t SrsDashController::refresh_init_mp4(SrsMediaPacket *msg, SrsFormat *format) { srs_error_t err = srs_success; @@ -796,7 +796,7 @@ srs_error_t SrsDash::on_publish() return err; } -srs_error_t SrsDash::on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format) +srs_error_t SrsDash::on_audio(SrsMediaPacket *shared_audio, SrsFormat *format) { srs_error_t err = srs_success; @@ -818,7 +818,7 @@ srs_error_t SrsDash::on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *form return err; } -srs_error_t SrsDash::on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format) +srs_error_t SrsDash::on_video(SrsMediaPacket *shared_video, SrsFormat *format) { srs_error_t err = srs_success; diff --git a/trunk/src/app/srs_app_dash.hpp b/trunk/src/app/srs_app_dash.hpp index 4bcdecfe9..8b6e570b1 100644 --- a/trunk/src/app/srs_app_dash.hpp +++ b/trunk/src/app/srs_app_dash.hpp @@ -16,7 +16,7 @@ class ISrsRequest; class SrsOriginHub; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsFormat; class SrsFileWriter; class SrsMpdWriter; @@ -54,7 +54,7 @@ public: // Initialize the fragment, create the home dir, open the file. virtual srs_error_t initialize(ISrsRequest *r, bool video, int64_t time, SrsMpdWriter *mpd, uint32_t tid); // Write media message to fragment. - virtual srs_error_t write(SrsSharedPtrMessage *shared_msg, SrsFormat *format); + virtual srs_error_t write(SrsMediaPacket *shared_msg, SrsFormat *format); // Reap the fragment, close the fd and rename tmp to official file. virtual srs_error_t reap(uint64_t &dts); }; @@ -154,12 +154,12 @@ public: virtual srs_error_t initialize(ISrsRequest *r); virtual srs_error_t on_publish(); virtual void on_unpublish(); - virtual srs_error_t on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format); - virtual srs_error_t on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format); + virtual srs_error_t on_audio(SrsMediaPacket *shared_audio, SrsFormat *format); + virtual srs_error_t on_video(SrsMediaPacket *shared_video, SrsFormat *format); private: virtual srs_error_t refresh_mpd(SrsFormat *format); - virtual srs_error_t refresh_init_mp4(SrsSharedPtrMessage *msg, SrsFormat *format); + virtual srs_error_t refresh_init_mp4(SrsMediaPacket *msg, SrsFormat *format); }; // The MPEG-DASH encoder, transmux RTMP to DASH. @@ -190,9 +190,9 @@ public: // When stream start publishing. virtual srs_error_t on_publish(); // When got an shared audio message. - virtual srs_error_t on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format); + virtual srs_error_t on_audio(SrsMediaPacket *shared_audio, SrsFormat *format); // When got an shared video message. - virtual srs_error_t on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format); + virtual srs_error_t on_video(SrsMediaPacket *shared_video, SrsFormat *format); // When stream stop publishing. virtual void on_unpublish(); }; diff --git a/trunk/src/app/srs_app_dvr.cpp b/trunk/src/app/srs_app_dvr.cpp index db5b994b5..c0f36c5b3 100644 --- a/trunk/src/app/srs_app_dvr.cpp +++ b/trunk/src/app/srs_app_dvr.cpp @@ -117,17 +117,17 @@ srs_error_t SrsDvrSegmenter::open() return err; } -srs_error_t SrsDvrSegmenter::write_metadata(SrsSharedPtrMessage *metadata) +srs_error_t SrsDvrSegmenter::write_metadata(SrsMediaPacket *metadata) { return encode_metadata(metadata); } -srs_error_t SrsDvrSegmenter::write_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format) +srs_error_t SrsDvrSegmenter::write_audio(SrsMediaPacket *shared_audio, SrsFormat *format) { srs_error_t err = srs_success; // TODO: FIXME: Use SrsSharedPtr instead. - SrsUniquePtr audio(shared_audio->copy()); + SrsUniquePtr audio(shared_audio->copy()); if ((err = jitter->correct(audio.get(), jitter_algorithm)) != srs_success) { return srs_error_wrap(err, "jitter"); @@ -144,12 +144,12 @@ srs_error_t SrsDvrSegmenter::write_audio(SrsSharedPtrMessage *shared_audio, SrsF return err; } -srs_error_t SrsDvrSegmenter::write_video(SrsSharedPtrMessage *shared_video, SrsFormat *format) +srs_error_t SrsDvrSegmenter::write_video(SrsMediaPacket *shared_video, SrsFormat *format) { srs_error_t err = srs_success; // TODO: FIXME: Use SrsSharedPtr instead. - SrsUniquePtr video(shared_video->copy()); + SrsUniquePtr video(shared_video->copy()); if ((err = jitter->correct(video.get(), jitter_algorithm)) != srs_success) { return srs_error_wrap(err, "jitter"); @@ -215,7 +215,7 @@ string SrsDvrSegmenter::generate_path() return flv_path; } -srs_error_t SrsDvrSegmenter::on_update_duration(SrsSharedPtrMessage *msg) +srs_error_t SrsDvrSegmenter::on_update_duration(SrsMediaPacket *msg) { fragment->append(msg->timestamp); return srs_success; @@ -310,7 +310,7 @@ srs_error_t SrsDvrFlvSegmenter::open_encoder() return err; } -srs_error_t SrsDvrFlvSegmenter::encode_metadata(SrsSharedPtrMessage *metadata) +srs_error_t SrsDvrFlvSegmenter::encode_metadata(SrsMediaPacket *metadata) { srs_error_t err = srs_success; @@ -366,7 +366,7 @@ srs_error_t SrsDvrFlvSegmenter::encode_metadata(SrsSharedPtrMessage *metadata) return err; } -srs_error_t SrsDvrFlvSegmenter::encode_audio(SrsSharedPtrMessage *audio, SrsFormat *format) +srs_error_t SrsDvrFlvSegmenter::encode_audio(SrsMediaPacket *audio, SrsFormat *format) { srs_error_t err = srs_success; @@ -379,7 +379,7 @@ srs_error_t SrsDvrFlvSegmenter::encode_audio(SrsSharedPtrMessage *audio, SrsForm return err; } -srs_error_t SrsDvrFlvSegmenter::encode_video(SrsSharedPtrMessage *video, SrsFormat *format) +srs_error_t SrsDvrFlvSegmenter::encode_video(SrsMediaPacket *video, SrsFormat *format) { srs_error_t err = srs_success; @@ -439,12 +439,12 @@ srs_error_t SrsDvrMp4Segmenter::open_encoder() return err; } -srs_error_t SrsDvrMp4Segmenter::encode_metadata(SrsSharedPtrMessage * /*metadata*/) +srs_error_t SrsDvrMp4Segmenter::encode_metadata(SrsMediaPacket * /*metadata*/) { return srs_success; } -srs_error_t SrsDvrMp4Segmenter::encode_audio(SrsSharedPtrMessage *audio, SrsFormat *format) +srs_error_t SrsDvrMp4Segmenter::encode_audio(SrsMediaPacket *audio, SrsFormat *format) { srs_error_t err = srs_success; @@ -472,7 +472,7 @@ srs_error_t SrsDvrMp4Segmenter::encode_audio(SrsSharedPtrMessage *audio, SrsForm return err; } -srs_error_t SrsDvrMp4Segmenter::encode_video(SrsSharedPtrMessage *video, SrsFormat *format) +srs_error_t SrsDvrMp4Segmenter::encode_video(SrsMediaPacket *video, SrsFormat *format) { srs_error_t err = srs_success; @@ -607,7 +607,7 @@ void SrsDvrPlan::on_unpublish() { } -srs_error_t SrsDvrPlan::on_meta_data(SrsSharedPtrMessage *shared_metadata) +srs_error_t SrsDvrPlan::on_meta_data(SrsMediaPacket *shared_metadata) { srs_error_t err = srs_success; @@ -618,7 +618,7 @@ srs_error_t SrsDvrPlan::on_meta_data(SrsSharedPtrMessage *shared_metadata) return segment->write_metadata(shared_metadata); } -srs_error_t SrsDvrPlan::on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format) +srs_error_t SrsDvrPlan::on_audio(SrsMediaPacket *shared_audio, SrsFormat *format) { srs_error_t err = srs_success; @@ -633,7 +633,7 @@ srs_error_t SrsDvrPlan::on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *f return err; } -srs_error_t SrsDvrPlan::on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format) +srs_error_t SrsDvrPlan::on_video(SrsMediaPacket *shared_video, SrsFormat *format) { srs_error_t err = srs_success; @@ -816,7 +816,7 @@ void SrsDvrSegmentPlan::on_unpublish() SrsDvrPlan::on_unpublish(); } -srs_error_t SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format) +srs_error_t SrsDvrSegmentPlan::on_audio(SrsMediaPacket *shared_audio, SrsFormat *format) { srs_error_t err = srs_success; @@ -831,7 +831,7 @@ srs_error_t SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage *shared_audio, SrsFo return err; } -srs_error_t SrsDvrSegmentPlan::on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format) +srs_error_t SrsDvrSegmentPlan::on_video(SrsMediaPacket *shared_video, SrsFormat *format) { srs_error_t err = srs_success; @@ -846,7 +846,7 @@ srs_error_t SrsDvrSegmentPlan::on_video(SrsSharedPtrMessage *shared_video, SrsFo return err; } -srs_error_t SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage *msg) +srs_error_t SrsDvrSegmentPlan::update_duration(SrsMediaPacket *msg) { srs_error_t err = srs_success; @@ -981,7 +981,7 @@ void SrsDvr::on_unpublish() plan->on_unpublish(); } -srs_error_t SrsDvr::on_meta_data(SrsSharedPtrMessage *metadata) +srs_error_t SrsDvr::on_meta_data(SrsMediaPacket *metadata) { srs_error_t err = srs_success; @@ -997,7 +997,7 @@ srs_error_t SrsDvr::on_meta_data(SrsSharedPtrMessage *metadata) return err; } -srs_error_t SrsDvr::on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format) +srs_error_t SrsDvr::on_audio(SrsMediaPacket *shared_audio, SrsFormat *format) { // the dvr for this stream is not actived. if (!actived) { @@ -1007,7 +1007,7 @@ srs_error_t SrsDvr::on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *forma return plan->on_audio(shared_audio, format); } -srs_error_t SrsDvr::on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format) +srs_error_t SrsDvr::on_video(SrsMediaPacket *shared_video, SrsFormat *format) { // the dvr for this stream is not actived. if (!actived) { diff --git a/trunk/src/app/srs_app_dvr.hpp b/trunk/src/app/srs_app_dvr.hpp index 60982b503..8df9cdbb0 100644 --- a/trunk/src/app/srs_app_dvr.hpp +++ b/trunk/src/app/srs_app_dvr.hpp @@ -17,7 +17,7 @@ class SrsOriginHub; class ISrsRequest; class SrsBuffer; class SrsRtmpJitter; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsFileWriter; class SrsFlvTransmuxer; class SrsDvrPlan; @@ -65,13 +65,13 @@ public: // @remark Ignore when file is already open. virtual srs_error_t open(); // Write the metadata. - virtual srs_error_t write_metadata(SrsSharedPtrMessage *metadata); + virtual srs_error_t write_metadata(SrsMediaPacket *metadata); // Write audio packet. // @param shared_audio, directly ptr, copy it if need to save it. - virtual srs_error_t write_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format); + virtual srs_error_t write_audio(SrsMediaPacket *shared_audio, SrsFormat *format); // Write video packet. // @param shared_video, directly ptr, copy it if need to save it. - virtual srs_error_t write_video(SrsSharedPtrMessage *shared_video, SrsFormat *format); + virtual srs_error_t write_video(SrsMediaPacket *shared_video, SrsFormat *format); // Refresh the metadata. For example, there is duration in flv metadata, // when DVR in append mode, the duration must be update every some seconds. // @remark Maybe ignored by concreate segmenter. @@ -82,16 +82,16 @@ public: protected: virtual srs_error_t open_encoder() = 0; - virtual srs_error_t encode_metadata(SrsSharedPtrMessage *metadata) = 0; - virtual srs_error_t encode_audio(SrsSharedPtrMessage *audio, SrsFormat *format) = 0; - virtual srs_error_t encode_video(SrsSharedPtrMessage *video, SrsFormat *format) = 0; + virtual srs_error_t encode_metadata(SrsMediaPacket *metadata) = 0; + virtual srs_error_t encode_audio(SrsMediaPacket *audio, SrsFormat *format) = 0; + virtual srs_error_t encode_video(SrsMediaPacket *video, SrsFormat *format) = 0; virtual srs_error_t close_encoder() = 0; private: // Generate the flv segment path. virtual std::string generate_path(); // When update the duration of segment by rtmp msg. - virtual srs_error_t on_update_duration(SrsSharedPtrMessage *msg); + virtual srs_error_t on_update_duration(SrsMediaPacket *msg); }; // The FLV segmenter to use FLV encoder to write file. @@ -120,9 +120,9 @@ public: protected: virtual srs_error_t open_encoder(); - virtual srs_error_t encode_metadata(SrsSharedPtrMessage *metadata); - virtual srs_error_t encode_audio(SrsSharedPtrMessage *audio, SrsFormat *format); - virtual srs_error_t encode_video(SrsSharedPtrMessage *video, SrsFormat *format); + virtual srs_error_t encode_metadata(SrsMediaPacket *metadata); + virtual srs_error_t encode_audio(SrsMediaPacket *audio, SrsFormat *format); + virtual srs_error_t encode_video(SrsMediaPacket *video, SrsFormat *format); virtual srs_error_t close_encoder(); }; @@ -142,9 +142,9 @@ public: protected: virtual srs_error_t open_encoder(); - virtual srs_error_t encode_metadata(SrsSharedPtrMessage *metadata); - virtual srs_error_t encode_audio(SrsSharedPtrMessage *audio, SrsFormat *format); - virtual srs_error_t encode_video(SrsSharedPtrMessage *video, SrsFormat *format); + virtual srs_error_t encode_metadata(SrsMediaPacket *metadata); + virtual srs_error_t encode_audio(SrsMediaPacket *audio, SrsFormat *format); + virtual srs_error_t encode_video(SrsMediaPacket *video, SrsFormat *format); virtual srs_error_t close_encoder(); }; @@ -184,9 +184,9 @@ public: virtual srs_error_t initialize(SrsOriginHub *h, SrsDvrSegmenter *s, ISrsRequest *r); virtual srs_error_t on_publish(ISrsRequest *r); virtual void on_unpublish(); - virtual srs_error_t on_meta_data(SrsSharedPtrMessage *shared_metadata); - virtual srs_error_t on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format); - virtual srs_error_t on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format); + virtual srs_error_t on_meta_data(SrsMediaPacket *shared_metadata); + virtual srs_error_t on_audio(SrsMediaPacket *shared_audio, SrsFormat *format); + virtual srs_error_t on_video(SrsMediaPacket *shared_video, SrsFormat *format); // Internal interface for segmenter. public: // When segmenter close a segment. @@ -226,11 +226,11 @@ public: virtual srs_error_t initialize(SrsOriginHub *h, SrsDvrSegmenter *s, ISrsRequest *r); virtual srs_error_t on_publish(ISrsRequest *r); virtual void on_unpublish(); - virtual srs_error_t on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format); - virtual srs_error_t on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format); + virtual srs_error_t on_audio(SrsMediaPacket *shared_audio, SrsFormat *format); + virtual srs_error_t on_video(SrsMediaPacket *shared_video, SrsFormat *format); private: - virtual srs_error_t update_duration(SrsSharedPtrMessage *msg); + virtual srs_error_t update_duration(SrsMediaPacket *msg); }; // DVR(Digital Video Recorder) to record RTMP stream to flv/mp4 file. @@ -264,13 +264,13 @@ public: // when encoder stop(unpublish) to publish RTMP stream. virtual void on_unpublish(); // get some information from metadata, it's optinal. - virtual srs_error_t on_meta_data(SrsSharedPtrMessage *metadata); + virtual srs_error_t on_meta_data(SrsMediaPacket *metadata); // mux the audio packets to dvr. // @param shared_audio, directly ptr, copy it if need to save it. - virtual srs_error_t on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *foramt); + virtual srs_error_t on_audio(SrsMediaPacket *shared_audio, SrsFormat *foramt); // mux the video packets to dvr. // @param shared_video, directly ptr, copy it if need to save it. - virtual srs_error_t on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format); + virtual srs_error_t on_video(SrsMediaPacket *shared_video, SrsFormat *format); }; extern SrsAsyncCallWorker *_srs_dvr_async; diff --git a/trunk/src/app/srs_app_edge.cpp b/trunk/src/app/srs_app_edge.cpp index b17585eab..a426bb8ff 100644 --- a/trunk/src/app/srs_app_edge.cpp +++ b/trunk/src/app/srs_app_edge.cpp @@ -130,7 +130,7 @@ srs_error_t SrsEdgeRtmpUpstream::recv_message(SrsCommonMessage **pmsg) return sdk->recv_message(pmsg); } -srs_error_t SrsEdgeRtmpUpstream::decode_message(SrsCommonMessage *msg, SrsPacket **ppacket) +srs_error_t SrsEdgeRtmpUpstream::decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket) { return sdk->decode_message(msg, ppacket); } @@ -333,11 +333,11 @@ srs_error_t SrsEdgeFlvUpstream::recv_message(SrsCommonMessage **pmsg) return err; } -srs_error_t SrsEdgeFlvUpstream::decode_message(SrsCommonMessage *msg, SrsPacket **ppacket) +srs_error_t SrsEdgeFlvUpstream::decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket) { srs_error_t err = srs_success; - SrsPacket *packet = NULL; + SrsRtmpCommand *packet = NULL; SrsBuffer stream(msg->payload(), msg->size()); SrsMessageHeader &header = msg->header; @@ -647,11 +647,11 @@ srs_error_t SrsEdgeIngester::process_publish_message(SrsCommonMessage *msg, stri // process onMetaData if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) { - SrsPacket *pkt_raw = NULL; + SrsRtmpCommand *pkt_raw = NULL; if ((err = upstream->decode_message(msg, &pkt_raw)) != srs_success) { return srs_error_wrap(err, "decode message"); } - SrsUniquePtr pkt(pkt_raw); + SrsUniquePtr pkt(pkt_raw); if (dynamic_cast(pkt.get())) { SrsOnMetaDataPacket *metadata = dynamic_cast(pkt.get()); @@ -666,11 +666,11 @@ srs_error_t SrsEdgeIngester::process_publish_message(SrsCommonMessage *msg, stri // call messages, for example, reject, redirect. if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) { - SrsPacket *pkt_raw = NULL; + SrsRtmpCommand *pkt_raw = NULL; if ((err = upstream->decode_message(msg, &pkt_raw)) != srs_success) { return srs_error_wrap(err, "decode message"); } - SrsUniquePtr pkt(pkt_raw); + SrsUniquePtr pkt(pkt_raw); // RTMP 302 redirect if (dynamic_cast(pkt.get())) { @@ -928,10 +928,8 @@ srs_error_t SrsEdgeForwarder::proxy(SrsCommonMessage *msg) return err; } - SrsSharedPtrMessage copy; - if ((err = copy.create(msg)) != srs_success) { - return srs_error_wrap(err, "create message"); - } + SrsMediaPacket copy; + msg->to_msg(©); copy.stream_id = sdk->sid(); if ((err = queue->enqueue(copy.copy())) != srs_success) { diff --git a/trunk/src/app/srs_app_edge.hpp b/trunk/src/app/srs_app_edge.hpp index e823aa654..4ed00b719 100644 --- a/trunk/src/app/srs_app_edge.hpp +++ b/trunk/src/app/srs_app_edge.hpp @@ -28,7 +28,7 @@ class SrsKbps; class SrsLbRoundRobin; class SrsTcpClient; class SrsSimpleRtmpClient; -class SrsPacket; +class SrsRtmpCommand; class SrsHttpClient; class ISrsHttpMessage; class SrsHttpFileReader; @@ -66,7 +66,7 @@ public: public: virtual srs_error_t connect(ISrsRequest *r, SrsLbRoundRobin *lb) = 0; virtual srs_error_t recv_message(SrsCommonMessage **pmsg) = 0; - virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsPacket **ppacket) = 0; + virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket) = 0; virtual void close() = 0; public: @@ -96,7 +96,7 @@ public: public: virtual srs_error_t connect(ISrsRequest *r, SrsLbRoundRobin *lb); virtual srs_error_t recv_message(SrsCommonMessage **pmsg); - virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsPacket **ppacket); + virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket); virtual void close(); public: @@ -135,7 +135,7 @@ private: public: virtual srs_error_t recv_message(SrsCommonMessage **pmsg); - virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsPacket **ppacket); + virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket); virtual void close(); public: diff --git a/trunk/src/app/srs_app_forward.cpp b/trunk/src/app/srs_app_forward.cpp index 6e50df3aa..e9d9d664d 100644 --- a/trunk/src/app/srs_app_forward.cpp +++ b/trunk/src/app/srs_app_forward.cpp @@ -98,11 +98,11 @@ void SrsForwarder::on_unpublish() sdk->close(); } -srs_error_t SrsForwarder::on_meta_data(SrsSharedPtrMessage *shared_metadata) +srs_error_t SrsForwarder::on_meta_data(SrsMediaPacket *shared_metadata) { srs_error_t err = srs_success; - SrsSharedPtrMessage *metadata = shared_metadata->copy(); + SrsMediaPacket *metadata = shared_metadata->copy(); // TODO: FIXME: config the jitter of Forwarder. if ((err = jitter->correct(metadata, SrsRtmpJitterAlgorithmOFF)) != srs_success) { @@ -116,11 +116,11 @@ srs_error_t SrsForwarder::on_meta_data(SrsSharedPtrMessage *shared_metadata) return err; } -srs_error_t SrsForwarder::on_audio(SrsSharedPtrMessage *shared_audio) +srs_error_t SrsForwarder::on_audio(SrsMediaPacket *shared_audio) { srs_error_t err = srs_success; - SrsSharedPtrMessage *msg = shared_audio->copy(); + SrsMediaPacket *msg = shared_audio->copy(); // TODO: FIXME: config the jitter of Forwarder. if ((err = jitter->correct(msg, SrsRtmpJitterAlgorithmOFF)) != srs_success) { @@ -139,11 +139,11 @@ srs_error_t SrsForwarder::on_audio(SrsSharedPtrMessage *shared_audio) return err; } -srs_error_t SrsForwarder::on_video(SrsSharedPtrMessage *shared_video) +srs_error_t SrsForwarder::on_video(SrsMediaPacket *shared_video) { srs_error_t err = srs_success; - SrsSharedPtrMessage *msg = shared_video->copy(); + SrsMediaPacket *msg = shared_video->copy(); // TODO: FIXME: config the jitter of Forwarder. if ((err = jitter->correct(msg, SrsRtmpJitterAlgorithmOFF)) != srs_success) { diff --git a/trunk/src/app/srs_app_forward.hpp b/trunk/src/app/srs_app_forward.hpp index 2dce9a1db..b77968aef 100644 --- a/trunk/src/app/srs_app_forward.hpp +++ b/trunk/src/app/srs_app_forward.hpp @@ -14,7 +14,7 @@ #include class ISrsProtocolReadWriter; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsOnMetaDataPacket; class SrsMessageQueue; class SrsRtmpJitter; @@ -46,8 +46,8 @@ private: SrsRtmpJitter *jitter; SrsMessageQueue *queue; // Cache the sequence header for retry when slave is failed. - SrsSharedPtrMessage *sh_audio; - SrsSharedPtrMessage *sh_video; + SrsMediaPacket *sh_audio; + SrsMediaPacket *sh_video; public: SrsForwarder(SrsOriginHub *h); @@ -62,13 +62,13 @@ public: virtual void on_unpublish(); // Forward the audio packet. // @param shared_metadata, directly ptr, copy it if need to save it. - virtual srs_error_t on_meta_data(SrsSharedPtrMessage *shared_metadata); + virtual srs_error_t on_meta_data(SrsMediaPacket *shared_metadata); // Forward the audio packet. // @param shared_audio, directly ptr, copy it if need to save it. - virtual srs_error_t on_audio(SrsSharedPtrMessage *shared_audio); + virtual srs_error_t on_audio(SrsMediaPacket *shared_audio); // Forward the video packet. // @param shared_video, directly ptr, copy it if need to save it. - virtual srs_error_t on_video(SrsSharedPtrMessage *shared_video); + virtual srs_error_t on_video(SrsMediaPacket *shared_video); // Interface ISrsReusableThread2Handler. public: virtual srs_error_t cycle(); diff --git a/trunk/src/app/srs_app_gb28181.cpp b/trunk/src/app/srs_app_gb28181.cpp index 18d4a7df2..6bb9a340f 100644 --- a/trunk/src/app/srs_app_gb28181.cpp +++ b/trunk/src/app/srs_app_gb28181.cpp @@ -1547,15 +1547,15 @@ SrsMpegpsQueue::SrsMpegpsQueue() SrsMpegpsQueue::~SrsMpegpsQueue() { - std::map::iterator it; + std::map::iterator it; for (it = msgs.begin(); it != msgs.end(); ++it) { - SrsSharedPtrMessage *msg = it->second; + SrsMediaPacket *msg = it->second; srs_freep(msg); } msgs.clear(); } -srs_error_t SrsMpegpsQueue::push(SrsSharedPtrMessage *msg) +srs_error_t SrsMpegpsQueue::push(SrsMediaPacket *msg) { srs_error_t err = srs_success; @@ -1588,7 +1588,7 @@ srs_error_t SrsMpegpsQueue::push(SrsSharedPtrMessage *msg) return err; } -SrsSharedPtrMessage *SrsMpegpsQueue::dequeue() +SrsMediaPacket *SrsMpegpsQueue::dequeue() { // got 2+ videos and audios, ok to dequeue. bool av_ok = nb_videos >= 2 && nb_audios >= 2; @@ -1596,8 +1596,8 @@ SrsSharedPtrMessage *SrsMpegpsQueue::dequeue() bool av_overflow = nb_videos > 100 || nb_audios > 300; if (av_ok || av_overflow) { - std::map::iterator it = msgs.begin(); - SrsSharedPtrMessage *msg = it->second; + std::map::iterator it = msgs.begin(); + SrsMediaPacket *msg = it->second; msgs.erase(it); if (msg->is_audio()) { @@ -2107,12 +2107,14 @@ srs_error_t SrsGbMuxer::rtmp_write_packet(char type, uint32_t timestamp, char *d return srs_error_wrap(err, "connect"); } - SrsSharedPtrMessage *msg = NULL; - - if ((err = srs_rtmp_create_msg(type, timestamp, data, size, sdk_->sid(), &msg)) != srs_success) { + SrsCommonMessage *cmsg = NULL; + if ((err = srs_rtmp_create_msg(type, timestamp, data, size, sdk_->sid(), &cmsg)) != srs_success) { return srs_error_wrap(err, "create message"); } - srs_assert(msg); + + SrsMediaPacket *msg = new SrsMediaPacket(); + cmsg->to_msg(msg); + srs_freep(cmsg); // push msg to queue. if ((err = queue_->push(msg)) != srs_success) { diff --git a/trunk/src/app/srs_app_gb28181.hpp b/trunk/src/app/srs_app_gb28181.hpp index 2b1ebbe99..77e3d9bf0 100644 --- a/trunk/src/app/srs_app_gb28181.hpp +++ b/trunk/src/app/srs_app_gb28181.hpp @@ -37,7 +37,7 @@ class SrsSimpleRtmpClient; struct SrsRawAacStreamCodec; class SrsRawH264Stream; class SrsRawHEVCStream; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsPithyPrint; class SrsRawAacStream; class ISrsHttpServeMux; @@ -485,7 +485,7 @@ class SrsMpegpsQueue { private: // The key: dts, value: msg. - std::map msgs; + std::map msgs; int nb_audios; int nb_videos; @@ -494,8 +494,8 @@ public: virtual ~SrsMpegpsQueue(); public: - virtual srs_error_t push(SrsSharedPtrMessage *msg); - virtual SrsSharedPtrMessage *dequeue(); + virtual srs_error_t push(SrsMediaPacket *msg); + virtual SrsMediaPacket *dequeue(); }; // Mux GB28181 to RTMP. diff --git a/trunk/src/app/srs_app_hds.cpp b/trunk/src/app/srs_app_hds.cpp index 378c8a2b3..ac2ba9bb5 100644 --- a/trunk/src/app/srs_app_hds.cpp +++ b/trunk/src/app/srs_app_hds.cpp @@ -38,7 +38,7 @@ char flv_header[] = {'F', 'L', 'V', 0x01, 0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00}; -string serialFlv(SrsSharedPtrMessage *msg) +string serialFlv(SrsMediaPacket *msg) { int size = 15 + msg->size(); char *byte = new char[size]; @@ -81,22 +81,22 @@ public: srs_freep(audioSh); // clean msgs - list::iterator iter; + list::iterator iter; for (iter = msgs.begin(); iter != msgs.end(); ++iter) { - SrsSharedPtrMessage *msg = *iter; + SrsMediaPacket *msg = *iter; srs_freep(msg); } } - void on_video(SrsSharedPtrMessage *msg) + void on_video(SrsMediaPacket *msg) { - SrsSharedPtrMessage *_msg = msg->copy(); + SrsMediaPacket *_msg = msg->copy(); msgs.push_back(_msg); } - void on_audio(SrsSharedPtrMessage *msg) + void on_audio(SrsMediaPacket *msg) { - SrsSharedPtrMessage *_msg = msg->copy(); + SrsMediaPacket *_msg = msg->copy(); msgs.push_back(_msg); } @@ -116,9 +116,9 @@ public: data.append(serialFlv(audioSh)); } - list::iterator iter; + list::iterator iter; for (iter = msgs.begin(); iter != msgs.end(); ++iter) { - SrsSharedPtrMessage *msg = *iter; + SrsMediaPacket *msg = *iter; data.append(serialFlv(msg)); } @@ -158,10 +158,10 @@ public: long long last_msg_ts = 0; if (msgs.size() >= 2) { - SrsSharedPtrMessage *first_msg = msgs.front(); + SrsMediaPacket *first_msg = msgs.front(); first_msg_ts = first_msg->timestamp; - SrsSharedPtrMessage *last_msg = msgs.back(); + SrsMediaPacket *last_msg = msgs.back(); last_msg_ts = last_msg->timestamp; duration_ms = (int)(last_msg_ts - first_msg_ts); @@ -200,13 +200,13 @@ public: return start_time; } - void set_video_sh(SrsSharedPtrMessage *msg) + void set_video_sh(SrsMediaPacket *msg) { srs_freep(videoSh); videoSh = msg->copy(); } - void set_audio_sh(SrsSharedPtrMessage *msg) + void set_audio_sh(SrsMediaPacket *msg) { srs_freep(audioSh); audioSh = msg->copy(); @@ -219,7 +219,7 @@ public: private: ISrsRequest *req; - list msgs; + list msgs; /*! the index of this fragment @@ -227,8 +227,8 @@ private: int index; long long start_time; - SrsSharedPtrMessage *videoSh; - SrsSharedPtrMessage *audioSh; + SrsMediaPacket *videoSh; + SrsMediaPacket *audioSh; string path; }; @@ -290,7 +290,7 @@ srs_error_t SrsHds::on_unpublish() return err; } -srs_error_t SrsHds::on_video(SrsSharedPtrMessage *msg) +srs_error_t SrsHds::on_video(SrsMediaPacket *msg) { srs_error_t err = srs_success; @@ -340,7 +340,7 @@ srs_error_t SrsHds::on_video(SrsSharedPtrMessage *msg) return err; } -srs_error_t SrsHds::on_audio(SrsSharedPtrMessage *msg) +srs_error_t SrsHds::on_audio(SrsMediaPacket *msg) { srs_error_t err = srs_success; diff --git a/trunk/src/app/srs_app_hds.hpp b/trunk/src/app/srs_app_hds.hpp index f7037bee9..6ae7b1959 100644 --- a/trunk/src/app/srs_app_hds.hpp +++ b/trunk/src/app/srs_app_hds.hpp @@ -14,7 +14,7 @@ #include class ISrsRequest; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsHdsFragment; class SrsLiveSource; @@ -28,8 +28,8 @@ public: srs_error_t on_publish(ISrsRequest *req); srs_error_t on_unpublish(); - srs_error_t on_video(SrsSharedPtrMessage *msg); - srs_error_t on_audio(SrsSharedPtrMessage *msg); + srs_error_t on_video(SrsMediaPacket *msg); + srs_error_t on_audio(SrsMediaPacket *msg); private: srs_error_t flush_mainfest(); @@ -40,8 +40,8 @@ private: std::list fragments; SrsHdsFragment *currentSegment; int fragment_index; - SrsSharedPtrMessage *video_sh; - SrsSharedPtrMessage *audio_sh; + SrsMediaPacket *video_sh; + SrsMediaPacket *audio_sh; ISrsRequest *hds_req; bool hds_enabled; diff --git a/trunk/src/app/srs_app_hls.cpp b/trunk/src/app/srs_app_hls.cpp index e48dc7887..33b552f75 100644 --- a/trunk/src/app/srs_app_hls.cpp +++ b/trunk/src/app/srs_app_hls.cpp @@ -203,7 +203,7 @@ void SrsHlsM4sSegment::config_cipher(unsigned char *key, unsigned char *iv) memcpy(this->iv, iv, 16); } -srs_error_t SrsHlsM4sSegment::write(SrsSharedPtrMessage *shared_msg, SrsFormat *format) +srs_error_t SrsHlsM4sSegment::write(SrsMediaPacket *shared_msg, SrsFormat *format) { srs_error_t err = srs_success; @@ -580,7 +580,7 @@ srs_error_t SrsHlsFmp4Muxer::write_init_mp4(SrsFormat *format, bool has_video, b return err; } -srs_error_t SrsHlsFmp4Muxer::write_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format) +srs_error_t SrsHlsFmp4Muxer::write_audio(SrsMediaPacket *shared_audio, SrsFormat *format) { srs_error_t err = srs_success; @@ -604,7 +604,7 @@ srs_error_t SrsHlsFmp4Muxer::write_audio(SrsSharedPtrMessage *shared_audio, SrsF return err; } -srs_error_t SrsHlsFmp4Muxer::write_video(SrsSharedPtrMessage *shared_video, SrsFormat *format) +srs_error_t SrsHlsFmp4Muxer::write_video(SrsMediaPacket *shared_video, SrsFormat *format) { srs_error_t err = srs_success; @@ -2039,7 +2039,7 @@ srs_error_t SrsHlsController::on_unpublish() return err; } -srs_error_t SrsHlsController::on_sequence_header(SrsSharedPtrMessage *msg, SrsFormat *format) +srs_error_t SrsHlsController::on_sequence_header(SrsMediaPacket *msg, SrsFormat *format) { // TODO: support discontinuity for the same stream // currently we reap and insert discontinity when encoder republish, @@ -2050,10 +2050,10 @@ srs_error_t SrsHlsController::on_sequence_header(SrsSharedPtrMessage *msg, SrsFo return muxer->on_sequence_header(); } -srs_error_t SrsHlsController::write_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format) +srs_error_t SrsHlsController::write_audio(SrsMediaPacket *shared_audio, SrsFormat *format) { srs_error_t err = srs_success; - SrsAudioFrame *frame = format->audio; + SrsParsedAudioPacket *frame = format->audio; // Reset the aac samples counter when DTS jitter. if (previous_audio_dts > shared_audio->timestamp) { @@ -2140,10 +2140,10 @@ srs_error_t SrsHlsController::write_audio(SrsSharedPtrMessage *shared_audio, Srs return err; } -srs_error_t SrsHlsController::write_video(SrsSharedPtrMessage *shared_video, SrsFormat *format) +srs_error_t SrsHlsController::write_video(SrsMediaPacket *shared_video, SrsFormat *format) { srs_error_t err = srs_success; - SrsVideoFrame *frame = format->video; + SrsParsedVideoPacket *frame = format->video; int64_t dts = shared_video->timestamp * 90; // Refresh the codec ASAP. @@ -2306,10 +2306,10 @@ srs_error_t SrsHlsMp4Controller::on_unpublish() return err; } -srs_error_t SrsHlsMp4Controller::write_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format) +srs_error_t SrsHlsMp4Controller::write_audio(SrsMediaPacket *shared_audio, SrsFormat *format) { srs_error_t err = srs_success; - SrsAudioFrame *frame = format->audio; + SrsParsedAudioPacket *frame = format->audio; // Ignore audio sequence header if (format->is_aac_sequence_header() || format->is_mp3_sequence_header()) { @@ -2332,10 +2332,10 @@ srs_error_t SrsHlsMp4Controller::write_audio(SrsSharedPtrMessage *shared_audio, return err; } -srs_error_t SrsHlsMp4Controller::write_video(SrsSharedPtrMessage *shared_video, SrsFormat *format) +srs_error_t SrsHlsMp4Controller::write_video(SrsMediaPacket *shared_video, SrsFormat *format) { srs_error_t err = srs_success; - SrsVideoFrame *frame = format->video; + SrsParsedVideoPacket *frame = format->video; // Refresh the codec ASAP. if (muxer_->latest_vcodec() != frame->vcodec()->id) { @@ -2353,7 +2353,7 @@ srs_error_t SrsHlsMp4Controller::write_video(SrsSharedPtrMessage *shared_video, return err; } -srs_error_t SrsHlsMp4Controller::on_sequence_header(SrsSharedPtrMessage *msg, SrsFormat *format) +srs_error_t SrsHlsMp4Controller::on_sequence_header(SrsMediaPacket *msg, SrsFormat *format) { srs_error_t err = srs_success; @@ -2622,7 +2622,7 @@ void SrsHls::on_unpublish() unpublishing_ = false; } -srs_error_t SrsHls::on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format) +srs_error_t SrsHls::on_audio(SrsMediaPacket *shared_audio, SrsFormat *format) { srs_error_t err = srs_success; @@ -2642,7 +2642,7 @@ srs_error_t SrsHls::on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *forma // update the hls time, for hls_dispose. last_update_time = srs_time_now_cached(); - SrsUniquePtr audio(shared_audio->copy()); + SrsUniquePtr audio(shared_audio->copy()); // ts support audio codec: aac/mp3 SrsAudioCodecId acodec = format->acodec->id; @@ -2669,7 +2669,7 @@ srs_error_t SrsHls::on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *forma return err; } -srs_error_t SrsHls::on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format) +srs_error_t SrsHls::on_video(SrsMediaPacket *shared_video, SrsFormat *format) { srs_error_t err = srs_success; @@ -2688,7 +2688,7 @@ srs_error_t SrsHls::on_video(SrsSharedPtrMessage *shared_video, SrsFormat *forma // update the hls time, for hls_dispose. last_update_time = srs_time_now_cached(); - SrsUniquePtr video(shared_video->copy()); + SrsUniquePtr video(shared_video->copy()); // ignore info frame, // @see https://github.com/ossrs/srs/issues/288#issuecomment-69863909 diff --git a/trunk/src/app/srs_app_hls.hpp b/trunk/src/app/srs_app_hls.hpp index db0258223..f451cdb67 100644 --- a/trunk/src/app/srs_app_hls.hpp +++ b/trunk/src/app/srs_app_hls.hpp @@ -19,7 +19,7 @@ #include class SrsFormat; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsAmf0Object; class SrsRtmpJitter; class SrsTsContextWriter; @@ -117,7 +117,7 @@ public: public: virtual srs_error_t initialize(int64_t time, uint32_t v_tid, uint32_t a_tid, int sequence_number, std::string m4s_path); virtual void config_cipher(unsigned char *key, unsigned char *iv); - virtual srs_error_t write(SrsSharedPtrMessage *shared_msg, SrsFormat *format); + virtual srs_error_t write(SrsMediaPacket *shared_msg, SrsFormat *format); // Finalizes segment virtual srs_error_t reap(uint64_t dts); }; @@ -410,8 +410,8 @@ public: public: virtual srs_error_t write_init_mp4(SrsFormat *format, bool has_video, bool has_audio); - virtual srs_error_t write_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format); - virtual srs_error_t write_video(SrsSharedPtrMessage *shared_video, SrsFormat *format); + virtual srs_error_t write_audio(SrsMediaPacket *shared_audio, SrsFormat *format); + virtual srs_error_t write_video(SrsMediaPacket *shared_video, SrsFormat *format); public: virtual srs_error_t on_unpublish(); @@ -459,11 +459,11 @@ public: virtual srs_error_t on_unpublish() = 0; public: - virtual srs_error_t write_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format) = 0; - virtual srs_error_t write_video(SrsSharedPtrMessage *shared_video, SrsFormat *format) = 0; + virtual srs_error_t write_audio(SrsMediaPacket *shared_audio, SrsFormat *format) = 0; + virtual srs_error_t write_video(SrsMediaPacket *shared_video, SrsFormat *format) = 0; public: - virtual srs_error_t on_sequence_header(SrsSharedPtrMessage *msg, SrsFormat *format) = 0; + virtual srs_error_t on_sequence_header(SrsMediaPacket *msg, SrsFormat *format) = 0; virtual int sequence_no() = 0; // TODO: maybe rename to segment_url? virtual std::string ts_url() = 0; @@ -524,11 +524,11 @@ public: // must write a #EXT-X-DISCONTINUITY to m3u8. // @see: hls-m3u8-draft-pantos-http-live-streaming-12.txt // @see: 3.4.11. EXT-X-DISCONTINUITY - virtual srs_error_t on_sequence_header(SrsSharedPtrMessage *shared_audio, SrsFormat *format); + virtual srs_error_t on_sequence_header(SrsMediaPacket *shared_audio, SrsFormat *format); // write audio to cache, if need to flush, flush to muxer. - virtual srs_error_t write_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format); + virtual srs_error_t write_audio(SrsMediaPacket *shared_audio, SrsFormat *format); // write video to muxer. - virtual srs_error_t write_video(SrsSharedPtrMessage *shared_video, SrsFormat *format); + virtual srs_error_t write_video(SrsMediaPacket *shared_video, SrsFormat *format); private: // Reopen the muxer for a new hls segment, @@ -572,11 +572,11 @@ public: // When publish or unpublish stream. virtual srs_error_t on_publish(ISrsRequest *req); virtual srs_error_t on_unpublish(); - virtual srs_error_t write_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format); - virtual srs_error_t write_video(SrsSharedPtrMessage *shared_video, SrsFormat *format); + virtual srs_error_t write_audio(SrsMediaPacket *shared_audio, SrsFormat *format); + virtual srs_error_t write_video(SrsMediaPacket *shared_video, SrsFormat *format); public: - virtual srs_error_t on_sequence_header(SrsSharedPtrMessage *shared_audio, SrsFormat *format); + virtual srs_error_t on_sequence_header(SrsMediaPacket *shared_audio, SrsFormat *format); virtual int sequence_no(); virtual std::string ts_url(); virtual srs_utime_t duration(); @@ -637,12 +637,12 @@ public: virtual void on_unpublish(); // Mux the audio packets to ts. // @param shared_audio, directly ptr, copy it if need to save it. - virtual srs_error_t on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format); + virtual srs_error_t on_audio(SrsMediaPacket *shared_audio, SrsFormat *format); // Mux the video packets to ts. // @param shared_video, directly ptr, copy it if need to save it. // @param is_sps_pps whether the video is h.264 sps/pps. // TODO: FIXME: Remove param is_sps_pps. - virtual srs_error_t on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format); + virtual srs_error_t on_video(SrsMediaPacket *shared_video, SrsFormat *format); private: virtual void hls_show_mux_log(); diff --git a/trunk/src/app/srs_app_http_conn.hpp b/trunk/src/app/srs_app_http_conn.hpp index 3bb3a6e3b..a0bbbe7ac 100644 --- a/trunk/src/app/srs_app_http_conn.hpp +++ b/trunk/src/app/srs_app_http_conn.hpp @@ -29,7 +29,7 @@ class SrsHttpParser; class ISrsHttpMessage; class SrsHttpHandler; class SrsMessageQueue; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsFastStream; class SrsHttpUri; class SrsHttpMessage; diff --git a/trunk/src/app/srs_app_http_stream.cpp b/trunk/src/app/srs_app_http_stream.cpp index 64019beb1..235f9ef1e 100644 --- a/trunk/src/app/srs_app_http_stream.cpp +++ b/trunk/src/app/srs_app_http_stream.cpp @@ -188,7 +188,7 @@ srs_error_t SrsBufferCache::cycle() // free the messages. for (int i = 0; i < count; i++) { - SrsSharedPtrMessage *msg = msgs.msgs[i]; + SrsMediaPacket *msg = msgs.msgs[i]; queue->enqueue(msg); } } @@ -369,7 +369,7 @@ srs_error_t SrsFlvStreamEncoder::dump_cache(SrsLiveConsumer * /*consumer*/, SrsR return srs_success; } -srs_error_t SrsFlvStreamEncoder::write_tags(SrsSharedPtrMessage **msgs, int count) +srs_error_t SrsFlvStreamEncoder::write_tags(SrsMediaPacket **msgs, int count) { srs_error_t err = srs_success; @@ -390,7 +390,7 @@ srs_error_t SrsFlvStreamEncoder::write_tags(SrsSharedPtrMessage **msgs, int coun // Note that we must iterate all messages to count the audio and video frames. for (int i = 0; i < count; i++) { - SrsSharedPtrMessage *msg = msgs[i]; + SrsMediaPacket *msg = msgs[i]; if (msg->is_video()) { if (!SrsFlvVideo::sh(msg->payload(), msg->size())) nn_video_frames++; @@ -862,7 +862,7 @@ srs_error_t SrsLiveStream::do_serve_http(SrsLiveSource *source, SrsLiveConsumer // free the messages. for (int i = 0; i < count; i++) { - SrsSharedPtrMessage *msg = msgs.msgs[i]; + SrsMediaPacket *msg = msgs.msgs[i]; srs_freep(msg); } @@ -948,14 +948,14 @@ void SrsLiveStream::http_hooks_on_stop(ISrsHttpMessage *r) return; } -srs_error_t SrsLiveStream::streaming_send_messages(ISrsBufferEncoder *enc, SrsSharedPtrMessage **msgs, int nb_msgs) +srs_error_t SrsLiveStream::streaming_send_messages(ISrsBufferEncoder *enc, SrsMediaPacket **msgs, int nb_msgs) { srs_error_t err = srs_success; // TODO: In gop cache, we know both the audio and video codec, so we should notice the encoder, which might depends // on setting the correct codec information, for example, HTTP-TS or HLS will write PMT. for (int i = 0; i < nb_msgs; i++) { - SrsSharedPtrMessage *msg = msgs[i]; + SrsMediaPacket *msg = msgs[i]; if (msg->is_audio()) { err = enc->write_audio(msg->timestamp, msg->payload(), msg->size()); diff --git a/trunk/src/app/srs_app_http_stream.hpp b/trunk/src/app/srs_app_http_stream.hpp index 64ee5d145..5dce80277 100644 --- a/trunk/src/app/srs_app_http_stream.hpp +++ b/trunk/src/app/srs_app_http_stream.hpp @@ -105,7 +105,7 @@ public: public: // Write the tags in a time. - virtual srs_error_t write_tags(SrsSharedPtrMessage **msgs, int count); + virtual srs_error_t write_tags(SrsMediaPacket **msgs, int count); private: virtual srs_error_t write_header(bool has_video, bool has_audio); @@ -239,7 +239,7 @@ private: virtual srs_error_t do_serve_http(SrsLiveSource *source, SrsLiveConsumer *consumer, ISrsHttpResponseWriter *w, ISrsHttpMessage *r); virtual srs_error_t http_hooks_on_play(ISrsHttpMessage *r); virtual void http_hooks_on_stop(ISrsHttpMessage *r); - virtual srs_error_t streaming_send_messages(ISrsBufferEncoder *enc, SrsSharedPtrMessage **msgs, int nb_msgs); + virtual srs_error_t streaming_send_messages(ISrsBufferEncoder *enc, SrsMediaPacket **msgs, int nb_msgs); }; // The Live Entry, to handle HTTP Live Streaming. diff --git a/trunk/src/app/srs_app_mpegts_udp.cpp b/trunk/src/app/srs_app_mpegts_udp.cpp index 6b74ee061..11d7fc5b1 100644 --- a/trunk/src/app/srs_app_mpegts_udp.cpp +++ b/trunk/src/app/srs_app_mpegts_udp.cpp @@ -84,15 +84,15 @@ SrsMpegtsQueue::SrsMpegtsQueue() SrsMpegtsQueue::~SrsMpegtsQueue() { - std::map::iterator it; + std::map::iterator it; for (it = msgs.begin(); it != msgs.end(); ++it) { - SrsSharedPtrMessage *msg = it->second; + SrsMediaPacket *msg = it->second; srs_freep(msg); } msgs.clear(); } -srs_error_t SrsMpegtsQueue::push(SrsSharedPtrMessage *msg) +srs_error_t SrsMpegtsQueue::push(SrsMediaPacket *msg) { srs_error_t err = srs_success; @@ -125,7 +125,7 @@ srs_error_t SrsMpegtsQueue::push(SrsSharedPtrMessage *msg) return err; } -SrsSharedPtrMessage *SrsMpegtsQueue::dequeue() +SrsMediaPacket *SrsMpegtsQueue::dequeue() { // got 2+ videos and audios, ok to dequeue. bool av_ok = nb_videos >= 2 && nb_audios >= 2; @@ -133,8 +133,8 @@ SrsSharedPtrMessage *SrsMpegtsQueue::dequeue() bool av_overflow = nb_videos > 100 || nb_audios > 300; if (av_ok || av_overflow) { - std::map::iterator it = msgs.begin(); - SrsSharedPtrMessage *msg = it->second; + std::map::iterator it = msgs.begin(); + SrsMediaPacket *msg = it->second; msgs.erase(it); if (msg->is_audio()) { @@ -604,12 +604,15 @@ srs_error_t SrsMpegtsOverUdp::rtmp_write_packet(char type, uint32_t timestamp, c return srs_error_wrap(err, "connect"); } - SrsSharedPtrMessage *msg = NULL; - - if ((err = srs_rtmp_create_msg(type, timestamp, data, size, sdk->sid(), &msg)) != srs_success) { + SrsCommonMessage *cmsg = NULL; + if ((err = srs_rtmp_create_msg(type, timestamp, data, size, sdk->sid(), &cmsg)) != srs_success) { return srs_error_wrap(err, "create message"); } - srs_assert(msg); + srs_assert(cmsg); + + SrsMediaPacket *msg = new SrsMediaPacket(); + cmsg->to_msg(msg); + srs_freep(cmsg); // push msg to queue. if ((err = queue->push(msg)) != srs_success) { diff --git a/trunk/src/app/srs_app_mpegts_udp.hpp b/trunk/src/app/srs_app_mpegts_udp.hpp index c8cd8faee..62dc3d46e 100644 --- a/trunk/src/app/srs_app_mpegts_udp.hpp +++ b/trunk/src/app/srs_app_mpegts_udp.hpp @@ -21,7 +21,7 @@ class SrsRtmpClient; class SrsStSocket; class ISrsRequest; class SrsRawH264Stream; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsRawAacStream; struct SrsRawAacStreamCodec; class SrsPithyPrint; @@ -56,7 +56,7 @@ class SrsMpegtsQueue { private: // The key: dts, value: msg. - std::map msgs; + std::map msgs; int nb_audios; int nb_videos; @@ -65,8 +65,8 @@ public: virtual ~SrsMpegtsQueue(); public: - virtual srs_error_t push(SrsSharedPtrMessage *msg); - virtual SrsSharedPtrMessage *dequeue(); + virtual srs_error_t push(SrsMediaPacket *msg); + virtual SrsMediaPacket *dequeue(); }; // The mpegts over udp stream caster. diff --git a/trunk/src/app/srs_app_rtc_codec.cpp b/trunk/src/app/srs_app_rtc_codec.cpp index 4ad118101..e2fb2a821 100644 --- a/trunk/src/app/srs_app_rtc_codec.cpp +++ b/trunk/src/app/srs_app_rtc_codec.cpp @@ -159,7 +159,7 @@ srs_error_t SrsAudioTranscoder::initialize(SrsAudioCodecId src_codec, SrsAudioCo return err; } -srs_error_t SrsAudioTranscoder::transcode(SrsAudioFrame *in_pkt, std::vector &out_pkts) +srs_error_t SrsAudioTranscoder::transcode(SrsParsedAudioPacket *in_pkt, std::vector &out_pkts) { srs_error_t err = srs_success; @@ -174,10 +174,10 @@ srs_error_t SrsAudioTranscoder::transcode(SrsAudioFrame *in_pkt, std::vector &frames) +void SrsAudioTranscoder::free_frames(std::vector &frames) { - for (std::vector::iterator it = frames.begin(); it != frames.end(); ++it) { - SrsAudioFrame *p = *it; + for (std::vector::iterator it = frames.begin(); it != frames.end(); ++it) { + SrsParsedAudioPacket *p = *it; for (int i = 0; i < p->nb_samples; i++) { char *pa = p->samples[i].bytes; @@ -325,7 +325,7 @@ srs_error_t SrsAudioTranscoder::init_fifo() return srs_success; } -srs_error_t SrsAudioTranscoder::decode_and_resample(SrsAudioFrame *pkt) +srs_error_t SrsAudioTranscoder::decode_and_resample(SrsParsedAudioPacket *pkt) { srs_error_t err = srs_success; @@ -380,7 +380,7 @@ srs_error_t SrsAudioTranscoder::decode_and_resample(SrsAudioFrame *pkt) return err; } -srs_error_t SrsAudioTranscoder::encode(std::vector &pkts) +srs_error_t SrsAudioTranscoder::encode(std::vector &pkts) { char err_buf[AV_ERROR_MAX_STRING_SIZE] = {0}; @@ -435,7 +435,7 @@ srs_error_t SrsAudioTranscoder::encode(std::vector &pkts) enc_packet_->dts = av_rescale(enc_packet_->dts, 1000, enc_->time_base.den); enc_packet_->pts = av_rescale(enc_packet_->pts, 1000, enc_->time_base.den); - SrsAudioFrame *out_frame = new SrsAudioFrame; + SrsParsedAudioPacket *out_frame = new SrsParsedAudioPacket; char *buf = new char[enc_packet_->size]; memcpy(buf, enc_packet_->data, enc_packet_->size); out_frame->add_sample(buf, enc_packet_->size); diff --git a/trunk/src/app/srs_app_rtc_codec.hpp b/trunk/src/app/srs_app_rtc_codec.hpp index 5b6c8fab8..9837c7997 100644 --- a/trunk/src/app/srs_app_rtc_codec.hpp +++ b/trunk/src/app/srs_app_rtc_codec.hpp @@ -10,6 +10,7 @@ #include #include +#include #include @@ -60,9 +61,9 @@ public: // The bit_rate specifies the bitrate of encoder, for example, 48000. srs_error_t initialize(SrsAudioCodecId from, SrsAudioCodecId to, int channels, int sample_rate, int bit_rate); // Transcode the input audio frame in, as output audio frames outs. - virtual srs_error_t transcode(SrsAudioFrame *in, std::vector &outs); + virtual srs_error_t transcode(SrsParsedAudioPacket *in, std::vector &outs); // Free the generated audio frames by transcode. - void free_frames(std::vector &frames); + void free_frames(std::vector &frames); public: // Get the aac codec header, for example, FLV sequence header. @@ -75,8 +76,8 @@ private: srs_error_t init_swr(AVCodecContext *decoder); srs_error_t init_fifo(); - srs_error_t decode_and_resample(SrsAudioFrame *pkt); - srs_error_t encode(std::vector &pkts); + srs_error_t decode_and_resample(SrsParsedAudioPacket *pkt); + srs_error_t encode(std::vector &pkts); srs_error_t add_samples_to_fifo(uint8_t **samples, int frame_size); void free_swr_samples(); diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 40b3ce927..03eca542d 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -35,7 +35,7 @@ class SrsLiveConsumer; class SrsStunPacket; class SrsServer; class SrsRtcConnection; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsRtcSource; class SrsRtpPacket; class ISrsCodec; diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index bd73043b6..f806f8343 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -68,7 +68,7 @@ using namespace std; #define SRS_RTC_SOURCE_CLEANUP (3 * SRS_UTIME_SECONDS) // TODO: Add this function into SrsRtpMux class. -srs_error_t aac_raw_append_adts_header(SrsSharedPtrMessage *shared_audio, SrsFormat *format, char **pbuf, int *pnn_buf) +srs_error_t aac_raw_append_adts_header(SrsMediaPacket *shared_audio, SrsFormat *format, char **pbuf, int *pnn_buf) { srs_error_t err = srs_success; @@ -1005,7 +1005,7 @@ void SrsRtcRtpBuilder::on_unpublish() meta->update_previous_ash(); } -srs_error_t SrsRtcRtpBuilder::on_frame(SrsSharedPtrMessage *frame) +srs_error_t SrsRtcRtpBuilder::on_frame(SrsMediaPacket *frame) { if (frame->is_audio()) { return on_audio(frame); @@ -1015,7 +1015,7 @@ srs_error_t SrsRtcRtpBuilder::on_frame(SrsSharedPtrMessage *frame) return srs_success; } -srs_error_t SrsRtcRtpBuilder::on_audio(SrsSharedPtrMessage *msg) +srs_error_t SrsRtcRtpBuilder::on_audio(SrsMediaPacket *msg) { srs_error_t err = srs_success; @@ -1072,7 +1072,7 @@ srs_error_t SrsRtcRtpBuilder::on_audio(SrsSharedPtrMessage *msg) return err; } - SrsAudioFrame aac; + SrsParsedAudioPacket aac; aac.dts = format->audio->dts; aac.cts = format->audio->cts; if ((err = aac.add_sample(adts_audio, nn_adts_audio)) == srs_success) { @@ -1115,11 +1115,11 @@ srs_error_t SrsRtcRtpBuilder::init_codec(SrsAudioCodecId codec) return err; } -srs_error_t SrsRtcRtpBuilder::transcode(SrsAudioFrame *audio) +srs_error_t SrsRtcRtpBuilder::transcode(SrsParsedAudioPacket *audio) { srs_error_t err = srs_success; - std::vector out_audios; + std::vector out_audios; if ((err = codec_->transcode(audio, out_audios)) != srs_success) { return srs_error_wrap(err, "recode error"); } @@ -1129,8 +1129,8 @@ srs_error_t SrsRtcRtpBuilder::transcode(SrsAudioFrame *audio) return err; } - for (std::vector::iterator it = out_audios.begin(); it != out_audios.end(); ++it) { - SrsAudioFrame *out_audio = *it; + for (std::vector::iterator it = out_audios.begin(); it != out_audios.end(); ++it) { + SrsParsedAudioPacket *out_audio = *it; SrsUniquePtr pkt(new SrsRtpPacket()); if ((err = package_opus(out_audio, pkt.get())) != srs_success) { @@ -1149,7 +1149,7 @@ srs_error_t SrsRtcRtpBuilder::transcode(SrsAudioFrame *audio) return err; } -srs_error_t SrsRtcRtpBuilder::package_opus(SrsAudioFrame *audio, SrsRtpPacket *pkt) +srs_error_t SrsRtcRtpBuilder::package_opus(SrsParsedAudioPacket *audio, SrsRtpPacket *pkt) { srs_error_t err = srs_success; @@ -1181,7 +1181,7 @@ static void free_packets(vector *pkts) pkts->clear(); } -srs_error_t SrsRtcRtpBuilder::on_video(SrsSharedPtrMessage *msg) +srs_error_t SrsRtcRtpBuilder::on_video(SrsMediaPacket *msg) { srs_error_t err = srs_success; @@ -1216,7 +1216,7 @@ srs_error_t SrsRtcRtpBuilder::on_video(SrsSharedPtrMessage *msg) } bool has_idr = false; - vector samples; + vector samples; if ((err = filter(msg, format, has_idr, samples)) != srs_success) { return srs_error_wrap(err, "filter video"); } @@ -1247,7 +1247,7 @@ srs_error_t SrsRtcRtpBuilder::on_video(SrsSharedPtrMessage *msg) } else { // By default, we package each NALU(sample) to a RTP or FUA packet. for (int i = 0; i < nn_samples; i++) { - SrsSample *sample = samples[i]; + SrsNaluSample *sample = samples[i]; if (sample->size <= kRtpMaxPayloadSize) { if ((err = package_single_nalu(msg, sample, pkts)) != srs_success) { @@ -1268,7 +1268,7 @@ srs_error_t SrsRtcRtpBuilder::on_video(SrsSharedPtrMessage *msg) return consume_packets(pkts); } -srs_error_t SrsRtcRtpBuilder::filter(SrsSharedPtrMessage *msg, SrsFormat *format, bool &has_idr, vector &samples) +srs_error_t SrsRtcRtpBuilder::filter(SrsMediaPacket *msg, SrsFormat *format, bool &has_idr, vector &samples) { srs_error_t err = srs_success; @@ -1279,12 +1279,12 @@ srs_error_t SrsRtcRtpBuilder::filter(SrsSharedPtrMessage *msg, SrsFormat *format // Update samples to shared frame. for (int i = 0; i < format->video->nb_samples; ++i) { - SrsSample *sample = &format->video->samples[i]; + SrsNaluSample *sample = &format->video->samples[i]; if (!keep_avc_nalu_sei && format->vcodec->id == SrsVideoCodecIdAVC) { SrsAvcNaluType avc_nalu_type; - if ((err = SrsVideoFrame::parse_avc_nalu_type(sample, avc_nalu_type)) != srs_success) { + if ((err = SrsParsedVideoPacket::parse_avc_nalu_type(sample, avc_nalu_type)) != srs_success) { return srs_error_wrap(err, "parse avc nalu_type"); } if (avc_nalu_type == SrsAvcNaluTypeSEI) { @@ -1298,11 +1298,11 @@ srs_error_t SrsRtcRtpBuilder::filter(SrsSharedPtrMessage *msg, SrsFormat *format if (!keep_bframe) { bool is_b_frame = false; if (format->vcodec->id == SrsVideoCodecIdAVC) { - if ((err = SrsVideoFrame::parse_avc_bframe(sample, is_b_frame)) != srs_success) { + if ((err = SrsParsedVideoPacket::parse_avc_bframe(sample, is_b_frame)) != srs_success) { return srs_error_wrap(err, "parse bframe"); } } else if (format->vcodec->id == SrsVideoCodecIdHEVC) { - if ((err = SrsVideoFrame::parse_hevc_bframe(sample, format, is_b_frame)) != srs_success) { + if ((err = SrsParsedVideoPacket::parse_hevc_bframe(sample, format, is_b_frame)) != srs_success) { return srs_error_wrap(err, "parse bframe"); } } @@ -1317,7 +1317,7 @@ srs_error_t SrsRtcRtpBuilder::filter(SrsSharedPtrMessage *msg, SrsFormat *format return err; } -srs_error_t SrsRtcRtpBuilder::package_stap_a(SrsSharedPtrMessage *msg, SrsRtpPacket *pkt) +srs_error_t SrsRtcRtpBuilder::package_stap_a(SrsMediaPacket *msg, SrsRtpPacket *pkt) { srs_error_t err = srs_success; @@ -1329,7 +1329,7 @@ srs_error_t SrsRtcRtpBuilder::package_stap_a(SrsSharedPtrMessage *msg, SrsRtpPac return video_builder_->package_stap_a(msg, pkt); } -srs_error_t SrsRtcRtpBuilder::package_nalus(SrsSharedPtrMessage *msg, const vector &samples, vector &pkts) +srs_error_t SrsRtcRtpBuilder::package_nalus(SrsMediaPacket *msg, const vector &samples, vector &pkts) { srs_error_t err = srs_success; @@ -1342,12 +1342,12 @@ srs_error_t SrsRtcRtpBuilder::package_nalus(SrsSharedPtrMessage *msg, const vect } // Single NAL Unit Packet @see https://tools.ietf.org/html/rfc6184#section-5.6 -srs_error_t SrsRtcRtpBuilder::package_single_nalu(SrsSharedPtrMessage *msg, SrsSample *sample, vector &pkts) +srs_error_t SrsRtcRtpBuilder::package_single_nalu(SrsMediaPacket *msg, SrsNaluSample *sample, vector &pkts) { return video_builder_->package_single_nalu(msg, sample, pkts); } -srs_error_t SrsRtcRtpBuilder::package_fu_a(SrsSharedPtrMessage *msg, SrsSample *sample, int fu_payload_size, vector &pkts) +srs_error_t SrsRtcRtpBuilder::package_fu_a(SrsMediaPacket *msg, SrsNaluSample *sample, int fu_payload_size, vector &pkts) { srs_error_t err = srs_success; @@ -1867,10 +1867,8 @@ srs_error_t SrsRtcFrameBuilder::transcode_audio(SrsRtpPacket *pkt) SrsCommonMessage out_rtmp; packet_aac(&out_rtmp, (char *)header, header_len, ts, is_first_audio_); - SrsSharedPtrMessage msg; - if ((err = msg.create(&out_rtmp)) != srs_success) { - return srs_error_wrap(err, "create message"); - } + SrsMediaPacket msg; + out_rtmp.to_msg(&msg); if ((err = bridge_->on_frame(&msg)) != srs_success) { return srs_error_wrap(err, "source on audio"); @@ -1880,10 +1878,10 @@ srs_error_t SrsRtcFrameBuilder::transcode_audio(SrsRtpPacket *pkt) } // TODO: FIXME: Should use SrsUniquePtr to dispose it automatically. - std::vector out_pkts; + std::vector out_pkts; SrsRtpRawPayload *payload = dynamic_cast(pkt->payload()); - SrsAudioFrame frame; + SrsParsedAudioPacket frame; frame.add_sample(payload->payload, payload->nn_payload); frame.dts = ts; frame.cts = 0; @@ -1893,16 +1891,14 @@ srs_error_t SrsRtcFrameBuilder::transcode_audio(SrsRtpPacket *pkt) return err; } - for (std::vector::iterator it = out_pkts.begin(); it != out_pkts.end(); ++it) { + for (std::vector::iterator it = out_pkts.begin(); it != out_pkts.end(); ++it) { SrsCommonMessage out_rtmp; // TODO: FIXME: Should never directly use it, please define a variable with class name. out_rtmp.header.timestamp = (*it)->dts; packet_aac(&out_rtmp, (*it)->samples[0].bytes, (*it)->samples[0].size, ts, is_first_audio_); - SrsSharedPtrMessage msg; - if ((err = msg.create(&out_rtmp)) != srs_success) { - return srs_error_wrap(err, "create message"); - } + SrsMediaPacket msg; + out_rtmp.to_msg(&msg); if ((err = bridge_->on_frame(&msg)) != srs_success) { err = srs_error_wrap(err, "source on audio"); @@ -2023,10 +2019,10 @@ srs_error_t SrsRtcFrameBuilder::packet_sequence_header_avc(SrsRtpPacket *pkt) // Handle SPS/PPS in cache or STAP-A packet. if (stap_payload || has_sps_pps_in_raw_payload) { // Get the SPS/PPS from cache or STAP-A packet. - SrsSample *sps = stap_payload ? stap_payload->get_sps() : NULL; + SrsNaluSample *sps = stap_payload ? stap_payload->get_sps() : NULL; if (!sps && obs_whip_sps_) sps = dynamic_cast(obs_whip_sps_->payload())->sample_; - SrsSample *pps = stap_payload ? stap_payload->get_pps() : NULL; + SrsNaluSample *pps = stap_payload ? stap_payload->get_pps() : NULL; if (!pps && obs_whip_pps_) pps = dynamic_cast(obs_whip_pps_->payload())->sample_; if (!sps || !pps) { @@ -2048,7 +2044,7 @@ srs_error_t SrsRtcFrameBuilder::packet_sequence_header_avc(SrsRtpPacket *pkt) return err; } -srs_error_t SrsRtcFrameBuilder::do_packet_sequence_header_avc(SrsRtpPacket *pkt, SrsSample *sps, SrsSample *pps) +srs_error_t SrsRtcFrameBuilder::do_packet_sequence_header_avc(SrsRtpPacket *pkt, SrsNaluSample *sps, SrsNaluSample *pps) { srs_error_t err = srs_success; @@ -2078,10 +2074,8 @@ srs_error_t SrsRtcFrameBuilder::do_packet_sequence_header_avc(SrsRtpPacket *pkt, return srs_error_wrap(err, "create rtmp"); } - SrsSharedPtrMessage msg; - if ((err = msg.create(&rtmp)) != srs_success) { - return srs_error_wrap(err, "create message"); - } + SrsMediaPacket msg; + rtmp.to_msg(&msg); if ((err = bridge_->on_frame(&msg)) != srs_success) { return err; @@ -2121,13 +2115,13 @@ srs_error_t SrsRtcFrameBuilder::packet_sequence_header_hevc(SrsRtpPacket *pkt) // Generally, there will be SPS+PPS+IDR in a STAP-A packet. SrsRtpSTAPPayloadHevc *stap_payload_hevc = dynamic_cast(pkt->payload()); if (video_codec_ == SrsVideoCodecIdHEVC && (stap_payload_hevc || has_vps_sps_pps_in_raw_payload)) { - SrsSample *vps = stap_payload_hevc ? stap_payload_hevc->get_vps() : NULL; + SrsNaluSample *vps = stap_payload_hevc ? stap_payload_hevc->get_vps() : NULL; if (!vps && obs_whip_vps_) vps = dynamic_cast(obs_whip_vps_->payload())->sample_; - SrsSample *sps = stap_payload_hevc ? stap_payload_hevc->get_sps() : NULL; + SrsNaluSample *sps = stap_payload_hevc ? stap_payload_hevc->get_sps() : NULL; if (!sps && obs_whip_sps_) sps = dynamic_cast(obs_whip_sps_->payload())->sample_; - SrsSample *pps = stap_payload_hevc ? stap_payload_hevc->get_pps() : NULL; + SrsNaluSample *pps = stap_payload_hevc ? stap_payload_hevc->get_pps() : NULL; if (!pps && obs_whip_pps_) pps = dynamic_cast(obs_whip_pps_->payload())->sample_; if (!vps || !sps || !pps) { @@ -2149,7 +2143,7 @@ srs_error_t SrsRtcFrameBuilder::packet_sequence_header_hevc(SrsRtpPacket *pkt) return err; } -srs_error_t SrsRtcFrameBuilder::do_packet_sequence_header_hevc(SrsRtpPacket *pkt, SrsSample *vps, SrsSample *sps, SrsSample *pps) +srs_error_t SrsRtcFrameBuilder::do_packet_sequence_header_hevc(SrsRtpPacket *pkt, SrsNaluSample *vps, SrsNaluSample *sps, SrsNaluSample *pps) { srs_error_t err = srs_success; @@ -2177,10 +2171,8 @@ srs_error_t SrsRtcFrameBuilder::do_packet_sequence_header_hevc(SrsRtpPacket *pkt return srs_error_wrap(err, "create rtmp"); } - SrsSharedPtrMessage msg; - if ((err = msg.create(&rtmp)) != srs_success) { - return srs_error_wrap(err, "create message"); - } + SrsMediaPacket msg; + rtmp.to_msg(&msg); if ((err = bridge_->on_frame(&msg)) != srs_success) { return err; @@ -2210,7 +2202,7 @@ int SrsRtcFrameBuilder::calculate_packet_payload_size(SrsRtpPacket *pkt) if (stap_payload) { int size = 0; for (int j = 0; j < (int)stap_payload->nalus.size(); ++j) { - SrsSample *sample = stap_payload->nalus.at(j); + SrsNaluSample *sample = stap_payload->nalus.at(j); if (sample->size > 0) { size += 4 + sample->size; // length prefix + NALU } @@ -2233,7 +2225,7 @@ int SrsRtcFrameBuilder::calculate_packet_payload_size(SrsRtpPacket *pkt) if (stap_payload_hevc) { int size = 0; for (int j = 0; j < (int)stap_payload_hevc->nalus.size(); ++j) { - SrsSample *sample = stap_payload_hevc->nalus.at(j); + SrsNaluSample *sample = stap_payload_hevc->nalus.at(j); if (sample->size > 0) { size += 4 + sample->size; // length prefix + NALU } @@ -2281,7 +2273,7 @@ void SrsRtcFrameBuilder::write_packet_payload_to_buffer(SrsRtpPacket *pkt, SrsBu SrsRtpSTAPPayload *stap_payload = dynamic_cast(pkt->payload()); if (stap_payload) { for (int j = 0; j < (int)stap_payload->nalus.size(); ++j) { - SrsSample *sample = stap_payload->nalus.at(j); + SrsNaluSample *sample = stap_payload->nalus.at(j); if (sample->size > 0) { payload.write_4bytes(sample->size); payload.write_bytes(sample->bytes, sample->size); @@ -2316,7 +2308,7 @@ void SrsRtcFrameBuilder::write_packet_payload_to_buffer(SrsRtpPacket *pkt, SrsBu SrsRtpSTAPPayloadHevc *stap_payload_hevc = dynamic_cast(pkt->payload()); if (stap_payload_hevc) { for (int j = 0; j < (int)stap_payload_hevc->nalus.size(); ++j) { - SrsSample *sample = stap_payload_hevc->nalus.at(j); + SrsNaluSample *sample = stap_payload_hevc->nalus.at(j); if (sample->size > 0) { payload.write_4bytes(sample->size); payload.write_bytes(sample->bytes, sample->size); @@ -2435,10 +2427,8 @@ srs_error_t SrsRtcFrameBuilder::packet_video_rtmp(const uint16_t start, const ui write_packet_payload_to_buffer(pkt.get(), payload, nalu_len); } - SrsSharedPtrMessage msg; - if ((err = msg.create(&rtmp)) != srs_success) { - return srs_error_wrap(err, "create message"); - } + SrsMediaPacket msg; + rtmp.to_msg(&msg); if ((err = bridge_->on_frame(&msg)) != srs_success) { srs_warn("fail to pack video frame: %s", srs_error_summary(err).c_str()); diff --git a/trunk/src/app/srs_app_rtc_source.hpp b/trunk/src/app/srs_app_rtc_source.hpp index 8c98fa5ac..55752cb9f 100644 --- a/trunk/src/app/srs_app_rtc_source.hpp +++ b/trunk/src/app/srs_app_rtc_source.hpp @@ -24,14 +24,14 @@ class ISrsRequest; class SrsMetaCache; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsCommonMessage; class SrsMessageArray; class SrsRtcSource; class SrsFrameToRtcBridge; class SrsAudioTranscoder; class SrsRtpPacket; -class SrsSample; +class SrsNaluSample; class SrsRtcSourceDescription; class SrsRtcTrackDescription; class SrsRtcConnection; @@ -346,25 +346,25 @@ public: virtual srs_error_t initialize(ISrsRequest *r); virtual srs_error_t on_publish(); virtual void on_unpublish(); - virtual srs_error_t on_frame(SrsSharedPtrMessage *frame); + virtual srs_error_t on_frame(SrsMediaPacket *frame); private: - virtual srs_error_t on_audio(SrsSharedPtrMessage *msg); + virtual srs_error_t on_audio(SrsMediaPacket *msg); private: srs_error_t init_codec(SrsAudioCodecId codec); - srs_error_t transcode(SrsAudioFrame *audio); - srs_error_t package_opus(SrsAudioFrame *audio, SrsRtpPacket *pkt); + srs_error_t transcode(SrsParsedAudioPacket *audio); + srs_error_t package_opus(SrsParsedAudioPacket *audio, SrsRtpPacket *pkt); private: - virtual srs_error_t on_video(SrsSharedPtrMessage *msg); + virtual srs_error_t on_video(SrsMediaPacket *msg); private: - srs_error_t filter(SrsSharedPtrMessage *msg, SrsFormat *format, bool &has_idr, std::vector &samples); - srs_error_t package_stap_a(SrsSharedPtrMessage *msg, SrsRtpPacket *pkt); - srs_error_t package_nalus(SrsSharedPtrMessage *msg, const std::vector &samples, std::vector &pkts); - srs_error_t package_single_nalu(SrsSharedPtrMessage *msg, SrsSample *sample, std::vector &pkts); - srs_error_t package_fu_a(SrsSharedPtrMessage *msg, SrsSample *sample, int fu_payload_size, std::vector &pkts); + srs_error_t filter(SrsMediaPacket *msg, SrsFormat *format, bool &has_idr, std::vector &samples); + srs_error_t package_stap_a(SrsMediaPacket *msg, SrsRtpPacket *pkt); + srs_error_t package_nalus(SrsMediaPacket *msg, const std::vector &samples, std::vector &pkts); + srs_error_t package_single_nalu(SrsMediaPacket *msg, SrsNaluSample *sample, std::vector &pkts); + srs_error_t package_fu_a(SrsMediaPacket *msg, SrsNaluSample *sample, int fu_payload_size, std::vector &pkts); srs_error_t consume_packets(std::vector &pkts); }; @@ -504,9 +504,9 @@ private: srs_error_t packet_video(SrsRtpPacket *pkt); srs_error_t packet_video_key_frame(SrsRtpPacket *pkt); srs_error_t packet_sequence_header_avc(SrsRtpPacket *pkt); - srs_error_t do_packet_sequence_header_avc(SrsRtpPacket *pkt, SrsSample *sps, SrsSample *pps); + srs_error_t do_packet_sequence_header_avc(SrsRtpPacket *pkt, SrsNaluSample *sps, SrsNaluSample *pps); srs_error_t packet_sequence_header_hevc(SrsRtpPacket *pkt); - srs_error_t do_packet_sequence_header_hevc(SrsRtpPacket *pkt, SrsSample *vps, SrsSample *sps, SrsSample *pps); + srs_error_t do_packet_sequence_header_hevc(SrsRtpPacket *pkt, SrsNaluSample *vps, SrsNaluSample *sps, SrsNaluSample *pps); private: srs_error_t packet_video_rtmp(const uint16_t start, const uint16_t end); diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index cf7bdb6a9..c7825bd81 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -825,7 +825,7 @@ srs_error_t SrsRtmpConn::do_playing(SrsSharedPtr source, SrsLiveC // we start to collect the durations for each message. if (user_specified_duration_to_stop) { for (int i = 0; i < count; i++) { - SrsSharedPtrMessage *msg = msgs.msgs[i]; + SrsMediaPacket *msg = msgs.msgs[i]; // foreach msg, collect the duration. // @remark: never use msg when sent it, for the protocol sdk will free it. @@ -1109,11 +1109,11 @@ srs_error_t SrsRtmpConn::handle_publish_message(SrsSharedPtr &sou // process publish event. if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) { - SrsPacket *pkt_raw = NULL; + SrsRtmpCommand *pkt_raw = NULL; if ((err = rtmp->decode_message(msg, &pkt_raw)) != srs_success) { return srs_error_wrap(err, "rtmp: decode message"); } - SrsUniquePtr pkt(pkt_raw); + SrsUniquePtr pkt(pkt_raw); // for flash, any packet is republish. if (info->type == SrsRtmpConnFlashPublish) { @@ -1181,11 +1181,11 @@ srs_error_t SrsRtmpConn::process_publish_message(SrsSharedPtr &so // process onMetaData if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) { - SrsPacket *pkt_raw = NULL; + SrsRtmpCommand *pkt_raw = NULL; if ((err = rtmp->decode_message(msg, &pkt_raw)) != srs_success) { return srs_error_wrap(err, "rtmp: decode message"); } - SrsUniquePtr pkt(pkt_raw); + SrsUniquePtr pkt(pkt_raw); if (dynamic_cast(pkt.get())) { SrsOnMetaDataPacket *metadata = dynamic_cast(pkt.get()); @@ -1213,11 +1213,11 @@ srs_error_t SrsRtmpConn::process_play_control_msg(SrsLiveConsumer *consumer, Srs return err; } - SrsPacket *pkt_raw = NULL; + SrsRtmpCommand *pkt_raw = NULL; if ((err = rtmp->decode_message(msg.get(), &pkt_raw)) != srs_success) { return srs_error_wrap(err, "rtmp: decode message"); } - SrsUniquePtr pkt(pkt_raw); + SrsUniquePtr pkt(pkt_raw); // for jwplayer/flowplayer, which send close as pause message. SrsCloseStreamPacket *close = dynamic_cast(pkt.get()); diff --git a/trunk/src/app/srs_app_rtmp_conn.hpp b/trunk/src/app/srs_app_rtmp_conn.hpp index 00752f9c2..370851385 100644 --- a/trunk/src/app/srs_app_rtmp_conn.hpp +++ b/trunk/src/app/srs_app_rtmp_conn.hpp @@ -31,13 +31,13 @@ class SrsHttpHooks; class SrsBandwidth; class SrsKbps; class SrsRtmpClient; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsQueueRecvThread; class SrsPublishRecvThread; class SrsSecurity; class ISrsWakable; class SrsCommonMessage; -class SrsPacket; +class SrsRtmpCommand; class SrsNetworkDelta; class SrsSslConnection; diff --git a/trunk/src/app/srs_app_rtsp_source.cpp b/trunk/src/app/srs_app_rtsp_source.cpp index 7912c8cc2..22ed3478c 100644 --- a/trunk/src/app/srs_app_rtsp_source.cpp +++ b/trunk/src/app/srs_app_rtsp_source.cpp @@ -692,7 +692,7 @@ void SrsRtspRtpBuilder::on_unpublish() meta->update_previous_ash(); } -srs_error_t SrsRtspRtpBuilder::on_frame(SrsSharedPtrMessage *frame) +srs_error_t SrsRtspRtpBuilder::on_frame(SrsMediaPacket *frame) { if (frame->is_audio()) { return on_audio(frame); @@ -702,7 +702,7 @@ srs_error_t SrsRtspRtpBuilder::on_frame(SrsSharedPtrMessage *frame) return srs_success; } -srs_error_t SrsRtspRtpBuilder::on_audio(SrsSharedPtrMessage *msg) +srs_error_t SrsRtspRtpBuilder::on_audio(SrsMediaPacket *msg) { srs_error_t err = srs_success; @@ -753,7 +753,7 @@ srs_error_t SrsRtspRtpBuilder::on_audio(SrsSharedPtrMessage *msg) return err; } -srs_error_t SrsRtspRtpBuilder::package_aac(SrsAudioFrame *audio, SrsRtpPacket *pkt) +srs_error_t SrsRtspRtpBuilder::package_aac(SrsParsedAudioPacket *audio, SrsRtpPacket *pkt) { srs_error_t err = srs_success; @@ -827,7 +827,7 @@ static void free_packets(vector *pkts) pkts->clear(); } -srs_error_t SrsRtspRtpBuilder::on_video(SrsSharedPtrMessage *msg) +srs_error_t SrsRtspRtpBuilder::on_video(SrsMediaPacket *msg) { srs_error_t err = srs_success; @@ -862,7 +862,7 @@ srs_error_t SrsRtspRtpBuilder::on_video(SrsSharedPtrMessage *msg) } bool has_idr = false; - vector samples; + vector samples; if ((err = filter(msg, format, has_idr, samples)) != srs_success) { return srs_error_wrap(err, "filter video"); } @@ -888,7 +888,7 @@ srs_error_t SrsRtspRtpBuilder::on_video(SrsSharedPtrMessage *msg) // By default, we package each NALU(sample) to a RTP or FUA packet. for (int i = 0; i < nn_samples; i++) { - SrsSample *sample = samples[i]; + SrsNaluSample *sample = samples[i]; if (sample->size <= kRtpMaxPayloadSize) { if ((err = package_single_nalu(msg, sample, pkts)) != srs_success) { @@ -908,7 +908,7 @@ srs_error_t SrsRtspRtpBuilder::on_video(SrsSharedPtrMessage *msg) return consume_packets(pkts); } -srs_error_t SrsRtspRtpBuilder::filter(SrsSharedPtrMessage *msg, SrsFormat *format, bool &has_idr, vector &samples) +srs_error_t SrsRtspRtpBuilder::filter(SrsMediaPacket *msg, SrsFormat *format, bool &has_idr, vector &samples) { srs_error_t err = srs_success; @@ -919,14 +919,14 @@ srs_error_t SrsRtspRtpBuilder::filter(SrsSharedPtrMessage *msg, SrsFormat *forma // Update samples to shared frame. for (int i = 0; i < format->video->nb_samples; ++i) { - SrsSample *sample = &format->video->samples[i]; + SrsNaluSample *sample = &format->video->samples[i]; samples.push_back(sample); } return err; } -srs_error_t SrsRtspRtpBuilder::package_stap_a(SrsSharedPtrMessage *msg, SrsRtpPacket *pkt) +srs_error_t SrsRtspRtpBuilder::package_stap_a(SrsMediaPacket *msg, SrsRtpPacket *pkt) { srs_error_t err = srs_success; @@ -938,7 +938,7 @@ srs_error_t SrsRtspRtpBuilder::package_stap_a(SrsSharedPtrMessage *msg, SrsRtpPa return video_builder_->package_stap_a(msg, pkt); } -srs_error_t SrsRtspRtpBuilder::package_nalus(SrsSharedPtrMessage *msg, const vector &samples, vector &pkts) +srs_error_t SrsRtspRtpBuilder::package_nalus(SrsMediaPacket *msg, const vector &samples, vector &pkts) { srs_error_t err = srs_success; @@ -951,12 +951,12 @@ srs_error_t SrsRtspRtpBuilder::package_nalus(SrsSharedPtrMessage *msg, const vec } // Single NAL Unit Packet @see https://tools.ietf.org/html/rfc6184#section-5.6 -srs_error_t SrsRtspRtpBuilder::package_single_nalu(SrsSharedPtrMessage *msg, SrsSample *sample, vector &pkts) +srs_error_t SrsRtspRtpBuilder::package_single_nalu(SrsMediaPacket *msg, SrsNaluSample *sample, vector &pkts) { return video_builder_->package_single_nalu(msg, sample, pkts); } -srs_error_t SrsRtspRtpBuilder::package_fu_a(SrsSharedPtrMessage *msg, SrsSample *sample, int fu_payload_size, vector &pkts) +srs_error_t SrsRtspRtpBuilder::package_fu_a(SrsMediaPacket *msg, SrsNaluSample *sample, int fu_payload_size, vector &pkts) { srs_error_t err = srs_success; diff --git a/trunk/src/app/srs_app_rtsp_source.hpp b/trunk/src/app/srs_app_rtsp_source.hpp index 3bb40b209..6a21a3fb8 100644 --- a/trunk/src/app/srs_app_rtsp_source.hpp +++ b/trunk/src/app/srs_app_rtsp_source.hpp @@ -223,23 +223,23 @@ public: virtual srs_error_t initialize(ISrsRequest *r); virtual srs_error_t on_publish(); virtual void on_unpublish(); - virtual srs_error_t on_frame(SrsSharedPtrMessage *frame); + virtual srs_error_t on_frame(SrsMediaPacket *frame); private: - virtual srs_error_t on_audio(SrsSharedPtrMessage *msg); + virtual srs_error_t on_audio(SrsMediaPacket *msg); private: - srs_error_t package_aac(SrsAudioFrame *audio, SrsRtpPacket *pkt); + srs_error_t package_aac(SrsParsedAudioPacket *audio, SrsRtpPacket *pkt); private: - virtual srs_error_t on_video(SrsSharedPtrMessage *msg); + virtual srs_error_t on_video(SrsMediaPacket *msg); private: - srs_error_t filter(SrsSharedPtrMessage *msg, SrsFormat *format, bool &has_idr, std::vector &samples); - srs_error_t package_stap_a(SrsSharedPtrMessage *msg, SrsRtpPacket *pkt); - srs_error_t package_nalus(SrsSharedPtrMessage *msg, const std::vector &samples, std::vector &pkts); - srs_error_t package_single_nalu(SrsSharedPtrMessage *msg, SrsSample *sample, std::vector &pkts); - srs_error_t package_fu_a(SrsSharedPtrMessage *msg, SrsSample *sample, int fu_payload_size, std::vector &pkts); + srs_error_t filter(SrsMediaPacket *msg, SrsFormat *format, bool &has_idr, std::vector &samples); + srs_error_t package_stap_a(SrsMediaPacket *msg, SrsRtpPacket *pkt); + srs_error_t package_nalus(SrsMediaPacket *msg, const std::vector &samples, std::vector &pkts); + srs_error_t package_single_nalu(SrsMediaPacket *msg, SrsNaluSample *sample, std::vector &pkts); + srs_error_t package_fu_a(SrsMediaPacket *msg, SrsNaluSample *sample, int fu_payload_size, std::vector &pkts); srs_error_t consume_packets(std::vector &pkts); }; diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 4b99120a1..d2c27ff44 100644 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -70,7 +70,7 @@ SrsRtmpJitter::~SrsRtmpJitter() { } -srs_error_t SrsRtmpJitter::correct(SrsSharedPtrMessage *msg, SrsRtmpJitterAlgorithm ag) +srs_error_t SrsRtmpJitter::correct(SrsMediaPacket *msg, SrsRtmpJitterAlgorithm ag) { srs_error_t err = srs_success; @@ -140,7 +140,7 @@ SrsFastVector::SrsFastVector() { count = 0; nb_msgs = 8; - msgs = new SrsSharedPtrMessage *[nb_msgs]; + msgs = new SrsMediaPacket *[nb_msgs]; } SrsFastVector::~SrsFastVector() @@ -164,12 +164,12 @@ int SrsFastVector::end() return count; } -SrsSharedPtrMessage **SrsFastVector::data() +SrsMediaPacket **SrsFastVector::data() { return msgs; } -SrsSharedPtrMessage *SrsFastVector::at(int index) +SrsMediaPacket *SrsFastVector::at(int index) { srs_assert(index < count); return msgs[index]; @@ -193,13 +193,13 @@ void SrsFastVector::erase(int _begin, int _end) count -= _end - _begin; } -void SrsFastVector::push_back(SrsSharedPtrMessage *msg) +void SrsFastVector::push_back(SrsMediaPacket *msg) { // increase vector. if (count >= nb_msgs) { int size = srs_max(SRS_PERF_MW_MSGS * 8, nb_msgs * 2); - SrsSharedPtrMessage **buf = msgs; - msgs = new SrsSharedPtrMessage *[size]; + SrsMediaPacket **buf = msgs; + msgs = new SrsMediaPacket *[size]; for (int i = 0; i < nb_msgs; i++) { msgs[i] = buf[i]; } @@ -216,7 +216,7 @@ void SrsFastVector::push_back(SrsSharedPtrMessage *msg) void SrsFastVector::free() { for (int i = 0; i < count; i++) { - SrsSharedPtrMessage *msg = msgs[i]; + SrsMediaPacket *msg = msgs[i]; srs_freep(msg); } count = 0; @@ -250,7 +250,7 @@ void SrsMessageQueue::set_queue_size(srs_utime_t queue_size) max_queue_size = queue_size; } -srs_error_t SrsMessageQueue::enqueue(SrsSharedPtrMessage *msg, bool *is_overflow) +srs_error_t SrsMessageQueue::enqueue(SrsMediaPacket *msg, bool *is_overflow) { srs_error_t err = srs_success; @@ -283,7 +283,7 @@ srs_error_t SrsMessageQueue::enqueue(SrsSharedPtrMessage *msg, bool *is_overflow return err; } -srs_error_t SrsMessageQueue::dump_packets(int max_count, SrsSharedPtrMessage **pmsgs, int &count) +srs_error_t SrsMessageQueue::dump_packets(int max_count, SrsMediaPacket **pmsgs, int &count) { srs_error_t err = srs_success; @@ -295,10 +295,10 @@ srs_error_t SrsMessageQueue::dump_packets(int max_count, SrsSharedPtrMessage **p srs_assert(max_count > 0); count = srs_min(max_count, nb_msgs); - SrsSharedPtrMessage **omsgs = msgs.data(); - memcpy(pmsgs, omsgs, count * sizeof(SrsSharedPtrMessage *)); + SrsMediaPacket **omsgs = msgs.data(); + memcpy(pmsgs, omsgs, count * sizeof(SrsMediaPacket *)); - SrsSharedPtrMessage *last = omsgs[count - 1]; + SrsMediaPacket *last = omsgs[count - 1]; av_start_time = srs_utime_t(last->timestamp * SRS_UTIME_MILLISECONDS); if (count >= nb_msgs) { @@ -324,9 +324,9 @@ srs_error_t SrsMessageQueue::dump_packets(SrsLiveConsumer *consumer, bool atc, S return err; } - SrsSharedPtrMessage **omsgs = msgs.data(); + SrsMediaPacket **omsgs = msgs.data(); for (int i = 0; i < nb_msgs; i++) { - SrsSharedPtrMessage *msg = omsgs[i]; + SrsMediaPacket *msg = omsgs[i]; if ((err = consumer->enqueue(msg, atc, ag)) != srs_success) { return srs_error_wrap(err, "consume message"); } @@ -337,13 +337,13 @@ srs_error_t SrsMessageQueue::dump_packets(SrsLiveConsumer *consumer, bool atc, S void SrsMessageQueue::shrink() { - SrsSharedPtrMessage *video_sh = NULL; - SrsSharedPtrMessage *audio_sh = NULL; + SrsMediaPacket *video_sh = NULL; + SrsMediaPacket *audio_sh = NULL; int msgs_size = (int)msgs.size(); // Remove all msgs, mark the sequence headers. for (int i = 0; i < (int)msgs.size(); i++) { - SrsSharedPtrMessage *msg = msgs.at(i); + SrsMediaPacket *msg = msgs.at(i); if (msg->is_video() && SrsFlvVideo::sh(msg->payload(), msg->size())) { srs_freep(video_sh); @@ -380,10 +380,10 @@ void SrsMessageQueue::shrink() void SrsMessageQueue::clear() { #ifndef SRS_PERF_QUEUE_FAST_VECTOR - std::vector::iterator it; + std::vector::iterator it; for (it = msgs.begin(); it != msgs.end(); ++it) { - SrsSharedPtrMessage *msg = *it; + SrsMediaPacket *msg = *it; srs_freep(msg); } #else @@ -445,11 +445,11 @@ int64_t SrsLiveConsumer::get_time() return jitter->get_time(); } -srs_error_t SrsLiveConsumer::enqueue(SrsSharedPtrMessage *shared_msg, bool atc, SrsRtmpJitterAlgorithm ag) +srs_error_t SrsLiveConsumer::enqueue(SrsMediaPacket *shared_msg, bool atc, SrsRtmpJitterAlgorithm ag) { srs_error_t err = srs_success; - SrsSharedPtrMessage *msg = shared_msg->copy(); + SrsMediaPacket *msg = shared_msg->copy(); if (!atc) { if ((err = jitter->correct(msg, ag)) != srs_success) { @@ -606,7 +606,7 @@ bool SrsGopCache::enabled() return enable_gop_cache; } -srs_error_t SrsGopCache::cache(SrsSharedPtrMessage *shared_msg) +srs_error_t SrsGopCache::cache(SrsMediaPacket *shared_msg) { srs_error_t err = srs_success; @@ -615,7 +615,7 @@ srs_error_t SrsGopCache::cache(SrsSharedPtrMessage *shared_msg) } // the gop cache know when to gop it. - SrsSharedPtrMessage *msg = shared_msg; + SrsMediaPacket *msg = shared_msg; // got video, update the video count if acceptable if (msg->is_video()) { @@ -669,9 +669,9 @@ srs_error_t SrsGopCache::cache(SrsSharedPtrMessage *shared_msg) void SrsGopCache::clear() { - std::vector::iterator it; + std::vector::iterator it; for (it = gop_cache.begin(); it != gop_cache.end(); ++it) { - SrsSharedPtrMessage *msg = *it; + SrsMediaPacket *msg = *it; srs_freep(msg); } gop_cache.clear(); @@ -684,9 +684,9 @@ srs_error_t SrsGopCache::dump(SrsLiveConsumer *consumer, bool atc, SrsRtmpJitter { srs_error_t err = srs_success; - std::vector::iterator it; + std::vector::iterator it; for (it = gop_cache.begin(); it != gop_cache.end(); ++it) { - SrsSharedPtrMessage *msg = *it; + SrsMediaPacket *msg = *it; if ((err = consumer->enqueue(msg, atc, jitter_algorithm)) != srs_success) { return srs_error_wrap(err, "enqueue message"); } @@ -707,7 +707,7 @@ srs_utime_t SrsGopCache::start_time() return 0; } - SrsSharedPtrMessage *msg = gop_cache[0]; + SrsMediaPacket *msg = gop_cache[0]; srs_assert(msg); return srs_utime_t(msg->timestamp * SRS_UTIME_MILLISECONDS); @@ -727,7 +727,7 @@ ISrsLiveSourceHandler::~ISrsLiveSourceHandler() } // TODO: FIXME: Remove it? -bool srs_hls_can_continue(int ret, SrsSharedPtrMessage *sh, SrsSharedPtrMessage *msg) +bool srs_hls_can_continue(int ret, SrsMediaPacket *sh, SrsMediaPacket *msg) { // only continue for decode error. if (ret != ERROR_HLS_DECODE_ERROR) { @@ -758,9 +758,9 @@ SrsMixQueue::~SrsMixQueue() void SrsMixQueue::clear() { - std::multimap::iterator it; + std::multimap::iterator it; for (it = msgs.begin(); it != msgs.end(); ++it) { - SrsSharedPtrMessage *msg = it->second; + SrsMediaPacket *msg = it->second; srs_freep(msg); } msgs.clear(); @@ -769,7 +769,7 @@ void SrsMixQueue::clear() nb_audios = 0; } -void SrsMixQueue::push(SrsSharedPtrMessage *msg) +void SrsMixQueue::push(SrsMediaPacket *msg) { msgs.insert(std::make_pair(msg->timestamp, msg)); @@ -780,7 +780,7 @@ void SrsMixQueue::push(SrsSharedPtrMessage *msg) } } -SrsSharedPtrMessage *SrsMixQueue::pop() +SrsMediaPacket *SrsMixQueue::pop() { bool mix_ok = false; @@ -804,8 +804,8 @@ SrsSharedPtrMessage *SrsMixQueue::pop() } // pop the first msg. - std::multimap::iterator it = msgs.begin(); - SrsSharedPtrMessage *msg = it->second; + std::multimap::iterator it = msgs.begin(); + SrsMediaPacket *msg = it->second; msgs.erase(it); if (msg->is_video()) { @@ -920,7 +920,7 @@ srs_utime_t SrsOriginHub::cleanup_delay() return srs_max(hls_delay, dash_delay); } -srs_error_t SrsOriginHub::on_meta_data(SrsSharedPtrMessage *shared_metadata, SrsOnMetaDataPacket *packet) +srs_error_t SrsOriginHub::on_meta_data(SrsMediaPacket *shared_metadata, SrsOnMetaDataPacket *packet) { srs_error_t err = srs_success; @@ -942,11 +942,11 @@ srs_error_t SrsOriginHub::on_meta_data(SrsSharedPtrMessage *shared_metadata, Srs return err; } -srs_error_t SrsOriginHub::on_audio(SrsSharedPtrMessage *shared_audio) +srs_error_t SrsOriginHub::on_audio(SrsMediaPacket *shared_audio) { srs_error_t err = srs_success; - SrsSharedPtrMessage *msg = shared_audio; + SrsMediaPacket *msg = shared_audio; SrsRtmpFormat *format = source_->format_; // Handle the metadata when got sequence header. @@ -1028,11 +1028,11 @@ srs_error_t SrsOriginHub::on_audio(SrsSharedPtrMessage *shared_audio) return err; } -srs_error_t SrsOriginHub::on_video(SrsSharedPtrMessage *shared_video, bool is_sequence_header) +srs_error_t SrsOriginHub::on_video(SrsMediaPacket *shared_video, bool is_sequence_header) { srs_error_t err = srs_success; - SrsSharedPtrMessage *msg = shared_video; + SrsMediaPacket *msg = shared_video; SrsRtmpFormat *format = source_->format_; // cache the sequence header if h264 @@ -1186,9 +1186,9 @@ srs_error_t SrsOriginHub::on_forwarder_start(SrsForwarder *forwarder) { srs_error_t err = srs_success; - SrsSharedPtrMessage *cache_metadata = source_->meta->data(); - SrsSharedPtrMessage *cache_sh_video = source_->meta->vsh(); - SrsSharedPtrMessage *cache_sh_audio = source_->meta->ash(); + SrsMediaPacket *cache_metadata = source_->meta->data(); + SrsMediaPacket *cache_sh_video = source_->meta->vsh(); + SrsMediaPacket *cache_sh_audio = source_->meta->ash(); // feed the forwarder the metadata/sequence header, // when reload to enable the forwarder. @@ -1209,9 +1209,9 @@ srs_error_t SrsOriginHub::on_dvr_request_sh() { srs_error_t err = srs_success; - SrsSharedPtrMessage *cache_metadata = source_->meta->data(); - SrsSharedPtrMessage *cache_sh_video = source_->meta->vsh(); - SrsSharedPtrMessage *cache_sh_audio = source_->meta->ash(); + SrsMediaPacket *cache_metadata = source_->meta->data(); + SrsMediaPacket *cache_sh_video = source_->meta->vsh(); + SrsMediaPacket *cache_sh_audio = source_->meta->ash(); // feed the dvr the metadata/sequence header, // when reload to start dvr, dvr will never get the sequence header in stream, @@ -1239,14 +1239,14 @@ srs_error_t SrsOriginHub::on_hls_request_sh() { srs_error_t err = srs_success; - SrsSharedPtrMessage *cache_sh_video = source_->meta->vsh(); + SrsMediaPacket *cache_sh_video = source_->meta->vsh(); if (cache_sh_video) { if ((err = hls->on_video(cache_sh_video, source_->meta->vsh_format())) != srs_success) { return srs_error_wrap(err, "hls video"); } } - SrsSharedPtrMessage *cache_sh_audio = source_->meta->ash(); + SrsMediaPacket *cache_sh_audio = source_->meta->ash(); if (cache_sh_audio) { if ((err = hls->on_audio(cache_sh_audio, source_->meta->ash_format())) != srs_success) { return srs_error_wrap(err, "hls audio"); @@ -1399,12 +1399,12 @@ void SrsMetaCache::clear() srs_freep(audio); } -SrsSharedPtrMessage *SrsMetaCache::data() +SrsMediaPacket *SrsMetaCache::data() { return meta; } -SrsSharedPtrMessage *SrsMetaCache::vsh() +SrsMediaPacket *SrsMetaCache::vsh() { return video; } @@ -1414,7 +1414,7 @@ SrsFormat *SrsMetaCache::vsh_format() return vformat; } -SrsSharedPtrMessage *SrsMetaCache::ash() +SrsMediaPacket *SrsMetaCache::ash() { return audio; } @@ -1448,12 +1448,12 @@ srs_error_t SrsMetaCache::dumps(SrsLiveConsumer *consumer, bool atc, SrsRtmpJitt return err; } -SrsSharedPtrMessage *SrsMetaCache::previous_vsh() +SrsMediaPacket *SrsMetaCache::previous_vsh() { return previous_video; } -SrsSharedPtrMessage *SrsMetaCache::previous_ash() +SrsMediaPacket *SrsMetaCache::previous_ash() { return previous_audio; } @@ -1520,19 +1520,21 @@ srs_error_t SrsMetaCache::update_data(SrsMessageHeader *header, SrsOnMetaDataPac // create a shared ptr message. srs_freep(meta); - meta = new SrsSharedPtrMessage(); + meta = new SrsMediaPacket(); updated = true; // dump message to shared ptr message. // the payload/size managed by cache_metadata, user should not free it. - if ((err = meta->create(header, payload, size)) != srs_success) { + SrsCommonMessage common_msg; + if ((err = common_msg.create(header, payload, size)) != srs_success) { return srs_error_wrap(err, "create metadata"); } + common_msg.to_msg(meta); return err; } -srs_error_t SrsMetaCache::update_ash(SrsSharedPtrMessage *msg) +srs_error_t SrsMetaCache::update_ash(SrsMediaPacket *msg) { srs_freep(audio); audio = msg->copy(); @@ -1540,7 +1542,7 @@ srs_error_t SrsMetaCache::update_ash(SrsSharedPtrMessage *msg) return aformat->on_audio(msg); } -srs_error_t SrsMetaCache::update_vsh(SrsSharedPtrMessage *msg) +srs_error_t SrsMetaCache::update_vsh(SrsMediaPacket *msg) { srs_freep(video); video = msg->copy(); @@ -1962,7 +1964,6 @@ srs_error_t SrsLiveSource::on_meta_data(SrsCommonMessage *msg, SrsOnMetaDataPack srs_error_t SrsLiveSource::on_audio(SrsCommonMessage *shared_audio) { - srs_error_t err = srs_success; // Detect where stream is monotonically increasing. if (!mix_correct && is_monotonically_increase) { @@ -1976,15 +1977,13 @@ srs_error_t SrsLiveSource::on_audio(SrsCommonMessage *shared_audio) // convert shared_audio to msg, user should not use shared_audio again. // the payload is transfer to msg, and set to NULL in shared_audio. - SrsSharedPtrMessage msg; - if ((err = msg.create(shared_audio)) != srs_success) { - return srs_error_wrap(err, "create message"); - } + SrsMediaPacket msg; + shared_audio->to_msg(&msg); return on_frame(&msg); } -srs_error_t SrsLiveSource::on_frame(SrsSharedPtrMessage *msg) +srs_error_t SrsLiveSource::on_frame(SrsMediaPacket *msg) { srs_error_t err = srs_success; @@ -2001,7 +2000,7 @@ srs_error_t SrsLiveSource::on_frame(SrsSharedPtrMessage *msg) mix_queue->push(msg->copy()); // fetch someone from mix queue. - SrsSharedPtrMessage *m = mix_queue->pop(); + SrsMediaPacket *m = mix_queue->pop(); if (!m) { return err; } @@ -2017,7 +2016,7 @@ srs_error_t SrsLiveSource::on_frame(SrsSharedPtrMessage *msg) return err; } -srs_error_t SrsLiveSource::on_audio_imp(SrsSharedPtrMessage *msg) +srs_error_t SrsLiveSource::on_audio_imp(SrsMediaPacket *msg) { srs_error_t err = srs_success; @@ -2122,15 +2121,13 @@ srs_error_t SrsLiveSource::on_video(SrsCommonMessage *shared_video) // convert shared_video to msg, user should not use shared_video again. // the payload is transfer to msg, and set to NULL in shared_video. - SrsSharedPtrMessage msg; - if ((err = msg.create(shared_video)) != srs_success) { - return srs_error_wrap(err, "create message"); - } + SrsMediaPacket msg; + shared_video->to_msg(&msg); return on_frame(&msg); } -srs_error_t SrsLiveSource::on_video_imp(SrsSharedPtrMessage *msg) +srs_error_t SrsLiveSource::on_video_imp(SrsMediaPacket *msg) { srs_error_t err = srs_success; @@ -2271,7 +2268,6 @@ srs_error_t SrsLiveSource::on_aggregate(SrsCommonMessage *msg) o.header.timestamp_delta = timestamp; o.header.timestamp = timestamp; o.header.stream_id = stream_id; - o.header.prefer_cid = msg->header.prefer_cid; if (data_size > 0) { o.create_payload(data_size); diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index 6ce12e9ad..26f699b16 100644 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -29,7 +29,7 @@ class SrsPublishEdge; class SrsLiveSource; class SrsCommonMessage; class SrsOnMetaDataPacket; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsForwarder; class ISrsRequest; class SrsStSocket; @@ -73,7 +73,7 @@ public: public: // detect the time jitter and correct it. // @param ag the algorithm to use for time jitter. - virtual srs_error_t correct(SrsSharedPtrMessage *msg, SrsRtmpJitterAlgorithm ag); + virtual srs_error_t correct(SrsMediaPacket *msg, SrsRtmpJitterAlgorithm ag); // Get current client time, the last packet time. virtual int64_t get_time(); }; @@ -83,7 +83,7 @@ public: class SrsFastVector { private: - SrsSharedPtrMessage **msgs; + SrsMediaPacket **msgs; int nb_msgs; int count; @@ -95,11 +95,11 @@ public: virtual int size(); virtual int begin(); virtual int end(); - virtual SrsSharedPtrMessage **data(); - virtual SrsSharedPtrMessage *at(int index); + virtual SrsMediaPacket **data(); + virtual SrsMediaPacket *at(int index); virtual void clear(); virtual void erase(int _begin, int _end); - virtual void push_back(SrsSharedPtrMessage *msg); + virtual void push_back(SrsMediaPacket *msg); virtual void free(); }; #endif @@ -121,7 +121,7 @@ private: #ifdef SRS_PERF_QUEUE_FAST_VECTOR SrsFastVector msgs; #else - std::vector msgs; + std::vector msgs; #endif public: SrsMessageQueue(bool ignore_shrink = false); @@ -140,12 +140,12 @@ public: // Enqueue the message, the timestamp always monotonically. // @param msg, the msg to enqueue, user never free it whatever the return code. // @param is_overflow, whether overflow and shrinked. NULL to ignore. - virtual srs_error_t enqueue(SrsSharedPtrMessage *msg, bool *is_overflow = NULL); + virtual srs_error_t enqueue(SrsMediaPacket *msg, bool *is_overflow = NULL); // Get packets in consumer queue. - // @pmsgs SrsSharedPtrMessage*[], used to store the msgs, user must alloc it. + // @pmsgs SrsMediaPacket*[], used to store the msgs, user must alloc it. // @count the count in array, output param. // @max_count the max count to dequeue, must be positive. - virtual srs_error_t dump_packets(int max_count, SrsSharedPtrMessage **pmsgs, int &count); + virtual srs_error_t dump_packets(int max_count, SrsMediaPacket **pmsgs, int &count); // Dumps packets to consumer, use specified args. // @remark the atc/tba/tbv/ag are same to SrsLiveConsumer.enqueue(). virtual srs_error_t dump_packets(SrsLiveConsumer *consumer, bool atc, SrsRtmpJitterAlgorithm ag); @@ -212,7 +212,7 @@ public: // @param shared_msg, directly ptr, copy it if need to save it. // @param whether atc, donot use jitter correct if true. // @param ag the algorithm of time jitter. - virtual srs_error_t enqueue(SrsSharedPtrMessage *shared_msg, bool atc, SrsRtmpJitterAlgorithm ag); + virtual srs_error_t enqueue(SrsMediaPacket *shared_msg, bool atc, SrsRtmpJitterAlgorithm ag); // Get packets in consumer queue. // @param msgs the msgs array to dump packets to send. // @param count the count in array, intput and output param. @@ -262,7 +262,7 @@ private: // @see: https://github.com/ossrs/srs/issues/124 int audio_after_last_video_count; // cached gop. - std::vector gop_cache; + std::vector gop_cache; public: SrsGopCache(); @@ -279,7 +279,7 @@ public: // 1. cache the gop when got h264 video packet. // 2. clear gop when got keyframe. // @param shared_msg, directly ptr, copy it if need to save it. - virtual srs_error_t cache(SrsSharedPtrMessage *shared_msg); + virtual srs_error_t cache(SrsMediaPacket *shared_msg); // clear the gop cache. virtual void clear(); // dump the cached gop to consumer. @@ -317,7 +317,7 @@ class SrsMixQueue private: uint32_t nb_videos; uint32_t nb_audios; - std::multimap msgs; + std::multimap msgs; public: SrsMixQueue(); @@ -325,8 +325,8 @@ public: public: virtual void clear(); - virtual void push(SrsSharedPtrMessage *msg); - virtual SrsSharedPtrMessage *pop(); + virtual void push(SrsMediaPacket *msg); + virtual SrsMediaPacket *pop(); }; // The hub for origin is a collection of utilities for origin only, @@ -381,11 +381,11 @@ public: public: // When got a parsed metadata. - virtual srs_error_t on_meta_data(SrsSharedPtrMessage *shared_metadata, SrsOnMetaDataPacket *packet); + virtual srs_error_t on_meta_data(SrsMediaPacket *shared_metadata, SrsOnMetaDataPacket *packet); // When got a parsed audio packet. - virtual srs_error_t on_audio(SrsSharedPtrMessage *shared_audio); + virtual srs_error_t on_audio(SrsMediaPacket *shared_audio); // When got a parsed video packet. - virtual srs_error_t on_video(SrsSharedPtrMessage *shared_video, bool is_sequence_header); + virtual srs_error_t on_video(SrsMediaPacket *shared_video, bool is_sequence_header); public: // When start publish stream. @@ -413,13 +413,13 @@ class SrsMetaCache { private: // The cached metadata, FLV script data tag. - SrsSharedPtrMessage *meta; + SrsMediaPacket *meta; // The cached video sequence header, for example, sps/pps for h.264. - SrsSharedPtrMessage *video; - SrsSharedPtrMessage *previous_video; + SrsMediaPacket *video; + SrsMediaPacket *previous_video; // The cached audio sequence header, for example, asc for aac. - SrsSharedPtrMessage *audio; - SrsSharedPtrMessage *previous_audio; + SrsMediaPacket *audio; + SrsMediaPacket *previous_audio; // The format for sequence header. SrsRtmpFormat *vformat; SrsRtmpFormat *aformat; @@ -436,12 +436,12 @@ public: public: // Get the cached metadata. - virtual SrsSharedPtrMessage *data(); + virtual SrsMediaPacket *data(); // Get the cached vsh(video sequence header). - virtual SrsSharedPtrMessage *vsh(); + virtual SrsMediaPacket *vsh(); virtual SrsFormat *vsh_format(); // Get the cached ash(audio sequence header). - virtual SrsSharedPtrMessage *ash(); + virtual SrsMediaPacket *ash(); virtual SrsFormat *ash_format(); // Dumps cached metadata to consumer. // @param dm Whether dumps the metadata. @@ -450,8 +450,8 @@ public: public: // Previous exists sequence header. - virtual SrsSharedPtrMessage *previous_vsh(); - virtual SrsSharedPtrMessage *previous_ash(); + virtual SrsMediaPacket *previous_vsh(); + virtual SrsMediaPacket *previous_ash(); // Update previous sequence header, drop old one, set to new sequence header. virtual void update_previous_vsh(); virtual void update_previous_ash(); @@ -460,9 +460,9 @@ public: // Update the cached metadata by packet. virtual srs_error_t update_data(SrsMessageHeader *header, SrsOnMetaDataPacket *metadata, bool &updated); // Update the cached audio sequence header. - virtual srs_error_t update_ash(SrsSharedPtrMessage *msg); + virtual srs_error_t update_ash(SrsMediaPacket *msg); // Update the cached video sequence header. - virtual srs_error_t update_vsh(SrsSharedPtrMessage *msg); + virtual srs_error_t update_vsh(SrsMediaPacket *msg); }; // The source manager to create and refresh all stream sources. @@ -595,19 +595,19 @@ public: virtual srs_error_t on_meta_data(SrsCommonMessage *msg, SrsOnMetaDataPacket *metadata); public: - // TODO: FIXME: Use SrsSharedPtrMessage instead. + // TODO: FIXME: Use SrsMediaPacket instead. virtual srs_error_t on_audio(SrsCommonMessage *audio); - srs_error_t on_frame(SrsSharedPtrMessage *msg); + srs_error_t on_frame(SrsMediaPacket *msg); private: - virtual srs_error_t on_audio_imp(SrsSharedPtrMessage *audio); + virtual srs_error_t on_audio_imp(SrsMediaPacket *audio); public: - // TODO: FIXME: Use SrsSharedPtrMessage instead. + // TODO: FIXME: Use SrsMediaPacket instead. virtual srs_error_t on_video(SrsCommonMessage *video); private: - virtual srs_error_t on_video_imp(SrsSharedPtrMessage *video); + virtual srs_error_t on_video_imp(SrsMediaPacket *video); public: virtual srs_error_t on_aggregate(SrsCommonMessage *msg); diff --git a/trunk/src/app/srs_app_srt_source.cpp b/trunk/src/app/srs_app_srt_source.cpp index e9e1c6c5c..d9abf9f97 100644 --- a/trunk/src/app/srs_app_srt_source.cpp +++ b/trunk/src/app/srs_app_srt_source.cpp @@ -46,7 +46,7 @@ char *SrsSrtPacket::wrap(int size) // Create a large enough message, with under-layer buffer. srs_freep(shared_buffer_); - shared_buffer_ = new SrsSharedPtrMessage(); + shared_buffer_ = new SrsMediaPacket(); char *buf = new char[size]; shared_buffer_->wrap(buf, size); @@ -61,7 +61,7 @@ char *SrsSrtPacket::wrap(char *data, int size) return buf; } -char *SrsSrtPacket::wrap(SrsSharedPtrMessage *msg) +char *SrsSrtPacket::wrap(SrsMediaPacket *msg) { // Generally, the wrap(msg) is used for RTMP to SRT, where the msg // is not generated by SRT. @@ -79,7 +79,7 @@ SrsSrtPacket *SrsSrtPacket::copy() { SrsSrtPacket *cp = new SrsSrtPacket(); - cp->shared_buffer_ = shared_buffer_ ? shared_buffer_->copy2() : NULL; + cp->shared_buffer_ = shared_buffer_ ? shared_buffer_->copy() : NULL; cp->actual_buffer_size_ = actual_buffer_size_; return cp; @@ -507,10 +507,8 @@ srs_error_t SrsSrtFrameBuilder::check_sps_pps_change(SrsTsMessage *msg) return srs_error_wrap(err, "create rtmp"); } - SrsSharedPtrMessage frame; - if ((err = frame.create(&rtmp)) != srs_success) { - return srs_error_wrap(err, "create frame"); - } + SrsMediaPacket frame; + rtmp.to_msg(&frame); if ((err = bridge_->on_frame(&frame)) != srs_success) { return srs_error_wrap(err, "srt to rtmp sps/pps"); @@ -567,10 +565,8 @@ srs_error_t SrsSrtFrameBuilder::on_h264_frame(SrsTsMessage *msg, vectoron_frame(&frame)) != srs_success) { return srs_error_wrap(err, "srt ts video to rtmp"); @@ -697,10 +693,8 @@ srs_error_t SrsSrtFrameBuilder::check_vps_sps_pps_change(SrsTsMessage *msg) return srs_error_wrap(err, "create rtmp"); } - SrsSharedPtrMessage frame; - if ((err = frame.create(&rtmp)) != srs_success) { - return srs_error_wrap(err, "create frame"); - } + SrsMediaPacket frame; + rtmp.to_msg(&frame); if ((err = bridge_->on_frame(&frame)) != srs_success) { return srs_error_wrap(err, "srt to rtmp vps/sps/pps"); @@ -764,10 +758,8 @@ srs_error_t SrsSrtFrameBuilder::on_hevc_frame(SrsTsMessage *msg, vectoron_frame(&frame)) != srs_success) { return srs_error_wrap(err, "srt ts hevc video to rtmp"); @@ -880,10 +872,8 @@ srs_error_t SrsSrtFrameBuilder::check_audio_sh_change(SrsTsMessage *msg, uint32_ stream.write_1bytes(0); stream.write_bytes((char *)audio_sh_.data(), audio_sh_.size()); - SrsSharedPtrMessage frame; - if ((err = frame.create(&rtmp)) != srs_success) { - return srs_error_wrap(err, "create frame"); - } + SrsMediaPacket frame; + rtmp.to_msg(&frame); if ((err = bridge_->on_frame(&frame)) != srs_success) { return srs_error_wrap(err, "srt to rtmp audio sh"); @@ -910,10 +900,8 @@ srs_error_t SrsSrtFrameBuilder::on_aac_frame(SrsTsMessage *msg, uint32_t pts, ch // Write audio frame. stream.write_bytes(data, data_size); - SrsSharedPtrMessage frame; - if ((err = frame.create(&rtmp)) != srs_success) { - return srs_error_wrap(err, "create frame"); - } + SrsMediaPacket frame; + rtmp.to_msg(&frame); if ((err = bridge_->on_frame(&frame)) != srs_success) { return srs_error_wrap(err, "srt to rtmp audio sh"); diff --git a/trunk/src/app/srs_app_srt_source.hpp b/trunk/src/app/srs_app_srt_source.hpp index 25c4b5ee1..63774f065 100644 --- a/trunk/src/app/srs_app_srt_source.hpp +++ b/trunk/src/app/srs_app_srt_source.hpp @@ -18,7 +18,7 @@ #include #include -class SrsSharedPtrMessage; +class SrsMediaPacket; class ISrsRequest; class SrsLiveSource; class SrsSrtSource; @@ -37,7 +37,7 @@ public: char *wrap(int size); char *wrap(char *data, int size); // Wrap the shared message, we copy it. - char *wrap(SrsSharedPtrMessage *msg); + char *wrap(SrsMediaPacket *msg); // Copy the SRT packet. virtual SrsSrtPacket *copy(); @@ -46,7 +46,7 @@ public: int size(); private: - SrsSharedPtrMessage *shared_buffer_; + SrsMediaPacket *shared_buffer_; // The size of SRT packet or SRT payload. int actual_buffer_size_; }; diff --git a/trunk/src/app/srs_app_stream_bridge.cpp b/trunk/src/app/srs_app_stream_bridge.cpp index 0b4d39ebd..20423c5e2 100644 --- a/trunk/src/app/srs_app_stream_bridge.cpp +++ b/trunk/src/app/srs_app_stream_bridge.cpp @@ -60,7 +60,7 @@ void SrsFrameToRtmpBridge::on_unpublish() source_->on_unpublish(); } -srs_error_t SrsFrameToRtmpBridge::on_frame(SrsSharedPtrMessage *frame) +srs_error_t SrsFrameToRtmpBridge::on_frame(SrsMediaPacket *frame) { return source_->on_frame(frame); } @@ -120,7 +120,7 @@ void SrsFrameToRtcBridge::on_unpublish() source_->on_unpublish(); } -srs_error_t SrsFrameToRtcBridge::on_frame(SrsSharedPtrMessage *frame) +srs_error_t SrsFrameToRtcBridge::on_frame(SrsMediaPacket *frame) { #ifdef SRS_FFMPEG_FIT return rtp_builder_->on_frame(frame); @@ -178,7 +178,7 @@ void SrsFrameToRtspBridge::on_unpublish() source_->on_unpublish(); } -srs_error_t SrsFrameToRtspBridge::on_frame(SrsSharedPtrMessage *frame) +srs_error_t SrsFrameToRtspBridge::on_frame(SrsMediaPacket *frame) { return rtp_builder_->on_frame(frame); } @@ -237,7 +237,7 @@ void SrsCompositeBridge::on_unpublish() } } -srs_error_t SrsCompositeBridge::on_frame(SrsSharedPtrMessage *frame) +srs_error_t SrsCompositeBridge::on_frame(SrsMediaPacket *frame) { srs_error_t err = srs_success; diff --git a/trunk/src/app/srs_app_stream_bridge.hpp b/trunk/src/app/srs_app_stream_bridge.hpp index 143a08566..b3aa26735 100644 --- a/trunk/src/app/srs_app_stream_bridge.hpp +++ b/trunk/src/app/srs_app_stream_bridge.hpp @@ -15,7 +15,7 @@ #include class ISrsRequest; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsLiveSource; class SrsRtcSource; class SrsRtmpFormat; @@ -37,7 +37,7 @@ public: public: virtual srs_error_t initialize(ISrsRequest *r) = 0; virtual srs_error_t on_publish() = 0; - virtual srs_error_t on_frame(SrsSharedPtrMessage *frame) = 0; + virtual srs_error_t on_frame(SrsMediaPacket *frame) = 0; virtual void on_unpublish() = 0; }; @@ -59,7 +59,7 @@ public: virtual void on_unpublish(); public: - virtual srs_error_t on_frame(SrsSharedPtrMessage *frame); + virtual srs_error_t on_frame(SrsMediaPacket *frame); }; // A bridge to covert AV frame to WebRTC stream. @@ -80,7 +80,7 @@ public: virtual srs_error_t initialize(ISrsRequest *r); virtual srs_error_t on_publish(); virtual void on_unpublish(); - virtual srs_error_t on_frame(SrsSharedPtrMessage *frame); + virtual srs_error_t on_frame(SrsMediaPacket *frame); srs_error_t on_rtp(SrsRtpPacket *pkt); }; @@ -102,7 +102,7 @@ public: virtual srs_error_t initialize(ISrsRequest *r); virtual srs_error_t on_publish(); virtual void on_unpublish(); - virtual srs_error_t on_frame(SrsSharedPtrMessage *frame); + virtual srs_error_t on_frame(SrsMediaPacket *frame); srs_error_t on_rtp(SrsRtpPacket *pkt); }; #endif @@ -124,7 +124,7 @@ public: virtual void on_unpublish(); public: - virtual srs_error_t on_frame(SrsSharedPtrMessage *frame); + virtual srs_error_t on_frame(SrsMediaPacket *frame); public: SrsCompositeBridge *append(ISrsStreamBridge *bridge); diff --git a/trunk/src/core/srs_core_version7.hpp b/trunk/src/core/srs_core_version7.hpp index cbd70bbab..a76ba6b5e 100644 --- a/trunk/src/core/srs_core_version7.hpp +++ b/trunk/src/core/srs_core_version7.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 7 #define VERSION_MINOR 0 -#define VERSION_REVISION 73 +#define VERSION_REVISION 74 #endif \ No newline at end of file diff --git a/trunk/src/kernel/srs_kernel_codec.cpp b/trunk/src/kernel/srs_kernel_codec.cpp index 05194cac9..dead7d652 100644 --- a/trunk/src/kernel/srs_kernel_codec.cpp +++ b/trunk/src/kernel/srs_kernel_codec.cpp @@ -14,6 +14,7 @@ using namespace std; #include #include #include +#include #include #include #include @@ -715,30 +716,6 @@ string srs_hevc_level2str(SrsHevcLevel level) } } -SrsSample::SrsSample() -{ - size = 0; - bytes = NULL; -} - -SrsSample::SrsSample(char *b, int s) -{ - size = s; - bytes = b; -} - -SrsSample::~SrsSample() -{ -} - -SrsSample *SrsSample::copy() -{ - SrsSample *p = new SrsSample(); - p->bytes = bytes; - p->size = size; - return p; -} - SrsCodecConfig::SrsCodecConfig() { } @@ -795,2354 +772,6 @@ bool SrsVideoCodecConfig::is_avc_codec_ok() return !avc_extra_data.empty(); } -SrsFrame::SrsFrame() -{ - codec = NULL; - nb_samples = 0; - dts = 0; - cts = 0; -} - -SrsFrame::~SrsFrame() -{ -} - -srs_error_t SrsFrame::initialize(SrsCodecConfig *c) -{ - codec = c; - nb_samples = 0; - dts = 0; - cts = 0; - return srs_success; -} - -srs_error_t SrsFrame::add_sample(char *bytes, int size) -{ - srs_error_t err = srs_success; - - // Ignore empty sample. - if (!bytes || size <= 0) - return err; - - if (nb_samples >= SrsMaxNbSamples) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "Frame samples overflow"); - } - - SrsSample *sample = &samples[nb_samples++]; - sample->bytes = bytes; - sample->size = size; - - return err; -} - -SrsAudioFrame::SrsAudioFrame() -{ - aac_packet_type = SrsAudioAacFrameTraitForbidden; -} - -SrsAudioFrame::~SrsAudioFrame() -{ -} - -SrsAudioCodecConfig *SrsAudioFrame::acodec() -{ - return (SrsAudioCodecConfig *)codec; -} - -SrsVideoFrame::SrsVideoFrame() -{ - frame_type = SrsVideoAvcFrameTypeForbidden; - avc_packet_type = SrsVideoAvcFrameTraitForbidden; - has_idr = has_aud = has_sps_pps = false; - first_nalu_type = SrsAvcNaluTypeForbidden; -} - -SrsVideoFrame::~SrsVideoFrame() -{ -} - -srs_error_t SrsVideoFrame::initialize(SrsCodecConfig *c) -{ - first_nalu_type = SrsAvcNaluTypeForbidden; - has_idr = has_sps_pps = has_aud = false; - return SrsFrame::initialize(c); -} - -srs_error_t SrsVideoFrame::add_sample(char *bytes, int size) -{ - srs_error_t err = srs_success; - - if ((err = SrsFrame::add_sample(bytes, size)) != srs_success) { - return srs_error_wrap(err, "add frame"); - } - - SrsVideoCodecConfig *c = vcodec(); - if (!bytes || size <= 0) - return err; - - // For HEVC(H.265), try to parse the IDR from NALUs. - if (c && c->id == SrsVideoCodecIdHEVC) { - SrsHevcNaluType nalu_type = SrsHevcNaluTypeParse(bytes[0]); - has_idr = SrsIsIRAP(nalu_type); - return err; - } - - // By default, use AVC(H.264) to parse NALU. - // For video, parse the nalu type, set the IDR flag. - SrsAvcNaluType nal_unit_type = SrsAvcNaluTypeParse(bytes[0]); - - if (nal_unit_type == SrsAvcNaluTypeIDR) { - has_idr = true; - } else if (nal_unit_type == SrsAvcNaluTypeSPS || nal_unit_type == SrsAvcNaluTypePPS) { - has_sps_pps = true; - } else if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) { - has_aud = true; - } - - if (first_nalu_type == SrsAvcNaluTypeReserved) { - first_nalu_type = nal_unit_type; - } - - return err; -} - -SrsVideoCodecConfig *SrsVideoFrame::vcodec() -{ - return (SrsVideoCodecConfig *)codec; -} - -srs_error_t SrsVideoFrame::parse_avc_nalu_type(const SrsSample *sample, SrsAvcNaluType &avc_nalu_type) -{ - srs_error_t err = srs_success; - - if (sample == NULL || sample->size < 1) { - return srs_error_new(ERROR_NALU_EMPTY, "empty nalu"); - } - - uint8_t header = sample->bytes[0]; - avc_nalu_type = SrsAvcNaluTypeParse(header); - - return err; -} - -srs_error_t SrsVideoFrame::parse_avc_bframe(const SrsSample *sample, bool &is_b_frame) -{ - srs_error_t err = srs_success; - - SrsAvcNaluType nalu_type; - if ((err = parse_avc_nalu_type(sample, nalu_type)) != srs_success) { - return srs_error_wrap(err, "parse avc nalu type error"); - } - - if (nalu_type != SrsAvcNaluTypeNonIDR && nalu_type != SrsAvcNaluTypeDataPartitionA && nalu_type != SrsAvcNaluTypeDataPartitionB && nalu_type != SrsAvcNaluTypeDataPartitionC) { - is_b_frame = false; - return err; - } - - SrsUniquePtr stream(new SrsBuffer(sample->bytes, sample->size)); - - // Skip nalu header. - stream->skip(1); - - SrsBitBuffer bitstream(stream.get()); - int32_t first_mb_in_slice = 0; - if ((err = srs_avc_nalu_read_uev(&bitstream, first_mb_in_slice)) != srs_success) { - return srs_error_wrap(err, "nalu read uev"); - } - - int32_t slice_type_v = 0; - if ((err = srs_avc_nalu_read_uev(&bitstream, slice_type_v)) != srs_success) { - return srs_error_wrap(err, "nalu read uev"); - } - SrsAvcSliceType slice_type = (SrsAvcSliceType)slice_type_v; - - is_b_frame = slice_type == SrsAvcSliceTypeB || slice_type == SrsAvcSliceTypeB1; - if (is_b_frame) { - srs_verbose("nalu_type=%d, slice type=%d", nalu_type, slice_type); - } - - return err; -} - -srs_error_t SrsVideoFrame::parse_hevc_nalu_type(const SrsSample *sample, SrsHevcNaluType &hevc_nalu_type) -{ - srs_error_t err = srs_success; - - if (sample == NULL || sample->size < 1) { - return srs_error_new(ERROR_NALU_EMPTY, "empty hevc nalu"); - } - - uint8_t header = sample->bytes[0]; - hevc_nalu_type = SrsHevcNaluTypeParse(header); - - return err; -} - -srs_error_t SrsVideoFrame::parse_hevc_bframe(const SrsSample *sample, SrsFormat *format, bool &is_b_frame) -{ - srs_error_t err = srs_success; - - SrsHevcNaluType nalu_type; - if ((err = parse_hevc_nalu_type(sample, nalu_type)) != srs_success) { - return srs_error_wrap(err, "parse hevc nalu type error"); - } - - if (nalu_type > SrsHevcNaluType_CODED_SLICE_TFD) { - is_b_frame = false; - return err; - } - - SrsUniquePtr stream(new SrsBuffer(sample->bytes, sample->size)); - stream->skip(2); - - // @see 7.3.6.1 General slice segment header syntax - // @doc ITU-T-H.265-2021.pdf, page 66. - SrsBitBuffer bs(stream.get()); - - uint8_t first_slice_segment_in_pic_flag = bs.read_bit(); - - uint32_t slice_pic_parameter_set_id; - if ((err = bs.read_bits_ue(slice_pic_parameter_set_id)) != srs_success) { - return srs_error_wrap(err, "read slice pic parameter set id"); - } - - if (slice_pic_parameter_set_id >= SrsHevcMax_PPS_COUNT) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "slice pic parameter set id out of range: %d", slice_pic_parameter_set_id); - } - - SrsHevcRbspPps *pps = &(format->vcodec->hevc_dec_conf_record_.pps_table[slice_pic_parameter_set_id]); - if (!pps) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps not found"); - } - - uint8_t dependent_slice_segment_flag = 0; - if (!first_slice_segment_in_pic_flag) { - if (pps->dependent_slice_segments_enabled_flag) { - dependent_slice_segment_flag = bs.read_bit(); - } - } - - if (dependent_slice_segment_flag) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "dependent slice segment flag is not supported"); - } - - for (int i = 0; i < pps->num_extra_slice_header_bits; i++) { - bs.skip_bits(1); - } - - uint32_t slice_type; - if ((err = bs.read_bits_ue(slice_type)) != srs_success) { - return srs_error_wrap(err, "read slice type"); - } - - is_b_frame = slice_type == SrsHevcSliceTypeB; - if (is_b_frame) { - srs_verbose("nalu_type=%d, slice type=%d", nalu_type, slice_type); - } - - // no need to evaluate the rest - - return err; -} - -SrsFormat::SrsFormat() -{ - acodec = NULL; - vcodec = NULL; - audio = NULL; - video = NULL; - avc_parse_sps = true; - try_annexb_first = true; - raw = NULL; - nb_raw = 0; -} - -SrsFormat::~SrsFormat() -{ - srs_freep(audio); - srs_freep(video); - srs_freep(acodec); - srs_freep(vcodec); -} - -// CRITICAL: This method is called AFTER the source has been added to the source pool -// in the fetch_or_create pattern (see PR 4449). -// -// IMPORTANT: All field initialization in this method MUST NOT cause coroutine context switches. -// This prevents the race condition where multiple coroutines could create duplicate sources -// for the same stream when context switches occurred during initialization. -srs_error_t SrsFormat::initialize() -{ - if (!vcodec) { - vcodec = new SrsVideoCodecConfig(); - } - - return srs_success; -} - -srs_error_t SrsFormat::on_audio(int64_t timestamp, char *data, int size) -{ - srs_error_t err = srs_success; - - if (!data || size <= 0) { - srs_info("no audio present, ignore it."); - return err; - } - - SrsUniquePtr buffer(new SrsBuffer(data, size)); - - // We already checked the size is positive and data is not NULL. - srs_assert(buffer->require(1)); - - // @see: E.4.2 Audio Tags, video_file_format_spec_v10_1.pdf, page 76 - uint8_t v = buffer->read_1bytes(); - SrsAudioCodecId codec = (SrsAudioCodecId)((v >> 4) & 0x0f); - - if (codec != SrsAudioCodecIdMP3 && codec != SrsAudioCodecIdAAC && codec != SrsAudioCodecIdOpus) { - return err; - } - - bool fresh = !acodec; - if (!acodec) { - acodec = new SrsAudioCodecConfig(); - } - if (!audio) { - audio = new SrsAudioFrame(); - } - - if ((err = audio->initialize(acodec)) != srs_success) { - return srs_error_wrap(err, "init audio"); - } - - // Parse by specified codec. - buffer->skip(-1 * buffer->pos()); - - if (codec == SrsAudioCodecIdMP3) { - return audio_mp3_demux(buffer.get(), timestamp, fresh); - } else if (codec == SrsAudioCodecIdAAC) { - return audio_aac_demux(buffer.get(), timestamp); - } else { - return srs_error_new(ERROR_NOT_IMPLEMENTED, "opus demuxer not implemented"); - } -} - -srs_error_t SrsFormat::on_video(int64_t timestamp, char *data, int size) -{ - srs_error_t err = srs_success; - - if (!data || size <= 0) { - srs_trace("no video present, ignore it."); - return err; - } - - SrsUniquePtr buffer(new SrsBuffer(data, size)); - return video_avc_demux(buffer.get(), timestamp); -} - -srs_error_t SrsFormat::on_aac_sequence_header(char *data, int size) -{ - srs_error_t err = srs_success; - - if (!acodec) { - acodec = new SrsAudioCodecConfig(); - } - if (!audio) { - audio = new SrsAudioFrame(); - } - - if ((err = audio->initialize(acodec)) != srs_success) { - return srs_error_wrap(err, "init audio"); - } - - return audio_aac_sequence_header_demux(data, size); -} - -bool SrsFormat::is_aac_sequence_header() -{ - return acodec && acodec->id == SrsAudioCodecIdAAC && audio && audio->aac_packet_type == SrsAudioAacFrameTraitSequenceHeader; -} - -bool SrsFormat::is_mp3_sequence_header() -{ - return acodec && acodec->id == SrsAudioCodecIdMP3 && audio && audio->aac_packet_type == SrsAudioMp3FrameTraitSequenceHeader; -} - -bool SrsFormat::is_avc_sequence_header() -{ - bool h264 = (vcodec && vcodec->id == SrsVideoCodecIdAVC); - bool h265 = (vcodec && vcodec->id == SrsVideoCodecIdHEVC); - bool av1 = (vcodec && vcodec->id == SrsVideoCodecIdAV1); - return vcodec && (h264 || h265 || av1) && video && video->avc_packet_type == SrsVideoAvcFrameTraitSequenceHeader; -} - -// Remove the emulation bytes from stream, and return num of bytes of the rbsp. -int srs_rbsp_remove_emulation_bytes(SrsBuffer *stream, std::vector &rbsp) -{ - int nb_rbsp = 0; - while (!stream->empty()) { - rbsp[nb_rbsp] = stream->read_1bytes(); - - // .. 00 00 03 xx, the 03 byte should be drop where xx represents any - // 2 bit pattern: 00, 01, 10, or 11. - if (nb_rbsp >= 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) { - // read 1byte more. - if (stream->empty()) { - nb_rbsp++; - break; - } - - // |---------------------|----------------------------| - // | rbsp | nalu with emulation bytes | - // |---------------------|----------------------------| - // | 0x00 0x00 0x00 | 0x00 0x00 0x03 0x00 | - // | 0x00 0x00 0x01 | 0x00 0x00 0x03 0x01 | - // | 0x00 0x00 0x02 | 0x00 0x00 0x03 0x02 | - // | 0x00 0x00 0x03 | 0x00 0x00 0x03 0x03 | - // | 0x00 0x00 0x03 0x04 | 0x00 0x00 0x03 0x04 | - // |---------------------|----------------------------| - uint8_t ev = stream->read_1bytes(); - if (ev > 3) { - nb_rbsp++; - } - rbsp[nb_rbsp] = ev; - } - - nb_rbsp++; - } - - return nb_rbsp; -} - -srs_error_t SrsFormat::video_avc_demux(SrsBuffer *stream, int64_t timestamp) -{ - srs_error_t err = srs_success; - - if (!stream->require(1)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "video avc demux shall atleast 1bytes"); - } - - // Parse the frame type and the first bit indicates the ext header. - uint8_t frame_type = stream->read_1bytes(); - bool is_ext_header = frame_type & 0x80; - - // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78 - SrsVideoCodecId codec_id = SrsVideoCodecIdForbidden; - SrsVideoAvcFrameTrait packet_type = SrsVideoAvcFrameTraitForbidden; - if (!is_ext_header) { - // See rtmp_specification_1.0.pdf - codec_id = (SrsVideoCodecId)(frame_type & 0x0f); - frame_type = (frame_type >> 4) & 0x0f; - } else { - // See https://github.com/veovera/enhanced-rtmp - packet_type = (SrsVideoAvcFrameTrait)(frame_type & 0x0f); - frame_type = (frame_type >> 4) & 0x07; - - if (!stream->require(4)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "fourCC requires 4bytes, only %dbytes", stream->left()); - } - - uint32_t four_cc = stream->read_4bytes(); - if (four_cc == 0x68766331) { // 'hvc1'=0x68766331 - codec_id = SrsVideoCodecIdHEVC; - } - } - - if (!vcodec) { - vcodec = new SrsVideoCodecConfig(); - } - - if (!video) { - video = new SrsVideoFrame(); - } - - if ((err = video->initialize(vcodec)) != srs_success) { - return srs_error_wrap(err, "init video"); - } - - video->frame_type = (SrsVideoAvcFrameType)frame_type; - - // ignore info frame without error, - // @see https://github.com/ossrs/srs/issues/288#issuecomment-69863909 - if (video->frame_type == SrsVideoAvcFrameTypeVideoInfoFrame) { - srs_warn("avc ignore the info frame"); - return err; - } - - // Check codec for H.264 and H.265. - bool codec_ok = (codec_id == SrsVideoCodecIdAVC); - codec_ok = codec_ok ? true : (codec_id == SrsVideoCodecIdHEVC); - if (!codec_ok) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "only support video H.264/H.265, actual=%d", codec_id); - } - vcodec->id = codec_id; - - int32_t composition_time = 0; - if (!is_ext_header) { - // See rtmp_specification_1.0.pdf - if (!stream->require(4)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "requires 4bytes, only %dbytes", stream->left()); - } - packet_type = (SrsVideoAvcFrameTrait)stream->read_1bytes(); - composition_time = stream->read_3bytes(); - } else { - // See https://github.com/veovera/enhanced-rtmp - if (packet_type == SrsVideoHEVCFrameTraitPacketTypeCodedFrames) { - if (!stream->require(3)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "requires 3 bytes, only %dbytes", stream->left()); - } - composition_time = stream->read_3bytes(); - } - } - - // pts = dts + cts. - video->dts = timestamp; - video->cts = composition_time; - video->avc_packet_type = packet_type; - - // Update the RAW AVC data. - raw = stream->data() + stream->pos(); - nb_raw = stream->size() - stream->pos(); - - // Parse sequence header for H.265/HEVC. - if (codec_id == SrsVideoCodecIdHEVC) { - if (packet_type == SrsVideoAvcFrameTraitSequenceHeader) { - // TODO: demux vps/sps/pps for hevc - if ((err = hevc_demux_hvcc(stream)) != srs_success) { - return srs_error_wrap(err, "demux hevc VPS/SPS/PPS"); - } - } else if (packet_type == SrsVideoAvcFrameTraitNALU || packet_type == SrsVideoHEVCFrameTraitPacketTypeCodedFramesX) { - // TODO: demux nalu for hevc - if ((err = video_nalu_demux(stream)) != srs_success) { - return srs_error_wrap(err, "demux hevc NALU"); - } - } - return err; - } - - // Parse sequence header for H.264/AVC. - if (packet_type == SrsVideoAvcFrameTraitSequenceHeader) { - // TODO: FIXME: Maybe we should ignore any error for parsing sps/pps. - if ((err = avc_demux_sps_pps(stream)) != srs_success) { - return srs_error_wrap(err, "demux SPS/PPS"); - } - } else if (packet_type == SrsVideoAvcFrameTraitNALU) { - if ((err = video_nalu_demux(stream)) != srs_success) { - return srs_error_wrap(err, "demux NALU"); - } - } else { - // ignored. - } - - return err; -} - -// For media server, we don't care the codec, so we just try to parse sps-pps, and we could ignore any error if fail. -// LCOV_EXCL_START - -// struct ptl -SrsHevcProfileTierLevel::SrsHevcProfileTierLevel() -{ - general_profile_space = 0; - general_tier_flag = 0; - general_profile_idc = 0; - memset(general_profile_compatibility_flag, 0, 32); - general_progressive_source_flag = 0; - general_interlaced_source_flag = 0; - general_non_packed_constraint_flag = 0; - general_frame_only_constraint_flag = 0; - general_max_12bit_constraint_flag = 0; - general_max_10bit_constraint_flag = 0; - general_max_8bit_constraint_flag = 0; - general_max_422chroma_constraint_flag = 0; - general_max_420chroma_constraint_flag = 0; - general_max_monochrome_constraint_flag = 0; - general_intra_constraint_flag = 0; - general_one_picture_only_constraint_flag = 0; - general_lower_bit_rate_constraint_flag = 0; - general_max_14bit_constraint_flag = 0; - general_reserved_zero_7bits = 0; - general_reserved_zero_33bits = 0; - general_reserved_zero_34bits = 0; - general_reserved_zero_35bits = 0; - general_reserved_zero_43bits = 0; - general_inbld_flag = 0; - general_reserved_zero_bit = 0; - general_level_idc = 0; - memset(reserved_zero_2bits, 0, 8); -} - -SrsHevcProfileTierLevel::~SrsHevcProfileTierLevel() -{ -} - -// Parse the hevc vps/sps/pps -srs_error_t SrsFormat::hevc_demux_hvcc(SrsBuffer *stream) -{ - srs_error_t err = srs_success; - - int avc_extra_size = stream->size() - stream->pos(); - if (avc_extra_size > 0) { - char *copy_stream_from = stream->data() + stream->pos(); - vcodec->avc_extra_data = std::vector(copy_stream_from, copy_stream_from + avc_extra_size); - } - - const int HEVC_MIN_SIZE = 23; // From configuration_version to numOfArrays - if (!stream->require(HEVC_MIN_SIZE)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "requires %d only %d bytes", HEVC_MIN_SIZE, stream->left()); - } - - SrsHevcDecoderConfigurationRecord *dec_conf_rec_p = &(vcodec->hevc_dec_conf_record_); - dec_conf_rec_p->configuration_version = stream->read_1bytes(); - if (dec_conf_rec_p->configuration_version != 1) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "invalid version=%d", dec_conf_rec_p->configuration_version); - } - - // Read general_profile_space(2bits), general_tier_flag(1bit), general_profile_idc(5bits) - uint8_t data_byte = stream->read_1bytes(); - dec_conf_rec_p->general_profile_space = (data_byte >> 6) & 0x03; - dec_conf_rec_p->general_tier_flag = (data_byte >> 5) & 0x01; - dec_conf_rec_p->general_profile_idc = data_byte & 0x1F; - srs_info("hevc version:%d, general_profile_space:%d, general_tier_flag:%d, general_profile_idc:%d", - dec_conf_rec_p->configuration_version, dec_conf_rec_p->general_profile_space, dec_conf_rec_p->general_tier_flag, - dec_conf_rec_p->general_profile_idc); - - // general_profile_compatibility_flags: 32bits - dec_conf_rec_p->general_profile_compatibility_flags = (uint32_t)stream->read_4bytes(); - - // general_constraint_indicator_flags: 48bits - uint64_t data_64bit = (uint64_t)stream->read_4bytes(); - data_64bit = (data_64bit << 16) | (stream->read_2bytes()); - dec_conf_rec_p->general_constraint_indicator_flags = data_64bit; - - // general_level_idc: 8bits - dec_conf_rec_p->general_level_idc = stream->read_1bytes(); - // min_spatial_segmentation_idc: xxxx 14bits - dec_conf_rec_p->min_spatial_segmentation_idc = stream->read_2bytes() & 0x0fff; - // parallelism_type: xxxx xx 2bits - dec_conf_rec_p->parallelism_type = stream->read_1bytes() & 0x03; - // chroma_format: xxxx xx 2bits - dec_conf_rec_p->chroma_format = stream->read_1bytes() & 0x03; - // bit_depth_luma_minus8: xxxx x 3bits - dec_conf_rec_p->bit_depth_luma_minus8 = stream->read_1bytes() & 0x07; - // bit_depth_chroma_minus8: xxxx x 3bits - dec_conf_rec_p->bit_depth_chroma_minus8 = stream->read_1bytes() & 0x07; - srs_info("general_constraint_indicator_flags:0x%x, general_level_idc:%d, min_spatial_segmentation_idc:%d, parallelism_type:%d, chroma_format:%d, bit_depth_luma_minus8:%d, bit_depth_chroma_minus8:%d", - dec_conf_rec_p->general_constraint_indicator_flags, dec_conf_rec_p->general_level_idc, - dec_conf_rec_p->min_spatial_segmentation_idc, dec_conf_rec_p->parallelism_type, dec_conf_rec_p->chroma_format, - dec_conf_rec_p->bit_depth_luma_minus8, dec_conf_rec_p->bit_depth_chroma_minus8); - - // avg_frame_rate: 16bits - vcodec->frame_rate = dec_conf_rec_p->avg_frame_rate = stream->read_2bytes(); - // 8bits: constant_frame_rate(2bits), num_temporal_layers(3bits), - // temporal_id_nested(1bit), length_size_minus_one(2bits) - data_byte = stream->read_1bytes(); - dec_conf_rec_p->constant_frame_rate = (data_byte >> 6) & 0x03; - dec_conf_rec_p->num_temporal_layers = (data_byte >> 3) & 0x07; - dec_conf_rec_p->temporal_id_nested = (data_byte >> 2) & 0x01; - - // Parse the NALU size. - dec_conf_rec_p->length_size_minus_one = data_byte & 0x03; - vcodec->NAL_unit_length = dec_conf_rec_p->length_size_minus_one; - - // 5.3.4.2.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16 - // 5.2.4.1 AVC decoder configuration record - // 5.2.4.1.2 Semantics - // The value of this field shall be one of 0, 1, or 3 corresponding to a - // length encoded with 1, 2, or 4 bytes, respectively. - if (vcodec->NAL_unit_length == 2) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "sps lengthSizeMinusOne should never be 2"); - } - - uint8_t numOfArrays = stream->read_1bytes(); - srs_info("avg_frame_rate:%d, constant_frame_rate:%d, num_temporal_layers:%d, temporal_id_nested:%d, length_size_minus_one:%d, numOfArrays:%d", - dec_conf_rec_p->avg_frame_rate, dec_conf_rec_p->constant_frame_rate, dec_conf_rec_p->num_temporal_layers, - dec_conf_rec_p->temporal_id_nested, dec_conf_rec_p->length_size_minus_one, numOfArrays); - - // parse vps/pps/sps - dec_conf_rec_p->nalu_vec.clear(); - for (int index = 0; index < numOfArrays; index++) { - if (!stream->require(3)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "requires 3 only %d bytes", stream->left()); - } - data_byte = stream->read_1bytes(); - - SrsHevcHvccNalu hevc_unit; - hevc_unit.array_completeness = (data_byte >> 7) & 0x01; - hevc_unit.nal_unit_type = data_byte & 0x3f; - hevc_unit.num_nalus = stream->read_2bytes(); - - for (int i = 0; i < hevc_unit.num_nalus; i++) { - if (!stream->require(2)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "num_nalus requires 2 only %d bytes", stream->left()); - } - - SrsHevcNalData data_item; - data_item.nal_unit_length = stream->read_2bytes(); - - if (!stream->require(data_item.nal_unit_length)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "requires %d only %d bytes", - data_item.nal_unit_length, stream->left()); - } - // copy vps/pps/sps data - data_item.nal_unit_data.resize(data_item.nal_unit_length); - - stream->read_bytes((char *)(&data_item.nal_unit_data[0]), data_item.nal_unit_length); - srs_info("hevc nalu type:%d, array_completeness:%d, num_nalus:%d, i:%d, nal_unit_length:%d", - hevc_unit.nal_unit_type, hevc_unit.array_completeness, hevc_unit.num_nalus, i, data_item.nal_unit_length); - hevc_unit.nal_data_vec.push_back(data_item); - } - dec_conf_rec_p->nalu_vec.push_back(hevc_unit); - - // demux nalu - if ((err = hevc_demux_vps_sps_pps(&hevc_unit)) != srs_success) { - return srs_error_wrap(err, "hevc demux vps/sps/pps failed"); - } - } - - return err; -} - -srs_error_t SrsFormat::hevc_demux_vps_sps_pps(SrsHevcHvccNalu *nal) -{ - srs_error_t err = srs_success; - - if (nal->nal_data_vec.empty()) { - return err; - } - - // TODO: FIXME: Support for multiple VPS/SPS/PPS, then pick the first non-empty one. - char *frame = (char *)(&nal->nal_data_vec[0].nal_unit_data[0]); - int nb_frame = nal->nal_data_vec[0].nal_unit_length; - SrsBuffer stream(frame, nb_frame); - - // nal data - switch (nal->nal_unit_type) { - case SrsHevcNaluType_VPS: - err = hevc_demux_vps(&stream); - break; - case SrsHevcNaluType_SPS: - err = hevc_demux_sps(&stream); - break; - case SrsHevcNaluType_PPS: - err = hevc_demux_pps(&stream); - break; - default: - break; - } - - return err; -} - -srs_error_t SrsFormat::hevc_demux_vps(SrsBuffer *stream) -{ - // for NALU, ITU-T H.265 7.3.2.1 Video parameter set RBSP syntax - // @see 7.3.1.2 NAL unit header syntax - // @doc ITU-T-H.265-2021.pdf, page 53. - - if (!stream->require(1)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "decode hevc vps requires 1 only %d bytes", stream->left()); - } - int8_t nutv = stream->read_1bytes(); - - // forbidden_zero_bit shall be equal to 0. - int8_t forbidden_zero_bit = (nutv >> 7) & 0x01; - if (forbidden_zero_bit) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc forbidden_zero_bit=%d shall be equal to 0", forbidden_zero_bit); - } - - // nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1. - // @see 7.4.2.2 NAL unit header semantics - // @doc ITU-T-H.265-2021.pdf, page 86. - SrsHevcNaluType nal_unit_type = (SrsHevcNaluType)((nutv >> 1) & 0x3f); - if (nal_unit_type != SrsHevcNaluType_VPS) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc vps nal_unit_type=%d shall be equal to 33", nal_unit_type); - } - - // nuh_layer_id + nuh_temporal_id_plus1 - stream->skip(1); - - // decode the rbsp from vps. - // rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes. - std::vector rbsp(stream->size()); - - int nb_rbsp = srs_rbsp_remove_emulation_bytes(stream, rbsp); - - return hevc_demux_vps_rbsp((char *)&rbsp[0], nb_rbsp); -} - -srs_error_t SrsFormat::hevc_demux_vps_rbsp(char *rbsp, int nb_rbsp) -{ - srs_error_t err = srs_success; - - // reparse the rbsp. - SrsBuffer stream(rbsp, nb_rbsp); - - // H265 VPS (video_parameter_set_rbsp()) NAL Unit. - // Section 7.3.2.1 ("Video parameter set RBSP syntax") of the H.265 - // ITU-T-H.265-2021.pdf, page 54. - if (!stream.require(4)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "vps requires 4 only %d bytes", stream.left()); - } - - SrsBitBuffer bs(&stream); - - // vps_video_parameter_set_id u(4) - int vps_video_parameter_set_id = bs.read_bits(4); - if (vps_video_parameter_set_id < 0 || vps_video_parameter_set_id > SrsHevcMax_VPS_COUNT) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "vps id out of range: %d", vps_video_parameter_set_id); - } - - // select table - SrsHevcDecoderConfigurationRecord *dec_conf_rec = &(vcodec->hevc_dec_conf_record_); - SrsHevcRbspVps *vps = &(dec_conf_rec->vps_table[vps_video_parameter_set_id]); - - vps->vps_video_parameter_set_id = vps_video_parameter_set_id; - // vps_base_layer_internal_flag u(1) - vps->vps_base_layer_internal_flag = bs.read_bit(); - // vps_base_layer_available_flag u(1) - vps->vps_base_layer_available_flag = bs.read_bit(); - // vps_max_layers_minus1 u(6) - vps->vps_max_layers_minus1 = bs.read_bits(6); - // vps_max_sub_layers_minus1 u(3) - vps->vps_max_sub_layers_minus1 = bs.read_bits(3); - // vps_temporal_id_nesting_flag u(1) - vps->vps_temporal_id_nesting_flag = bs.read_bit(); - // vps_reserved_0xffff_16bits u(16) - vps->vps_reserved_0xffff_16bits = bs.read_bits(16); - - // profile_tier_level(1, vps_max_sub_layers_minus1) - if ((err = hevc_demux_rbsp_ptl(&bs, &vps->ptl, 1, vps->vps_max_sub_layers_minus1)) != srs_success) { - return srs_error_wrap(err, "vps rbsp ptl vps_max_sub_layers_minus1=%d", vps->vps_max_sub_layers_minus1); - } - - dec_conf_rec->general_profile_idc = vps->ptl.general_profile_idc; - dec_conf_rec->general_level_idc = vps->ptl.general_level_idc; - dec_conf_rec->general_tier_flag = vps->ptl.general_tier_flag; - - if (!bs.require_bits(1)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "sublayer flag requires 1 only %d bits", bs.left_bits()); - } - - // vps_sub_layer_ordering_info_present_flag u(1) - vps->vps_sub_layer_ordering_info_present_flag = bs.read_bit(); - - for (int i = (vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers_minus1); - i <= vps->vps_max_sub_layers_minus1; i++) { - // vps_max_dec_pic_buffering_minus1[i] ue(v) - if ((err = bs.read_bits_ue(vps->vps_max_dec_pic_buffering_minus1[i])) != srs_success) { - return srs_error_wrap(err, "max_dec_pic_buffering_minus1"); - } - // vps_max_num_reorder_pics[i] ue(v) - if ((err = bs.read_bits_ue(vps->vps_max_num_reorder_pics[i])) != srs_success) { - return srs_error_wrap(err, "max_num_reorder_pics"); - } - // vps_max_latency_increase_plus1[i] ue(v) - if ((err = bs.read_bits_ue(vps->vps_max_latency_increase_plus1[i])) != srs_success) { - return srs_error_wrap(err, "max_latency_increase_plus1"); - } - } - - if (!bs.require_bits(6)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "vps maxlayer requires 10 only %d bits", bs.left_bits()); - } - - // vps_max_layer_id u(6) - vps->vps_max_layer_id = bs.read_bits(6); - - // vps_num_layer_sets_minus1 ue(v) - if ((err = bs.read_bits_ue(vps->vps_num_layer_sets_minus1)) != srs_success) { - return srs_error_wrap(err, "num_layer_sets_minus1"); - } - - // TODO: FIXME: Implements it, you might parse remain bits for video_parameter_set_rbsp. - // @see 7.3.2.1 Video parameter set RBSP - // @doc ITU-T-H.265-2021.pdf, page 54. - - return err; -} - -srs_error_t SrsFormat::hevc_demux_sps(SrsBuffer *stream) -{ - // for NALU, ITU-T H.265 7.3.2.2 Sequence parameter set RBSP syntax - // @see 7.3.2.2.1 General sequence parameter set RBSP syntax - // @doc ITU-T-H.265-2021.pdf, page 55. - - if (!stream->require(1)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "decode hevc sps requires 1 only %d bytes", stream->left()); - } - int8_t nutv = stream->read_1bytes(); - - // forbidden_zero_bit shall be equal to 0. - int8_t forbidden_zero_bit = (nutv >> 7) & 0x01; - if (forbidden_zero_bit) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc forbidden_zero_bit=%d shall be equal to 0", forbidden_zero_bit); - } - - // nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1. - // @see 7.4.2.2 NAL unit header semantics - // @doc ITU-T-H.265-2021.pdf, page 86. - SrsHevcNaluType nal_unit_type = (SrsHevcNaluType)((nutv >> 1) & 0x3f); - if (nal_unit_type != SrsHevcNaluType_SPS) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc sps nal_unit_type=%d shall be equal to 33", nal_unit_type); - } - - // nuh_layer_id + nuh_temporal_id_plus1 - stream->skip(1); - - // decode the rbsp from sps. - // rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes. - std::vector rbsp(stream->size()); - - int nb_rbsp = srs_rbsp_remove_emulation_bytes(stream, rbsp); - - return hevc_demux_sps_rbsp((char *)&rbsp[0], nb_rbsp); -} - -srs_error_t SrsFormat::hevc_demux_sps_rbsp(char *rbsp, int nb_rbsp) -{ - srs_error_t err = srs_success; - - // we donot parse the detail of sps. - // @see https://github.com/ossrs/srs/issues/474 - if (!avc_parse_sps) { - return err; - } - - // reparse the rbsp. - SrsBuffer stream(rbsp, nb_rbsp); - - // H265 SPS Nal Unit (seq_parameter_set_rbsp()) parser. - // Section 7.3.2.2 ("Sequence parameter set RBSP syntax") of the H.265 - // ITU-T-H.265-2021.pdf, page 55. - if (!stream.require(2)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "sps requires 2 only %d bytes", stream.left()); - } - uint8_t nutv = stream.read_1bytes(); - - // sps_video_parameter_set_id u(4) - int sps_video_parameter_set_id = (nutv >> 4) & 0x0f; - // sps_max_sub_layers_minus1 u(3) - int sps_max_sub_layers_minus1 = (nutv >> 1) & 0x07; - // sps_temporal_id_nesting_flag u(1) - int sps_temporal_id_nesting_flag = nutv & 0x01; - - SrsBitBuffer bs(&stream); - - // profile tier level... - SrsHevcProfileTierLevel profile_tier_level; - // profile_tier_level(1, sps_max_sub_layers_minus1) - if ((err = hevc_demux_rbsp_ptl(&bs, &profile_tier_level, 1, sps_max_sub_layers_minus1)) != srs_success) { - return srs_error_wrap(err, "sps rbsp ptl sps_max_sub_layers_minus1=%d", sps_max_sub_layers_minus1); - } - - vcodec->hevc_profile = (SrsHevcProfile)profile_tier_level.general_profile_idc; - vcodec->hevc_level = (SrsHevcLevel)profile_tier_level.general_level_idc; - - // sps_seq_parameter_set_id ue(v) - uint32_t sps_seq_parameter_set_id = 0; - if ((err = bs.read_bits_ue(sps_seq_parameter_set_id)) != srs_success) { - return srs_error_wrap(err, "sps_seq_parameter_set_id"); - } - if (sps_seq_parameter_set_id < 0 || sps_seq_parameter_set_id >= SrsHevcMax_SPS_COUNT) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "sps id out of range: %d", sps_seq_parameter_set_id); - } - - // for sps_table - SrsHevcDecoderConfigurationRecord *dec_conf_rec = &(vcodec->hevc_dec_conf_record_); - SrsHevcRbspSps *sps = &(dec_conf_rec->sps_table[sps_seq_parameter_set_id]); - - sps->sps_video_parameter_set_id = sps_video_parameter_set_id; - sps->sps_max_sub_layers_minus1 = sps_max_sub_layers_minus1; - sps->sps_temporal_id_nesting_flag = sps_temporal_id_nesting_flag; - sps->sps_seq_parameter_set_id = sps_seq_parameter_set_id; - sps->ptl = profile_tier_level; - - // chroma_format_idc ue(v) - if ((err = bs.read_bits_ue(sps->chroma_format_idc)) != srs_success) { - return srs_error_wrap(err, "chroma_format_idc"); - } - - if (sps->chroma_format_idc == 3) { - if (!bs.require_bits(1)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "separate_colour_plane_flag requires 1 only %d bits", bs.left_bits()); - } - - // separate_colour_plane_flag u(1) - sps->separate_colour_plane_flag = bs.read_bit(); - } - - // pic_width_in_luma_samples ue(v) - if ((err = bs.read_bits_ue(sps->pic_width_in_luma_samples)) != srs_success) { - return srs_error_wrap(err, "pic_width_in_luma_samples"); - } - - // pic_height_in_luma_samples ue(v) - if ((err = bs.read_bits_ue(sps->pic_height_in_luma_samples)) != srs_success) { - return srs_error_wrap(err, "pic_height_in_luma_samples"); - } - - vcodec->width = sps->pic_width_in_luma_samples; - vcodec->height = sps->pic_height_in_luma_samples; - - if (!bs.require_bits(1)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "conformance_window_flag requires 1 only %d bits", bs.left_bits()); - } - - // conformance_window_flag u(1) - sps->conformance_window_flag = bs.read_bit(); - if (sps->conformance_window_flag) { - // conf_win_left_offset ue(v) - if ((err = bs.read_bits_ue(sps->conf_win_left_offset)) != srs_success) { - return srs_error_wrap(err, "conf_win_left_offset"); - } - // conf_win_right_offset ue(v) - if ((err = bs.read_bits_ue(sps->conf_win_right_offset)) != srs_success) { - return srs_error_wrap(err, "conf_win_right_offset"); - } - // conf_win_top_offset ue(v) - if ((err = bs.read_bits_ue(sps->conf_win_top_offset)) != srs_success) { - return srs_error_wrap(err, "conf_win_top_offset"); - } - // conf_win_bottom_offset ue(v) - if ((err = bs.read_bits_ue(sps->conf_win_bottom_offset)) != srs_success) { - return srs_error_wrap(err, "conf_win_bottom_offset"); - } - - // Table 6-1, 7.4.3.2.1 - // ITU-T-H.265-2021.pdf, page 42. - // Recalculate width and height - // Note: 1 is added to the manual, but it is not actually used - // https://gitlab.com/mbunkus/mkvtoolnix/-/issues/1152 - int sub_width_c = ((1 == sps->chroma_format_idc) || (2 == sps->chroma_format_idc)) && (0 == sps->separate_colour_plane_flag) ? 2 : 1; - int sub_height_c = (1 == sps->chroma_format_idc) && (0 == sps->separate_colour_plane_flag) ? 2 : 1; - vcodec->width -= (sub_width_c * sps->conf_win_right_offset + sub_width_c * sps->conf_win_left_offset); - vcodec->height -= (sub_height_c * sps->conf_win_bottom_offset + sub_height_c * sps->conf_win_top_offset); - } - - // bit_depth_luma_minus8 ue(v) - if ((err = bs.read_bits_ue(sps->bit_depth_luma_minus8)) != srs_success) { - return srs_error_wrap(err, "bit_depth_luma_minus8"); - } - // bit_depth_chroma_minus8 ue(v) - if ((err = bs.read_bits_ue(sps->bit_depth_chroma_minus8)) != srs_success) { - return srs_error_wrap(err, "bit_depth_chroma_minus8"); - } - - // bit depth - dec_conf_rec->bit_depth_luma_minus8 = sps->bit_depth_luma_minus8 + 8; - dec_conf_rec->bit_depth_chroma_minus8 = sps->bit_depth_chroma_minus8 + 8; - - // log2_max_pic_order_cnt_lsb_minus4 ue(v) - if ((err = bs.read_bits_ue(sps->log2_max_pic_order_cnt_lsb_minus4)) != srs_success) { - return srs_error_wrap(err, "log2_max_pic_order_cnt_lsb_minus4"); - } - - // TODO: FIXME: Implements it, you might parse remain bits for seq_parameter_set_rbsp. - // 7.3.2.2 Sequence parameter set RBSP syntax - // ITU-T-H.265-2021.pdf, page 55 ~ page 57. - - // 7.3.2.11 RBSP trailing bits syntax - // ITU-T-H.265-2021.pdf, page 61. - // rbsp_trailing_bits() - - return err; -} - -srs_error_t SrsFormat::hevc_demux_pps(SrsBuffer *stream) -{ - // for NALU, ITU-T H.265 7.3.2.3 Picture parameter set RBSP syntax - // @see 7.3.2.3 Picture parameter set RBSP syntax - // @doc ITU-T-H.265-2021.pdf, page 57. - if (!stream->require(1)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "decode hevc pps requires 1 only %d bytes", stream->left()); - } - int8_t nutv = stream->read_1bytes(); - - // forbidden_zero_bit shall be equal to 0. - int8_t forbidden_zero_bit = (nutv >> 7) & 0x01; - if (forbidden_zero_bit) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc forbidden_zero_bit=%d shall be equal to 0", forbidden_zero_bit); - } - - // nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1. - // @see 7.4.2.2 NAL unit header semantics - // @doc ITU-T-H.265-2021.pdf, page 86. - SrsHevcNaluType nal_unit_type = (SrsHevcNaluType)((nutv >> 1) & 0x3f); - if (nal_unit_type != SrsHevcNaluType_PPS) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc pps nal_unit_type=%d shall be equal to 33", nal_unit_type); - } - - // nuh_layer_id + nuh_temporal_id_plus1 - stream->skip(1); - - // decode the rbsp from pps. - // rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes. - std::vector rbsp(stream->size()); - - int nb_rbsp = srs_rbsp_remove_emulation_bytes(stream, rbsp); - - return hevc_demux_pps_rbsp((char *)&rbsp[0], nb_rbsp); -} - -srs_error_t SrsFormat::hevc_demux_pps_rbsp(char *rbsp, int nb_rbsp) -{ - srs_error_t err = srs_success; - - // reparse the rbsp. - SrsBuffer stream(rbsp, nb_rbsp); - - // H265 PPS NAL Unit (pic_parameter_set_rbsp()) parser. - // Section 7.3.2.3 ("Picture parameter set RBSP syntax") of the H.265 - // ITU-T-H.265-2021.pdf, page 57. - SrsBitBuffer bs(&stream); - - // pps_pic_parameter_set_id ue(v) - uint32_t pps_pic_parameter_set_id = 0; - if ((err = bs.read_bits_ue(pps_pic_parameter_set_id)) != srs_success) { - return srs_error_wrap(err, "pps_pic_parameter_set_id"); - } - if (pps_pic_parameter_set_id < 0 || pps_pic_parameter_set_id >= SrsHevcMax_PPS_COUNT) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps id out of range: %d", pps_pic_parameter_set_id); - } - - // select table - SrsHevcDecoderConfigurationRecord *dec_conf_rec = &(vcodec->hevc_dec_conf_record_); - SrsHevcRbspPps *pps = &(dec_conf_rec->pps_table[pps_pic_parameter_set_id]); - pps->pps_pic_parameter_set_id = pps_pic_parameter_set_id; - - // pps_seq_parameter_set_id ue(v) - uint32_t pps_seq_parameter_set_id = 0; - if ((err = bs.read_bits_ue(pps_seq_parameter_set_id)) != srs_success) { - return srs_error_wrap(err, "pps_seq_parameter_set_id"); - } - pps->pps_seq_parameter_set_id = pps_seq_parameter_set_id; - - if (!bs.require_bits(7)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps slice requires 7 only %d bits", bs.left_bits()); - } - - // dependent_slice_segments_enabled_flag u(1) - pps->dependent_slice_segments_enabled_flag = bs.read_bit(); - // output_flag_present_flag u(1) - pps->output_flag_present_flag = bs.read_bit(); - // num_extra_slice_header_bits u(3) - pps->num_extra_slice_header_bits = bs.read_bits(3); - // sign_data_hiding_enabled_flag u(1) - pps->sign_data_hiding_enabled_flag = bs.read_bit(); - // cabac_init_present_flag u(1) - pps->cabac_init_present_flag = bs.read_bit(); - - // num_ref_idx_l0_default_active_minus1 ue(v) - if ((err = bs.read_bits_ue(pps->num_ref_idx_l0_default_active_minus1)) != srs_success) { - return srs_error_wrap(err, "num_ref_idx_l0_default_active_minus1"); - } - // num_ref_idx_l1_default_active_minus1 ue(v) - if ((err = bs.read_bits_ue(pps->num_ref_idx_l1_default_active_minus1)) != srs_success) { - return srs_error_wrap(err, "num_ref_idx_l1_default_active_minus1"); - } - // init_qp_minus26 se(v) - if ((err = bs.read_bits_se(pps->init_qp_minus26)) != srs_success) { - return srs_error_wrap(err, "init_qp_minus26"); - } - - if (!bs.require_bits(3)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps requires 3 only %d bits", bs.left_bits()); - } - - // constrained_intra_pred_flag u(1) - pps->constrained_intra_pred_flag = bs.read_bit(); - // transform_skip_enabled_flag u(1) - pps->transform_skip_enabled_flag = bs.read_bit(); - // cu_qp_delta_enabled_flag u(1) - pps->cu_qp_delta_enabled_flag = bs.read_bit(); - if (pps->cu_qp_delta_enabled_flag) { - // diff_cu_qp_delta_depth ue(v) - if ((err = bs.read_bits_ue(pps->diff_cu_qp_delta_depth)) != srs_success) { - return srs_error_wrap(err, "diff_cu_qp_delta_depth"); - } - } - // pps_cb_qp_offset se(v) - if ((err = bs.read_bits_se(pps->pps_cb_qp_offset)) != srs_success) { - return srs_error_wrap(err, "pps_cb_qp_offset"); - } - // pps_cr_qp_offset se(v) - if ((err = bs.read_bits_se(pps->pps_cr_qp_offset)) != srs_success) { - return srs_error_wrap(err, "pps_cr_qp_offset"); - } - - if (!bs.require_bits(6)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps slice_chroma_qp requires 6 only %d bits", bs.left_bits()); - } - - // pps_slice_chroma_qp_offsets_present_flag u(1) - pps->pps_slice_chroma_qp_offsets_present_flag = bs.read_bit(); - // weighted_pred_flag u(1) - pps->weighted_pred_flag = bs.read_bit(); - // weighted_bipred_flag u(1) - pps->weighted_bipred_flag = bs.read_bit(); - // transquant_bypass_enabled_flag u(1) - pps->transquant_bypass_enabled_flag = bs.read_bit(); - // tiles_enabled_flag u(1) - pps->tiles_enabled_flag = bs.read_bit(); - // entropy_coding_sync_enabled_flag u(1) - pps->entropy_coding_sync_enabled_flag = bs.read_bit(); - - if (pps->tiles_enabled_flag) { - // num_tile_columns_minus1 ue(v) - if ((err = bs.read_bits_ue(pps->num_tile_columns_minus1)) != srs_success) { - return srs_error_wrap(err, "num_tile_columns_minus1"); - } - // num_tile_rows_minus1 ue(v) - if ((err = bs.read_bits_ue(pps->num_tile_rows_minus1)) != srs_success) { - return srs_error_wrap(err, "num_tile_rows_minus1"); - } - - if (!bs.require_bits(1)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "uniform_spacing_flag requires 1 only %d bits", bs.left_bits()); - } - - // uniform_spacing_flag u(1) - pps->uniform_spacing_flag = bs.read_bit(); - if (!pps->uniform_spacing_flag) { - pps->column_width_minus1.resize(pps->num_tile_columns_minus1); - pps->row_height_minus1.resize(pps->num_tile_rows_minus1); - - for (int i = 0; i < (int)pps->num_tile_columns_minus1; i++) { - // column_width_minus1[i] ue(v) - if ((err = bs.read_bits_ue(pps->column_width_minus1[i])) != srs_success) { - return srs_error_wrap(err, "column_width_minus1"); - } - } - - for (int i = 0; i < (int)pps->num_tile_rows_minus1; i++) { - // row_height_minus1[i] ue(v) - if ((err = bs.read_bits_ue(pps->row_height_minus1[i])) != srs_success) { - return srs_error_wrap(err, "row_height_minus1"); - } - } - } - - if (!bs.require_bits(1)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "loop_filter_across_tiles_enabled_flag requires 1 only %d bits", bs.left_bits()); - } - - // loop_filter_across_tiles_enabled_flag u(1) - pps->loop_filter_across_tiles_enabled_flag = bs.read_bit(); - } - - if (!bs.require_bits(2)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps loop deblocking filter requires 2 only %d bits", bs.left_bits()); - } - - // pps_loop_filter_across_slices_enabled_flag u(1) - pps->pps_loop_filter_across_slices_enabled_flag = bs.read_bit(); - // deblocking_filter_control_present_flag u(1) - pps->deblocking_filter_control_present_flag = bs.read_bit(); - if (pps->deblocking_filter_control_present_flag) { - if (!bs.require_bits(2)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps loop deblocking filter flag requires 2 only %d bits", bs.left_bits()); - } - - // deblocking_filter_override_enabled_flag u(1) - pps->deblocking_filter_override_enabled_flag = bs.read_bit(); - // pps_deblocking_filter_disabled_flag u(1) - pps->pps_deblocking_filter_disabled_flag = bs.read_bit(); - if (!pps->pps_deblocking_filter_disabled_flag) { - // pps_beta_offset_div2 se(v) - if ((err = bs.read_bits_se(pps->pps_beta_offset_div2)) != srs_success) { - return srs_error_wrap(err, "pps_beta_offset_div2"); - } - // pps_tc_offset_div2 se(v) - if ((err = bs.read_bits_se(pps->pps_tc_offset_div2)) != srs_success) { - return srs_error_wrap(err, "pps_tc_offset_div2"); - } - } - } - - if (!bs.require_bits(1)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps scaling_list_data requires 1 only %d bits", bs.left_bits()); - } - - // pps_scaling_list_data_present_flag u(1) - pps->pps_scaling_list_data_present_flag = bs.read_bit(); - if (pps->pps_scaling_list_data_present_flag) { - // 7.3.4 Scaling list data syntax - SrsHevcScalingListData *sld = &pps->scaling_list_data; - for (int sizeId = 0; sizeId < 4; sizeId++) { - for (int matrixId = 0; matrixId < 6; matrixId += (sizeId == 3) ? 3 : 1) { - // scaling_list_pred_mode_flag u(1) - sld->scaling_list_pred_mode_flag[sizeId][matrixId] = bs.read_bit(); - if (!sld->scaling_list_pred_mode_flag[sizeId][matrixId]) { - // scaling_list_pred_matrix_id_delta ue(v) - if ((err = bs.read_bits_ue(sld->scaling_list_pred_matrix_id_delta[sizeId][matrixId])) != srs_success) { - return srs_error_wrap(err, "scaling_list_pred_matrix_id_delta"); - } - } else { - int nextCoef = 8; - int coefNum = srs_min(64, (1 << (4 + (sizeId << 1)))); - sld->coefNum = coefNum; // tmp store - if (sizeId > 1) { - // scaling_list_dc_coef_minus8 se(v) - if ((err = bs.read_bits_se(sld->scaling_list_dc_coef_minus8[sizeId - 2][matrixId])) != srs_success) { - return srs_error_wrap(err, "scaling_list_dc_coef_minus8"); - } - nextCoef = sld->scaling_list_dc_coef_minus8[sizeId - 2][matrixId] + 8; - } - - for (int i = 0; i < sld->coefNum; i++) { - // scaling_list_delta_coef se(v) - int scaling_list_delta_coef = 0; - if ((err = bs.read_bits_se(scaling_list_delta_coef)) != srs_success) { - return srs_error_wrap(err, "scaling_list_delta_coef"); - } - nextCoef = (nextCoef + scaling_list_delta_coef + 256) % 256; - sld->ScalingList[sizeId][matrixId][i] = nextCoef; - } - } - } - } - } - - if (!bs.require_bits(1)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "lists_modification_present_flag requires 1 only %d bits", bs.left_bits()); - } - // lists_modification_present_flag u(1) - pps->lists_modification_present_flag = bs.read_bit(); - - // log2_parallel_merge_level_minus2 ue(v) - if ((err = bs.read_bits_ue(pps->log2_parallel_merge_level_minus2)) != srs_success) { - return srs_error_wrap(err, "log2_parallel_merge_level_minus2"); - } - - if (!bs.require_bits(2)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "extension_present_flag requires 2 only %d bits", bs.left_bits()); - } - - // slice_segment_header_extension_present_flag u(1) - pps->slice_segment_header_extension_present_flag = bs.read_bit(); - // pps_extension_present_flag u(1) - pps->pps_extension_present_flag = bs.read_bit(); - if (pps->pps_extension_present_flag) { - if (!bs.require_bits(8)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps_range_extension_flag requires 8 only %d bits", bs.left_bits()); - } - - // pps_range_extension_flag u(1) - pps->pps_range_extension_flag = bs.read_bit(); - // pps_multilayer_extension_flag u(1) - pps->pps_multilayer_extension_flag = bs.read_bit(); - // pps_3d_extension_flag u(1) - pps->pps_3d_extension_flag = bs.read_bit(); - // pps_scc_extension_flag u(1) - pps->pps_scc_extension_flag = bs.read_bit(); - // pps_extension_4bits u(4) - pps->pps_extension_4bits = bs.read_bits(4); - } - - // TODO: FIXME: Implements it, you might parse remain bits for pic_parameter_set_rbsp. - // @see 7.3.2.3 Picture parameter set RBSP syntax - // @doc ITU-T-H.265-2021.pdf, page 59. - - // TODO: FIXME: rbsp_trailing_bits - - return err; -} - -srs_error_t SrsFormat::hevc_demux_rbsp_ptl(SrsBitBuffer *bs, SrsHevcProfileTierLevel *ptl, int profile_present_flag, int max_sub_layers_minus1) -{ - srs_error_t err = srs_success; - - // profile_tier_level() parser. - // Section 7.3.3 ("Profile, tier and level syntax") of the H.265 - // ITU-T-H.265-2021.pdf, page 62. - if (profile_present_flag) { - if (!bs->require_bits(88)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl profile requires 88 only %d bits", bs->left_bits()); - } - - // profile_space u(2) - ptl->general_profile_space = bs->read_bits(2); - // tier_flag u(1) - ptl->general_tier_flag = bs->read_bit(); - // profile_idc u(5) - ptl->general_profile_idc = bs->read_bits(5); - for (int i = 0; i < 32; i++) { - // profile_compatibility_flag[j] u(1) - ptl->general_profile_compatibility_flag[i] = bs->read_bit(); - } - // progressive_source_flag u(1) - ptl->general_progressive_source_flag = bs->read_bit(); - // interlaced_source_flag u(1) - ptl->general_interlaced_source_flag = bs->read_bit(); - // non_packed_constraint_flag u(1) - ptl->general_non_packed_constraint_flag = bs->read_bit(); - // frame_only_constraint_flag u(1) - ptl->general_frame_only_constraint_flag = bs->read_bit(); - if (ptl->general_profile_idc == 4 || ptl->general_profile_compatibility_flag[4] || - ptl->general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] || - ptl->general_profile_idc == 6 || ptl->general_profile_compatibility_flag[6] || - ptl->general_profile_idc == 7 || ptl->general_profile_compatibility_flag[7] || - ptl->general_profile_idc == 8 || ptl->general_profile_compatibility_flag[8] || - ptl->general_profile_idc == 9 || ptl->general_profile_compatibility_flag[9] || - ptl->general_profile_idc == 10 || ptl->general_profile_compatibility_flag[10] || - ptl->general_profile_idc == 11 || ptl->general_profile_compatibility_flag[11]) { - // The number of bits in this syntax structure is not affected by this condition - // max_12bit_constraint_flag u(1) - ptl->general_max_12bit_constraint_flag = bs->read_bit(); - // max_10bit_constraint_flag u(1) - ptl->general_max_10bit_constraint_flag = bs->read_bit(); - // max_8bit_constraint_flag u(1) - ptl->general_max_8bit_constraint_flag = bs->read_bit(); - // max_422chroma_constraint_flag u(1) - ptl->general_max_422chroma_constraint_flag = bs->read_bit(); - // max_420chroma_constraint_flag u(1) - ptl->general_max_420chroma_constraint_flag = bs->read_bit(); - // max_monochrome_constraint_flag u(1) - ptl->general_max_monochrome_constraint_flag = bs->read_bit(); - // intra_constraint_flag u(1) - ptl->general_intra_constraint_flag = bs->read_bit(); - // one_picture_only_constraint_flag u(1) - ptl->general_one_picture_only_constraint_flag = bs->read_bit(); - // lower_bit_rate_constraint_flag u(1) - ptl->general_lower_bit_rate_constraint_flag = bs->read_bit(); - - if (ptl->general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] == 1 || - ptl->general_profile_idc == 9 || ptl->general_profile_compatibility_flag[9] == 1 || - ptl->general_profile_idc == 10 || ptl->general_profile_compatibility_flag[10] == 1 || - ptl->general_profile_idc == 11 || ptl->general_profile_compatibility_flag[11] == 1) { - // max_14bit_constraint_flag u(1) - ptl->general_max_14bit_constraint_flag = bs->read_bit(); - // reserved_zero_33bits u(33) - uint32_t bits_tmp_hi = bs->read_bit(); - uint32_t bits_tmp = bs->read_bits(32); - ptl->general_reserved_zero_33bits = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; - } else { - // reserved_zero_34bits u(34) - uint32_t bits_tmp_hi = bs->read_bits(2); - uint32_t bits_tmp = bs->read_bits(32); - ptl->general_reserved_zero_34bits = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; - } - } else if (ptl->general_profile_idc == 2 || ptl->general_profile_compatibility_flag[2]) { - // general_reserved_zero_7bits u(7) - ptl->general_reserved_zero_7bits = bs->read_bits(7); - // general_one_picture_only_constraint_flag u(1) - ptl->general_one_picture_only_constraint_flag = bs->read_bit(); - // general_reserved_zero_35bits u(35) - uint32_t bits_tmp_hi = bs->read_bits(3); - uint32_t bits_tmp = bs->read_bits(32); - ptl->general_reserved_zero_35bits = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; - } else { - // reserved_zero_43bits u(43) - uint32_t bits_tmp_hi = bs->read_bits(11); - uint32_t bits_tmp = bs->read_bits(32); - ptl->general_reserved_zero_43bits = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; - } - - // The number of bits in this syntax structure is not affected by this condition - if (ptl->general_profile_idc == 1 || ptl->general_profile_compatibility_flag[1] || - ptl->general_profile_idc == 2 || ptl->general_profile_compatibility_flag[2] || - ptl->general_profile_idc == 3 || ptl->general_profile_compatibility_flag[3] || - ptl->general_profile_idc == 4 || ptl->general_profile_compatibility_flag[4] || - ptl->general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] || - ptl->general_profile_idc == 9 || ptl->general_profile_compatibility_flag[9] || - ptl->general_profile_idc == 11 || ptl->general_profile_compatibility_flag[11]) { - // inbld_flag u(1) - ptl->general_inbld_flag = bs->read_bit(); - } else { - // reserved_zero_bit u(1) - ptl->general_reserved_zero_bit = bs->read_bit(); - } - } - - if (!bs->require_bits(8)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl level requires 8 only %d bits", bs->left_bits()); - } - - // general_level_idc u(8) - ptl->general_level_idc = bs->read_8bits(); - - ptl->sub_layer_profile_present_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_level_present_flag.resize(max_sub_layers_minus1); - for (int i = 0; i < max_sub_layers_minus1; i++) { - if (!bs->require_bits(2)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl present_flag requires 2 only %d bits", bs->left_bits()); - } - // sub_layer_profile_present_flag[i] u(1) - ptl->sub_layer_profile_present_flag[i] = bs->read_bit(); - // sub_layer_level_present_flag[i] u(1) - ptl->sub_layer_level_present_flag[i] = bs->read_bit(); - } - - for (int i = max_sub_layers_minus1; max_sub_layers_minus1 > 0 && i < 8; i++) { - if (!bs->require_bits(2)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl reserved_zero requires 2 only %d bits", bs->left_bits()); - } - // reserved_zero_2bits[i] u(2) - ptl->reserved_zero_2bits[i] = bs->read_bits(2); - } - - ptl->sub_layer_profile_space.resize(max_sub_layers_minus1); - ptl->sub_layer_tier_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_profile_idc.resize(max_sub_layers_minus1); - ptl->sub_layer_profile_compatibility_flag.resize(max_sub_layers_minus1); - for (int i = 0; i < max_sub_layers_minus1; i++) { - ptl->sub_layer_profile_compatibility_flag[i].resize(32); - } - ptl->sub_layer_progressive_source_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_interlaced_source_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_non_packed_constraint_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_frame_only_constraint_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_max_12bit_constraint_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_max_10bit_constraint_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_max_8bit_constraint_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_max_422chroma_constraint_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_max_420chroma_constraint_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_max_monochrome_constraint_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_intra_constraint_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_one_picture_only_constraint_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_lower_bit_rate_constraint_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_reserved_zero_34bits.resize(max_sub_layers_minus1); - ptl->sub_layer_reserved_zero_43bits.resize(max_sub_layers_minus1); - ptl->sub_layer_inbld_flag.resize(max_sub_layers_minus1); - ptl->sub_layer_reserved_zero_bit.resize(max_sub_layers_minus1); - ptl->sub_layer_level_idc.resize(max_sub_layers_minus1); - for (int i = 0; i < max_sub_layers_minus1; i++) { - if (ptl->sub_layer_profile_present_flag[i]) { - if (!bs->require_bits(88)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl sub_layer_profile requires 88 only %d bits", bs->left_bits()); - } - // profile_space u(2) - ptl->sub_layer_profile_space[i] = bs->read_bits(2); - // tier_flag u(1) - ptl->sub_layer_tier_flag[i] = bs->read_bit(); - // profile_idc u(5) - ptl->sub_layer_profile_idc[i] = bs->read_bits(5); - for (int j = 0; j < 32; j++) { - // profile_compatibility_flag[j] u(1) - ptl->sub_layer_profile_compatibility_flag[i][j] = bs->read_bit(); - } - // progressive_source_flag u(1) - ptl->sub_layer_progressive_source_flag[i] = bs->read_bit(); - // interlaced_source_flag u(1) - ptl->sub_layer_interlaced_source_flag[i] = bs->read_bit(); - // non_packed_constraint_flag u(1) - ptl->sub_layer_non_packed_constraint_flag[i] = bs->read_bit(); - // frame_only_constraint_flag u(1) - ptl->sub_layer_frame_only_constraint_flag[i] = bs->read_bit(); - if (ptl->sub_layer_profile_idc[i] == 4 || ptl->sub_layer_profile_compatibility_flag[i][4] || - ptl->sub_layer_profile_idc[i] == 5 || ptl->sub_layer_profile_compatibility_flag[i][5] || - ptl->sub_layer_profile_idc[i] == 6 || ptl->sub_layer_profile_compatibility_flag[i][6] || - ptl->sub_layer_profile_idc[i] == 7 || ptl->sub_layer_profile_compatibility_flag[i][7] || - ptl->sub_layer_profile_idc[i] == 8 || ptl->sub_layer_profile_compatibility_flag[i][8] || - ptl->sub_layer_profile_idc[i] == 9 || ptl->sub_layer_profile_compatibility_flag[i][9] || - ptl->sub_layer_profile_idc[i] == 10 || ptl->sub_layer_profile_compatibility_flag[i][10] || - ptl->sub_layer_profile_idc[i] == 11 || ptl->sub_layer_profile_compatibility_flag[i][11]) { - // The number of bits in this syntax structure is not affected by this condition. - // max_12bit_constraint_flag u(1) - ptl->sub_layer_max_12bit_constraint_flag[i] = bs->read_bit(); - // max_10bit_constraint_flag u(1) - ptl->sub_layer_max_10bit_constraint_flag[i] = bs->read_bit(); - // max_8bit_constraint_flag u(1) - ptl->sub_layer_max_8bit_constraint_flag[i] = bs->read_bit(); - // max_422chroma_constraint_flag u(1) - ptl->sub_layer_max_422chroma_constraint_flag[i] = bs->read_bit(); - // max_420chroma_constraint_flag u(1) - ptl->sub_layer_max_420chroma_constraint_flag[i] = bs->read_bit(); - // max_monochrome_constraint_flag u(1) - ptl->sub_layer_max_monochrome_constraint_flag[i] = bs->read_bit(); - // intra_constraint_flag u(1) - ptl->sub_layer_intra_constraint_flag[i] = bs->read_bit(); - // one_picture_only_constraint_flag u(1) - ptl->sub_layer_one_picture_only_constraint_flag[i] = bs->read_bit(); - // lower_bit_rate_constraint_flag u(1) - ptl->sub_layer_lower_bit_rate_constraint_flag[i] = bs->read_bit(); - - if (ptl->sub_layer_profile_idc[i] == 5 || - ptl->sub_layer_profile_compatibility_flag[i][5] == 1 || - ptl->sub_layer_profile_idc[i] == 9 || - ptl->sub_layer_profile_compatibility_flag[i][9] == 1 || - ptl->sub_layer_profile_idc[i] == 10 || - ptl->sub_layer_profile_compatibility_flag[i][10] == 1 || - ptl->sub_layer_profile_idc[i] == 11 || - ptl->sub_layer_profile_compatibility_flag[i][11] == 1) { - // max_14bit_constraint_flag u(1) - ptl->general_max_14bit_constraint_flag = bs->read_bit(); - // reserved_zero_33bits u(33) - uint32_t bits_tmp_hi = bs->read_bit(); - uint32_t bits_tmp = bs->read_bits(32); - ptl->sub_layer_reserved_zero_33bits[i] = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; - } else { - // reserved_zero_34bits u(34) - uint32_t bits_tmp_hi = bs->read_bits(2); - uint32_t bits_tmp = bs->read_bits(32); - ptl->sub_layer_reserved_zero_34bits[i] = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; - } - } else if (ptl->sub_layer_profile_idc[i] == 2 || ptl->sub_layer_profile_compatibility_flag[i][2]) { - // sub_layer_reserved_zero_7bits u(7) - ptl->sub_layer_reserved_zero_7bits[i] = bs->read_bits(7); - // sub_layer_one_picture_only_constraint_flag u(1) - ptl->sub_layer_one_picture_only_constraint_flag[i] = bs->read_bit(); - // sub_layer_reserved_zero_35bits u(35) - uint32_t bits_tmp_hi = bs->read_bits(3); - uint32_t bits_tmp = bs->read_bits(32); - ptl->sub_layer_reserved_zero_35bits[i] = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; - } else { - // reserved_zero_43bits u(43) - uint32_t bits_tmp_hi = bs->read_bits(11); - uint32_t bits_tmp = bs->read_bits(32); - ptl->sub_layer_reserved_zero_43bits[i] = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; - } - - // The number of bits in this syntax structure is not affected by this condition - if (ptl->sub_layer_profile_idc[i] == 1 || ptl->sub_layer_profile_compatibility_flag[i][1] || - ptl->sub_layer_profile_idc[i] == 2 || ptl->sub_layer_profile_compatibility_flag[i][2] || - ptl->sub_layer_profile_idc[i] == 3 || ptl->sub_layer_profile_compatibility_flag[i][3] || - ptl->sub_layer_profile_idc[i] == 4 || ptl->sub_layer_profile_compatibility_flag[i][4] || - ptl->sub_layer_profile_idc[i] == 5 || ptl->sub_layer_profile_compatibility_flag[i][5] || - ptl->sub_layer_profile_idc[i] == 9 || ptl->sub_layer_profile_compatibility_flag[i][9] || - ptl->sub_layer_profile_idc[i] == 11 || ptl->sub_layer_profile_compatibility_flag[i][11]) { - // inbld_flag u(1) - ptl->sub_layer_inbld_flag[i] = bs->read_bit(); - } else { - // reserved_zero_bit u(1) - ptl->sub_layer_reserved_zero_bit[i] = bs->read_bit(); - } - } - - if (ptl->sub_layer_level_present_flag[i]) { - if (!bs->require_bits(8)) { - return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl sub_layer_level requires 8 only %d bits", bs->left_bits()); - } - // sub_layer_level_idc u(8) - ptl->sub_layer_level_idc[i] = bs->read_bits(8); - } - } - - return err; -} - -srs_error_t SrsFormat::avc_demux_sps_pps(SrsBuffer *stream) -{ - // AVCDecoderConfigurationRecord - // 5.2.4.1.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16 - int avc_extra_size = stream->size() - stream->pos(); - if (avc_extra_size > 0) { - char *copy_stream_from = stream->data() + stream->pos(); - vcodec->avc_extra_data = std::vector(copy_stream_from, copy_stream_from + avc_extra_size); - } - - if (!stream->require(6)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "avc decode sequence header"); - } - // int8_t configuration_version = stream->read_1bytes(); - stream->read_1bytes(); - // int8_t AVCProfileIndication = stream->read_1bytes(); - vcodec->avc_profile = (SrsAvcProfile)stream->read_1bytes(); - // int8_t profile_compatibility = stream->read_1bytes(); - stream->read_1bytes(); - // int8_t AVCLevelIndication = stream->read_1bytes(); - vcodec->avc_level = (SrsAvcLevel)stream->read_1bytes(); - - // parse the NALU size. - int8_t lengthSizeMinusOne = stream->read_1bytes(); - lengthSizeMinusOne &= 0x03; - vcodec->NAL_unit_length = lengthSizeMinusOne; - - // 5.3.4.2.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16 - // 5.2.4.1 AVC decoder configuration record - // 5.2.4.1.2 Semantics - // The value of this field shall be one of 0, 1, or 3 corresponding to a - // length encoded with 1, 2, or 4 bytes, respectively. - if (vcodec->NAL_unit_length == 2) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps lengthSizeMinusOne should never be 2"); - } - - // 1 sps, 7.3.2.1 Sequence parameter set RBSP syntax - // ISO_IEC_14496-10-AVC-2003.pdf, page 45. - if (!stream->require(1)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS"); - } - int8_t numOfSequenceParameterSets = stream->read_1bytes(); - numOfSequenceParameterSets &= 0x1f; - if (numOfSequenceParameterSets < 1) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS"); - } - // Support for multiple SPS, then pick the first non-empty one. - for (int i = 0; i < numOfSequenceParameterSets; ++i) { - if (!stream->require(2)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS size"); - } - uint16_t sequenceParameterSetLength = stream->read_2bytes(); - if (!stream->require(sequenceParameterSetLength)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS data"); - } - if (sequenceParameterSetLength > 0) { - vcodec->sequenceParameterSetNALUnit.resize(sequenceParameterSetLength); - stream->read_bytes(&vcodec->sequenceParameterSetNALUnit[0], sequenceParameterSetLength); - } - } - - // 1 pps - if (!stream->require(1)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode PPS"); - } - int8_t numOfPictureParameterSets = stream->read_1bytes(); - numOfPictureParameterSets &= 0x1f; - if (numOfPictureParameterSets < 1) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS"); - } - // Support for multiple PPS, then pick the first non-empty one. - for (int i = 0; i < numOfPictureParameterSets; ++i) { - if (!stream->require(2)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode PPS size"); - } - uint16_t pictureParameterSetLength = stream->read_2bytes(); - if (!stream->require(pictureParameterSetLength)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode PPS data"); - } - if (pictureParameterSetLength > 0) { - vcodec->pictureParameterSetNALUnit.resize(pictureParameterSetLength); - stream->read_bytes(&vcodec->pictureParameterSetNALUnit[0], pictureParameterSetLength); - } - } - return avc_demux_sps(); -} - -srs_error_t SrsFormat::avc_demux_sps() -{ - srs_error_t err = srs_success; - - if (vcodec->sequenceParameterSetNALUnit.empty()) { - return err; - } - - char *sps = &vcodec->sequenceParameterSetNALUnit[0]; - int nbsps = (int)vcodec->sequenceParameterSetNALUnit.size(); - - SrsBuffer stream(sps, nbsps); - - // for NALU, 7.3.1 NAL unit syntax - // ISO_IEC_14496-10-AVC-2012.pdf, page 61. - if (!stream.require(1)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS"); - } - int8_t nutv = stream.read_1bytes(); - - // forbidden_zero_bit shall be equal to 0. - int8_t forbidden_zero_bit = (nutv >> 7) & 0x01; - if (forbidden_zero_bit) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "forbidden_zero_bit shall be equal to 0"); - } - - // nal_ref_idc not equal to 0 specifies that the content of the NAL unit contains a sequence parameter set or a picture - // parameter set or a slice of a reference picture or a slice data partition of a reference picture. - int8_t nal_ref_idc = (nutv >> 5) & 0x03; - if (!nal_ref_idc) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "for sps, nal_ref_idc shall be not be equal to 0"); - } - - // 7.4.1 NAL unit semantics - // ISO_IEC_14496-10-AVC-2012.pdf, page 61. - // nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1. - SrsAvcNaluType nal_unit_type = SrsAvcNaluTypeParse(nutv); - if (nal_unit_type != 7) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "for sps, nal_unit_type shall be equal to 7"); - } - - // decode the rbsp from sps. - // rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes. - std::vector rbsp(vcodec->sequenceParameterSetNALUnit.size()); - - int nb_rbsp = srs_rbsp_remove_emulation_bytes(&stream, rbsp); - - return avc_demux_sps_rbsp((char *)&rbsp[0], nb_rbsp); -} - -srs_error_t SrsFormat::avc_demux_sps_rbsp(char *rbsp, int nb_rbsp) -{ - srs_error_t err = srs_success; - - // we donot parse the detail of sps. - // @see https://github.com/ossrs/srs/issues/474 - if (!avc_parse_sps) { - return err; - } - - // reparse the rbsp. - SrsBuffer stream(rbsp, nb_rbsp); - - // for SPS, 7.3.2.1.1 Sequence parameter set data syntax - // ISO_IEC_14496-10-AVC-2012.pdf, page 62. - if (!stream.require(3)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps shall atleast 3bytes"); - } - uint8_t profile_idc = stream.read_1bytes(); - if (!profile_idc) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps the profile_idc invalid"); - } - - int8_t flags = stream.read_1bytes(); - if (flags & 0x03) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps the flags invalid"); - } - - uint8_t level_idc = stream.read_1bytes(); - if (!level_idc) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps the level_idc invalid"); - } - - SrsBitBuffer bs(&stream); - - int32_t seq_parameter_set_id = -1; - if ((err = srs_avc_nalu_read_uev(&bs, seq_parameter_set_id)) != srs_success) { - return srs_error_wrap(err, "read seq_parameter_set_id"); - } - if (seq_parameter_set_id < 0) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps the seq_parameter_set_id invalid"); - } - - int32_t chroma_format_idc = -1; - if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 || profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118 || profile_idc == 128) { - if ((err = srs_avc_nalu_read_uev(&bs, chroma_format_idc)) != srs_success) { - return srs_error_wrap(err, "read chroma_format_idc"); - } - if (chroma_format_idc == 3) { - int8_t separate_colour_plane_flag = -1; - if ((err = srs_avc_nalu_read_bit(&bs, separate_colour_plane_flag)) != srs_success) { - return srs_error_wrap(err, "read separate_colour_plane_flag"); - } - } - - int32_t bit_depth_luma_minus8 = -1; - if ((err = srs_avc_nalu_read_uev(&bs, bit_depth_luma_minus8)) != srs_success) { - return srs_error_wrap(err, "read bit_depth_luma_minus8"); - ; - } - - int32_t bit_depth_chroma_minus8 = -1; - if ((err = srs_avc_nalu_read_uev(&bs, bit_depth_chroma_minus8)) != srs_success) { - return srs_error_wrap(err, "read bit_depth_chroma_minus8"); - ; - } - - int8_t qpprime_y_zero_transform_bypass_flag = -1; - if ((err = srs_avc_nalu_read_bit(&bs, qpprime_y_zero_transform_bypass_flag)) != srs_success) { - return srs_error_wrap(err, "read qpprime_y_zero_transform_bypass_flag"); - ; - } - - int8_t seq_scaling_matrix_present_flag = -1; - if ((err = srs_avc_nalu_read_bit(&bs, seq_scaling_matrix_present_flag)) != srs_success) { - return srs_error_wrap(err, "read seq_scaling_matrix_present_flag"); - ; - } - if (seq_scaling_matrix_present_flag) { - int nb_scmpfs = ((chroma_format_idc != 3) ? 8 : 12); - for (int i = 0; i < nb_scmpfs; i++) { - int8_t seq_scaling_matrix_present_flag_i = -1; - if ((err = srs_avc_nalu_read_bit(&bs, seq_scaling_matrix_present_flag_i)) != srs_success) { - return srs_error_wrap(err, "read seq_scaling_matrix_present_flag_i"); - ; - } - } - } - } - - int32_t log2_max_frame_num_minus4 = -1; - if ((err = srs_avc_nalu_read_uev(&bs, log2_max_frame_num_minus4)) != srs_success) { - return srs_error_wrap(err, "read log2_max_frame_num_minus4"); - ; - } - - int32_t pic_order_cnt_type = -1; - if ((err = srs_avc_nalu_read_uev(&bs, pic_order_cnt_type)) != srs_success) { - return srs_error_wrap(err, "read pic_order_cnt_type"); - ; - } - - if (pic_order_cnt_type == 0) { - int32_t log2_max_pic_order_cnt_lsb_minus4 = -1; - if ((err = srs_avc_nalu_read_uev(&bs, log2_max_pic_order_cnt_lsb_minus4)) != srs_success) { - return srs_error_wrap(err, "read log2_max_pic_order_cnt_lsb_minus4"); - ; - } - } else if (pic_order_cnt_type == 1) { - int8_t delta_pic_order_always_zero_flag = -1; - if ((err = srs_avc_nalu_read_bit(&bs, delta_pic_order_always_zero_flag)) != srs_success) { - return srs_error_wrap(err, "read delta_pic_order_always_zero_flag"); - ; - } - - int32_t offset_for_non_ref_pic = -1; - if ((err = srs_avc_nalu_read_uev(&bs, offset_for_non_ref_pic)) != srs_success) { - return srs_error_wrap(err, "read offset_for_non_ref_pic"); - ; - } - - int32_t offset_for_top_to_bottom_field = -1; - if ((err = srs_avc_nalu_read_uev(&bs, offset_for_top_to_bottom_field)) != srs_success) { - return srs_error_wrap(err, "read offset_for_top_to_bottom_field"); - ; - } - - int32_t num_ref_frames_in_pic_order_cnt_cycle = -1; - if ((err = srs_avc_nalu_read_uev(&bs, num_ref_frames_in_pic_order_cnt_cycle)) != srs_success) { - return srs_error_wrap(err, "read num_ref_frames_in_pic_order_cnt_cycle"); - ; - } - if (num_ref_frames_in_pic_order_cnt_cycle < 0) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps the num_ref_frames_in_pic_order_cnt_cycle"); - } - for (int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) { - int32_t offset_for_ref_frame_i = -1; - if ((err = srs_avc_nalu_read_uev(&bs, offset_for_ref_frame_i)) != srs_success) { - return srs_error_wrap(err, "read offset_for_ref_frame_i"); - ; - } - } - } - - int32_t max_num_ref_frames = -1; - if ((err = srs_avc_nalu_read_uev(&bs, max_num_ref_frames)) != srs_success) { - return srs_error_wrap(err, "read max_num_ref_frames"); - ; - } - - int8_t gaps_in_frame_num_value_allowed_flag = -1; - if ((err = srs_avc_nalu_read_bit(&bs, gaps_in_frame_num_value_allowed_flag)) != srs_success) { - return srs_error_wrap(err, "read gaps_in_frame_num_value_allowed_flag"); - ; - } - - int32_t pic_width_in_mbs_minus1 = -1; - if ((err = srs_avc_nalu_read_uev(&bs, pic_width_in_mbs_minus1)) != srs_success) { - return srs_error_wrap(err, "read pic_width_in_mbs_minus1"); - ; - } - - int32_t pic_height_in_map_units_minus1 = -1; - if ((err = srs_avc_nalu_read_uev(&bs, pic_height_in_map_units_minus1)) != srs_success) { - return srs_error_wrap(err, "read pic_height_in_map_units_minus1"); - ; - } - - int8_t frame_mbs_only_flag = -1; - if ((err = srs_avc_nalu_read_bit(&bs, frame_mbs_only_flag)) != srs_success) { - return srs_error_wrap(err, "read frame_mbs_only_flag"); - ; - } - if (!frame_mbs_only_flag) { - /* Skip mb_adaptive_frame_field_flag */ - int8_t mb_adaptive_frame_field_flag = -1; - if ((err = srs_avc_nalu_read_bit(&bs, mb_adaptive_frame_field_flag)) != srs_success) { - return srs_error_wrap(err, "read mb_adaptive_frame_field_flag"); - ; - } - } - - /* Skip direct_8x8_inference_flag */ - int8_t direct_8x8_inference_flag = -1; - if ((err = srs_avc_nalu_read_bit(&bs, direct_8x8_inference_flag)) != srs_success) { - return srs_error_wrap(err, "read direct_8x8_inference_flag"); - ; - } - - /* We need the following value to evaluate offsets, if any */ - int8_t frame_cropping_flag = -1; - if ((err = srs_avc_nalu_read_bit(&bs, frame_cropping_flag)) != srs_success) { - return srs_error_wrap(err, "read frame_cropping_flag"); - ; - } - int32_t frame_crop_left_offset = 0, frame_crop_right_offset = 0, - frame_crop_top_offset = 0, frame_crop_bottom_offset = 0; - if (frame_cropping_flag) { - if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_left_offset)) != srs_success) { - return srs_error_wrap(err, "read frame_crop_left_offset"); - ; - } - if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_right_offset)) != srs_success) { - return srs_error_wrap(err, "read frame_crop_right_offset"); - ; - } - if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_top_offset)) != srs_success) { - return srs_error_wrap(err, "read frame_crop_top_offset"); - ; - } - if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_bottom_offset)) != srs_success) { - return srs_error_wrap(err, "read frame_crop_bottom_offset"); - ; - } - } - - /* Skip vui_parameters_present_flag */ - int8_t vui_parameters_present_flag = -1; - if ((err = srs_avc_nalu_read_bit(&bs, vui_parameters_present_flag)) != srs_success) { - return srs_error_wrap(err, "read vui_parameters_present_flag"); - ; - } - - vcodec->width = ((pic_width_in_mbs_minus1 + 1) * 16) - frame_crop_left_offset * 2 - frame_crop_right_offset * 2; - vcodec->height = ((2 - frame_mbs_only_flag) * (pic_height_in_map_units_minus1 + 1) * 16) - (frame_crop_top_offset * 2) - (frame_crop_bottom_offset * 2); - - return err; -} - -// LCOV_EXCL_STOP - -srs_error_t SrsFormat::video_nalu_demux(SrsBuffer *stream) -{ - srs_error_t err = srs_success; - - // ensure the sequence header demuxed - if (!vcodec->is_avc_codec_ok()) { - srs_warn("avc ignore type=%d for no sequence header", SrsVideoAvcFrameTraitNALU); - return err; - } - - if (vcodec->id == SrsVideoCodecIdHEVC) { - // TODO: FIXME: Might need to guess format? - return do_avc_demux_ibmf_format(stream); - } - - // Parse the SPS/PPS in ANNEXB or IBMF format. - if (vcodec->payload_format == SrsAvcPayloadFormatIbmf) { - if ((err = avc_demux_ibmf_format(stream)) != srs_success) { - return srs_error_wrap(err, "avc demux ibmf"); - } - } else if (vcodec->payload_format == SrsAvcPayloadFormatAnnexb) { - if ((err = avc_demux_annexb_format(stream)) != srs_success) { - return srs_error_wrap(err, "avc demux annexb"); - } - } else { - if ((err = try_annexb_first ? avc_demux_annexb_format(stream) : avc_demux_ibmf_format(stream)) == srs_success) { - vcodec->payload_format = try_annexb_first ? SrsAvcPayloadFormatAnnexb : SrsAvcPayloadFormatIbmf; - } else { - srs_freep(err); - if ((err = try_annexb_first ? avc_demux_ibmf_format(stream) : avc_demux_annexb_format(stream)) == srs_success) { - vcodec->payload_format = try_annexb_first ? SrsAvcPayloadFormatIbmf : SrsAvcPayloadFormatAnnexb; - } else { - return srs_error_wrap(err, "avc demux try_annexb_first=%d", try_annexb_first); - } - } - } - - return err; -} - -srs_error_t SrsFormat::avc_demux_annexb_format(SrsBuffer *stream) -{ - srs_error_t err = srs_success; - - int pos = stream->pos(); - err = do_avc_demux_annexb_format(stream); - - // Restore the stream if error. - if (err != srs_success) { - stream->skip(pos - stream->pos()); - } - - return err; -} - -srs_error_t SrsFormat::do_avc_demux_annexb_format(SrsBuffer *stream) -{ - srs_error_t err = srs_success; - - // not annexb, try others - if (!srs_avc_startswith_annexb(stream, NULL)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "not annexb"); - } - - // AnnexB - // B.1.1 Byte stream NAL unit syntax, - // ISO_IEC_14496-10-AVC-2003.pdf, page 211. - while (!stream->empty()) { - // find start code - int nb_start_code = 0; - if (!srs_avc_startswith_annexb(stream, &nb_start_code)) { - return err; - } - - // skip the start code. - if (nb_start_code > 0) { - stream->skip(nb_start_code); - } - - // the NALU start bytes. - char *p = stream->data() + stream->pos(); - - // get the last matched NALU - while (!stream->empty()) { - if (srs_avc_startswith_annexb(stream, NULL)) { - break; - } - - stream->skip(1); - } - - char *pp = stream->data() + stream->pos(); - - // skip the empty. - if (pp - p <= 0) { - continue; - } - - // got the NALU. - if ((err = video->add_sample(p, (int)(pp - p))) != srs_success) { - return srs_error_wrap(err, "add video frame"); - } - } - - return err; -} - -srs_error_t SrsFormat::avc_demux_ibmf_format(SrsBuffer *stream) -{ - srs_error_t err = srs_success; - - int pos = stream->pos(); - err = do_avc_demux_ibmf_format(stream); - - // Restore the stream if error. - if (err != srs_success) { - stream->skip(pos - stream->pos()); - } - - return err; -} - -srs_error_t SrsFormat::do_avc_demux_ibmf_format(SrsBuffer *stream) -{ - srs_error_t err = srs_success; - - int PictureLength = stream->size() - stream->pos(); - - // 5.3.4.2.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16 - // 5.2.4.1 AVC decoder configuration record - // 5.2.4.1.2 Semantics - // The value of this field shall be one of 0, 1, or 3 corresponding to a - // length encoded with 1, 2, or 4 bytes, respectively. - srs_assert(vcodec->NAL_unit_length != 2); - - // 5.3.4.2.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 20 - for (int i = 0; i < PictureLength;) { - // unsigned int((NAL_unit_length+1)*8) NALUnitLength; - // TODO: FIXME: Should ignore error? See https://github.com/ossrs/srs-gb28181/commit/a13b9b54938a14796abb9011e7a8ee779439a452 - if (!stream->require(vcodec->NAL_unit_length + 1)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "PictureLength:%d, i:%d, NaluLength:%d, left:%d", - PictureLength, i, vcodec->NAL_unit_length, stream->left()); - } - int32_t NALUnitLength = 0; - if (vcodec->NAL_unit_length == 3) { - NALUnitLength = stream->read_4bytes(); - } else if (vcodec->NAL_unit_length == 1) { - NALUnitLength = stream->read_2bytes(); - } else { - NALUnitLength = stream->read_1bytes(); - } - - // The stream format mighe be incorrect, see: https://github.com/ossrs/srs/issues/183 - if (NALUnitLength < 0) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "PictureLength:%d, i:%d, NaluLength:%d, left:%d, NALUnitLength:%d", - PictureLength, i, vcodec->NAL_unit_length, stream->left(), NALUnitLength); - } - - // NALUnit - if (!stream->require(NALUnitLength)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "PictureLength:%d, i:%d, NaluLength:%d, left:%d, NALUnitLength:%d", - PictureLength, i, vcodec->NAL_unit_length, stream->left(), NALUnitLength); - } - // 7.3.1 NAL unit syntax, ISO_IEC_14496-10-AVC-2003.pdf, page 44. - if ((err = video->add_sample(stream->data() + stream->pos(), NALUnitLength)) != srs_success) { - return srs_error_wrap(err, "avc add video frame"); - } - - stream->skip(NALUnitLength); - i += vcodec->NAL_unit_length + 1 + NALUnitLength; - } - - return err; -} - -srs_error_t SrsFormat::audio_aac_demux(SrsBuffer *stream, int64_t timestamp) -{ - srs_error_t err = srs_success; - - audio->cts = 0; - audio->dts = timestamp; - - // @see: E.4.2 Audio Tags, video_file_format_spec_v10_1.pdf, page 76 - int8_t sound_format = stream->read_1bytes(); - - int8_t sound_type = sound_format & 0x01; - int8_t sound_size = (sound_format >> 1) & 0x01; - int8_t sound_rate = (sound_format >> 2) & 0x03; - sound_format = (sound_format >> 4) & 0x0f; - - SrsAudioCodecId codec_id = (SrsAudioCodecId)sound_format; - acodec->id = codec_id; - - acodec->sound_type = (SrsAudioChannels)sound_type; - acodec->sound_rate = (SrsAudioSampleRate)sound_rate; - acodec->sound_size = (SrsAudioSampleBits)sound_size; - - // we support h.264+mp3 for hls. - if (codec_id == SrsAudioCodecIdMP3) { - return srs_error_new(ERROR_HLS_TRY_MP3, "try mp3"); - } - - // only support aac - if (codec_id != SrsAudioCodecIdAAC) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "not supported codec %d", codec_id); - } - - if (!stream->require(1)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "aac decode aac_packet_type"); - } - - SrsAudioAacFrameTrait aac_packet_type = (SrsAudioAacFrameTrait)stream->read_1bytes(); - audio->aac_packet_type = (SrsAudioAacFrameTrait)aac_packet_type; - - // Update the RAW AAC data. - raw = stream->data() + stream->pos(); - nb_raw = stream->size() - stream->pos(); - - if (aac_packet_type == SrsAudioAacFrameTraitSequenceHeader) { - // AudioSpecificConfig - // 1.6.2.1 AudioSpecificConfig, in ISO_IEC_14496-3-AAC-2001.pdf, page 33. - int aac_extra_size = stream->size() - stream->pos(); - if (aac_extra_size > 0) { - char *copy_stream_from = stream->data() + stream->pos(); - acodec->aac_extra_data = std::vector(copy_stream_from, copy_stream_from + aac_extra_size); - - if ((err = audio_aac_sequence_header_demux(&acodec->aac_extra_data[0], aac_extra_size)) != srs_success) { - return srs_error_wrap(err, "demux aac sh"); - } - } - } else if (aac_packet_type == SrsAudioAacFrameTraitRawData) { - // ensure the sequence header demuxed - if (!acodec->is_aac_codec_ok()) { - srs_warn("aac ignore type=%d for no sequence header", aac_packet_type); - return err; - } - - // Raw AAC frame data in UI8 [] - // 6.3 Raw Data, ISO_IEC_13818-7-AAC-2004.pdf, page 28 - if ((err = audio->add_sample(stream->data() + stream->pos(), stream->size() - stream->pos())) != srs_success) { - return srs_error_wrap(err, "add audio frame"); - } - } else { - // ignored. - } - - // reset the sample rate by sequence header - if (acodec->aac_sample_rate != SrsAacSampleRateUnset) { - static int srs_aac_srates[] = { - 96000, 88200, 64000, 48000, - 44100, 32000, 24000, 22050, - 16000, 12000, 11025, 8000, - 7350, 0, 0, 0}; - switch (srs_aac_srates[acodec->aac_sample_rate]) { - case 11025: - acodec->sound_rate = SrsAudioSampleRate11025; - break; - case 22050: - acodec->sound_rate = SrsAudioSampleRate22050; - break; - case 44100: - acodec->sound_rate = SrsAudioSampleRate44100; - break; - default: - break; - }; - } - - return err; -} - -srs_error_t SrsFormat::audio_mp3_demux(SrsBuffer *stream, int64_t timestamp, bool fresh) -{ - srs_error_t err = srs_success; - - audio->cts = 0; - audio->dts = timestamp; - audio->aac_packet_type = fresh ? SrsAudioMp3FrameTraitSequenceHeader : SrsAudioMp3FrameTraitRawData; - - // @see: E.4.2 Audio Tags, video_file_format_spec_v10_1.pdf, page 76 - int8_t sound_format = stream->read_1bytes(); - - int8_t sound_type = sound_format & 0x01; - int8_t sound_size = (sound_format >> 1) & 0x01; - int8_t sound_rate = (sound_format >> 2) & 0x03; - sound_format = (sound_format >> 4) & 0x0f; - - SrsAudioCodecId codec_id = (SrsAudioCodecId)sound_format; - acodec->id = codec_id; - - acodec->sound_type = (SrsAudioChannels)sound_type; - acodec->sound_rate = (SrsAudioSampleRate)sound_rate; - acodec->sound_size = (SrsAudioSampleBits)sound_size; - - // we always decode aac then mp3. - srs_assert(acodec->id == SrsAudioCodecIdMP3); - - // Update the RAW MP3 data. Note the start is 12 bits syncword 0xFFF, so we should not skip any bytes, for detail - // please see ISO_IEC_11172-3-MP3-1993.pdf page 20 and 26. - raw = stream->data() + stream->pos(); - nb_raw = stream->size() - stream->pos(); - - // mp3 payload. - if ((err = audio->add_sample(raw, nb_raw)) != srs_success) { - return srs_error_wrap(err, "add audio frame"); - } - - return err; -} - -srs_error_t SrsFormat::audio_aac_sequence_header_demux(char *data, int size) -{ - srs_error_t err = srs_success; - - SrsUniquePtr buffer(new SrsBuffer(data, size)); - - // only need to decode the first 2bytes: - // audioObjectType, aac_profile, 5bits. - // samplingFrequencyIndex, aac_sample_rate, 4bits. - // channelConfiguration, aac_channels, 4bits - if (!buffer->require(2)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "audio codec decode aac sh"); - } - uint8_t profile_ObjectType = buffer->read_1bytes(); - uint8_t samplingFrequencyIndex = buffer->read_1bytes(); - - acodec->aac_channels = (samplingFrequencyIndex >> 3) & 0x0f; - samplingFrequencyIndex = ((profile_ObjectType << 1) & 0x0e) | ((samplingFrequencyIndex >> 7) & 0x01); - profile_ObjectType = (profile_ObjectType >> 3) & 0x1f; - - // set the aac sample rate. - acodec->aac_sample_rate = samplingFrequencyIndex; - - // convert the object type in sequence header to aac profile of ADTS. - acodec->aac_object = (SrsAacObjectType)profile_ObjectType; - if (acodec->aac_object == SrsAacObjectTypeReserved) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "aac decode sh object %d", profile_ObjectType); - } - - // TODO: FIXME: to support aac he/he-v2, see: ngx_rtmp_codec_parse_aac_header - // @see: https://github.com/winlinvip/nginx-rtmp-module/commit/3a5f9eea78fc8d11e8be922aea9ac349b9dcbfc2 - // - // donot force to LC, @see: https://github.com/ossrs/srs/issues/81 - // the source will print the sequence header info. - // if (aac_profile > 3) { - // Mark all extended profiles as LC - // to make Android as happy as possible. - // @see: ngx_rtmp_hls_parse_aac_header - // aac_profile = 1; - //} - - return err; -} - bool srs_avc_startswith_annexb(SrsBuffer *stream, int *pnb_start_code) { if (!stream) { diff --git a/trunk/src/kernel/srs_kernel_codec.hpp b/trunk/src/kernel/srs_kernel_codec.hpp index 667f4e5d2..68c3d32dd 100644 --- a/trunk/src/kernel/srs_kernel_codec.hpp +++ b/trunk/src/kernel/srs_kernel_codec.hpp @@ -12,6 +12,9 @@ #include #include +#include +#include + class SrsBuffer; class SrsBitBuffer; class SrsFormat; @@ -264,6 +267,8 @@ enum SrsFrameType { SrsFrameTypeVideo = 9, // 18 = script data SrsFrameTypeScript = 18, + // 20 = command data + SrsFrameTypeCommand = 20, }; /** @@ -1107,30 +1112,6 @@ enum SrsHevcLevel { }; std::string srs_hevc_level2str(SrsHevcLevel level); -/** - * A sample is the unit of frame. - * It's a NALU for H.264, H.265. - * It's the whole AAC raw data for AAC. - * @remark Neither SPS/PPS or ASC is sample unit, it's codec sequence header. - */ -class SrsSample -{ -public: - // The size of unit. - int size; - // The ptr of unit, user must free it. - char *bytes; - -public: - SrsSample(); - SrsSample(char *b, int s); - ~SrsSample(); - -public: - // Copy sample, share the bytes pointer. - SrsSample *copy(); -}; - /** * The codec is the information of encoder, * corresponding to the sequence header of FLV, @@ -1248,183 +1229,6 @@ public: virtual bool is_avc_codec_ok(); }; -// A frame, consists of a codec and a group of samples. -// TODO: FIXME: Rename to packet to follow names of FFmpeg, which means before decoding or after decoding. -class SrsFrame -{ -public: - // The DTS/PTS in milliseconds, which is TBN=1000. - int64_t dts; - // PTS = DTS + CTS. - int32_t cts; - -public: - // The codec info of frame. - SrsCodecConfig *codec; - // The actual parsed number of samples. - int nb_samples; - // The sampels cache. - SrsSample samples[SrsMaxNbSamples]; - -public: - SrsFrame(); - virtual ~SrsFrame(); - -public: - // Initialize the frame, to parse sampels. - virtual srs_error_t initialize(SrsCodecConfig *c); - // Add a sample to frame. - virtual srs_error_t add_sample(char *bytes, int size); -}; - -// A audio frame, besides a frame, contains the audio frame info, such as frame type. -// TODO: FIXME: Rename to packet to follow names of FFmpeg, which means before decoding or after decoding. -class SrsAudioFrame : public SrsFrame -{ -public: - SrsAudioAacFrameTrait aac_packet_type; - -public: - SrsAudioFrame(); - virtual ~SrsAudioFrame(); - -public: - virtual SrsAudioCodecConfig *acodec(); -}; - -// A video frame, besides a frame, contains the video frame info, such as frame type. -// TODO: FIXME: Rename to packet to follow names of FFmpeg, which means before decoding or after decoding. -class SrsVideoFrame : public SrsFrame -{ -public: - // video specified - SrsVideoAvcFrameType frame_type; - SrsVideoAvcFrameTrait avc_packet_type; - // whether sample_units contains IDR frame. - bool has_idr; - // Whether exists AUD NALU. - bool has_aud; - // Whether exists SPS/PPS NALU. - bool has_sps_pps; - // The first nalu type. - SrsAvcNaluType first_nalu_type; - -public: - SrsVideoFrame(); - virtual ~SrsVideoFrame(); - -public: - // Initialize the frame, to parse sampels. - virtual srs_error_t initialize(SrsCodecConfig *c); - // Add the sample without ANNEXB or IBMF header, or RAW AAC or MP3 data. - virtual srs_error_t add_sample(char *bytes, int size); - -public: - virtual SrsVideoCodecConfig *vcodec(); - -public: - static srs_error_t parse_avc_nalu_type(const SrsSample *sample, SrsAvcNaluType &avc_nalu_type); - static srs_error_t parse_avc_bframe(const SrsSample *sample, bool &is_b_frame); - static srs_error_t parse_hevc_nalu_type(const SrsSample *sample, SrsHevcNaluType &hevc_nalu_type); - static srs_error_t parse_hevc_bframe(const SrsSample *sample, SrsFormat *format, bool &is_b_frame); -}; - -/** - * A codec format, including one or many stream, each stream identified by a frame. - * For example, a typical RTMP stream format, consits of a video and audio frame. - * Maybe some RTMP stream only has a audio stream, for instance, redio application. - */ -class SrsFormat -{ -public: - SrsAudioFrame *audio; - SrsAudioCodecConfig *acodec; - SrsVideoFrame *video; - SrsVideoCodecConfig *vcodec; - -public: - char *raw; - int nb_raw; - -public: - // for sequence header, whether parse the h.264 sps. - // TODO: FIXME: Refine it. - bool avc_parse_sps; - // Whether try to parse in ANNEXB, then by IBMF. - bool try_annexb_first; - -public: - SrsFormat(); - virtual ~SrsFormat(); - -public: - // Initialize the format. - virtual srs_error_t initialize(); - // When got a parsed audio packet. - // @param data The data in FLV format. - virtual srs_error_t on_audio(int64_t timestamp, char *data, int size); - // When got a parsed video packet. - // @param data The data in FLV format. - virtual srs_error_t on_video(int64_t timestamp, char *data, int size); - // When got a audio aac sequence header. - virtual srs_error_t on_aac_sequence_header(char *data, int size); - -public: - virtual bool is_aac_sequence_header(); - virtual bool is_mp3_sequence_header(); - // TODO: is avc|hevc|av1 sequence header - virtual bool is_avc_sequence_header(); - -private: - // Demux the video packet in H.264 codec. - // The packet is muxed in FLV format, defined in flv specification. - // Demux the sps/pps from sequence header. - // Demux the samples from NALUs. - virtual srs_error_t video_avc_demux(SrsBuffer *stream, int64_t timestamp); - -private: - virtual srs_error_t hevc_demux_hvcc(SrsBuffer *stream); - -private: - virtual srs_error_t hevc_demux_vps_sps_pps(SrsHevcHvccNalu *nal); - virtual srs_error_t hevc_demux_vps_rbsp(char *rbsp, int nb_rbsp); - virtual srs_error_t hevc_demux_sps_rbsp(char *rbsp, int nb_rbsp); - virtual srs_error_t hevc_demux_pps_rbsp(char *rbsp, int nb_rbsp); - virtual srs_error_t hevc_demux_rbsp_ptl(SrsBitBuffer *bs, SrsHevcProfileTierLevel *ptl, int profile_present_flag, int max_sub_layers_minus1); - -public: - virtual srs_error_t hevc_demux_vps(SrsBuffer *stream); - virtual srs_error_t hevc_demux_sps(SrsBuffer *stream); - virtual srs_error_t hevc_demux_pps(SrsBuffer *stream); - -private: - // Parse the H.264 SPS/PPS. - virtual srs_error_t avc_demux_sps_pps(SrsBuffer *stream); - virtual srs_error_t avc_demux_sps(); - virtual srs_error_t avc_demux_sps_rbsp(char *rbsp, int nb_rbsp); - -private: - // Parse the H.264 or H.265 NALUs. - virtual srs_error_t video_nalu_demux(SrsBuffer *stream); - // Demux the avc NALU in "AnnexB" from ISO_IEC_14496-10-AVC-2003.pdf, page 211. - virtual srs_error_t avc_demux_annexb_format(SrsBuffer *stream); - virtual srs_error_t do_avc_demux_annexb_format(SrsBuffer *stream); - // Demux the avc NALU in "ISO Base Media File Format" from ISO_IEC_14496-15-AVC-format-2012.pdf, page 20 - virtual srs_error_t avc_demux_ibmf_format(SrsBuffer *stream); - virtual srs_error_t do_avc_demux_ibmf_format(SrsBuffer *stream); - -private: - // Demux the audio packet in AAC codec. - // Demux the asc from sequence header. - // Demux the sampels from RAW data. - virtual srs_error_t audio_aac_demux(SrsBuffer *stream, int64_t timestamp); - virtual srs_error_t audio_mp3_demux(SrsBuffer *stream, int64_t timestamp, bool fresh); - -public: - // Directly demux the sequence header, without RTMP packet header. - virtual srs_error_t audio_aac_sequence_header_demux(char *data, int size); -}; - // To read H.264 NALU uev. extern srs_error_t srs_avc_nalu_read_uev(SrsBitBuffer *stream, int32_t &v); extern srs_error_t srs_avc_nalu_read_bit(SrsBitBuffer *stream, int8_t &v); diff --git a/trunk/src/kernel/srs_kernel_flv.cpp b/trunk/src/kernel/srs_kernel_flv.cpp index 390a211ef..0f948626f 100644 --- a/trunk/src/kernel/srs_kernel_flv.cpp +++ b/trunk/src/kernel/srs_kernel_flv.cpp @@ -20,13 +20,48 @@ using namespace std; #include #include #include +#include #include #include #include -#include +int srs_rtmp_prefer_cid(SrsFrameType message_type) +{ + if (message_type == SrsFrameTypeVideo) { + return RTMP_CID_Video; + } else if (message_type == SrsFrameTypeAudio) { + return RTMP_CID_Audio; + } else if (message_type == SrsFrameTypeCommand || message_type == SrsFrameTypeScript) { + return RTMP_CID_OverStream; + } else if (message_type == (SrsFrameType)RTMP_MSG_AMF0CommandMessage) { + return RTMP_CID_OverStream; + } else if (message_type == (SrsFrameType)RTMP_MSG_AMF3DataMessage) { + return RTMP_CID_OverStream; + } else { + return RTMP_CID_OverConnection; + } +} -SrsPps *_srs_pps_objs_msgs = NULL; +int srs_rtmp_write_chunk_header(SrsMediaPacket *msg, char *cache, int nb_cache, bool c0) +{ + int payload_length = msg->payload_.get() ? msg->payload_->size() : 0; + int chunk_id = srs_rtmp_prefer_cid(msg->message_type); + + if (c0) { + return srs_chunk_header_c0(chunk_id, + (uint32_t)msg->timestamp, + payload_length, + msg->message_type, + msg->stream_id, + cache, + nb_cache); + } else { + return srs_chunk_header_c3(chunk_id, + (uint32_t)msg->timestamp, + cache, + nb_cache); + } +} int srs_chunk_header_c0(int prefer_cid, uint32_t timestamp, int32_t payload_length, int8_t message_type, int32_t stream_id, char *cache, int nb_cache) { @@ -159,8 +194,6 @@ SrsMessageHeader::SrsMessageHeader() stream_id = 0; timestamp = 0; - // we always use the connection chunk-id - prefer_cid = RTMP_CID_OverConnection; } SrsMessageHeader::~SrsMessageHeader() @@ -234,9 +267,6 @@ void SrsMessageHeader::initialize_amf0_script(int size, int stream) timestamp_delta = (int32_t)0; timestamp = (int64_t)0; stream_id = (int32_t)stream; - - // amf0 script use connection2 chunk-id - prefer_cid = RTMP_CID_OverConnection2; } void SrsMessageHeader::initialize_audio(int size, uint32_t time, int stream) @@ -246,9 +276,6 @@ void SrsMessageHeader::initialize_audio(int size, uint32_t time, int stream) timestamp_delta = (int32_t)time; timestamp = (int64_t)time; stream_id = (int32_t)stream; - - // audio chunk-id - prefer_cid = RTMP_CID_Audio; } void SrsMessageHeader::initialize_video(int size, uint32_t time, int stream) @@ -258,9 +285,6 @@ void SrsMessageHeader::initialize_video(int size, uint32_t time, int stream) timestamp_delta = (int32_t)time; timestamp = (int64_t)time; stream_id = (int32_t)stream; - - // video chunk-id - prefer_cid = RTMP_CID_Video; } SrsCommonMessage::SrsCommonMessage() @@ -299,126 +323,12 @@ srs_error_t SrsCommonMessage::create(SrsMessageHeader *pheader, char *body, int return err; } -SrsSharedPtrMessage::SrsSharedPtrMessage() : timestamp(0), stream_id(0), message_type(0), prefer_cid(RTMP_CID_OverConnection) +void SrsCommonMessage::to_msg(SrsMediaPacket *msg) { - payload_ = SrsSharedPtr(NULL); - - ++_srs_pps_objs_msgs->sugar; -} - -SrsSharedPtrMessage::~SrsSharedPtrMessage() -{ - // payload_ automatically cleaned up by SrsSharedPtr -} - -srs_error_t SrsSharedPtrMessage::create(SrsCommonMessage *msg) -{ - srs_error_t err = srs_success; - - // Share the memory block from the common message - payload_ = msg->payload_; - this->timestamp = msg->header.timestamp; - this->stream_id = msg->header.stream_id; - this->message_type = msg->header.message_type; - this->prefer_cid = msg->header.prefer_cid; - - return err; -} - -srs_error_t SrsSharedPtrMessage::create(SrsMessageHeader *pheader, char *payload, int size) -{ - srs_error_t err = srs_success; - - if (size < 0) { - return srs_error_new(ERROR_RTMP_MESSAGE_CREATE, "create message size=%d", size); - } - - // Create new memory block and attach the payload - payload_ = SrsSharedPtr(new SrsMemoryBlock()); - payload_->attach(payload, size); - - // Set header information - if (pheader) { - this->timestamp = pheader->timestamp; - this->stream_id = pheader->stream_id; - this->message_type = pheader->message_type; - this->prefer_cid = pheader->prefer_cid; - } - - return err; -} - -void SrsSharedPtrMessage::wrap(char *payload, int size) -{ - // Create new memory block and wrap the payload - payload_ = SrsSharedPtr(new SrsMemoryBlock()); - payload_->attach(payload, size); -} - -bool SrsSharedPtrMessage::check(int stream_id) -{ - // Ignore error when message has no payload. - if (!payload_.get()) { - return true; - } - - // we assume that the stream_id in a group must be the same. - if (this->stream_id == stream_id) { - return true; - } - this->stream_id = stream_id; - - return false; -} - -bool SrsSharedPtrMessage::is_av() -{ - return message_type == RTMP_MSG_AudioMessage || message_type == RTMP_MSG_VideoMessage; -} - -bool SrsSharedPtrMessage::is_audio() -{ - return message_type == RTMP_MSG_AudioMessage; -} - -bool SrsSharedPtrMessage::is_video() -{ - return message_type == RTMP_MSG_VideoMessage; -} - -int SrsSharedPtrMessage::chunk_header(char *cache, int nb_cache, bool c0) -{ - int payload_length = payload_.get() ? payload_->size() : 0; - - if (c0) { - return srs_chunk_header_c0(prefer_cid, (uint32_t)timestamp, - payload_length, message_type, stream_id, cache, nb_cache); - } else { - return srs_chunk_header_c3(prefer_cid, (uint32_t)timestamp, - cache, nb_cache); - } -} - -SrsSharedPtrMessage *SrsSharedPtrMessage::copy() -{ - SrsSharedPtrMessage *copy = copy2(); - - copy->timestamp = timestamp; - copy->stream_id = stream_id; - copy->message_type = message_type; - copy->prefer_cid = prefer_cid; - - return copy; -} - -SrsSharedPtrMessage *SrsSharedPtrMessage::copy2() -{ - SrsSharedPtrMessage *copy = new SrsSharedPtrMessage(); - - // Share the memory block - copy->payload_ = payload_; - - return copy; + msg->payload_ = payload_; + msg->timestamp = header.timestamp; + msg->stream_id = header.stream_id; + msg->message_type = (SrsFrameType)header.message_type; } SrsFlvTransmuxer::SrsFlvTransmuxer() @@ -566,7 +476,7 @@ int SrsFlvTransmuxer::size_tag(int data_size) return SRS_FLV_TAG_HEADER_SIZE + data_size + SRS_FLV_PREVIOUS_TAG_SIZE; } -srs_error_t SrsFlvTransmuxer::write_tags(SrsSharedPtrMessage **msgs, int count) +srs_error_t SrsFlvTransmuxer::write_tags(SrsMediaPacket **msgs, int count) { srs_error_t err = srs_success; @@ -604,7 +514,7 @@ srs_error_t SrsFlvTransmuxer::write_tags(SrsSharedPtrMessage **msgs, int count) iovec *iovs = iovss; int nn_real_iovss = 0; for (int i = 0; i < count; i++) { - SrsSharedPtrMessage *msg = msgs[i]; + SrsMediaPacket *msg = msgs[i]; // Cache FLV packet header. if (msg->is_audio()) { diff --git a/trunk/src/kernel/srs_kernel_flv.hpp b/trunk/src/kernel/srs_kernel_flv.hpp index 9a05bb1fc..9fa1ef126 100644 --- a/trunk/src/kernel/srs_kernel_flv.hpp +++ b/trunk/src/kernel/srs_kernel_flv.hpp @@ -14,6 +14,8 @@ #include #include +#include +#include // For srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifndef _WIN32 @@ -24,8 +26,8 @@ class SrsBuffer; class ISrsWriter; class ISrsReader; class SrsFileReader; -class SrsPacket; -class SrsSample; +class SrsRtmpCommand; +class SrsNaluSample; #define SRS_FLV_TAG_HEADER_SIZE 11 #define SRS_FLV_PREVIOUS_TAG_SIZE 4 @@ -156,12 +158,6 @@ public: // @remark, we use 64bits for large time for jitter detect and hls. int64_t timestamp; -public: - // Get the prefered cid(chunk stream id) which sendout over. - // set at decoding, and canbe used for directly send message, - // For example, dispatch to all connections. - int prefer_cid; - public: SrsMessageHeader(); virtual ~SrsMessageHeader(); @@ -222,80 +218,9 @@ public: // @remark user should never free the body. // @param pheader, the header to copy to the message. NULL to ignore. virtual srs_error_t create(SrsMessageHeader *pheader, char *body, int size); -}; -// The shared ptr message. -// For audio/video/data message that need less memory copy. -// and only for output. -// -// Create first object by constructor and create(), -// use copy if need reference count message. -class SrsSharedPtrMessage -{ - // 4.1. Message Header -public: - // Four-byte field that contains a timestamp of the message. - // The 4 bytes are packed in the big-endian order. - // @remark, used as calc timestamp when decode and encode time. - // @remark, we use 64bits for large time for jitter detect and hls. - int64_t timestamp; - // 4bytes. - // Four-byte field that identifies the stream of the message. These - // bytes are set in big-endian format. - int32_t stream_id; - // Message type for determining audio/video/data - int8_t message_type; - // Preferred chunk ID for RTMP chunking - int prefer_cid; - -public: - // 4.2. Message Payload - SrsSharedPtr payload_; - -public: - SrsSharedPtrMessage(); - virtual ~SrsSharedPtrMessage(); - -public: - // Backward compatibility accessors - char *payload() { return payload_.get() ? payload_->payload() : NULL; } - int size() { return payload_.get() ? payload_->size() : 0; } - -public: - // Create shared ptr message, - // copy header, manage the payload of msg, - // set the payload to NULL to prevent double free. - // @remark payload of msg set to NULL if success. - // @remark User should free the msg. - virtual srs_error_t create(SrsCommonMessage *msg); - // Create shared ptr message, - // from the header and payload. - // @remark user should never free the payload. - // @param pheader, the header to copy to the message. NULL to ignore. - virtual srs_error_t create(SrsMessageHeader *pheader, char *payload, int size); - // Create shared ptr message from RAW payload. - // @remark Note that the header is set to zero. - virtual void wrap(char *payload, int size); - // check prefer cid and stream id. - // @return whether stream id already set. - virtual bool check(int stream_id); - -public: - virtual bool is_av(); - virtual bool is_audio(); - virtual bool is_video(); - -public: - // generate the chunk header to cache. - // @return the size of header. - virtual int chunk_header(char *cache, int nb_cache, bool c0); - -public: - // copy current shared ptr message, use ref-count. - // @remark, assert object is created. - virtual SrsSharedPtrMessage *copy(); - // Only copy the buffer, without header fields. - virtual SrsSharedPtrMessage *copy2(); + // Convert to shared ptr message. + void to_msg(SrsMediaPacket *msg); }; // Transmux RTMP packets to FLV stream. @@ -363,7 +288,7 @@ private: public: // Write the tags in a time. - virtual srs_error_t write_tags(SrsSharedPtrMessage **msgs, int count); + virtual srs_error_t write_tags(SrsMediaPacket **msgs, int count); private: virtual void cache_metadata(char type, char *data, int size, char *cache); @@ -439,6 +364,17 @@ public: virtual srs_error_t seek2(int64_t offset); }; +// Get the prefer cid for message type. +extern int srs_rtmp_prefer_cid(SrsFrameType message_type); + +// Generate the RTMP chunk header for shared ptr message. +// @param msg, the shared ptr message to generate header for. +// @param cache, the cache to write header. +// @param nb_cache, the size of cache. +// @param c0, whether to use c0 format (true) or c3 format (false). +// @return the size of header. 0 if cache not enough. +extern int srs_rtmp_write_chunk_header(SrsMediaPacket *msg, char *cache, int nb_cache, bool c0); + // Generate the c0 chunk header for msg. // @param cache, the cache to write header. // @param nb_cache, the size of cache. diff --git a/trunk/src/kernel/srs_kernel_kbps.cpp b/trunk/src/kernel/srs_kernel_kbps.cpp index 85bc91b5c..cc2f60fc1 100644 --- a/trunk/src/kernel/srs_kernel_kbps.cpp +++ b/trunk/src/kernel/srs_kernel_kbps.cpp @@ -154,6 +154,8 @@ SrsPps *_srs_pps_rrtcps = NULL; // NACK and loss statistics (only _srs_pps_aloss2 was originally in srs_app_server.cpp) SrsPps *_srs_pps_aloss2 = NULL; +SrsPps *_srs_pps_objs_msgs = NULL; + #if defined(SRS_DEBUG) && defined(SRS_DEBUG_STATS) // Debug thread statistics SrsPps *_srs_pps_thread_run = NULL; diff --git a/trunk/src/kernel/srs_kernel_kbps.hpp b/trunk/src/kernel/srs_kernel_kbps.hpp index f7e2bef08..e77d00d15 100644 --- a/trunk/src/kernel/srs_kernel_kbps.hpp +++ b/trunk/src/kernel/srs_kernel_kbps.hpp @@ -167,6 +167,8 @@ extern SrsPps *_srs_pps_objs_rbuf; extern SrsPps *_srs_pps_objs_msgs; extern SrsPps *_srs_pps_objs_rothers; +extern SrsPps *_srs_pps_objs_msgs; + #if defined(SRS_DEBUG) && defined(SRS_DEBUG_STATS) // Debug thread statistics extern SrsPps *_srs_pps_thread_run; diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index 9841c80d5..62e32e0a4 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/trunk/src/kernel/srs_kernel_packet.cpp b/trunk/src/kernel/srs_kernel_packet.cpp new file mode 100644 index 000000000..219cd3177 --- /dev/null +++ b/trunk/src/kernel/srs_kernel_packet.cpp @@ -0,0 +1,2451 @@ +// +// Copyright (c) 2013-2025 The SRS Authors +// +// SPDX-License-Identifier: MIT +// +#include + +#include +#include +#include +#include +#include + +using namespace std; + +SrsNaluSample::SrsNaluSample() +{ + size = 0; + bytes = NULL; +} + +SrsNaluSample::SrsNaluSample(char *b, int s) +{ + size = s; + bytes = b; +} + +SrsNaluSample::~SrsNaluSample() +{ +} + +SrsNaluSample *SrsNaluSample::copy() +{ + SrsNaluSample *p = new SrsNaluSample(); + p->bytes = bytes; + p->size = size; + return p; +} + +SrsMediaPacket::SrsMediaPacket() +{ + timestamp = 0; + stream_id = 0; + message_type = SrsFrameTypeForbidden; + payload_ = SrsSharedPtr(NULL); + + ++_srs_pps_objs_msgs->sugar; +} + +SrsMediaPacket::~SrsMediaPacket() +{ + // payload_ automatically cleaned up by SrsSharedPtr +} + +void SrsMediaPacket::wrap(char *payload, int size) +{ + // Create new memory block and wrap the payload + payload_ = SrsSharedPtr(new SrsMemoryBlock()); + payload_->attach(payload, size); +} + +bool SrsMediaPacket::check(int stream_id) +{ + // Ignore error when message has no payload. + if (!payload_.get()) { + return true; + } + + // we assume that the stream_id in a group must be the same. + if (this->stream_id == stream_id) { + return true; + } + this->stream_id = stream_id; + + return false; +} + +bool SrsMediaPacket::is_av() +{ + return message_type == SrsFrameTypeAudio || message_type == SrsFrameTypeVideo; +} + +bool SrsMediaPacket::is_audio() +{ + return message_type == SrsFrameTypeAudio; +} + +bool SrsMediaPacket::is_video() +{ + return message_type == SrsFrameTypeVideo; +} + +SrsMediaPacket *SrsMediaPacket::copy() +{ + SrsMediaPacket *copy = new SrsMediaPacket(); + + copy->timestamp = timestamp; + copy->stream_id = stream_id; + copy->message_type = message_type; + copy->payload_ = payload_; + + return copy; +} + +SrsParsedPacket::SrsParsedPacket() +{ + codec = NULL; + nb_samples = 0; + dts = 0; + cts = 0; +} + +SrsParsedPacket::~SrsParsedPacket() +{ +} + +srs_error_t SrsParsedPacket::initialize(SrsCodecConfig *c) +{ + codec = c; + nb_samples = 0; + dts = 0; + cts = 0; + return srs_success; +} + +srs_error_t SrsParsedPacket::add_sample(char *bytes, int size) +{ + srs_error_t err = srs_success; + + // Ignore empty sample. + if (!bytes || size <= 0) + return err; + + if (nb_samples >= SrsMaxNbSamples) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "Frame samples overflow"); + } + + SrsNaluSample *sample = &samples[nb_samples++]; + sample->bytes = bytes; + sample->size = size; + + return err; +} + +SrsParsedAudioPacket::SrsParsedAudioPacket() +{ + aac_packet_type = SrsAudioAacFrameTraitForbidden; +} + +SrsParsedAudioPacket::~SrsParsedAudioPacket() +{ +} + +SrsAudioCodecConfig *SrsParsedAudioPacket::acodec() +{ + return (SrsAudioCodecConfig *)codec; +} + +SrsParsedVideoPacket::SrsParsedVideoPacket() +{ + frame_type = SrsVideoAvcFrameTypeForbidden; + avc_packet_type = SrsVideoAvcFrameTraitForbidden; + has_idr = has_aud = has_sps_pps = false; + first_nalu_type = SrsAvcNaluTypeForbidden; +} + +SrsParsedVideoPacket::~SrsParsedVideoPacket() +{ +} + +srs_error_t SrsParsedVideoPacket::initialize(SrsCodecConfig *c) +{ + first_nalu_type = SrsAvcNaluTypeForbidden; + has_idr = has_sps_pps = has_aud = false; + return SrsParsedPacket::initialize(c); +} + +srs_error_t SrsParsedVideoPacket::add_sample(char *bytes, int size) +{ + srs_error_t err = srs_success; + + if ((err = SrsParsedPacket::add_sample(bytes, size)) != srs_success) { + return srs_error_wrap(err, "add frame"); + } + + SrsVideoCodecConfig *c = vcodec(); + if (!bytes || size <= 0) + return err; + + // For HEVC(H.265), try to parse the IDR from NALUs. + if (c && c->id == SrsVideoCodecIdHEVC) { + SrsHevcNaluType nalu_type = SrsHevcNaluTypeParse(bytes[0]); + has_idr = SrsIsIRAP(nalu_type); + return err; + } + + // By default, use AVC(H.264) to parse NALU. + // For video, parse the nalu type, set the IDR flag. + SrsAvcNaluType nal_unit_type = SrsAvcNaluTypeParse(bytes[0]); + + if (nal_unit_type == SrsAvcNaluTypeIDR) { + has_idr = true; + } else if (nal_unit_type == SrsAvcNaluTypeSPS || nal_unit_type == SrsAvcNaluTypePPS) { + has_sps_pps = true; + } else if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) { + has_aud = true; + } + + if (first_nalu_type == SrsAvcNaluTypeReserved) { + first_nalu_type = nal_unit_type; + } + + return err; +} + +SrsVideoCodecConfig *SrsParsedVideoPacket::vcodec() +{ + return (SrsVideoCodecConfig *)codec; +} + +srs_error_t SrsParsedVideoPacket::parse_avc_nalu_type(const SrsNaluSample *sample, SrsAvcNaluType &avc_nalu_type) +{ + srs_error_t err = srs_success; + + if (sample == NULL || sample->size < 1) { + return srs_error_new(ERROR_NALU_EMPTY, "empty nalu"); + } + + uint8_t header = sample->bytes[0]; + avc_nalu_type = SrsAvcNaluTypeParse(header); + + return err; +} + +srs_error_t SrsParsedVideoPacket::parse_avc_bframe(const SrsNaluSample *sample, bool &is_b_frame) +{ + srs_error_t err = srs_success; + + SrsAvcNaluType nalu_type; + if ((err = parse_avc_nalu_type(sample, nalu_type)) != srs_success) { + return srs_error_wrap(err, "parse avc nalu type error"); + } + + if (nalu_type != SrsAvcNaluTypeNonIDR && nalu_type != SrsAvcNaluTypeDataPartitionA && nalu_type != SrsAvcNaluTypeDataPartitionB && nalu_type != SrsAvcNaluTypeDataPartitionC) { + is_b_frame = false; + return err; + } + + SrsUniquePtr stream(new SrsBuffer(sample->bytes, sample->size)); + + // Skip nalu header. + stream->skip(1); + + SrsBitBuffer bitstream(stream.get()); + int32_t first_mb_in_slice = 0; + if ((err = srs_avc_nalu_read_uev(&bitstream, first_mb_in_slice)) != srs_success) { + return srs_error_wrap(err, "nalu read uev"); + } + + int32_t slice_type_v = 0; + if ((err = srs_avc_nalu_read_uev(&bitstream, slice_type_v)) != srs_success) { + return srs_error_wrap(err, "nalu read uev"); + } + SrsAvcSliceType slice_type = (SrsAvcSliceType)slice_type_v; + + is_b_frame = slice_type == SrsAvcSliceTypeB || slice_type == SrsAvcSliceTypeB1; + if (is_b_frame) { + srs_verbose("nalu_type=%d, slice type=%d", nalu_type, slice_type); + } + + return err; +} + +srs_error_t SrsParsedVideoPacket::parse_hevc_nalu_type(const SrsNaluSample *sample, SrsHevcNaluType &hevc_nalu_type) +{ + srs_error_t err = srs_success; + + if (sample == NULL || sample->size < 1) { + return srs_error_new(ERROR_NALU_EMPTY, "empty hevc nalu"); + } + + uint8_t header = sample->bytes[0]; + hevc_nalu_type = SrsHevcNaluTypeParse(header); + + return err; +} + +srs_error_t SrsParsedVideoPacket::parse_hevc_bframe(const SrsNaluSample *sample, SrsFormat *format, bool &is_b_frame) +{ + srs_error_t err = srs_success; + + SrsHevcNaluType nalu_type; + if ((err = parse_hevc_nalu_type(sample, nalu_type)) != srs_success) { + return srs_error_wrap(err, "parse hevc nalu type error"); + } + + if (nalu_type > SrsHevcNaluType_CODED_SLICE_TFD) { + is_b_frame = false; + return err; + } + + SrsUniquePtr stream(new SrsBuffer(sample->bytes, sample->size)); + stream->skip(2); + + // @see 7.3.6.1 General slice segment header syntax + // @doc ITU-T-H.265-2021.pdf, page 66. + SrsBitBuffer bs(stream.get()); + + uint8_t first_slice_segment_in_pic_flag = bs.read_bit(); + + uint32_t slice_pic_parameter_set_id; + if ((err = bs.read_bits_ue(slice_pic_parameter_set_id)) != srs_success) { + return srs_error_wrap(err, "read slice pic parameter set id"); + } + + if (slice_pic_parameter_set_id >= SrsHevcMax_PPS_COUNT) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "slice pic parameter set id out of range: %d", slice_pic_parameter_set_id); + } + + SrsHevcRbspPps *pps = &(format->vcodec->hevc_dec_conf_record_.pps_table[slice_pic_parameter_set_id]); + if (!pps) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps not found"); + } + + uint8_t dependent_slice_segment_flag = 0; + if (!first_slice_segment_in_pic_flag) { + if (pps->dependent_slice_segments_enabled_flag) { + dependent_slice_segment_flag = bs.read_bit(); + } + } + + if (dependent_slice_segment_flag) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "dependent slice segment flag is not supported"); + } + + for (int i = 0; i < pps->num_extra_slice_header_bits; i++) { + bs.skip_bits(1); + } + + uint32_t slice_type; + if ((err = bs.read_bits_ue(slice_type)) != srs_success) { + return srs_error_wrap(err, "read slice type"); + } + + is_b_frame = slice_type == SrsHevcSliceTypeB; + if (is_b_frame) { + srs_verbose("nalu_type=%d, slice type=%d", nalu_type, slice_type); + } + + // no need to evaluate the rest + + return err; +} + +SrsFormat::SrsFormat() +{ + acodec = NULL; + vcodec = NULL; + audio = NULL; + video = NULL; + avc_parse_sps = true; + try_annexb_first = true; + raw = NULL; + nb_raw = 0; +} + +SrsFormat::~SrsFormat() +{ + srs_freep(audio); + srs_freep(video); + srs_freep(acodec); + srs_freep(vcodec); +} + +// CRITICAL: This method is called AFTER the source has been added to the source pool +// in the fetch_or_create pattern (see PR 4449). +// +// IMPORTANT: All field initialization in this method MUST NOT cause coroutine context switches. +// This prevents the race condition where multiple coroutines could create duplicate sources +// for the same stream when context switches occurred during initialization. +srs_error_t SrsFormat::initialize() +{ + if (!vcodec) { + vcodec = new SrsVideoCodecConfig(); + } + + return srs_success; +} + +srs_error_t SrsFormat::on_audio(int64_t timestamp, char *data, int size) +{ + srs_error_t err = srs_success; + + if (!data || size <= 0) { + srs_info("no audio present, ignore it."); + return err; + } + + SrsUniquePtr buffer(new SrsBuffer(data, size)); + + // We already checked the size is positive and data is not NULL. + srs_assert(buffer->require(1)); + + // @see: E.4.2 Audio Tags, video_file_format_spec_v10_1.pdf, page 76 + uint8_t v = buffer->read_1bytes(); + SrsAudioCodecId codec = (SrsAudioCodecId)((v >> 4) & 0x0f); + + if (codec != SrsAudioCodecIdMP3 && codec != SrsAudioCodecIdAAC && codec != SrsAudioCodecIdOpus) { + return err; + } + + bool fresh = !acodec; + if (!acodec) { + acodec = new SrsAudioCodecConfig(); + } + if (!audio) { + audio = new SrsParsedAudioPacket(); + } + + if ((err = audio->initialize(acodec)) != srs_success) { + return srs_error_wrap(err, "init audio"); + } + + // Parse by specified codec. + buffer->skip(-1 * buffer->pos()); + + if (codec == SrsAudioCodecIdMP3) { + return audio_mp3_demux(buffer.get(), timestamp, fresh); + } else if (codec == SrsAudioCodecIdAAC) { + return audio_aac_demux(buffer.get(), timestamp); + } else { + return srs_error_new(ERROR_NOT_IMPLEMENTED, "opus demuxer not implemented"); + } +} + +srs_error_t SrsFormat::on_video(int64_t timestamp, char *data, int size) +{ + srs_error_t err = srs_success; + + if (!data || size <= 0) { + srs_trace("no video present, ignore it."); + return err; + } + + SrsUniquePtr buffer(new SrsBuffer(data, size)); + return video_avc_demux(buffer.get(), timestamp); +} + +srs_error_t SrsFormat::on_aac_sequence_header(char *data, int size) +{ + srs_error_t err = srs_success; + + if (!acodec) { + acodec = new SrsAudioCodecConfig(); + } + if (!audio) { + audio = new SrsParsedAudioPacket(); + } + + if ((err = audio->initialize(acodec)) != srs_success) { + return srs_error_wrap(err, "init audio"); + } + + return audio_aac_sequence_header_demux(data, size); +} + +bool SrsFormat::is_aac_sequence_header() +{ + return acodec && acodec->id == SrsAudioCodecIdAAC && audio && audio->aac_packet_type == SrsAudioAacFrameTraitSequenceHeader; +} + +bool SrsFormat::is_mp3_sequence_header() +{ + return acodec && acodec->id == SrsAudioCodecIdMP3 && audio && audio->aac_packet_type == SrsAudioMp3FrameTraitSequenceHeader; +} + +bool SrsFormat::is_avc_sequence_header() +{ + bool h264 = (vcodec && vcodec->id == SrsVideoCodecIdAVC); + bool h265 = (vcodec && vcodec->id == SrsVideoCodecIdHEVC); + bool av1 = (vcodec && vcodec->id == SrsVideoCodecIdAV1); + return vcodec && (h264 || h265 || av1) && video && video->avc_packet_type == SrsVideoAvcFrameTraitSequenceHeader; +} + +// Remove the emulation bytes from stream, and return num of bytes of the rbsp. +int srs_rbsp_remove_emulation_bytes(SrsBuffer *stream, std::vector &rbsp) +{ + int nb_rbsp = 0; + while (!stream->empty()) { + rbsp[nb_rbsp] = stream->read_1bytes(); + + // .. 00 00 03 xx, the 03 byte should be drop where xx represents any + // 2 bit pattern: 00, 01, 10, or 11. + if (nb_rbsp >= 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) { + // read 1byte more. + if (stream->empty()) { + nb_rbsp++; + break; + } + + // |---------------------|----------------------------| + // | rbsp | nalu with emulation bytes | + // |---------------------|----------------------------| + // | 0x00 0x00 0x00 | 0x00 0x00 0x03 0x00 | + // | 0x00 0x00 0x01 | 0x00 0x00 0x03 0x01 | + // | 0x00 0x00 0x02 | 0x00 0x00 0x03 0x02 | + // | 0x00 0x00 0x03 | 0x00 0x00 0x03 0x03 | + // | 0x00 0x00 0x03 0x04 | 0x00 0x00 0x03 0x04 | + // |---------------------|----------------------------| + uint8_t ev = stream->read_1bytes(); + if (ev > 3) { + nb_rbsp++; + } + rbsp[nb_rbsp] = ev; + } + + nb_rbsp++; + } + + return nb_rbsp; +} + +srs_error_t SrsFormat::video_avc_demux(SrsBuffer *stream, int64_t timestamp) +{ + srs_error_t err = srs_success; + + if (!stream->require(1)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "video avc demux shall atleast 1bytes"); + } + + // Parse the frame type and the first bit indicates the ext header. + uint8_t frame_type = stream->read_1bytes(); + bool is_ext_header = frame_type & 0x80; + + // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78 + SrsVideoCodecId codec_id = SrsVideoCodecIdForbidden; + SrsVideoAvcFrameTrait packet_type = SrsVideoAvcFrameTraitForbidden; + if (!is_ext_header) { + // See rtmp_specification_1.0.pdf + codec_id = (SrsVideoCodecId)(frame_type & 0x0f); + frame_type = (frame_type >> 4) & 0x0f; + } else { + // See https://github.com/veovera/enhanced-rtmp + packet_type = (SrsVideoAvcFrameTrait)(frame_type & 0x0f); + frame_type = (frame_type >> 4) & 0x07; + + if (!stream->require(4)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "fourCC requires 4bytes, only %dbytes", stream->left()); + } + + uint32_t four_cc = stream->read_4bytes(); + if (four_cc == 0x68766331) { // 'hvc1'=0x68766331 + codec_id = SrsVideoCodecIdHEVC; + } + } + + if (!vcodec) { + vcodec = new SrsVideoCodecConfig(); + } + + if (!video) { + video = new SrsParsedVideoPacket(); + } + + if ((err = video->initialize(vcodec)) != srs_success) { + return srs_error_wrap(err, "init video"); + } + + video->frame_type = (SrsVideoAvcFrameType)frame_type; + + // ignore info frame without error, + // @see https://github.com/ossrs/srs/issues/288#issuecomment-69863909 + if (video->frame_type == SrsVideoAvcFrameTypeVideoInfoFrame) { + srs_warn("avc ignore the info frame"); + return err; + } + + // Check codec for H.264 and H.265. + bool codec_ok = (codec_id == SrsVideoCodecIdAVC); + codec_ok = codec_ok ? true : (codec_id == SrsVideoCodecIdHEVC); + if (!codec_ok) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "only support video H.264/H.265, actual=%d", codec_id); + } + vcodec->id = codec_id; + + int32_t composition_time = 0; + if (!is_ext_header) { + // See rtmp_specification_1.0.pdf + if (!stream->require(4)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "requires 4bytes, only %dbytes", stream->left()); + } + packet_type = (SrsVideoAvcFrameTrait)stream->read_1bytes(); + composition_time = stream->read_3bytes(); + } else { + // See https://github.com/veovera/enhanced-rtmp + if (packet_type == SrsVideoHEVCFrameTraitPacketTypeCodedFrames) { + if (!stream->require(3)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "requires 3 bytes, only %dbytes", stream->left()); + } + composition_time = stream->read_3bytes(); + } + } + + // pts = dts + cts. + video->dts = timestamp; + video->cts = composition_time; + video->avc_packet_type = packet_type; + + // Update the RAW AVC data. + raw = stream->data() + stream->pos(); + nb_raw = stream->size() - stream->pos(); + + // Parse sequence header for H.265/HEVC. + if (codec_id == SrsVideoCodecIdHEVC) { + if (packet_type == SrsVideoAvcFrameTraitSequenceHeader) { + // TODO: demux vps/sps/pps for hevc + if ((err = hevc_demux_hvcc(stream)) != srs_success) { + return srs_error_wrap(err, "demux hevc VPS/SPS/PPS"); + } + } else if (packet_type == SrsVideoAvcFrameTraitNALU || packet_type == SrsVideoHEVCFrameTraitPacketTypeCodedFramesX) { + // TODO: demux nalu for hevc + if ((err = video_nalu_demux(stream)) != srs_success) { + return srs_error_wrap(err, "demux hevc NALU"); + } + } + return err; + } + + // Parse sequence header for H.264/AVC. + if (packet_type == SrsVideoAvcFrameTraitSequenceHeader) { + // TODO: FIXME: Maybe we should ignore any error for parsing sps/pps. + if ((err = avc_demux_sps_pps(stream)) != srs_success) { + return srs_error_wrap(err, "demux SPS/PPS"); + } + } else if (packet_type == SrsVideoAvcFrameTraitNALU) { + if ((err = video_nalu_demux(stream)) != srs_success) { + return srs_error_wrap(err, "demux NALU"); + } + } else { + // ignored. + } + + return err; +} + +// For media server, we don't care the codec, so we just try to parse sps-pps, and we could ignore any error if fail. +// LCOV_EXCL_START + +// struct ptl +SrsHevcProfileTierLevel::SrsHevcProfileTierLevel() +{ + general_profile_space = 0; + general_tier_flag = 0; + general_profile_idc = 0; + memset(general_profile_compatibility_flag, 0, 32); + general_progressive_source_flag = 0; + general_interlaced_source_flag = 0; + general_non_packed_constraint_flag = 0; + general_frame_only_constraint_flag = 0; + general_max_12bit_constraint_flag = 0; + general_max_10bit_constraint_flag = 0; + general_max_8bit_constraint_flag = 0; + general_max_422chroma_constraint_flag = 0; + general_max_420chroma_constraint_flag = 0; + general_max_monochrome_constraint_flag = 0; + general_intra_constraint_flag = 0; + general_one_picture_only_constraint_flag = 0; + general_lower_bit_rate_constraint_flag = 0; + general_max_14bit_constraint_flag = 0; + general_reserved_zero_7bits = 0; + general_reserved_zero_33bits = 0; + general_reserved_zero_34bits = 0; + general_reserved_zero_35bits = 0; + general_reserved_zero_43bits = 0; + general_inbld_flag = 0; + general_reserved_zero_bit = 0; + general_level_idc = 0; + memset(reserved_zero_2bits, 0, 8); +} + +SrsHevcProfileTierLevel::~SrsHevcProfileTierLevel() +{ +} + +// Parse the hevc vps/sps/pps +srs_error_t SrsFormat::hevc_demux_hvcc(SrsBuffer *stream) +{ + srs_error_t err = srs_success; + + int avc_extra_size = stream->size() - stream->pos(); + if (avc_extra_size > 0) { + char *copy_stream_from = stream->data() + stream->pos(); + vcodec->avc_extra_data = std::vector(copy_stream_from, copy_stream_from + avc_extra_size); + } + + const int HEVC_MIN_SIZE = 23; // From configuration_version to numOfArrays + if (!stream->require(HEVC_MIN_SIZE)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "requires %d only %d bytes", HEVC_MIN_SIZE, stream->left()); + } + + SrsHevcDecoderConfigurationRecord *dec_conf_rec_p = &(vcodec->hevc_dec_conf_record_); + dec_conf_rec_p->configuration_version = stream->read_1bytes(); + if (dec_conf_rec_p->configuration_version != 1) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "invalid version=%d", dec_conf_rec_p->configuration_version); + } + + // Read general_profile_space(2bits), general_tier_flag(1bit), general_profile_idc(5bits) + uint8_t data_byte = stream->read_1bytes(); + dec_conf_rec_p->general_profile_space = (data_byte >> 6) & 0x03; + dec_conf_rec_p->general_tier_flag = (data_byte >> 5) & 0x01; + dec_conf_rec_p->general_profile_idc = data_byte & 0x1F; + srs_info("hevc version:%d, general_profile_space:%d, general_tier_flag:%d, general_profile_idc:%d", + dec_conf_rec_p->configuration_version, dec_conf_rec_p->general_profile_space, dec_conf_rec_p->general_tier_flag, + dec_conf_rec_p->general_profile_idc); + + // general_profile_compatibility_flags: 32bits + dec_conf_rec_p->general_profile_compatibility_flags = (uint32_t)stream->read_4bytes(); + + // general_constraint_indicator_flags: 48bits + uint64_t data_64bit = (uint64_t)stream->read_4bytes(); + data_64bit = (data_64bit << 16) | (stream->read_2bytes()); + dec_conf_rec_p->general_constraint_indicator_flags = data_64bit; + + // general_level_idc: 8bits + dec_conf_rec_p->general_level_idc = stream->read_1bytes(); + // min_spatial_segmentation_idc: xxxx 14bits + dec_conf_rec_p->min_spatial_segmentation_idc = stream->read_2bytes() & 0x0fff; + // parallelism_type: xxxx xx 2bits + dec_conf_rec_p->parallelism_type = stream->read_1bytes() & 0x03; + // chroma_format: xxxx xx 2bits + dec_conf_rec_p->chroma_format = stream->read_1bytes() & 0x03; + // bit_depth_luma_minus8: xxxx x 3bits + dec_conf_rec_p->bit_depth_luma_minus8 = stream->read_1bytes() & 0x07; + // bit_depth_chroma_minus8: xxxx x 3bits + dec_conf_rec_p->bit_depth_chroma_minus8 = stream->read_1bytes() & 0x07; + srs_info("general_constraint_indicator_flags:0x%x, general_level_idc:%d, min_spatial_segmentation_idc:%d, parallelism_type:%d, chroma_format:%d, bit_depth_luma_minus8:%d, bit_depth_chroma_minus8:%d", + dec_conf_rec_p->general_constraint_indicator_flags, dec_conf_rec_p->general_level_idc, + dec_conf_rec_p->min_spatial_segmentation_idc, dec_conf_rec_p->parallelism_type, dec_conf_rec_p->chroma_format, + dec_conf_rec_p->bit_depth_luma_minus8, dec_conf_rec_p->bit_depth_chroma_minus8); + + // avg_frame_rate: 16bits + vcodec->frame_rate = dec_conf_rec_p->avg_frame_rate = stream->read_2bytes(); + // 8bits: constant_frame_rate(2bits), num_temporal_layers(3bits), + // temporal_id_nested(1bit), length_size_minus_one(2bits) + data_byte = stream->read_1bytes(); + dec_conf_rec_p->constant_frame_rate = (data_byte >> 6) & 0x03; + dec_conf_rec_p->num_temporal_layers = (data_byte >> 3) & 0x07; + dec_conf_rec_p->temporal_id_nested = (data_byte >> 2) & 0x01; + + // Parse the NALU size. + dec_conf_rec_p->length_size_minus_one = data_byte & 0x03; + vcodec->NAL_unit_length = dec_conf_rec_p->length_size_minus_one; + + // 5.3.4.2.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16 + // 5.2.4.1 AVC decoder configuration record + // 5.2.4.1.2 Semantics + // The value of this field shall be one of 0, 1, or 3 corresponding to a + // length encoded with 1, 2, or 4 bytes, respectively. + if (vcodec->NAL_unit_length == 2) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "sps lengthSizeMinusOne should never be 2"); + } + + uint8_t numOfArrays = stream->read_1bytes(); + srs_info("avg_frame_rate:%d, constant_frame_rate:%d, num_temporal_layers:%d, temporal_id_nested:%d, length_size_minus_one:%d, numOfArrays:%d", + dec_conf_rec_p->avg_frame_rate, dec_conf_rec_p->constant_frame_rate, dec_conf_rec_p->num_temporal_layers, + dec_conf_rec_p->temporal_id_nested, dec_conf_rec_p->length_size_minus_one, numOfArrays); + + // parse vps/pps/sps + dec_conf_rec_p->nalu_vec.clear(); + for (int index = 0; index < numOfArrays; index++) { + if (!stream->require(3)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "requires 3 only %d bytes", stream->left()); + } + data_byte = stream->read_1bytes(); + + SrsHevcHvccNalu hevc_unit; + hevc_unit.array_completeness = (data_byte >> 7) & 0x01; + hevc_unit.nal_unit_type = data_byte & 0x3f; + hevc_unit.num_nalus = stream->read_2bytes(); + + for (int i = 0; i < hevc_unit.num_nalus; i++) { + if (!stream->require(2)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "num_nalus requires 2 only %d bytes", stream->left()); + } + + SrsHevcNalData data_item; + data_item.nal_unit_length = stream->read_2bytes(); + + if (!stream->require(data_item.nal_unit_length)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "requires %d only %d bytes", + data_item.nal_unit_length, stream->left()); + } + // copy vps/pps/sps data + data_item.nal_unit_data.resize(data_item.nal_unit_length); + + stream->read_bytes((char *)(&data_item.nal_unit_data[0]), data_item.nal_unit_length); + srs_info("hevc nalu type:%d, array_completeness:%d, num_nalus:%d, i:%d, nal_unit_length:%d", + hevc_unit.nal_unit_type, hevc_unit.array_completeness, hevc_unit.num_nalus, i, data_item.nal_unit_length); + hevc_unit.nal_data_vec.push_back(data_item); + } + dec_conf_rec_p->nalu_vec.push_back(hevc_unit); + + // demux nalu + if ((err = hevc_demux_vps_sps_pps(&hevc_unit)) != srs_success) { + return srs_error_wrap(err, "hevc demux vps/sps/pps failed"); + } + } + + return err; +} + +srs_error_t SrsFormat::hevc_demux_vps_sps_pps(SrsHevcHvccNalu *nal) +{ + srs_error_t err = srs_success; + + if (nal->nal_data_vec.empty()) { + return err; + } + + // TODO: FIXME: Support for multiple VPS/SPS/PPS, then pick the first non-empty one. + char *frame = (char *)(&nal->nal_data_vec[0].nal_unit_data[0]); + int nb_frame = nal->nal_data_vec[0].nal_unit_length; + SrsBuffer stream(frame, nb_frame); + + // nal data + switch (nal->nal_unit_type) { + case SrsHevcNaluType_VPS: + err = hevc_demux_vps(&stream); + break; + case SrsHevcNaluType_SPS: + err = hevc_demux_sps(&stream); + break; + case SrsHevcNaluType_PPS: + err = hevc_demux_pps(&stream); + break; + default: + break; + } + + return err; +} + +srs_error_t SrsFormat::hevc_demux_vps(SrsBuffer *stream) +{ + // for NALU, ITU-T H.265 7.3.2.1 Video parameter set RBSP syntax + // @see 7.3.1.2 NAL unit header syntax + // @doc ITU-T-H.265-2021.pdf, page 53. + + if (!stream->require(1)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "decode hevc vps requires 1 only %d bytes", stream->left()); + } + int8_t nutv = stream->read_1bytes(); + + // forbidden_zero_bit shall be equal to 0. + int8_t forbidden_zero_bit = (nutv >> 7) & 0x01; + if (forbidden_zero_bit) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc forbidden_zero_bit=%d shall be equal to 0", forbidden_zero_bit); + } + + // nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1. + // @see 7.4.2.2 NAL unit header semantics + // @doc ITU-T-H.265-2021.pdf, page 86. + SrsHevcNaluType nal_unit_type = (SrsHevcNaluType)((nutv >> 1) & 0x3f); + if (nal_unit_type != SrsHevcNaluType_VPS) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc vps nal_unit_type=%d shall be equal to 33", nal_unit_type); + } + + // nuh_layer_id + nuh_temporal_id_plus1 + stream->skip(1); + + // decode the rbsp from vps. + // rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes. + std::vector rbsp(stream->size()); + + int nb_rbsp = srs_rbsp_remove_emulation_bytes(stream, rbsp); + + return hevc_demux_vps_rbsp((char *)&rbsp[0], nb_rbsp); +} + +srs_error_t SrsFormat::hevc_demux_vps_rbsp(char *rbsp, int nb_rbsp) +{ + srs_error_t err = srs_success; + + // reparse the rbsp. + SrsBuffer stream(rbsp, nb_rbsp); + + // H265 VPS (video_parameter_set_rbsp()) NAL Unit. + // Section 7.3.2.1 ("Video parameter set RBSP syntax") of the H.265 + // ITU-T-H.265-2021.pdf, page 54. + if (!stream.require(4)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "vps requires 4 only %d bytes", stream.left()); + } + + SrsBitBuffer bs(&stream); + + // vps_video_parameter_set_id u(4) + int vps_video_parameter_set_id = bs.read_bits(4); + if (vps_video_parameter_set_id < 0 || vps_video_parameter_set_id > SrsHevcMax_VPS_COUNT) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "vps id out of range: %d", vps_video_parameter_set_id); + } + + // select table + SrsHevcDecoderConfigurationRecord *dec_conf_rec = &(vcodec->hevc_dec_conf_record_); + SrsHevcRbspVps *vps = &(dec_conf_rec->vps_table[vps_video_parameter_set_id]); + + vps->vps_video_parameter_set_id = vps_video_parameter_set_id; + // vps_base_layer_internal_flag u(1) + vps->vps_base_layer_internal_flag = bs.read_bit(); + // vps_base_layer_available_flag u(1) + vps->vps_base_layer_available_flag = bs.read_bit(); + // vps_max_layers_minus1 u(6) + vps->vps_max_layers_minus1 = bs.read_bits(6); + // vps_max_sub_layers_minus1 u(3) + vps->vps_max_sub_layers_minus1 = bs.read_bits(3); + // vps_temporal_id_nesting_flag u(1) + vps->vps_temporal_id_nesting_flag = bs.read_bit(); + // vps_reserved_0xffff_16bits u(16) + vps->vps_reserved_0xffff_16bits = bs.read_bits(16); + + // profile_tier_level(1, vps_max_sub_layers_minus1) + if ((err = hevc_demux_rbsp_ptl(&bs, &vps->ptl, 1, vps->vps_max_sub_layers_minus1)) != srs_success) { + return srs_error_wrap(err, "vps rbsp ptl vps_max_sub_layers_minus1=%d", vps->vps_max_sub_layers_minus1); + } + + dec_conf_rec->general_profile_idc = vps->ptl.general_profile_idc; + dec_conf_rec->general_level_idc = vps->ptl.general_level_idc; + dec_conf_rec->general_tier_flag = vps->ptl.general_tier_flag; + + if (!bs.require_bits(1)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "sublayer flag requires 1 only %d bits", bs.left_bits()); + } + + // vps_sub_layer_ordering_info_present_flag u(1) + vps->vps_sub_layer_ordering_info_present_flag = bs.read_bit(); + + for (int i = (vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers_minus1); + i <= vps->vps_max_sub_layers_minus1; i++) { + // vps_max_dec_pic_buffering_minus1[i] ue(v) + if ((err = bs.read_bits_ue(vps->vps_max_dec_pic_buffering_minus1[i])) != srs_success) { + return srs_error_wrap(err, "max_dec_pic_buffering_minus1"); + } + // vps_max_num_reorder_pics[i] ue(v) + if ((err = bs.read_bits_ue(vps->vps_max_num_reorder_pics[i])) != srs_success) { + return srs_error_wrap(err, "max_num_reorder_pics"); + } + // vps_max_latency_increase_plus1[i] ue(v) + if ((err = bs.read_bits_ue(vps->vps_max_latency_increase_plus1[i])) != srs_success) { + return srs_error_wrap(err, "max_latency_increase_plus1"); + } + } + + if (!bs.require_bits(6)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "vps maxlayer requires 10 only %d bits", bs.left_bits()); + } + + // vps_max_layer_id u(6) + vps->vps_max_layer_id = bs.read_bits(6); + + // vps_num_layer_sets_minus1 ue(v) + if ((err = bs.read_bits_ue(vps->vps_num_layer_sets_minus1)) != srs_success) { + return srs_error_wrap(err, "num_layer_sets_minus1"); + } + + // TODO: FIXME: Implements it, you might parse remain bits for video_parameter_set_rbsp. + // @see 7.3.2.1 Video parameter set RBSP + // @doc ITU-T-H.265-2021.pdf, page 54. + + return err; +} + +srs_error_t SrsFormat::hevc_demux_sps(SrsBuffer *stream) +{ + // for NALU, ITU-T H.265 7.3.2.2 Sequence parameter set RBSP syntax + // @see 7.3.2.2.1 General sequence parameter set RBSP syntax + // @doc ITU-T-H.265-2021.pdf, page 55. + + if (!stream->require(1)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "decode hevc sps requires 1 only %d bytes", stream->left()); + } + int8_t nutv = stream->read_1bytes(); + + // forbidden_zero_bit shall be equal to 0. + int8_t forbidden_zero_bit = (nutv >> 7) & 0x01; + if (forbidden_zero_bit) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc forbidden_zero_bit=%d shall be equal to 0", forbidden_zero_bit); + } + + // nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1. + // @see 7.4.2.2 NAL unit header semantics + // @doc ITU-T-H.265-2021.pdf, page 86. + SrsHevcNaluType nal_unit_type = (SrsHevcNaluType)((nutv >> 1) & 0x3f); + if (nal_unit_type != SrsHevcNaluType_SPS) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc sps nal_unit_type=%d shall be equal to 33", nal_unit_type); + } + + // nuh_layer_id + nuh_temporal_id_plus1 + stream->skip(1); + + // decode the rbsp from sps. + // rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes. + std::vector rbsp(stream->size()); + + int nb_rbsp = srs_rbsp_remove_emulation_bytes(stream, rbsp); + + return hevc_demux_sps_rbsp((char *)&rbsp[0], nb_rbsp); +} + +srs_error_t SrsFormat::hevc_demux_sps_rbsp(char *rbsp, int nb_rbsp) +{ + srs_error_t err = srs_success; + + // we donot parse the detail of sps. + // @see https://github.com/ossrs/srs/issues/474 + if (!avc_parse_sps) { + return err; + } + + // reparse the rbsp. + SrsBuffer stream(rbsp, nb_rbsp); + + // H265 SPS Nal Unit (seq_parameter_set_rbsp()) parser. + // Section 7.3.2.2 ("Sequence parameter set RBSP syntax") of the H.265 + // ITU-T-H.265-2021.pdf, page 55. + if (!stream.require(2)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "sps requires 2 only %d bytes", stream.left()); + } + uint8_t nutv = stream.read_1bytes(); + + // sps_video_parameter_set_id u(4) + int sps_video_parameter_set_id = (nutv >> 4) & 0x0f; + // sps_max_sub_layers_minus1 u(3) + int sps_max_sub_layers_minus1 = (nutv >> 1) & 0x07; + // sps_temporal_id_nesting_flag u(1) + int sps_temporal_id_nesting_flag = nutv & 0x01; + + SrsBitBuffer bs(&stream); + + // profile tier level... + SrsHevcProfileTierLevel profile_tier_level; + // profile_tier_level(1, sps_max_sub_layers_minus1) + if ((err = hevc_demux_rbsp_ptl(&bs, &profile_tier_level, 1, sps_max_sub_layers_minus1)) != srs_success) { + return srs_error_wrap(err, "sps rbsp ptl sps_max_sub_layers_minus1=%d", sps_max_sub_layers_minus1); + } + + vcodec->hevc_profile = (SrsHevcProfile)profile_tier_level.general_profile_idc; + vcodec->hevc_level = (SrsHevcLevel)profile_tier_level.general_level_idc; + + // sps_seq_parameter_set_id ue(v) + uint32_t sps_seq_parameter_set_id = 0; + if ((err = bs.read_bits_ue(sps_seq_parameter_set_id)) != srs_success) { + return srs_error_wrap(err, "sps_seq_parameter_set_id"); + } + if (sps_seq_parameter_set_id < 0 || sps_seq_parameter_set_id >= SrsHevcMax_SPS_COUNT) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "sps id out of range: %d", sps_seq_parameter_set_id); + } + + // for sps_table + SrsHevcDecoderConfigurationRecord *dec_conf_rec = &(vcodec->hevc_dec_conf_record_); + SrsHevcRbspSps *sps = &(dec_conf_rec->sps_table[sps_seq_parameter_set_id]); + + sps->sps_video_parameter_set_id = sps_video_parameter_set_id; + sps->sps_max_sub_layers_minus1 = sps_max_sub_layers_minus1; + sps->sps_temporal_id_nesting_flag = sps_temporal_id_nesting_flag; + sps->sps_seq_parameter_set_id = sps_seq_parameter_set_id; + sps->ptl = profile_tier_level; + + // chroma_format_idc ue(v) + if ((err = bs.read_bits_ue(sps->chroma_format_idc)) != srs_success) { + return srs_error_wrap(err, "chroma_format_idc"); + } + + if (sps->chroma_format_idc == 3) { + if (!bs.require_bits(1)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "separate_colour_plane_flag requires 1 only %d bits", bs.left_bits()); + } + + // separate_colour_plane_flag u(1) + sps->separate_colour_plane_flag = bs.read_bit(); + } + + // pic_width_in_luma_samples ue(v) + if ((err = bs.read_bits_ue(sps->pic_width_in_luma_samples)) != srs_success) { + return srs_error_wrap(err, "pic_width_in_luma_samples"); + } + + // pic_height_in_luma_samples ue(v) + if ((err = bs.read_bits_ue(sps->pic_height_in_luma_samples)) != srs_success) { + return srs_error_wrap(err, "pic_height_in_luma_samples"); + } + + vcodec->width = sps->pic_width_in_luma_samples; + vcodec->height = sps->pic_height_in_luma_samples; + + if (!bs.require_bits(1)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "conformance_window_flag requires 1 only %d bits", bs.left_bits()); + } + + // conformance_window_flag u(1) + sps->conformance_window_flag = bs.read_bit(); + if (sps->conformance_window_flag) { + // conf_win_left_offset ue(v) + if ((err = bs.read_bits_ue(sps->conf_win_left_offset)) != srs_success) { + return srs_error_wrap(err, "conf_win_left_offset"); + } + // conf_win_right_offset ue(v) + if ((err = bs.read_bits_ue(sps->conf_win_right_offset)) != srs_success) { + return srs_error_wrap(err, "conf_win_right_offset"); + } + // conf_win_top_offset ue(v) + if ((err = bs.read_bits_ue(sps->conf_win_top_offset)) != srs_success) { + return srs_error_wrap(err, "conf_win_top_offset"); + } + // conf_win_bottom_offset ue(v) + if ((err = bs.read_bits_ue(sps->conf_win_bottom_offset)) != srs_success) { + return srs_error_wrap(err, "conf_win_bottom_offset"); + } + + // Table 6-1, 7.4.3.2.1 + // ITU-T-H.265-2021.pdf, page 42. + // Recalculate width and height + // Note: 1 is added to the manual, but it is not actually used + // https://gitlab.com/mbunkus/mkvtoolnix/-/issues/1152 + int sub_width_c = ((1 == sps->chroma_format_idc) || (2 == sps->chroma_format_idc)) && (0 == sps->separate_colour_plane_flag) ? 2 : 1; + int sub_height_c = (1 == sps->chroma_format_idc) && (0 == sps->separate_colour_plane_flag) ? 2 : 1; + vcodec->width -= (sub_width_c * sps->conf_win_right_offset + sub_width_c * sps->conf_win_left_offset); + vcodec->height -= (sub_height_c * sps->conf_win_bottom_offset + sub_height_c * sps->conf_win_top_offset); + } + + // bit_depth_luma_minus8 ue(v) + if ((err = bs.read_bits_ue(sps->bit_depth_luma_minus8)) != srs_success) { + return srs_error_wrap(err, "bit_depth_luma_minus8"); + } + // bit_depth_chroma_minus8 ue(v) + if ((err = bs.read_bits_ue(sps->bit_depth_chroma_minus8)) != srs_success) { + return srs_error_wrap(err, "bit_depth_chroma_minus8"); + } + + // bit depth + dec_conf_rec->bit_depth_luma_minus8 = sps->bit_depth_luma_minus8 + 8; + dec_conf_rec->bit_depth_chroma_minus8 = sps->bit_depth_chroma_minus8 + 8; + + // log2_max_pic_order_cnt_lsb_minus4 ue(v) + if ((err = bs.read_bits_ue(sps->log2_max_pic_order_cnt_lsb_minus4)) != srs_success) { + return srs_error_wrap(err, "log2_max_pic_order_cnt_lsb_minus4"); + } + + // TODO: FIXME: Implements it, you might parse remain bits for seq_parameter_set_rbsp. + // 7.3.2.2 Sequence parameter set RBSP syntax + // ITU-T-H.265-2021.pdf, page 55 ~ page 57. + + // 7.3.2.11 RBSP trailing bits syntax + // ITU-T-H.265-2021.pdf, page 61. + // rbsp_trailing_bits() + + return err; +} + +srs_error_t SrsFormat::hevc_demux_pps(SrsBuffer *stream) +{ + // for NALU, ITU-T H.265 7.3.2.3 Picture parameter set RBSP syntax + // @see 7.3.2.3 Picture parameter set RBSP syntax + // @doc ITU-T-H.265-2021.pdf, page 57. + if (!stream->require(1)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "decode hevc pps requires 1 only %d bytes", stream->left()); + } + int8_t nutv = stream->read_1bytes(); + + // forbidden_zero_bit shall be equal to 0. + int8_t forbidden_zero_bit = (nutv >> 7) & 0x01; + if (forbidden_zero_bit) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc forbidden_zero_bit=%d shall be equal to 0", forbidden_zero_bit); + } + + // nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1. + // @see 7.4.2.2 NAL unit header semantics + // @doc ITU-T-H.265-2021.pdf, page 86. + SrsHevcNaluType nal_unit_type = (SrsHevcNaluType)((nutv >> 1) & 0x3f); + if (nal_unit_type != SrsHevcNaluType_PPS) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc pps nal_unit_type=%d shall be equal to 33", nal_unit_type); + } + + // nuh_layer_id + nuh_temporal_id_plus1 + stream->skip(1); + + // decode the rbsp from pps. + // rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes. + std::vector rbsp(stream->size()); + + int nb_rbsp = srs_rbsp_remove_emulation_bytes(stream, rbsp); + + return hevc_demux_pps_rbsp((char *)&rbsp[0], nb_rbsp); +} + +srs_error_t SrsFormat::hevc_demux_pps_rbsp(char *rbsp, int nb_rbsp) +{ + srs_error_t err = srs_success; + + // reparse the rbsp. + SrsBuffer stream(rbsp, nb_rbsp); + + // H265 PPS NAL Unit (pic_parameter_set_rbsp()) parser. + // Section 7.3.2.3 ("Picture parameter set RBSP syntax") of the H.265 + // ITU-T-H.265-2021.pdf, page 57. + SrsBitBuffer bs(&stream); + + // pps_pic_parameter_set_id ue(v) + uint32_t pps_pic_parameter_set_id = 0; + if ((err = bs.read_bits_ue(pps_pic_parameter_set_id)) != srs_success) { + return srs_error_wrap(err, "pps_pic_parameter_set_id"); + } + if (pps_pic_parameter_set_id < 0 || pps_pic_parameter_set_id >= SrsHevcMax_PPS_COUNT) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps id out of range: %d", pps_pic_parameter_set_id); + } + + // select table + SrsHevcDecoderConfigurationRecord *dec_conf_rec = &(vcodec->hevc_dec_conf_record_); + SrsHevcRbspPps *pps = &(dec_conf_rec->pps_table[pps_pic_parameter_set_id]); + pps->pps_pic_parameter_set_id = pps_pic_parameter_set_id; + + // pps_seq_parameter_set_id ue(v) + uint32_t pps_seq_parameter_set_id = 0; + if ((err = bs.read_bits_ue(pps_seq_parameter_set_id)) != srs_success) { + return srs_error_wrap(err, "pps_seq_parameter_set_id"); + } + pps->pps_seq_parameter_set_id = pps_seq_parameter_set_id; + + if (!bs.require_bits(7)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps slice requires 7 only %d bits", bs.left_bits()); + } + + // dependent_slice_segments_enabled_flag u(1) + pps->dependent_slice_segments_enabled_flag = bs.read_bit(); + // output_flag_present_flag u(1) + pps->output_flag_present_flag = bs.read_bit(); + // num_extra_slice_header_bits u(3) + pps->num_extra_slice_header_bits = bs.read_bits(3); + // sign_data_hiding_enabled_flag u(1) + pps->sign_data_hiding_enabled_flag = bs.read_bit(); + // cabac_init_present_flag u(1) + pps->cabac_init_present_flag = bs.read_bit(); + + // num_ref_idx_l0_default_active_minus1 ue(v) + if ((err = bs.read_bits_ue(pps->num_ref_idx_l0_default_active_minus1)) != srs_success) { + return srs_error_wrap(err, "num_ref_idx_l0_default_active_minus1"); + } + // num_ref_idx_l1_default_active_minus1 ue(v) + if ((err = bs.read_bits_ue(pps->num_ref_idx_l1_default_active_minus1)) != srs_success) { + return srs_error_wrap(err, "num_ref_idx_l1_default_active_minus1"); + } + // init_qp_minus26 se(v) + if ((err = bs.read_bits_se(pps->init_qp_minus26)) != srs_success) { + return srs_error_wrap(err, "init_qp_minus26"); + } + + if (!bs.require_bits(3)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps requires 3 only %d bits", bs.left_bits()); + } + + // constrained_intra_pred_flag u(1) + pps->constrained_intra_pred_flag = bs.read_bit(); + // transform_skip_enabled_flag u(1) + pps->transform_skip_enabled_flag = bs.read_bit(); + // cu_qp_delta_enabled_flag u(1) + pps->cu_qp_delta_enabled_flag = bs.read_bit(); + if (pps->cu_qp_delta_enabled_flag) { + // diff_cu_qp_delta_depth ue(v) + if ((err = bs.read_bits_ue(pps->diff_cu_qp_delta_depth)) != srs_success) { + return srs_error_wrap(err, "diff_cu_qp_delta_depth"); + } + } + // pps_cb_qp_offset se(v) + if ((err = bs.read_bits_se(pps->pps_cb_qp_offset)) != srs_success) { + return srs_error_wrap(err, "pps_cb_qp_offset"); + } + // pps_cr_qp_offset se(v) + if ((err = bs.read_bits_se(pps->pps_cr_qp_offset)) != srs_success) { + return srs_error_wrap(err, "pps_cr_qp_offset"); + } + + if (!bs.require_bits(6)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps slice_chroma_qp requires 6 only %d bits", bs.left_bits()); + } + + // pps_slice_chroma_qp_offsets_present_flag u(1) + pps->pps_slice_chroma_qp_offsets_present_flag = bs.read_bit(); + // weighted_pred_flag u(1) + pps->weighted_pred_flag = bs.read_bit(); + // weighted_bipred_flag u(1) + pps->weighted_bipred_flag = bs.read_bit(); + // transquant_bypass_enabled_flag u(1) + pps->transquant_bypass_enabled_flag = bs.read_bit(); + // tiles_enabled_flag u(1) + pps->tiles_enabled_flag = bs.read_bit(); + // entropy_coding_sync_enabled_flag u(1) + pps->entropy_coding_sync_enabled_flag = bs.read_bit(); + + if (pps->tiles_enabled_flag) { + // num_tile_columns_minus1 ue(v) + if ((err = bs.read_bits_ue(pps->num_tile_columns_minus1)) != srs_success) { + return srs_error_wrap(err, "num_tile_columns_minus1"); + } + // num_tile_rows_minus1 ue(v) + if ((err = bs.read_bits_ue(pps->num_tile_rows_minus1)) != srs_success) { + return srs_error_wrap(err, "num_tile_rows_minus1"); + } + + if (!bs.require_bits(1)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "uniform_spacing_flag requires 1 only %d bits", bs.left_bits()); + } + + // uniform_spacing_flag u(1) + pps->uniform_spacing_flag = bs.read_bit(); + if (!pps->uniform_spacing_flag) { + pps->column_width_minus1.resize(pps->num_tile_columns_minus1); + pps->row_height_minus1.resize(pps->num_tile_rows_minus1); + + for (int i = 0; i < (int)pps->num_tile_columns_minus1; i++) { + // column_width_minus1[i] ue(v) + if ((err = bs.read_bits_ue(pps->column_width_minus1[i])) != srs_success) { + return srs_error_wrap(err, "column_width_minus1"); + } + } + + for (int i = 0; i < (int)pps->num_tile_rows_minus1; i++) { + // row_height_minus1[i] ue(v) + if ((err = bs.read_bits_ue(pps->row_height_minus1[i])) != srs_success) { + return srs_error_wrap(err, "row_height_minus1"); + } + } + } + + if (!bs.require_bits(1)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "loop_filter_across_tiles_enabled_flag requires 1 only %d bits", bs.left_bits()); + } + + // loop_filter_across_tiles_enabled_flag u(1) + pps->loop_filter_across_tiles_enabled_flag = bs.read_bit(); + } + + if (!bs.require_bits(2)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps loop deblocking filter requires 2 only %d bits", bs.left_bits()); + } + + // pps_loop_filter_across_slices_enabled_flag u(1) + pps->pps_loop_filter_across_slices_enabled_flag = bs.read_bit(); + // deblocking_filter_control_present_flag u(1) + pps->deblocking_filter_control_present_flag = bs.read_bit(); + if (pps->deblocking_filter_control_present_flag) { + if (!bs.require_bits(2)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps loop deblocking filter flag requires 2 only %d bits", bs.left_bits()); + } + + // deblocking_filter_override_enabled_flag u(1) + pps->deblocking_filter_override_enabled_flag = bs.read_bit(); + // pps_deblocking_filter_disabled_flag u(1) + pps->pps_deblocking_filter_disabled_flag = bs.read_bit(); + if (!pps->pps_deblocking_filter_disabled_flag) { + // pps_beta_offset_div2 se(v) + if ((err = bs.read_bits_se(pps->pps_beta_offset_div2)) != srs_success) { + return srs_error_wrap(err, "pps_beta_offset_div2"); + } + // pps_tc_offset_div2 se(v) + if ((err = bs.read_bits_se(pps->pps_tc_offset_div2)) != srs_success) { + return srs_error_wrap(err, "pps_tc_offset_div2"); + } + } + } + + if (!bs.require_bits(1)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps scaling_list_data requires 1 only %d bits", bs.left_bits()); + } + + // pps_scaling_list_data_present_flag u(1) + pps->pps_scaling_list_data_present_flag = bs.read_bit(); + if (pps->pps_scaling_list_data_present_flag) { + // 7.3.4 Scaling list data syntax + SrsHevcScalingListData *sld = &pps->scaling_list_data; + for (int sizeId = 0; sizeId < 4; sizeId++) { + for (int matrixId = 0; matrixId < 6; matrixId += (sizeId == 3) ? 3 : 1) { + // scaling_list_pred_mode_flag u(1) + sld->scaling_list_pred_mode_flag[sizeId][matrixId] = bs.read_bit(); + if (!sld->scaling_list_pred_mode_flag[sizeId][matrixId]) { + // scaling_list_pred_matrix_id_delta ue(v) + if ((err = bs.read_bits_ue(sld->scaling_list_pred_matrix_id_delta[sizeId][matrixId])) != srs_success) { + return srs_error_wrap(err, "scaling_list_pred_matrix_id_delta"); + } + } else { + int nextCoef = 8; + int coefNum = srs_min(64, (1 << (4 + (sizeId << 1)))); + sld->coefNum = coefNum; // tmp store + if (sizeId > 1) { + // scaling_list_dc_coef_minus8 se(v) + if ((err = bs.read_bits_se(sld->scaling_list_dc_coef_minus8[sizeId - 2][matrixId])) != srs_success) { + return srs_error_wrap(err, "scaling_list_dc_coef_minus8"); + } + nextCoef = sld->scaling_list_dc_coef_minus8[sizeId - 2][matrixId] + 8; + } + + for (int i = 0; i < sld->coefNum; i++) { + // scaling_list_delta_coef se(v) + int scaling_list_delta_coef = 0; + if ((err = bs.read_bits_se(scaling_list_delta_coef)) != srs_success) { + return srs_error_wrap(err, "scaling_list_delta_coef"); + } + nextCoef = (nextCoef + scaling_list_delta_coef + 256) % 256; + sld->ScalingList[sizeId][matrixId][i] = nextCoef; + } + } + } + } + } + + if (!bs.require_bits(1)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "lists_modification_present_flag requires 1 only %d bits", bs.left_bits()); + } + // lists_modification_present_flag u(1) + pps->lists_modification_present_flag = bs.read_bit(); + + // log2_parallel_merge_level_minus2 ue(v) + if ((err = bs.read_bits_ue(pps->log2_parallel_merge_level_minus2)) != srs_success) { + return srs_error_wrap(err, "log2_parallel_merge_level_minus2"); + } + + if (!bs.require_bits(2)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "extension_present_flag requires 2 only %d bits", bs.left_bits()); + } + + // slice_segment_header_extension_present_flag u(1) + pps->slice_segment_header_extension_present_flag = bs.read_bit(); + // pps_extension_present_flag u(1) + pps->pps_extension_present_flag = bs.read_bit(); + if (pps->pps_extension_present_flag) { + if (!bs.require_bits(8)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "pps_range_extension_flag requires 8 only %d bits", bs.left_bits()); + } + + // pps_range_extension_flag u(1) + pps->pps_range_extension_flag = bs.read_bit(); + // pps_multilayer_extension_flag u(1) + pps->pps_multilayer_extension_flag = bs.read_bit(); + // pps_3d_extension_flag u(1) + pps->pps_3d_extension_flag = bs.read_bit(); + // pps_scc_extension_flag u(1) + pps->pps_scc_extension_flag = bs.read_bit(); + // pps_extension_4bits u(4) + pps->pps_extension_4bits = bs.read_bits(4); + } + + // TODO: FIXME: Implements it, you might parse remain bits for pic_parameter_set_rbsp. + // @see 7.3.2.3 Picture parameter set RBSP syntax + // @doc ITU-T-H.265-2021.pdf, page 59. + + // TODO: FIXME: rbsp_trailing_bits + + return err; +} + +srs_error_t SrsFormat::hevc_demux_rbsp_ptl(SrsBitBuffer *bs, SrsHevcProfileTierLevel *ptl, int profile_present_flag, int max_sub_layers_minus1) +{ + srs_error_t err = srs_success; + + // profile_tier_level() parser. + // Section 7.3.3 ("Profile, tier and level syntax") of the H.265 + // ITU-T-H.265-2021.pdf, page 62. + if (profile_present_flag) { + if (!bs->require_bits(88)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl profile requires 88 only %d bits", bs->left_bits()); + } + + // profile_space u(2) + ptl->general_profile_space = bs->read_bits(2); + // tier_flag u(1) + ptl->general_tier_flag = bs->read_bit(); + // profile_idc u(5) + ptl->general_profile_idc = bs->read_bits(5); + for (int i = 0; i < 32; i++) { + // profile_compatibility_flag[j] u(1) + ptl->general_profile_compatibility_flag[i] = bs->read_bit(); + } + // progressive_source_flag u(1) + ptl->general_progressive_source_flag = bs->read_bit(); + // interlaced_source_flag u(1) + ptl->general_interlaced_source_flag = bs->read_bit(); + // non_packed_constraint_flag u(1) + ptl->general_non_packed_constraint_flag = bs->read_bit(); + // frame_only_constraint_flag u(1) + ptl->general_frame_only_constraint_flag = bs->read_bit(); + if (ptl->general_profile_idc == 4 || ptl->general_profile_compatibility_flag[4] || + ptl->general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] || + ptl->general_profile_idc == 6 || ptl->general_profile_compatibility_flag[6] || + ptl->general_profile_idc == 7 || ptl->general_profile_compatibility_flag[7] || + ptl->general_profile_idc == 8 || ptl->general_profile_compatibility_flag[8] || + ptl->general_profile_idc == 9 || ptl->general_profile_compatibility_flag[9] || + ptl->general_profile_idc == 10 || ptl->general_profile_compatibility_flag[10] || + ptl->general_profile_idc == 11 || ptl->general_profile_compatibility_flag[11]) { + // The number of bits in this syntax structure is not affected by this condition + // max_12bit_constraint_flag u(1) + ptl->general_max_12bit_constraint_flag = bs->read_bit(); + // max_10bit_constraint_flag u(1) + ptl->general_max_10bit_constraint_flag = bs->read_bit(); + // max_8bit_constraint_flag u(1) + ptl->general_max_8bit_constraint_flag = bs->read_bit(); + // max_422chroma_constraint_flag u(1) + ptl->general_max_422chroma_constraint_flag = bs->read_bit(); + // max_420chroma_constraint_flag u(1) + ptl->general_max_420chroma_constraint_flag = bs->read_bit(); + // max_monochrome_constraint_flag u(1) + ptl->general_max_monochrome_constraint_flag = bs->read_bit(); + // intra_constraint_flag u(1) + ptl->general_intra_constraint_flag = bs->read_bit(); + // one_picture_only_constraint_flag u(1) + ptl->general_one_picture_only_constraint_flag = bs->read_bit(); + // lower_bit_rate_constraint_flag u(1) + ptl->general_lower_bit_rate_constraint_flag = bs->read_bit(); + + if (ptl->general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] == 1 || + ptl->general_profile_idc == 9 || ptl->general_profile_compatibility_flag[9] == 1 || + ptl->general_profile_idc == 10 || ptl->general_profile_compatibility_flag[10] == 1 || + ptl->general_profile_idc == 11 || ptl->general_profile_compatibility_flag[11] == 1) { + // max_14bit_constraint_flag u(1) + ptl->general_max_14bit_constraint_flag = bs->read_bit(); + // reserved_zero_33bits u(33) + uint32_t bits_tmp_hi = bs->read_bit(); + uint32_t bits_tmp = bs->read_bits(32); + ptl->general_reserved_zero_33bits = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; + } else { + // reserved_zero_34bits u(34) + uint32_t bits_tmp_hi = bs->read_bits(2); + uint32_t bits_tmp = bs->read_bits(32); + ptl->general_reserved_zero_34bits = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; + } + } else if (ptl->general_profile_idc == 2 || ptl->general_profile_compatibility_flag[2]) { + // general_reserved_zero_7bits u(7) + ptl->general_reserved_zero_7bits = bs->read_bits(7); + // general_one_picture_only_constraint_flag u(1) + ptl->general_one_picture_only_constraint_flag = bs->read_bit(); + // general_reserved_zero_35bits u(35) + uint32_t bits_tmp_hi = bs->read_bits(3); + uint32_t bits_tmp = bs->read_bits(32); + ptl->general_reserved_zero_35bits = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; + } else { + // reserved_zero_43bits u(43) + uint32_t bits_tmp_hi = bs->read_bits(11); + uint32_t bits_tmp = bs->read_bits(32); + ptl->general_reserved_zero_43bits = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; + } + + // The number of bits in this syntax structure is not affected by this condition + if (ptl->general_profile_idc == 1 || ptl->general_profile_compatibility_flag[1] || + ptl->general_profile_idc == 2 || ptl->general_profile_compatibility_flag[2] || + ptl->general_profile_idc == 3 || ptl->general_profile_compatibility_flag[3] || + ptl->general_profile_idc == 4 || ptl->general_profile_compatibility_flag[4] || + ptl->general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] || + ptl->general_profile_idc == 9 || ptl->general_profile_compatibility_flag[9] || + ptl->general_profile_idc == 11 || ptl->general_profile_compatibility_flag[11]) { + // inbld_flag u(1) + ptl->general_inbld_flag = bs->read_bit(); + } else { + // reserved_zero_bit u(1) + ptl->general_reserved_zero_bit = bs->read_bit(); + } + } + + if (!bs->require_bits(8)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl level requires 8 only %d bits", bs->left_bits()); + } + + // general_level_idc u(8) + ptl->general_level_idc = bs->read_8bits(); + + ptl->sub_layer_profile_present_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_level_present_flag.resize(max_sub_layers_minus1); + for (int i = 0; i < max_sub_layers_minus1; i++) { + if (!bs->require_bits(2)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl present_flag requires 2 only %d bits", bs->left_bits()); + } + // sub_layer_profile_present_flag[i] u(1) + ptl->sub_layer_profile_present_flag[i] = bs->read_bit(); + // sub_layer_level_present_flag[i] u(1) + ptl->sub_layer_level_present_flag[i] = bs->read_bit(); + } + + for (int i = max_sub_layers_minus1; max_sub_layers_minus1 > 0 && i < 8; i++) { + if (!bs->require_bits(2)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl reserved_zero requires 2 only %d bits", bs->left_bits()); + } + // reserved_zero_2bits[i] u(2) + ptl->reserved_zero_2bits[i] = bs->read_bits(2); + } + + ptl->sub_layer_profile_space.resize(max_sub_layers_minus1); + ptl->sub_layer_tier_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_profile_idc.resize(max_sub_layers_minus1); + ptl->sub_layer_profile_compatibility_flag.resize(max_sub_layers_minus1); + for (int i = 0; i < max_sub_layers_minus1; i++) { + ptl->sub_layer_profile_compatibility_flag[i].resize(32); + } + ptl->sub_layer_progressive_source_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_interlaced_source_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_non_packed_constraint_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_frame_only_constraint_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_max_12bit_constraint_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_max_10bit_constraint_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_max_8bit_constraint_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_max_422chroma_constraint_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_max_420chroma_constraint_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_max_monochrome_constraint_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_intra_constraint_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_one_picture_only_constraint_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_lower_bit_rate_constraint_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_reserved_zero_34bits.resize(max_sub_layers_minus1); + ptl->sub_layer_reserved_zero_43bits.resize(max_sub_layers_minus1); + ptl->sub_layer_inbld_flag.resize(max_sub_layers_minus1); + ptl->sub_layer_reserved_zero_bit.resize(max_sub_layers_minus1); + ptl->sub_layer_level_idc.resize(max_sub_layers_minus1); + for (int i = 0; i < max_sub_layers_minus1; i++) { + if (ptl->sub_layer_profile_present_flag[i]) { + if (!bs->require_bits(88)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl sub_layer_profile requires 88 only %d bits", bs->left_bits()); + } + // profile_space u(2) + ptl->sub_layer_profile_space[i] = bs->read_bits(2); + // tier_flag u(1) + ptl->sub_layer_tier_flag[i] = bs->read_bit(); + // profile_idc u(5) + ptl->sub_layer_profile_idc[i] = bs->read_bits(5); + for (int j = 0; j < 32; j++) { + // profile_compatibility_flag[j] u(1) + ptl->sub_layer_profile_compatibility_flag[i][j] = bs->read_bit(); + } + // progressive_source_flag u(1) + ptl->sub_layer_progressive_source_flag[i] = bs->read_bit(); + // interlaced_source_flag u(1) + ptl->sub_layer_interlaced_source_flag[i] = bs->read_bit(); + // non_packed_constraint_flag u(1) + ptl->sub_layer_non_packed_constraint_flag[i] = bs->read_bit(); + // frame_only_constraint_flag u(1) + ptl->sub_layer_frame_only_constraint_flag[i] = bs->read_bit(); + if (ptl->sub_layer_profile_idc[i] == 4 || ptl->sub_layer_profile_compatibility_flag[i][4] || + ptl->sub_layer_profile_idc[i] == 5 || ptl->sub_layer_profile_compatibility_flag[i][5] || + ptl->sub_layer_profile_idc[i] == 6 || ptl->sub_layer_profile_compatibility_flag[i][6] || + ptl->sub_layer_profile_idc[i] == 7 || ptl->sub_layer_profile_compatibility_flag[i][7] || + ptl->sub_layer_profile_idc[i] == 8 || ptl->sub_layer_profile_compatibility_flag[i][8] || + ptl->sub_layer_profile_idc[i] == 9 || ptl->sub_layer_profile_compatibility_flag[i][9] || + ptl->sub_layer_profile_idc[i] == 10 || ptl->sub_layer_profile_compatibility_flag[i][10] || + ptl->sub_layer_profile_idc[i] == 11 || ptl->sub_layer_profile_compatibility_flag[i][11]) { + // The number of bits in this syntax structure is not affected by this condition. + // max_12bit_constraint_flag u(1) + ptl->sub_layer_max_12bit_constraint_flag[i] = bs->read_bit(); + // max_10bit_constraint_flag u(1) + ptl->sub_layer_max_10bit_constraint_flag[i] = bs->read_bit(); + // max_8bit_constraint_flag u(1) + ptl->sub_layer_max_8bit_constraint_flag[i] = bs->read_bit(); + // max_422chroma_constraint_flag u(1) + ptl->sub_layer_max_422chroma_constraint_flag[i] = bs->read_bit(); + // max_420chroma_constraint_flag u(1) + ptl->sub_layer_max_420chroma_constraint_flag[i] = bs->read_bit(); + // max_monochrome_constraint_flag u(1) + ptl->sub_layer_max_monochrome_constraint_flag[i] = bs->read_bit(); + // intra_constraint_flag u(1) + ptl->sub_layer_intra_constraint_flag[i] = bs->read_bit(); + // one_picture_only_constraint_flag u(1) + ptl->sub_layer_one_picture_only_constraint_flag[i] = bs->read_bit(); + // lower_bit_rate_constraint_flag u(1) + ptl->sub_layer_lower_bit_rate_constraint_flag[i] = bs->read_bit(); + + if (ptl->sub_layer_profile_idc[i] == 5 || + ptl->sub_layer_profile_compatibility_flag[i][5] == 1 || + ptl->sub_layer_profile_idc[i] == 9 || + ptl->sub_layer_profile_compatibility_flag[i][9] == 1 || + ptl->sub_layer_profile_idc[i] == 10 || + ptl->sub_layer_profile_compatibility_flag[i][10] == 1 || + ptl->sub_layer_profile_idc[i] == 11 || + ptl->sub_layer_profile_compatibility_flag[i][11] == 1) { + // max_14bit_constraint_flag u(1) + ptl->general_max_14bit_constraint_flag = bs->read_bit(); + // reserved_zero_33bits u(33) + uint32_t bits_tmp_hi = bs->read_bit(); + uint32_t bits_tmp = bs->read_bits(32); + ptl->sub_layer_reserved_zero_33bits[i] = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; + } else { + // reserved_zero_34bits u(34) + uint32_t bits_tmp_hi = bs->read_bits(2); + uint32_t bits_tmp = bs->read_bits(32); + ptl->sub_layer_reserved_zero_34bits[i] = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; + } + } else if (ptl->sub_layer_profile_idc[i] == 2 || ptl->sub_layer_profile_compatibility_flag[i][2]) { + // sub_layer_reserved_zero_7bits u(7) + ptl->sub_layer_reserved_zero_7bits[i] = bs->read_bits(7); + // sub_layer_one_picture_only_constraint_flag u(1) + ptl->sub_layer_one_picture_only_constraint_flag[i] = bs->read_bit(); + // sub_layer_reserved_zero_35bits u(35) + uint32_t bits_tmp_hi = bs->read_bits(3); + uint32_t bits_tmp = bs->read_bits(32); + ptl->sub_layer_reserved_zero_35bits[i] = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; + } else { + // reserved_zero_43bits u(43) + uint32_t bits_tmp_hi = bs->read_bits(11); + uint32_t bits_tmp = bs->read_bits(32); + ptl->sub_layer_reserved_zero_43bits[i] = ((uint64_t)bits_tmp_hi << 32) | bits_tmp; + } + + // The number of bits in this syntax structure is not affected by this condition + if (ptl->sub_layer_profile_idc[i] == 1 || ptl->sub_layer_profile_compatibility_flag[i][1] || + ptl->sub_layer_profile_idc[i] == 2 || ptl->sub_layer_profile_compatibility_flag[i][2] || + ptl->sub_layer_profile_idc[i] == 3 || ptl->sub_layer_profile_compatibility_flag[i][3] || + ptl->sub_layer_profile_idc[i] == 4 || ptl->sub_layer_profile_compatibility_flag[i][4] || + ptl->sub_layer_profile_idc[i] == 5 || ptl->sub_layer_profile_compatibility_flag[i][5] || + ptl->sub_layer_profile_idc[i] == 9 || ptl->sub_layer_profile_compatibility_flag[i][9] || + ptl->sub_layer_profile_idc[i] == 11 || ptl->sub_layer_profile_compatibility_flag[i][11]) { + // inbld_flag u(1) + ptl->sub_layer_inbld_flag[i] = bs->read_bit(); + } else { + // reserved_zero_bit u(1) + ptl->sub_layer_reserved_zero_bit[i] = bs->read_bit(); + } + } + + if (ptl->sub_layer_level_present_flag[i]) { + if (!bs->require_bits(8)) { + return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl sub_layer_level requires 8 only %d bits", bs->left_bits()); + } + // sub_layer_level_idc u(8) + ptl->sub_layer_level_idc[i] = bs->read_bits(8); + } + } + + return err; +} + +srs_error_t SrsFormat::avc_demux_sps_pps(SrsBuffer *stream) +{ + // AVCDecoderConfigurationRecord + // 5.2.4.1.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16 + int avc_extra_size = stream->size() - stream->pos(); + if (avc_extra_size > 0) { + char *copy_stream_from = stream->data() + stream->pos(); + vcodec->avc_extra_data = std::vector(copy_stream_from, copy_stream_from + avc_extra_size); + } + + if (!stream->require(6)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "avc decode sequence header"); + } + // int8_t configuration_version = stream->read_1bytes(); + stream->read_1bytes(); + // int8_t AVCProfileIndication = stream->read_1bytes(); + vcodec->avc_profile = (SrsAvcProfile)stream->read_1bytes(); + // int8_t profile_compatibility = stream->read_1bytes(); + stream->read_1bytes(); + // int8_t AVCLevelIndication = stream->read_1bytes(); + vcodec->avc_level = (SrsAvcLevel)stream->read_1bytes(); + + // parse the NALU size. + int8_t lengthSizeMinusOne = stream->read_1bytes(); + lengthSizeMinusOne &= 0x03; + vcodec->NAL_unit_length = lengthSizeMinusOne; + + // 5.3.4.2.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16 + // 5.2.4.1 AVC decoder configuration record + // 5.2.4.1.2 Semantics + // The value of this field shall be one of 0, 1, or 3 corresponding to a + // length encoded with 1, 2, or 4 bytes, respectively. + if (vcodec->NAL_unit_length == 2) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps lengthSizeMinusOne should never be 2"); + } + + // 1 sps, 7.3.2.1 Sequence parameter set RBSP syntax + // ISO_IEC_14496-10-AVC-2003.pdf, page 45. + if (!stream->require(1)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS"); + } + int8_t numOfSequenceParameterSets = stream->read_1bytes(); + numOfSequenceParameterSets &= 0x1f; + if (numOfSequenceParameterSets < 1) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS"); + } + // Support for multiple SPS, then pick the first non-empty one. + for (int i = 0; i < numOfSequenceParameterSets; ++i) { + if (!stream->require(2)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS size"); + } + uint16_t sequenceParameterSetLength = stream->read_2bytes(); + if (!stream->require(sequenceParameterSetLength)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS data"); + } + if (sequenceParameterSetLength > 0) { + vcodec->sequenceParameterSetNALUnit.resize(sequenceParameterSetLength); + stream->read_bytes(&vcodec->sequenceParameterSetNALUnit[0], sequenceParameterSetLength); + } + } + + // 1 pps + if (!stream->require(1)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode PPS"); + } + int8_t numOfPictureParameterSets = stream->read_1bytes(); + numOfPictureParameterSets &= 0x1f; + if (numOfPictureParameterSets < 1) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS"); + } + // Support for multiple PPS, then pick the first non-empty one. + for (int i = 0; i < numOfPictureParameterSets; ++i) { + if (!stream->require(2)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode PPS size"); + } + uint16_t pictureParameterSetLength = stream->read_2bytes(); + if (!stream->require(pictureParameterSetLength)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode PPS data"); + } + if (pictureParameterSetLength > 0) { + vcodec->pictureParameterSetNALUnit.resize(pictureParameterSetLength); + stream->read_bytes(&vcodec->pictureParameterSetNALUnit[0], pictureParameterSetLength); + } + } + return avc_demux_sps(); +} + +srs_error_t SrsFormat::avc_demux_sps() +{ + srs_error_t err = srs_success; + + if (vcodec->sequenceParameterSetNALUnit.empty()) { + return err; + } + + char *sps = &vcodec->sequenceParameterSetNALUnit[0]; + int nbsps = (int)vcodec->sequenceParameterSetNALUnit.size(); + + SrsBuffer stream(sps, nbsps); + + // for NALU, 7.3.1 NAL unit syntax + // ISO_IEC_14496-10-AVC-2012.pdf, page 61. + if (!stream.require(1)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS"); + } + int8_t nutv = stream.read_1bytes(); + + // forbidden_zero_bit shall be equal to 0. + int8_t forbidden_zero_bit = (nutv >> 7) & 0x01; + if (forbidden_zero_bit) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "forbidden_zero_bit shall be equal to 0"); + } + + // nal_ref_idc not equal to 0 specifies that the content of the NAL unit contains a sequence parameter set or a picture + // parameter set or a slice of a reference picture or a slice data partition of a reference picture. + int8_t nal_ref_idc = (nutv >> 5) & 0x03; + if (!nal_ref_idc) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "for sps, nal_ref_idc shall be not be equal to 0"); + } + + // 7.4.1 NAL unit semantics + // ISO_IEC_14496-10-AVC-2012.pdf, page 61. + // nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1. + SrsAvcNaluType nal_unit_type = SrsAvcNaluTypeParse(nutv); + if (nal_unit_type != 7) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "for sps, nal_unit_type shall be equal to 7"); + } + + // decode the rbsp from sps. + // rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes. + std::vector rbsp(vcodec->sequenceParameterSetNALUnit.size()); + + int nb_rbsp = srs_rbsp_remove_emulation_bytes(&stream, rbsp); + + return avc_demux_sps_rbsp((char *)&rbsp[0], nb_rbsp); +} + +srs_error_t SrsFormat::avc_demux_sps_rbsp(char *rbsp, int nb_rbsp) +{ + srs_error_t err = srs_success; + + // we donot parse the detail of sps. + // @see https://github.com/ossrs/srs/issues/474 + if (!avc_parse_sps) { + return err; + } + + // reparse the rbsp. + SrsBuffer stream(rbsp, nb_rbsp); + + // for SPS, 7.3.2.1.1 Sequence parameter set data syntax + // ISO_IEC_14496-10-AVC-2012.pdf, page 62. + if (!stream.require(3)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps shall atleast 3bytes"); + } + uint8_t profile_idc = stream.read_1bytes(); + if (!profile_idc) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps the profile_idc invalid"); + } + + int8_t flags = stream.read_1bytes(); + if (flags & 0x03) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps the flags invalid"); + } + + uint8_t level_idc = stream.read_1bytes(); + if (!level_idc) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps the level_idc invalid"); + } + + SrsBitBuffer bs(&stream); + + int32_t seq_parameter_set_id = -1; + if ((err = srs_avc_nalu_read_uev(&bs, seq_parameter_set_id)) != srs_success) { + return srs_error_wrap(err, "read seq_parameter_set_id"); + } + if (seq_parameter_set_id < 0) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps the seq_parameter_set_id invalid"); + } + + int32_t chroma_format_idc = -1; + if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 || profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118 || profile_idc == 128) { + if ((err = srs_avc_nalu_read_uev(&bs, chroma_format_idc)) != srs_success) { + return srs_error_wrap(err, "read chroma_format_idc"); + } + if (chroma_format_idc == 3) { + int8_t separate_colour_plane_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, separate_colour_plane_flag)) != srs_success) { + return srs_error_wrap(err, "read separate_colour_plane_flag"); + } + } + + int32_t bit_depth_luma_minus8 = -1; + if ((err = srs_avc_nalu_read_uev(&bs, bit_depth_luma_minus8)) != srs_success) { + return srs_error_wrap(err, "read bit_depth_luma_minus8"); + ; + } + + int32_t bit_depth_chroma_minus8 = -1; + if ((err = srs_avc_nalu_read_uev(&bs, bit_depth_chroma_minus8)) != srs_success) { + return srs_error_wrap(err, "read bit_depth_chroma_minus8"); + ; + } + + int8_t qpprime_y_zero_transform_bypass_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, qpprime_y_zero_transform_bypass_flag)) != srs_success) { + return srs_error_wrap(err, "read qpprime_y_zero_transform_bypass_flag"); + ; + } + + int8_t seq_scaling_matrix_present_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, seq_scaling_matrix_present_flag)) != srs_success) { + return srs_error_wrap(err, "read seq_scaling_matrix_present_flag"); + ; + } + if (seq_scaling_matrix_present_flag) { + int nb_scmpfs = ((chroma_format_idc != 3) ? 8 : 12); + for (int i = 0; i < nb_scmpfs; i++) { + int8_t seq_scaling_matrix_present_flag_i = -1; + if ((err = srs_avc_nalu_read_bit(&bs, seq_scaling_matrix_present_flag_i)) != srs_success) { + return srs_error_wrap(err, "read seq_scaling_matrix_present_flag_i"); + ; + } + } + } + } + + int32_t log2_max_frame_num_minus4 = -1; + if ((err = srs_avc_nalu_read_uev(&bs, log2_max_frame_num_minus4)) != srs_success) { + return srs_error_wrap(err, "read log2_max_frame_num_minus4"); + ; + } + + int32_t pic_order_cnt_type = -1; + if ((err = srs_avc_nalu_read_uev(&bs, pic_order_cnt_type)) != srs_success) { + return srs_error_wrap(err, "read pic_order_cnt_type"); + ; + } + + if (pic_order_cnt_type == 0) { + int32_t log2_max_pic_order_cnt_lsb_minus4 = -1; + if ((err = srs_avc_nalu_read_uev(&bs, log2_max_pic_order_cnt_lsb_minus4)) != srs_success) { + return srs_error_wrap(err, "read log2_max_pic_order_cnt_lsb_minus4"); + ; + } + } else if (pic_order_cnt_type == 1) { + int8_t delta_pic_order_always_zero_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, delta_pic_order_always_zero_flag)) != srs_success) { + return srs_error_wrap(err, "read delta_pic_order_always_zero_flag"); + ; + } + + int32_t offset_for_non_ref_pic = -1; + if ((err = srs_avc_nalu_read_uev(&bs, offset_for_non_ref_pic)) != srs_success) { + return srs_error_wrap(err, "read offset_for_non_ref_pic"); + ; + } + + int32_t offset_for_top_to_bottom_field = -1; + if ((err = srs_avc_nalu_read_uev(&bs, offset_for_top_to_bottom_field)) != srs_success) { + return srs_error_wrap(err, "read offset_for_top_to_bottom_field"); + ; + } + + int32_t num_ref_frames_in_pic_order_cnt_cycle = -1; + if ((err = srs_avc_nalu_read_uev(&bs, num_ref_frames_in_pic_order_cnt_cycle)) != srs_success) { + return srs_error_wrap(err, "read num_ref_frames_in_pic_order_cnt_cycle"); + ; + } + if (num_ref_frames_in_pic_order_cnt_cycle < 0) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps the num_ref_frames_in_pic_order_cnt_cycle"); + } + for (int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) { + int32_t offset_for_ref_frame_i = -1; + if ((err = srs_avc_nalu_read_uev(&bs, offset_for_ref_frame_i)) != srs_success) { + return srs_error_wrap(err, "read offset_for_ref_frame_i"); + ; + } + } + } + + int32_t max_num_ref_frames = -1; + if ((err = srs_avc_nalu_read_uev(&bs, max_num_ref_frames)) != srs_success) { + return srs_error_wrap(err, "read max_num_ref_frames"); + ; + } + + int8_t gaps_in_frame_num_value_allowed_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, gaps_in_frame_num_value_allowed_flag)) != srs_success) { + return srs_error_wrap(err, "read gaps_in_frame_num_value_allowed_flag"); + ; + } + + int32_t pic_width_in_mbs_minus1 = -1; + if ((err = srs_avc_nalu_read_uev(&bs, pic_width_in_mbs_minus1)) != srs_success) { + return srs_error_wrap(err, "read pic_width_in_mbs_minus1"); + ; + } + + int32_t pic_height_in_map_units_minus1 = -1; + if ((err = srs_avc_nalu_read_uev(&bs, pic_height_in_map_units_minus1)) != srs_success) { + return srs_error_wrap(err, "read pic_height_in_map_units_minus1"); + ; + } + + int8_t frame_mbs_only_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, frame_mbs_only_flag)) != srs_success) { + return srs_error_wrap(err, "read frame_mbs_only_flag"); + ; + } + if (!frame_mbs_only_flag) { + /* Skip mb_adaptive_frame_field_flag */ + int8_t mb_adaptive_frame_field_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, mb_adaptive_frame_field_flag)) != srs_success) { + return srs_error_wrap(err, "read mb_adaptive_frame_field_flag"); + ; + } + } + + /* Skip direct_8x8_inference_flag */ + int8_t direct_8x8_inference_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, direct_8x8_inference_flag)) != srs_success) { + return srs_error_wrap(err, "read direct_8x8_inference_flag"); + ; + } + + /* We need the following value to evaluate offsets, if any */ + int8_t frame_cropping_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, frame_cropping_flag)) != srs_success) { + return srs_error_wrap(err, "read frame_cropping_flag"); + ; + } + int32_t frame_crop_left_offset = 0, frame_crop_right_offset = 0, + frame_crop_top_offset = 0, frame_crop_bottom_offset = 0; + if (frame_cropping_flag) { + if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_left_offset)) != srs_success) { + return srs_error_wrap(err, "read frame_crop_left_offset"); + ; + } + if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_right_offset)) != srs_success) { + return srs_error_wrap(err, "read frame_crop_right_offset"); + ; + } + if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_top_offset)) != srs_success) { + return srs_error_wrap(err, "read frame_crop_top_offset"); + ; + } + if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_bottom_offset)) != srs_success) { + return srs_error_wrap(err, "read frame_crop_bottom_offset"); + ; + } + } + + /* Skip vui_parameters_present_flag */ + int8_t vui_parameters_present_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, vui_parameters_present_flag)) != srs_success) { + return srs_error_wrap(err, "read vui_parameters_present_flag"); + ; + } + + vcodec->width = ((pic_width_in_mbs_minus1 + 1) * 16) - frame_crop_left_offset * 2 - frame_crop_right_offset * 2; + vcodec->height = ((2 - frame_mbs_only_flag) * (pic_height_in_map_units_minus1 + 1) * 16) - (frame_crop_top_offset * 2) - (frame_crop_bottom_offset * 2); + + return err; +} + +// LCOV_EXCL_STOP + +srs_error_t SrsFormat::video_nalu_demux(SrsBuffer *stream) +{ + srs_error_t err = srs_success; + + // ensure the sequence header demuxed + if (!vcodec->is_avc_codec_ok()) { + srs_warn("avc ignore type=%d for no sequence header", SrsVideoAvcFrameTraitNALU); + return err; + } + + if (vcodec->id == SrsVideoCodecIdHEVC) { + // TODO: FIXME: Might need to guess format? + return do_avc_demux_ibmf_format(stream); + } + + // Parse the SPS/PPS in ANNEXB or IBMF format. + if (vcodec->payload_format == SrsAvcPayloadFormatIbmf) { + if ((err = avc_demux_ibmf_format(stream)) != srs_success) { + return srs_error_wrap(err, "avc demux ibmf"); + } + } else if (vcodec->payload_format == SrsAvcPayloadFormatAnnexb) { + if ((err = avc_demux_annexb_format(stream)) != srs_success) { + return srs_error_wrap(err, "avc demux annexb"); + } + } else { + if ((err = try_annexb_first ? avc_demux_annexb_format(stream) : avc_demux_ibmf_format(stream)) == srs_success) { + vcodec->payload_format = try_annexb_first ? SrsAvcPayloadFormatAnnexb : SrsAvcPayloadFormatIbmf; + } else { + srs_freep(err); + if ((err = try_annexb_first ? avc_demux_ibmf_format(stream) : avc_demux_annexb_format(stream)) == srs_success) { + vcodec->payload_format = try_annexb_first ? SrsAvcPayloadFormatIbmf : SrsAvcPayloadFormatAnnexb; + } else { + return srs_error_wrap(err, "avc demux try_annexb_first=%d", try_annexb_first); + } + } + } + + return err; +} + +srs_error_t SrsFormat::avc_demux_annexb_format(SrsBuffer *stream) +{ + srs_error_t err = srs_success; + + int pos = stream->pos(); + err = do_avc_demux_annexb_format(stream); + + // Restore the stream if error. + if (err != srs_success) { + stream->skip(pos - stream->pos()); + } + + return err; +} + +srs_error_t SrsFormat::do_avc_demux_annexb_format(SrsBuffer *stream) +{ + srs_error_t err = srs_success; + + // not annexb, try others + if (!srs_avc_startswith_annexb(stream, NULL)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "not annexb"); + } + + // AnnexB + // B.1.1 Byte stream NAL unit syntax, + // ISO_IEC_14496-10-AVC-2003.pdf, page 211. + while (!stream->empty()) { + // find start code + int nb_start_code = 0; + if (!srs_avc_startswith_annexb(stream, &nb_start_code)) { + return err; + } + + // skip the start code. + if (nb_start_code > 0) { + stream->skip(nb_start_code); + } + + // the NALU start bytes. + char *p = stream->data() + stream->pos(); + + // get the last matched NALU + while (!stream->empty()) { + if (srs_avc_startswith_annexb(stream, NULL)) { + break; + } + + stream->skip(1); + } + + char *pp = stream->data() + stream->pos(); + + // skip the empty. + if (pp - p <= 0) { + continue; + } + + // got the NALU. + if ((err = video->add_sample(p, (int)(pp - p))) != srs_success) { + return srs_error_wrap(err, "add video frame"); + } + } + + return err; +} + +srs_error_t SrsFormat::avc_demux_ibmf_format(SrsBuffer *stream) +{ + srs_error_t err = srs_success; + + int pos = stream->pos(); + err = do_avc_demux_ibmf_format(stream); + + // Restore the stream if error. + if (err != srs_success) { + stream->skip(pos - stream->pos()); + } + + return err; +} + +srs_error_t SrsFormat::do_avc_demux_ibmf_format(SrsBuffer *stream) +{ + srs_error_t err = srs_success; + + int PictureLength = stream->size() - stream->pos(); + + // 5.3.4.2.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16 + // 5.2.4.1 AVC decoder configuration record + // 5.2.4.1.2 Semantics + // The value of this field shall be one of 0, 1, or 3 corresponding to a + // length encoded with 1, 2, or 4 bytes, respectively. + srs_assert(vcodec->NAL_unit_length != 2); + + // 5.3.4.2.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 20 + for (int i = 0; i < PictureLength;) { + // unsigned int((NAL_unit_length+1)*8) NALUnitLength; + // TODO: FIXME: Should ignore error? See https://github.com/ossrs/srs-gb28181/commit/a13b9b54938a14796abb9011e7a8ee779439a452 + if (!stream->require(vcodec->NAL_unit_length + 1)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "PictureLength:%d, i:%d, NaluLength:%d, left:%d", + PictureLength, i, vcodec->NAL_unit_length, stream->left()); + } + int32_t NALUnitLength = 0; + if (vcodec->NAL_unit_length == 3) { + NALUnitLength = stream->read_4bytes(); + } else if (vcodec->NAL_unit_length == 1) { + NALUnitLength = stream->read_2bytes(); + } else { + NALUnitLength = stream->read_1bytes(); + } + + // The stream format mighe be incorrect, see: https://github.com/ossrs/srs/issues/183 + if (NALUnitLength < 0) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "PictureLength:%d, i:%d, NaluLength:%d, left:%d, NALUnitLength:%d", + PictureLength, i, vcodec->NAL_unit_length, stream->left(), NALUnitLength); + } + + // NALUnit + if (!stream->require(NALUnitLength)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "PictureLength:%d, i:%d, NaluLength:%d, left:%d, NALUnitLength:%d", + PictureLength, i, vcodec->NAL_unit_length, stream->left(), NALUnitLength); + } + // 7.3.1 NAL unit syntax, ISO_IEC_14496-10-AVC-2003.pdf, page 44. + if ((err = video->add_sample(stream->data() + stream->pos(), NALUnitLength)) != srs_success) { + return srs_error_wrap(err, "avc add video frame"); + } + + stream->skip(NALUnitLength); + i += vcodec->NAL_unit_length + 1 + NALUnitLength; + } + + return err; +} + +srs_error_t SrsFormat::audio_aac_demux(SrsBuffer *stream, int64_t timestamp) +{ + srs_error_t err = srs_success; + + audio->cts = 0; + audio->dts = timestamp; + + // @see: E.4.2 Audio Tags, video_file_format_spec_v10_1.pdf, page 76 + int8_t sound_format = stream->read_1bytes(); + + int8_t sound_type = sound_format & 0x01; + int8_t sound_size = (sound_format >> 1) & 0x01; + int8_t sound_rate = (sound_format >> 2) & 0x03; + sound_format = (sound_format >> 4) & 0x0f; + + SrsAudioCodecId codec_id = (SrsAudioCodecId)sound_format; + acodec->id = codec_id; + + acodec->sound_type = (SrsAudioChannels)sound_type; + acodec->sound_rate = (SrsAudioSampleRate)sound_rate; + acodec->sound_size = (SrsAudioSampleBits)sound_size; + + // we support h.264+mp3 for hls. + if (codec_id == SrsAudioCodecIdMP3) { + return srs_error_new(ERROR_HLS_TRY_MP3, "try mp3"); + } + + // only support aac + if (codec_id != SrsAudioCodecIdAAC) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "not supported codec %d", codec_id); + } + + if (!stream->require(1)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "aac decode aac_packet_type"); + } + + SrsAudioAacFrameTrait aac_packet_type = (SrsAudioAacFrameTrait)stream->read_1bytes(); + audio->aac_packet_type = (SrsAudioAacFrameTrait)aac_packet_type; + + // Update the RAW AAC data. + raw = stream->data() + stream->pos(); + nb_raw = stream->size() - stream->pos(); + + if (aac_packet_type == SrsAudioAacFrameTraitSequenceHeader) { + // AudioSpecificConfig + // 1.6.2.1 AudioSpecificConfig, in ISO_IEC_14496-3-AAC-2001.pdf, page 33. + int aac_extra_size = stream->size() - stream->pos(); + if (aac_extra_size > 0) { + char *copy_stream_from = stream->data() + stream->pos(); + acodec->aac_extra_data = std::vector(copy_stream_from, copy_stream_from + aac_extra_size); + + if ((err = audio_aac_sequence_header_demux(&acodec->aac_extra_data[0], aac_extra_size)) != srs_success) { + return srs_error_wrap(err, "demux aac sh"); + } + } + } else if (aac_packet_type == SrsAudioAacFrameTraitRawData) { + // ensure the sequence header demuxed + if (!acodec->is_aac_codec_ok()) { + srs_warn("aac ignore type=%d for no sequence header", aac_packet_type); + return err; + } + + // Raw AAC frame data in UI8 [] + // 6.3 Raw Data, ISO_IEC_13818-7-AAC-2004.pdf, page 28 + if ((err = audio->add_sample(stream->data() + stream->pos(), stream->size() - stream->pos())) != srs_success) { + return srs_error_wrap(err, "add audio frame"); + } + } else { + // ignored. + } + + // reset the sample rate by sequence header + if (acodec->aac_sample_rate != SrsAacSampleRateUnset) { + static int srs_aac_srates[] = { + 96000, 88200, 64000, 48000, + 44100, 32000, 24000, 22050, + 16000, 12000, 11025, 8000, + 7350, 0, 0, 0}; + switch (srs_aac_srates[acodec->aac_sample_rate]) { + case 11025: + acodec->sound_rate = SrsAudioSampleRate11025; + break; + case 22050: + acodec->sound_rate = SrsAudioSampleRate22050; + break; + case 44100: + acodec->sound_rate = SrsAudioSampleRate44100; + break; + default: + break; + }; + } + + return err; +} + +srs_error_t SrsFormat::audio_mp3_demux(SrsBuffer *stream, int64_t timestamp, bool fresh) +{ + srs_error_t err = srs_success; + + audio->cts = 0; + audio->dts = timestamp; + audio->aac_packet_type = fresh ? SrsAudioMp3FrameTraitSequenceHeader : SrsAudioMp3FrameTraitRawData; + + // @see: E.4.2 Audio Tags, video_file_format_spec_v10_1.pdf, page 76 + int8_t sound_format = stream->read_1bytes(); + + int8_t sound_type = sound_format & 0x01; + int8_t sound_size = (sound_format >> 1) & 0x01; + int8_t sound_rate = (sound_format >> 2) & 0x03; + sound_format = (sound_format >> 4) & 0x0f; + + SrsAudioCodecId codec_id = (SrsAudioCodecId)sound_format; + acodec->id = codec_id; + + acodec->sound_type = (SrsAudioChannels)sound_type; + acodec->sound_rate = (SrsAudioSampleRate)sound_rate; + acodec->sound_size = (SrsAudioSampleBits)sound_size; + + // we always decode aac then mp3. + srs_assert(acodec->id == SrsAudioCodecIdMP3); + + // Update the RAW MP3 data. Note the start is 12 bits syncword 0xFFF, so we should not skip any bytes, for detail + // please see ISO_IEC_11172-3-MP3-1993.pdf page 20 and 26. + raw = stream->data() + stream->pos(); + nb_raw = stream->size() - stream->pos(); + + // mp3 payload. + if ((err = audio->add_sample(raw, nb_raw)) != srs_success) { + return srs_error_wrap(err, "add audio frame"); + } + + return err; +} + +srs_error_t SrsFormat::audio_aac_sequence_header_demux(char *data, int size) +{ + srs_error_t err = srs_success; + + SrsUniquePtr buffer(new SrsBuffer(data, size)); + + // only need to decode the first 2bytes: + // audioObjectType, aac_profile, 5bits. + // samplingFrequencyIndex, aac_sample_rate, 4bits. + // channelConfiguration, aac_channels, 4bits + if (!buffer->require(2)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "audio codec decode aac sh"); + } + uint8_t profile_ObjectType = buffer->read_1bytes(); + uint8_t samplingFrequencyIndex = buffer->read_1bytes(); + + acodec->aac_channels = (samplingFrequencyIndex >> 3) & 0x0f; + samplingFrequencyIndex = ((profile_ObjectType << 1) & 0x0e) | ((samplingFrequencyIndex >> 7) & 0x01); + profile_ObjectType = (profile_ObjectType >> 3) & 0x1f; + + // set the aac sample rate. + acodec->aac_sample_rate = samplingFrequencyIndex; + + // convert the object type in sequence header to aac profile of ADTS. + acodec->aac_object = (SrsAacObjectType)profile_ObjectType; + if (acodec->aac_object == SrsAacObjectTypeReserved) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "aac decode sh object %d", profile_ObjectType); + } + + // TODO: FIXME: to support aac he/he-v2, see: ngx_rtmp_codec_parse_aac_header + // @see: https://github.com/winlinvip/nginx-rtmp-module/commit/3a5f9eea78fc8d11e8be922aea9ac349b9dcbfc2 + // + // donot force to LC, @see: https://github.com/ossrs/srs/issues/81 + // the source will print the sequence header info. + // if (aac_profile > 3) { + // Mark all extended profiles as LC + // to make Android as happy as possible. + // @see: ngx_rtmp_hls_parse_aac_header + // aac_profile = 1; + //} + + return err; +} diff --git a/trunk/src/kernel/srs_kernel_packet.hpp b/trunk/src/kernel/srs_kernel_packet.hpp new file mode 100644 index 000000000..31c572c11 --- /dev/null +++ b/trunk/src/kernel/srs_kernel_packet.hpp @@ -0,0 +1,260 @@ +// +// Copyright (c) 2013-2025 The SRS Authors +// +// SPDX-License-Identifier: MIT +// + +#ifndef SRS_KERNEL_PACKET_HPP +#define SRS_KERNEL_PACKET_HPP + +#include + +#include + +/** + * A sample is the NAL unit of a parsed packet. + * It's a NALU for H.264, H.265. + * It's the whole AAC raw data for AAC. + * @remark Neither SPS/PPS or ASC is sample unit, it's codec sequence header. + */ +class SrsNaluSample +{ +public: + // The size of unit. + int size; + // The ptr of unit, user must free it. + char *bytes; + +public: + SrsNaluSample(); + SrsNaluSample(char *b, int s); + ~SrsNaluSample(); + +public: + // Copy sample, share the bytes pointer. + SrsNaluSample *copy(); +}; + +// A media packet containing raw, undecoded media data. +// This represents a single media frame or packet with timing information +// and payload data, but without codec-specific parsing or decoding. +class SrsMediaPacket +{ +public: + // Timestamp of the media packet. The timebase is defined by context. + int64_t timestamp; + // Type of the media packet (audio, video, or script). + SrsFrameType message_type; + +public: + // Stream identifier for the packet. It's optional, so only used for some + // protocols, for example, RTMP. + int32_t stream_id; + +public: + // Raw payload data of the media packet. + SrsSharedPtr payload_; + +public: + SrsMediaPacket(); + virtual ~SrsMediaPacket(); + +public: + // Backward compatibility accessors + char *payload() { return payload_.get() ? payload_->payload() : NULL; } + int size() { return payload_.get() ? payload_->size() : 0; } + +public: + // Create shared ptr message from RAW payload. + // @remark Note that the header is set to zero. + virtual void wrap(char *payload, int size); + // check prefer cid and stream id. + // @return whether stream id already set. + virtual bool check(int stream_id); + +public: + virtual bool is_av(); + virtual bool is_audio(); + virtual bool is_video(); + +public: + // copy current shared ptr message, use ref-count. + // @remark, assert object is created. + virtual SrsMediaPacket *copy(); +}; + +// A parsed packet, consists of a codec and a group of samples. +class SrsParsedPacket +{ +public: + // The DTS/PTS in milliseconds, which is TBN=1000. + int64_t dts; + // PTS = DTS + CTS. + int32_t cts; + +public: + // The codec info of frame. + SrsCodecConfig *codec; + // The actual parsed number of samples. + int nb_samples; + // The sampels cache. + SrsNaluSample samples[SrsMaxNbSamples]; + +public: + SrsParsedPacket(); + virtual ~SrsParsedPacket(); + +public: + // Initialize the frame, to parse sampels. + virtual srs_error_t initialize(SrsCodecConfig *c); + // Add a sample to frame. + virtual srs_error_t add_sample(char *bytes, int size); +}; + +// A parsed audio packet, besides a frame, contains the audio frame info, such as frame type. +class SrsParsedAudioPacket : public SrsParsedPacket +{ +public: + SrsAudioAacFrameTrait aac_packet_type; + +public: + SrsParsedAudioPacket(); + virtual ~SrsParsedAudioPacket(); + +public: + virtual SrsAudioCodecConfig *acodec(); +}; + +// A parsed video packet, besides a frame, contains the video frame info, such as frame type. +class SrsParsedVideoPacket : public SrsParsedPacket +{ +public: + // video specified + SrsVideoAvcFrameType frame_type; + SrsVideoAvcFrameTrait avc_packet_type; + // whether sample_units contains IDR frame. + bool has_idr; + // Whether exists AUD NALU. + bool has_aud; + // Whether exists SPS/PPS NALU. + bool has_sps_pps; + // The first nalu type. + SrsAvcNaluType first_nalu_type; + +public: + SrsParsedVideoPacket(); + virtual ~SrsParsedVideoPacket(); + +public: + // Initialize the frame, to parse sampels. + virtual srs_error_t initialize(SrsCodecConfig *c); + // Add the sample without ANNEXB or IBMF header, or RAW AAC or MP3 data. + virtual srs_error_t add_sample(char *bytes, int size); + +public: + virtual SrsVideoCodecConfig *vcodec(); + +public: + static srs_error_t parse_avc_nalu_type(const SrsNaluSample *sample, SrsAvcNaluType &avc_nalu_type); + static srs_error_t parse_avc_bframe(const SrsNaluSample *sample, bool &is_b_frame); + static srs_error_t parse_hevc_nalu_type(const SrsNaluSample *sample, SrsHevcNaluType &hevc_nalu_type); + static srs_error_t parse_hevc_bframe(const SrsNaluSample *sample, SrsFormat *format, bool &is_b_frame); +}; + +/** + * A codec format, including one or many stream, each stream identified by a frame. + * For example, a typical RTMP stream format, consits of a video and audio frame. + * Maybe some RTMP stream only has a audio stream, for instance, redio application. + */ +class SrsFormat +{ +public: + SrsParsedAudioPacket *audio; + SrsAudioCodecConfig *acodec; + SrsParsedVideoPacket *video; + SrsVideoCodecConfig *vcodec; + +public: + char *raw; + int nb_raw; + +public: + // for sequence header, whether parse the h.264 sps. + // TODO: FIXME: Refine it. + bool avc_parse_sps; + // Whether try to parse in ANNEXB, then by IBMF. + bool try_annexb_first; + +public: + SrsFormat(); + virtual ~SrsFormat(); + +public: + // Initialize the format. + virtual srs_error_t initialize(); + // When got a parsed audio packet. + // @param data The data in FLV format. + virtual srs_error_t on_audio(int64_t timestamp, char *data, int size); + // When got a parsed video packet. + // @param data The data in FLV format. + virtual srs_error_t on_video(int64_t timestamp, char *data, int size); + // When got a audio aac sequence header. + virtual srs_error_t on_aac_sequence_header(char *data, int size); + +public: + virtual bool is_aac_sequence_header(); + virtual bool is_mp3_sequence_header(); + // TODO: is avc|hevc|av1 sequence header + virtual bool is_avc_sequence_header(); + +private: + // Demux the video packet in H.264 codec. + // The packet is muxed in FLV format, defined in flv specification. + // Demux the sps/pps from sequence header. + // Demux the samples from NALUs. + virtual srs_error_t video_avc_demux(SrsBuffer *stream, int64_t timestamp); + +private: + virtual srs_error_t hevc_demux_hvcc(SrsBuffer *stream); + +private: + virtual srs_error_t hevc_demux_vps_sps_pps(SrsHevcHvccNalu *nal); + virtual srs_error_t hevc_demux_vps_rbsp(char *rbsp, int nb_rbsp); + virtual srs_error_t hevc_demux_sps_rbsp(char *rbsp, int nb_rbsp); + virtual srs_error_t hevc_demux_pps_rbsp(char *rbsp, int nb_rbsp); + virtual srs_error_t hevc_demux_rbsp_ptl(SrsBitBuffer *bs, SrsHevcProfileTierLevel *ptl, int profile_present_flag, int max_sub_layers_minus1); + +public: + virtual srs_error_t hevc_demux_vps(SrsBuffer *stream); + virtual srs_error_t hevc_demux_sps(SrsBuffer *stream); + virtual srs_error_t hevc_demux_pps(SrsBuffer *stream); + +private: + // Parse the H.264 SPS/PPS. + virtual srs_error_t avc_demux_sps_pps(SrsBuffer *stream); + virtual srs_error_t avc_demux_sps(); + virtual srs_error_t avc_demux_sps_rbsp(char *rbsp, int nb_rbsp); + +private: + // Parse the H.264 or H.265 NALUs. + virtual srs_error_t video_nalu_demux(SrsBuffer *stream); + // Demux the avc NALU in "AnnexB" from ISO_IEC_14496-10-AVC-2003.pdf, page 211. + virtual srs_error_t avc_demux_annexb_format(SrsBuffer *stream); + virtual srs_error_t do_avc_demux_annexb_format(SrsBuffer *stream); + // Demux the avc NALU in "ISO Base Media File Format" from ISO_IEC_14496-15-AVC-format-2012.pdf, page 20 + virtual srs_error_t avc_demux_ibmf_format(SrsBuffer *stream); + virtual srs_error_t do_avc_demux_ibmf_format(SrsBuffer *stream); + +private: + // Demux the audio packet in AAC codec. + // Demux the asc from sequence header. + // Demux the sampels from RAW data. + virtual srs_error_t audio_aac_demux(SrsBuffer *stream, int64_t timestamp); + virtual srs_error_t audio_mp3_demux(SrsBuffer *stream, int64_t timestamp, bool fresh); + +public: + // Directly demux the sequence header, without RTMP packet header. + virtual srs_error_t audio_aac_sequence_header_demux(char *data, int size); +}; + +#endif diff --git a/trunk/src/kernel/srs_kernel_rtc_rtp.cpp b/trunk/src/kernel/srs_kernel_rtc_rtp.cpp index 9150acf3f..32db27cd1 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtp.cpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtp.cpp @@ -1006,7 +1006,7 @@ SrsRtpRawPayload::SrsRtpRawPayload() { payload = NULL; nn_payload = 0; - sample_ = new SrsSample(); + sample_ = new SrsNaluSample(); ++_srs_pps_objs_rraw->sugar; } @@ -1077,19 +1077,19 @@ SrsRtpRawNALUs::~SrsRtpRawNALUs() { int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; srs_freep(p); } } -void SrsRtpRawNALUs::push_back(SrsSample *sample) +void SrsRtpRawNALUs::push_back(SrsNaluSample *sample) { if (sample->size <= 0) { return; } if (!nalus.empty()) { - SrsSample *p = new SrsSample(); + SrsNaluSample *p = new SrsNaluSample(); p->bytes = (char *)"\0\0\1"; p->size = 3; nn_bytes += 3; @@ -1107,7 +1107,7 @@ uint8_t SrsRtpRawNALUs::skip_bytes(int count) return uint8_t(nalus[0]->bytes[0]); } -srs_error_t SrsRtpRawNALUs::read_samples(vector &samples, int packet_size) +srs_error_t SrsRtpRawNALUs::read_samples(vector &samples, int packet_size) { if (cursor + packet_size < 0 || cursor + packet_size > nn_bytes) { return srs_error_new(ERROR_RTC_RTP_MUXER, "cursor=%d, max=%d, size=%d", cursor, nn_bytes, packet_size); @@ -1119,7 +1119,7 @@ srs_error_t SrsRtpRawNALUs::read_samples(vector &samples, int packe int nn_nalus = (int)nalus.size(); for (int i = 0; left > 0 && i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; // Ignore previous consumed samples. if (pos && pos - p->size >= 0) { @@ -1131,7 +1131,7 @@ srs_error_t SrsRtpRawNALUs::read_samples(vector &samples, int packe int nn = srs_min(left, p->size - pos); srs_assert(nn > 0); - SrsSample *sample = new SrsSample(); + SrsNaluSample *sample = new SrsNaluSample(); samples.push_back(sample); sample->bytes = p->bytes + pos; @@ -1150,7 +1150,7 @@ uint64_t SrsRtpRawNALUs::nb_bytes() int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; size += p->size; } @@ -1161,7 +1161,7 @@ srs_error_t SrsRtpRawNALUs::encode(SrsBuffer *buf) { int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; if (!buf->require(p->size)) { return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", p->size); @@ -1179,7 +1179,7 @@ srs_error_t SrsRtpRawNALUs::decode(SrsBuffer *buf) return srs_success; } - SrsSample *sample = new SrsSample(); + SrsNaluSample *sample = new SrsNaluSample(); sample->bytes = buf->head(); sample->size = buf->left(); buf->skip(sample->size); @@ -1198,7 +1198,7 @@ ISrsRtpPayloader *SrsRtpRawNALUs::copy() int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; cp->nalus.push_back(p->copy()); } @@ -1216,16 +1216,16 @@ SrsRtpSTAPPayload::~SrsRtpSTAPPayload() { int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; srs_freep(p); } } -SrsSample *SrsRtpSTAPPayload::get_sps() +SrsNaluSample *SrsRtpSTAPPayload::get_sps() { int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; if (!p || !p->size) { continue; } @@ -1239,11 +1239,11 @@ SrsSample *SrsRtpSTAPPayload::get_sps() return NULL; } -SrsSample *SrsRtpSTAPPayload::get_pps() +SrsNaluSample *SrsRtpSTAPPayload::get_pps() { int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; if (!p || !p->size) { continue; } @@ -1263,7 +1263,7 @@ uint64_t SrsRtpSTAPPayload::nb_bytes() int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; size += 2 + p->size; } @@ -1285,7 +1285,7 @@ srs_error_t SrsRtpSTAPPayload::encode(SrsBuffer *buf) // NALUs. int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; if (!buf->require(2 + p->size)) { return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", 2 + p->size); @@ -1328,7 +1328,7 @@ srs_error_t SrsRtpSTAPPayload::decode(SrsBuffer *buf) return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", size); } - SrsSample *sample = new SrsSample(); + SrsNaluSample *sample = new SrsNaluSample(); sample->bytes = buf->head(); sample->size = size; buf->skip(size); @@ -1347,7 +1347,7 @@ ISrsRtpPayloader *SrsRtpSTAPPayload::copy() int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; cp->nalus.push_back(p->copy()); } @@ -1366,7 +1366,7 @@ SrsRtpFUAPayload::~SrsRtpFUAPayload() { int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; srs_freep(p); } } @@ -1377,7 +1377,7 @@ uint64_t SrsRtpFUAPayload::nb_bytes() int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; size += p->size; } @@ -1408,7 +1408,7 @@ srs_error_t SrsRtpFUAPayload::encode(SrsBuffer *buf) // FU payload, @see https://tools.ietf.org/html/rfc6184#section-5.8 int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; if (!buf->require(p->size)) { return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", p->size); @@ -1440,7 +1440,7 @@ srs_error_t SrsRtpFUAPayload::decode(SrsBuffer *buf) return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", 1); } - SrsSample *sample = new SrsSample(); + SrsNaluSample *sample = new SrsNaluSample(); sample->bytes = buf->head(); sample->size = buf->left(); buf->skip(sample->size); @@ -1461,7 +1461,7 @@ ISrsRtpPayloader *SrsRtpFUAPayload::copy() int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; cp->nalus.push_back(p->copy()); } @@ -1571,16 +1571,16 @@ SrsRtpSTAPPayloadHevc::~SrsRtpSTAPPayloadHevc() { int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; srs_freep(p); } } -SrsSample *SrsRtpSTAPPayloadHevc::get_vps() +SrsNaluSample *SrsRtpSTAPPayloadHevc::get_vps() { int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; if (!p || !p->size) { continue; } @@ -1594,11 +1594,11 @@ SrsSample *SrsRtpSTAPPayloadHevc::get_vps() return NULL; } -SrsSample *SrsRtpSTAPPayloadHevc::get_sps() +SrsNaluSample *SrsRtpSTAPPayloadHevc::get_sps() { int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; if (!p || !p->size) { continue; } @@ -1612,11 +1612,11 @@ SrsSample *SrsRtpSTAPPayloadHevc::get_sps() return NULL; } -SrsSample *SrsRtpSTAPPayloadHevc::get_pps() +SrsNaluSample *SrsRtpSTAPPayloadHevc::get_pps() { int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; if (!p || !p->size) { continue; } @@ -1636,7 +1636,7 @@ uint64_t SrsRtpSTAPPayloadHevc::nb_bytes() int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; size += 2 + p->size; } @@ -1657,7 +1657,7 @@ srs_error_t SrsRtpSTAPPayloadHevc::encode(SrsBuffer *buf) // NALUs. int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; if (!buf->require(2 + p->size)) { return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", 2 + p->size); @@ -1699,7 +1699,7 @@ srs_error_t SrsRtpSTAPPayloadHevc::decode(SrsBuffer *buf) return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", size); } - SrsSample *sample = new SrsSample(); + SrsNaluSample *sample = new SrsNaluSample(); sample->bytes = buf->head(); sample->size = size; buf->skip(size); @@ -1716,7 +1716,7 @@ ISrsRtpPayloader *SrsRtpSTAPPayloadHevc::copy() int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; cp->nalus.push_back(p->copy()); } @@ -1735,7 +1735,7 @@ SrsRtpFUAPayloadHevc::~SrsRtpFUAPayloadHevc() { int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; srs_freep(p); } } @@ -1746,7 +1746,7 @@ uint64_t SrsRtpFUAPayloadHevc::nb_bytes() int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; size += p->size; } @@ -1770,7 +1770,7 @@ srs_error_t SrsRtpFUAPayloadHevc::encode(SrsBuffer *buf) int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; if (!buf->require(p->size)) { return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", p->size); @@ -1799,7 +1799,7 @@ srs_error_t SrsRtpFUAPayloadHevc::decode(SrsBuffer *buf) return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", 1); } - SrsSample *sample = new SrsSample(); + SrsNaluSample *sample = new SrsNaluSample(); sample->bytes = buf->head(); sample->size = buf->left(); buf->skip(sample->size); @@ -1819,7 +1819,7 @@ ISrsRtpPayloader *SrsRtpFUAPayloadHevc::copy() int nn_nalus = (int)nalus.size(); for (int i = 0; i < nn_nalus; i++) { - SrsSample *p = nalus[i]; + SrsNaluSample *p = nalus[i]; cp->nalus.push_back(p->copy()); } diff --git a/trunk/src/kernel/srs_kernel_rtc_rtp.hpp b/trunk/src/kernel/srs_kernel_rtc_rtp.hpp index 3cb3175d7..241b6af97 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtp.hpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtp.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -411,7 +412,7 @@ public: public: // Use the whole RAW RTP payload as a sample. - SrsSample *sample_; + SrsNaluSample *sample_; public: SrsRtpRawPayload(); @@ -429,7 +430,7 @@ class SrsRtpRawNALUs : public ISrsRtpPayloader { private: // We will manage the samples, but the sample itself point to the shared memory. - std::vector nalus; + std::vector nalus; int nn_bytes; int cursor; @@ -438,12 +439,12 @@ public: virtual ~SrsRtpRawNALUs(); public: - void push_back(SrsSample *sample); + void push_back(SrsNaluSample *sample); public: uint8_t skip_bytes(int count); // We will manage the returned samples, if user want to manage it, please copy it. - srs_error_t read_samples(std::vector &samples, int packet_size); + srs_error_t read_samples(std::vector &samples, int packet_size); // interface ISrsRtpPayloader public: virtual uint64_t nb_bytes(); @@ -460,15 +461,15 @@ public: SrsAvcNaluType nri; // The NALU samples, we will manage the samples. // @remark We only refer to the memory, user must free its bytes. - std::vector nalus; + std::vector nalus; public: SrsRtpSTAPPayload(); virtual ~SrsRtpSTAPPayload(); public: - SrsSample *get_sps(); - SrsSample *get_pps(); + SrsNaluSample *get_sps(); + SrsNaluSample *get_pps(); // interface ISrsRtpPayloader public: virtual uint64_t nb_bytes(); @@ -490,7 +491,7 @@ public: SrsAvcNaluType nalu_type; // The NALU samples, we manage the samples. // @remark We only refer to the memory, user must free its bytes. - std::vector nalus; + std::vector nalus; public: SrsRtpFUAPayload(); @@ -534,16 +535,16 @@ class SrsRtpSTAPPayloadHevc : public ISrsRtpPayloader public: // The NALU samples, we will manage the samples. // @remark We only refer to the memory, user must free its bytes. - std::vector nalus; + std::vector nalus; public: SrsRtpSTAPPayloadHevc(); virtual ~SrsRtpSTAPPayloadHevc(); public: - SrsSample *get_vps(); - SrsSample *get_sps(); - SrsSample *get_pps(); + SrsNaluSample *get_vps(); + SrsNaluSample *get_sps(); + SrsNaluSample *get_pps(); // interface ISrsRtpPayloader public: virtual uint64_t nb_bytes(); @@ -563,7 +564,7 @@ public: SrsHevcNaluType nalu_type; // The NALU samples, we manage the samples. // @remark We only refer to the memory, user must free its bytes. - std::vector nalus; + std::vector nalus; public: SrsRtpFUAPayloadHevc(); diff --git a/trunk/src/kernel/srs_kernel_ts.cpp b/trunk/src/kernel/srs_kernel_ts.cpp index 41745b820..80995123d 100644 --- a/trunk/src/kernel/srs_kernel_ts.cpp +++ b/trunk/src/kernel/srs_kernel_ts.cpp @@ -2917,7 +2917,7 @@ SrsTsMessageCache::~SrsTsMessageCache() srs_freep(video); } -srs_error_t SrsTsMessageCache::cache_audio(SrsAudioFrame *frame, int64_t dts) +srs_error_t SrsTsMessageCache::cache_audio(SrsParsedAudioPacket *frame, int64_t dts) { srs_error_t err = srs_success; @@ -2951,7 +2951,7 @@ srs_error_t SrsTsMessageCache::cache_audio(SrsAudioFrame *frame, int64_t dts) return err; } -srs_error_t SrsTsMessageCache::cache_video(SrsVideoFrame *frame, int64_t dts) +srs_error_t SrsTsMessageCache::cache_video(SrsParsedVideoPacket *frame, int64_t dts) { srs_error_t err = srs_success; @@ -2979,21 +2979,21 @@ srs_error_t SrsTsMessageCache::cache_video(SrsVideoFrame *frame, int64_t dts) return err; } -srs_error_t SrsTsMessageCache::do_cache_mp3(SrsAudioFrame *frame) +srs_error_t SrsTsMessageCache::do_cache_mp3(SrsParsedAudioPacket *frame) { srs_error_t err = srs_success; // for mp3, directly write to cache. // TODO: FIXME: implements the ts jitter. for (int i = 0; i < frame->nb_samples; i++) { - SrsSample *sample = &frame->samples[i]; + SrsNaluSample *sample = &frame->samples[i]; audio->payload->append(sample->bytes, sample->size); } return err; } -srs_error_t SrsTsMessageCache::do_cache_aac(SrsAudioFrame *frame) +srs_error_t SrsTsMessageCache::do_cache_aac(SrsParsedAudioPacket *frame) { srs_error_t err = srs_success; @@ -3001,7 +3001,7 @@ srs_error_t SrsTsMessageCache::do_cache_aac(SrsAudioFrame *frame) srs_assert(codec); for (int i = 0; i < frame->nb_samples; i++) { - SrsSample *sample = &frame->samples[i]; + SrsNaluSample *sample = &frame->samples[i]; int32_t size = sample->size; if (!sample->bytes || size <= 0 || size > 0x1fff) { @@ -3118,7 +3118,7 @@ void srs_avc_insert_aud(SrsSimpleStream *payload, bool aud_inserted) } } -srs_error_t SrsTsMessageCache::do_cache_avc(SrsVideoFrame *frame) +srs_error_t SrsTsMessageCache::do_cache_avc(SrsParsedVideoPacket *frame) { srs_error_t err = srs_success; @@ -3169,7 +3169,7 @@ srs_error_t SrsTsMessageCache::do_cache_avc(SrsVideoFrame *frame) // all sample use cont nalu header, except the sps-pps before IDR frame. for (int i = 0; i < frame->nb_samples; i++) { - SrsSample *sample = &frame->samples[i]; + SrsNaluSample *sample = &frame->samples[i]; int32_t size = sample->size; if (!sample->bytes || size <= 0) { @@ -3202,7 +3202,7 @@ srs_error_t SrsTsMessageCache::do_cache_avc(SrsVideoFrame *frame) return err; } -srs_error_t SrsTsMessageCache::do_cache_hevc(SrsVideoFrame *frame) +srs_error_t SrsTsMessageCache::do_cache_hevc(SrsParsedVideoPacket *frame) { srs_error_t err = srs_success; @@ -3216,7 +3216,7 @@ srs_error_t SrsTsMessageCache::do_cache_hevc(SrsVideoFrame *frame) // all sample use cont nalu header, except the sps-pps before IDR frame. for (int i = 0; i < frame->nb_samples; i++) { - SrsSample *sample = &frame->samples[i]; + SrsNaluSample *sample = &frame->samples[i]; int32_t size = sample->size; if (!sample->bytes || size <= 0) { diff --git a/trunk/src/kernel/srs_kernel_ts.hpp b/trunk/src/kernel/srs_kernel_ts.hpp index 29746cf52..28328b031 100644 --- a/trunk/src/kernel/srs_kernel_ts.hpp +++ b/trunk/src/kernel/srs_kernel_ts.hpp @@ -15,6 +15,7 @@ #include #include +#include class SrsBuffer; class SrsTsMessageCache; @@ -1366,15 +1367,15 @@ public: public: // Write audio to cache - virtual srs_error_t cache_audio(SrsAudioFrame *frame, int64_t dts); + virtual srs_error_t cache_audio(SrsParsedAudioPacket *frame, int64_t dts); // Write video to muxer. - virtual srs_error_t cache_video(SrsVideoFrame *frame, int64_t dts); + virtual srs_error_t cache_video(SrsParsedVideoPacket *frame, int64_t dts); private: - virtual srs_error_t do_cache_mp3(SrsAudioFrame *frame); - virtual srs_error_t do_cache_aac(SrsAudioFrame *frame); - virtual srs_error_t do_cache_avc(SrsVideoFrame *frame); - virtual srs_error_t do_cache_hevc(SrsVideoFrame *frame); + virtual srs_error_t do_cache_mp3(SrsParsedAudioPacket *frame); + virtual srs_error_t do_cache_aac(SrsParsedAudioPacket *frame); + virtual srs_error_t do_cache_avc(SrsParsedVideoPacket *frame); + virtual srs_error_t do_cache_hevc(SrsParsedVideoPacket *frame); }; // Transmux the RTMP stream to HTTP-TS stream. diff --git a/trunk/src/protocol/srs_protocol_format.cpp b/trunk/src/protocol/srs_protocol_format.cpp index 8b37f6b93..c9739fd8a 100644 --- a/trunk/src/protocol/srs_protocol_format.cpp +++ b/trunk/src/protocol/srs_protocol_format.cpp @@ -27,9 +27,9 @@ srs_error_t SrsRtmpFormat::on_metadata(SrsOnMetaDataPacket *meta) return srs_success; } -srs_error_t SrsRtmpFormat::on_audio(SrsSharedPtrMessage *shared_audio) +srs_error_t SrsRtmpFormat::on_audio(SrsMediaPacket *shared_audio) { - SrsSharedPtrMessage *msg = shared_audio; + SrsMediaPacket *msg = shared_audio; char *data = msg->payload(); int size = msg->size(); @@ -41,9 +41,9 @@ srs_error_t SrsRtmpFormat::on_audio(int64_t timestamp, char *data, int size) return SrsFormat::on_audio(timestamp, data, size); } -srs_error_t SrsRtmpFormat::on_video(SrsSharedPtrMessage *shared_video) +srs_error_t SrsRtmpFormat::on_video(SrsMediaPacket *shared_video) { - SrsSharedPtrMessage *msg = shared_video; + SrsMediaPacket *msg = shared_video; char *data = msg->payload(); int size = msg->size(); diff --git a/trunk/src/protocol/srs_protocol_format.hpp b/trunk/src/protocol/srs_protocol_format.hpp index cc65b70a8..bc58f5321 100644 --- a/trunk/src/protocol/srs_protocol_format.hpp +++ b/trunk/src/protocol/srs_protocol_format.hpp @@ -10,9 +10,10 @@ #include #include +#include class SrsOnMetaDataPacket; -class SrsSharedPtrMessage; +class SrsMediaPacket; /** * Create special structure from RTMP stream, for example, the metadata. @@ -27,10 +28,10 @@ public: // Initialize the format from metadata, optional. virtual srs_error_t on_metadata(SrsOnMetaDataPacket *meta); // When got a parsed audio packet. - virtual srs_error_t on_audio(SrsSharedPtrMessage *shared_audio); + virtual srs_error_t on_audio(SrsMediaPacket *shared_audio); virtual srs_error_t on_audio(int64_t timestamp, char *data, int size); // When got a parsed video packet. - virtual srs_error_t on_video(SrsSharedPtrMessage *shared_video); + virtual srs_error_t on_video(SrsMediaPacket *shared_video); virtual srs_error_t on_video(int64_t timestamp, char *data, int size); }; diff --git a/trunk/src/protocol/srs_protocol_raw_avc.cpp b/trunk/src/protocol/srs_protocol_raw_avc.cpp index da2426a3e..f22ca09e7 100644 --- a/trunk/src/protocol/srs_protocol_raw_avc.cpp +++ b/trunk/src/protocol/srs_protocol_raw_avc.cpp @@ -14,6 +14,7 @@ using namespace std; #include #include #include +#include #include bool srs_aac_startswith_adts(SrsBuffer *stream) diff --git a/trunk/src/protocol/srs_protocol_rtmp_conn.cpp b/trunk/src/protocol/srs_protocol_rtmp_conn.cpp index 255e562e1..d51bcf083 100644 --- a/trunk/src/protocol/srs_protocol_rtmp_conn.cpp +++ b/trunk/src/protocol/srs_protocol_rtmp_conn.cpp @@ -206,17 +206,17 @@ srs_error_t SrsBasicRtmpClient::recv_message(SrsCommonMessage **pmsg) return client->recv_message(pmsg); } -srs_error_t SrsBasicRtmpClient::decode_message(SrsCommonMessage *msg, SrsPacket **ppacket) +srs_error_t SrsBasicRtmpClient::decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket) { return client->decode_message(msg, ppacket); } -srs_error_t SrsBasicRtmpClient::send_and_free_messages(SrsSharedPtrMessage **msgs, int nb_msgs) +srs_error_t SrsBasicRtmpClient::send_and_free_messages(SrsMediaPacket **msgs, int nb_msgs) { return client->send_and_free_messages(msgs, nb_msgs, stream_id); } -srs_error_t SrsBasicRtmpClient::send_and_free_message(SrsSharedPtrMessage *msg) +srs_error_t SrsBasicRtmpClient::send_and_free_message(SrsMediaPacket *msg) { return client->send_and_free_message(msg, stream_id); } diff --git a/trunk/src/protocol/srs_protocol_rtmp_conn.hpp b/trunk/src/protocol/srs_protocol_rtmp_conn.hpp index 981114a92..e0a1a67a7 100644 --- a/trunk/src/protocol/srs_protocol_rtmp_conn.hpp +++ b/trunk/src/protocol/srs_protocol_rtmp_conn.hpp @@ -15,8 +15,8 @@ class ISrsRequest; class SrsTcpClient; class SrsRtmpClient; class SrsCommonMessage; -class SrsSharedPtrMessage; -class SrsPacket; +class SrsMediaPacket; +class SrsRtmpCommand; class SrsNetworkKbps; class SrsWallClock; class SrsAmf0Object; @@ -75,9 +75,9 @@ public: public: virtual srs_error_t recv_message(SrsCommonMessage **pmsg); - virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsPacket **ppacket); - virtual srs_error_t send_and_free_messages(SrsSharedPtrMessage **msgs, int nb_msgs); - virtual srs_error_t send_and_free_message(SrsSharedPtrMessage *msg); + virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket); + virtual srs_error_t send_and_free_messages(SrsMediaPacket **msgs, int nb_msgs); + virtual srs_error_t send_and_free_message(SrsMediaPacket *msg); public: virtual void set_recv_timeout(srs_utime_t timeout); diff --git a/trunk/src/protocol/srs_protocol_rtmp_msg_array.cpp b/trunk/src/protocol/srs_protocol_rtmp_msg_array.cpp index cf1c33092..a504166b8 100644 --- a/trunk/src/protocol/srs_protocol_rtmp_msg_array.cpp +++ b/trunk/src/protocol/srs_protocol_rtmp_msg_array.cpp @@ -12,7 +12,7 @@ SrsMessageArray::SrsMessageArray(int max_msgs) { srs_assert(max_msgs > 0); - msgs = new SrsSharedPtrMessage *[max_msgs]; + msgs = new SrsMediaPacket *[max_msgs]; max = max_msgs; zero(max_msgs); @@ -30,7 +30,7 @@ void SrsMessageArray::free(int count) { // initialize for (int i = 0; i < count; i++) { - SrsSharedPtrMessage *msg = msgs[i]; + SrsMediaPacket *msg = msgs[i]; srs_freep(msg); msgs[i] = NULL; diff --git a/trunk/src/protocol/srs_protocol_rtmp_msg_array.hpp b/trunk/src/protocol/srs_protocol_rtmp_msg_array.hpp index 2e0b8a675..0476a617d 100644 --- a/trunk/src/protocol/srs_protocol_rtmp_msg_array.hpp +++ b/trunk/src/protocol/srs_protocol_rtmp_msg_array.hpp @@ -9,7 +9,7 @@ #include -class SrsSharedPtrMessage; +class SrsMediaPacket; // The class to auto free the shared ptr message array. // When need to get some messages, for instance, from Consumer queue, @@ -24,7 +24,7 @@ public: // When user already send all msgs, please set to NULL, // for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg), // where send(msg) will always send and free it. - SrsSharedPtrMessage **msgs; + SrsMediaPacket **msgs; int max; public: diff --git a/trunk/src/protocol/srs_protocol_rtmp_stack.cpp b/trunk/src/protocol/srs_protocol_rtmp_stack.cpp index 8626a73c7..06506c980 100644 --- a/trunk/src/protocol/srs_protocol_rtmp_stack.cpp +++ b/trunk/src/protocol/srs_protocol_rtmp_stack.cpp @@ -79,15 +79,15 @@ using namespace std; ***************************************************************************** ****************************************************************************/ -SrsPacket::SrsPacket() +SrsRtmpCommand::SrsRtmpCommand() { } -SrsPacket::~SrsPacket() +SrsRtmpCommand::~SrsRtmpCommand() { } -srs_error_t SrsPacket::to_msg(SrsCommonMessage *msg, int stream_id) +srs_error_t SrsRtmpCommand::to_msg(SrsCommonMessage *msg, int stream_id) { srs_error_t err = srs_success; @@ -108,7 +108,6 @@ srs_error_t SrsPacket::to_msg(SrsCommonMessage *msg, int stream_id) header.payload_length = size; header.message_type = get_message_type(); header.stream_id = stream_id; - header.prefer_cid = get_prefer_cid(); if ((err = msg->create(&header, payload, size)) != srs_success) { return srs_error_wrap(err, "create %dB message", size); @@ -117,7 +116,7 @@ srs_error_t SrsPacket::to_msg(SrsCommonMessage *msg, int stream_id) return err; } -srs_error_t SrsPacket::encode(int &psize, char *&ppayload) +srs_error_t SrsRtmpCommand::encode(int &psize, char *&ppayload) { srs_error_t err = srs_success; @@ -140,27 +139,22 @@ srs_error_t SrsPacket::encode(int &psize, char *&ppayload) return err; } -srs_error_t SrsPacket::decode(SrsBuffer *stream) +srs_error_t SrsRtmpCommand::decode(SrsBuffer *stream) { return srs_error_new(ERROR_SYSTEM_PACKET_INVALID, "decode"); } -int SrsPacket::get_prefer_cid() +int SrsRtmpCommand::get_message_type() { return 0; } -int SrsPacket::get_message_type() +int SrsRtmpCommand::get_size() { return 0; } -int SrsPacket::get_size() -{ - return 0; -} - -srs_error_t SrsPacket::encode_packet(SrsBuffer *stream) +srs_error_t SrsRtmpCommand::encode_packet(SrsBuffer *stream) { return srs_error_new(ERROR_SYSTEM_PACKET_INVALID, "encode"); } @@ -196,10 +190,6 @@ SrsProtocol::SrsProtocol(ISrsProtocolReadWriter *io) } for (int cid = 0; cid < SRS_PERF_CHUNK_STREAM_CACHE; cid++) { SrsChunkStream *cs = new SrsChunkStream(cid); - // set the prefer cid of chunk, - // which will copy to the message received. - cs->header.prefer_cid = cid; - cs_cache[cid] = cs; } @@ -220,9 +210,9 @@ SrsProtocol::~SrsProtocol() } if (true) { - std::vector::iterator it; + std::vector::iterator it; for (it = manual_response_queue.begin(); it != manual_response_queue.end(); ++it) { - SrsPacket *pkt = *it; + SrsRtmpCommand *pkt = *it; srs_freep(pkt); } manual_response_queue.clear(); @@ -259,9 +249,9 @@ srs_error_t SrsProtocol::manual_response_flush() return err; } - std::vector::iterator it; + std::vector::iterator it; for (it = manual_response_queue.begin(); it != manual_response_queue.end();) { - SrsPacket *pkt = *it; + SrsRtmpCommand *pkt = *it; // erase this packet, the send api always free it. it = manual_response_queue.erase(it); @@ -361,7 +351,7 @@ srs_error_t SrsProtocol::recv_message(SrsCommonMessage **pmsg) return err; } -srs_error_t SrsProtocol::decode_message(SrsCommonMessage *msg, SrsPacket **ppacket) +srs_error_t SrsProtocol::decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket) { *ppacket = NULL; @@ -374,7 +364,7 @@ srs_error_t SrsProtocol::decode_message(SrsCommonMessage *msg, SrsPacket **ppack SrsBuffer stream(msg->payload(), msg->size()); // decode the packet. - SrsPacket *packet = NULL; + SrsRtmpCommand *packet = NULL; if ((err = do_decode_message(msg->header, &stream, &packet)) != srs_success) { srs_freep(packet); return srs_error_wrap(err, "decode message"); @@ -386,7 +376,7 @@ srs_error_t SrsProtocol::decode_message(SrsCommonMessage *msg, SrsPacket **ppack return err; } -srs_error_t SrsProtocol::do_send_messages(SrsSharedPtrMessage **msgs, int nb_msgs) +srs_error_t SrsProtocol::do_send_messages(SrsMediaPacket **msgs, int nb_msgs) { srs_error_t err = srs_success; @@ -400,7 +390,7 @@ srs_error_t SrsProtocol::do_send_messages(SrsSharedPtrMessage **msgs, int nb_msg // try to send use the c0c3 header cache, // if cache is consumed, try another loop. for (int i = 0; i < nb_msgs; i++) { - SrsSharedPtrMessage *msg = msgs[i]; + SrsMediaPacket *msg = msgs[i]; if (!msg) { continue; @@ -420,7 +410,7 @@ srs_error_t SrsProtocol::do_send_messages(SrsSharedPtrMessage **msgs, int nb_msg while (p < pend) { // always has header int nb_cache = SRS_CONSTS_C0C3_HEADERS_MAX - c0c3_cache_index; - int nbh = msg->chunk_header(c0c3_cache, nb_cache, p == msg->payload()); + int nbh = srs_rtmp_write_chunk_header(msg, c0c3_cache, nb_cache, p == msg->payload()); srs_assert(nbh > 0); // header iov @@ -498,7 +488,7 @@ srs_error_t SrsProtocol::do_send_messages(SrsSharedPtrMessage **msgs, int nb_msg // try to send use the c0c3 header cache, // if cache is consumed, try another loop. for (int i = 0; i < nb_msgs; i++) { - SrsSharedPtrMessage *msg = msgs[i]; + SrsMediaPacket *msg = msgs[i]; if (!msg) { continue; @@ -522,7 +512,7 @@ srs_error_t SrsProtocol::do_send_messages(SrsSharedPtrMessage **msgs, int nb_msg int nb_cache = SRS_CONSTS_C0C3_HEADERS_MAX; // always has header - int nbh = msg->chunk_header(c0c3_cache, nb_cache, p == msg->payload); + int nbh = srs_rtmp_write_chunk_header(msg, c0c3_cache, nb_cache, p == msg->payload); srs_assert(nbh > 0); // header iov @@ -552,23 +542,20 @@ srs_error_t SrsProtocol::do_iovs_send(iovec *iovs, int size) return srs_write_large_iovs(skt, iovs, size); } -srs_error_t SrsProtocol::do_send_and_free_packet(SrsPacket *packet_raw, int stream_id) +srs_error_t SrsProtocol::do_send_and_free_packet(SrsRtmpCommand *packet_raw, int stream_id) { srs_error_t err = srs_success; srs_assert(packet_raw); - SrsUniquePtr packet(packet_raw); + SrsUniquePtr packet(packet_raw); SrsUniquePtr msg(new SrsCommonMessage()); if ((err = packet->to_msg(msg.get(), stream_id)) != srs_success) { return srs_error_wrap(err, "to message"); } - SrsSharedPtrMessage *shared_msg = new SrsSharedPtrMessage(); - if ((err = shared_msg->create(msg.get())) != srs_success) { - srs_freep(shared_msg); - return srs_error_wrap(err, "create message"); - } + SrsMediaPacket *shared_msg = new SrsMediaPacket(); + msg->to_msg(shared_msg); if ((err = send_and_free_message(shared_msg, stream_id)) != srs_success) { return srs_error_wrap(err, "send packet"); @@ -581,11 +568,11 @@ srs_error_t SrsProtocol::do_send_and_free_packet(SrsPacket *packet_raw, int stre return err; } -srs_error_t SrsProtocol::do_decode_message(SrsMessageHeader &header, SrsBuffer *stream, SrsPacket **ppacket) +srs_error_t SrsProtocol::do_decode_message(SrsMessageHeader &header, SrsBuffer *stream, SrsRtmpCommand **ppacket) { srs_error_t err = srs_success; - SrsPacket *packet = NULL; + SrsRtmpCommand *packet = NULL; // decode specified packet type if (header.is_amf0_command() || header.is_amf3_command() || header.is_amf0_data() || header.is_amf3_data()) { @@ -692,7 +679,7 @@ srs_error_t SrsProtocol::do_decode_message(SrsMessageHeader &header, SrsBuffer * } // default packet to drop message. - *ppacket = packet = new SrsPacket(); + *ppacket = packet = new SrsRtmpCommand(); return err; } else if (header.is_user_control_message()) { *ppacket = packet = new SrsUserControlPacket(); @@ -715,12 +702,12 @@ srs_error_t SrsProtocol::do_decode_message(SrsMessageHeader &header, SrsBuffer * return err; } -srs_error_t SrsProtocol::send_and_free_message(SrsSharedPtrMessage *msg, int stream_id) +srs_error_t SrsProtocol::send_and_free_message(SrsMediaPacket *msg, int stream_id) { return send_and_free_messages(&msg, 1, stream_id); } -srs_error_t SrsProtocol::send_and_free_messages(SrsSharedPtrMessage **msgs, int nb_msgs, int stream_id) +srs_error_t SrsProtocol::send_and_free_messages(SrsMediaPacket **msgs, int nb_msgs, int stream_id) { // always not NULL msg. srs_assert(msgs); @@ -728,7 +715,7 @@ srs_error_t SrsProtocol::send_and_free_messages(SrsSharedPtrMessage **msgs, int // update the stream id in header. for (int i = 0; i < nb_msgs; i++) { - SrsSharedPtrMessage *msg = msgs[i]; + SrsMediaPacket *msg = msgs[i]; if (!msg) { continue; @@ -746,7 +733,7 @@ srs_error_t SrsProtocol::send_and_free_messages(SrsSharedPtrMessage **msgs, int srs_error_t err = do_send_messages(msgs, nb_msgs); for (int i = 0; i < nb_msgs; i++) { - SrsSharedPtrMessage *msg = msgs[i]; + SrsMediaPacket *msg = msgs[i]; srs_freep(msg); } @@ -765,7 +752,7 @@ srs_error_t SrsProtocol::send_and_free_messages(SrsSharedPtrMessage **msgs, int return err; } -srs_error_t SrsProtocol::send_and_free_packet(SrsPacket *packet, int stream_id) +srs_error_t SrsProtocol::send_and_free_packet(SrsRtmpCommand *packet, int stream_id) { srs_error_t err = srs_success; @@ -806,9 +793,6 @@ srs_error_t SrsProtocol::recv_interlaced_message(SrsCommonMessage **pmsg) // chunk stream cache miss, use map. if (chunk_streams.find(cid) == chunk_streams.end()) { chunk = chunk_streams[cid] = new SrsChunkStream(cid); - // set the prefer cid of chunk, - // which will copy to the message received. - chunk->header.prefer_cid = cid; } else { chunk = chunk_streams[cid]; } @@ -1250,7 +1234,7 @@ srs_error_t SrsProtocol::on_recv_message(SrsCommonMessage *msg) return srs_error_wrap(err, "response ack"); } - SrsPacket *packet_raw = NULL; + SrsRtmpCommand *packet_raw = NULL; switch (msg->header.message_type) { case RTMP_MSG_SetChunkSize: case RTMP_MSG_UserControlMessage: @@ -1268,7 +1252,7 @@ srs_error_t SrsProtocol::on_recv_message(SrsCommonMessage *msg) // always free the packet. srs_assert(packet_raw); - SrsUniquePtr packet(packet_raw); + SrsUniquePtr packet(packet_raw); switch (msg->header.message_type) { case RTMP_MSG_WindowAcknowledgementSize: { @@ -1324,7 +1308,7 @@ srs_error_t SrsProtocol::on_recv_message(SrsCommonMessage *msg) return err; } -srs_error_t SrsProtocol::on_send_packet(SrsMessageHeader *mh, SrsPacket *packet) +srs_error_t SrsProtocol::on_send_packet(SrsMessageHeader *mh, SrsRtmpCommand *packet) { srs_error_t err = srs_success; @@ -1831,22 +1815,22 @@ srs_error_t SrsRtmpClient::recv_message(SrsCommonMessage **pmsg) return protocol->recv_message(pmsg); } -srs_error_t SrsRtmpClient::decode_message(SrsCommonMessage *msg, SrsPacket **ppacket) +srs_error_t SrsRtmpClient::decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket) { return protocol->decode_message(msg, ppacket); } -srs_error_t SrsRtmpClient::send_and_free_message(SrsSharedPtrMessage *msg, int stream_id) +srs_error_t SrsRtmpClient::send_and_free_message(SrsMediaPacket *msg, int stream_id) { return protocol->send_and_free_message(msg, stream_id); } -srs_error_t SrsRtmpClient::send_and_free_messages(SrsSharedPtrMessage **msgs, int nb_msgs, int stream_id) +srs_error_t SrsRtmpClient::send_and_free_messages(SrsMediaPacket **msgs, int nb_msgs, int stream_id) { return protocol->send_and_free_messages(msgs, nb_msgs, stream_id); } -srs_error_t SrsRtmpClient::send_and_free_packet(SrsPacket *packet, int stream_id) +srs_error_t SrsRtmpClient::send_and_free_packet(SrsRtmpCommand *packet, int stream_id) { return protocol->send_and_free_packet(packet, stream_id); } @@ -2232,22 +2216,22 @@ srs_error_t SrsRtmpServer::recv_message(SrsCommonMessage **pmsg) return protocol->recv_message(pmsg); } -srs_error_t SrsRtmpServer::decode_message(SrsCommonMessage *msg, SrsPacket **ppacket) +srs_error_t SrsRtmpServer::decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket) { return protocol->decode_message(msg, ppacket); } -srs_error_t SrsRtmpServer::send_and_free_message(SrsSharedPtrMessage *msg, int stream_id) +srs_error_t SrsRtmpServer::send_and_free_message(SrsMediaPacket *msg, int stream_id) { return protocol->send_and_free_message(msg, stream_id); } -srs_error_t SrsRtmpServer::send_and_free_messages(SrsSharedPtrMessage **msgs, int nb_msgs, int stream_id) +srs_error_t SrsRtmpServer::send_and_free_messages(SrsMediaPacket **msgs, int nb_msgs, int stream_id) { return protocol->send_and_free_messages(msgs, nb_msgs, stream_id); } -srs_error_t SrsRtmpServer::send_and_free_packet(SrsPacket *packet, int stream_id) +srs_error_t SrsRtmpServer::send_and_free_packet(SrsRtmpCommand *packet, int stream_id) { return protocol->send_and_free_packet(packet, stream_id); } @@ -2496,11 +2480,11 @@ srs_error_t SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType &type, continue; } - SrsPacket *pkt_raw = NULL; + SrsRtmpCommand *pkt_raw = NULL; if ((err = protocol->decode_message(msg.get(), &pkt_raw)) != srs_success) { return srs_error_wrap(err, "decode identify"); } - SrsUniquePtr pkt(pkt_raw); + SrsUniquePtr pkt(pkt_raw); if (dynamic_cast(pkt.get())) { return identify_create_stream_client(dynamic_cast(pkt.get()), stream_id, 3, type, stream_name, duration); @@ -2598,7 +2582,7 @@ srs_error_t SrsRtmpServer::start_play(int stream_id) // |RtmpSampleAccess(false, false) if (true) { - SrsSampleAccessPacket *pkt = new SrsSampleAccessPacket(); + SrsNaluSampleAccessPacket *pkt = new SrsNaluSampleAccessPacket(); // allow audio/video sample. // @see: https://github.com/ossrs/srs/issues/49 @@ -2887,11 +2871,11 @@ srs_error_t SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket * continue; } - SrsPacket *pkt_raw = NULL; + SrsRtmpCommand *pkt_raw = NULL; if ((err = protocol->decode_message(msg.get(), &pkt_raw)) != srs_success) { return srs_error_wrap(err, "decode identify"); } - SrsUniquePtr pkt(pkt_raw); + SrsUniquePtr pkt(pkt_raw); if (dynamic_cast(pkt.get())) { return identify_play_client(dynamic_cast(pkt.get()), type, stream_name, duration); @@ -3033,11 +3017,6 @@ srs_error_t SrsConnectAppPacket::decode(SrsBuffer *stream) return err; } -int SrsConnectAppPacket::get_prefer_cid() -{ - return RTMP_CID_OverConnection; -} - int SrsConnectAppPacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -3139,11 +3118,6 @@ srs_error_t SrsConnectAppResPacket::decode(SrsBuffer *stream) return err; } -int SrsConnectAppResPacket::get_prefer_cid() -{ - return RTMP_CID_OverConnection; -} - int SrsConnectAppResPacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -3227,11 +3201,6 @@ srs_error_t SrsCallPacket::decode(SrsBuffer *stream) return err; } -int SrsCallPacket::get_prefer_cid() -{ - return RTMP_CID_OverConnection; -} - int SrsCallPacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -3291,11 +3260,6 @@ SrsCallResPacket::~SrsCallResPacket() srs_freep(response); } -int SrsCallResPacket::get_prefer_cid() -{ - return RTMP_CID_OverConnection; -} - int SrsCallResPacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -3381,11 +3345,6 @@ srs_error_t SrsCreateStreamPacket::decode(SrsBuffer *stream) return err; } -int SrsCreateStreamPacket::get_prefer_cid() -{ - return RTMP_CID_OverConnection; -} - int SrsCreateStreamPacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -3454,11 +3413,6 @@ srs_error_t SrsCreateStreamResPacket::decode(SrsBuffer *stream) return err; } -int SrsCreateStreamResPacket::get_prefer_cid() -{ - return RTMP_CID_OverConnection; -} - int SrsCreateStreamResPacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -3569,11 +3523,6 @@ srs_error_t SrsFMLEStartPacket::decode(SrsBuffer *stream) return err; } -int SrsFMLEStartPacket::get_prefer_cid() -{ - return RTMP_CID_OverConnection; -} - int SrsFMLEStartPacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -3681,11 +3630,6 @@ srs_error_t SrsFMLEStartResPacket::decode(SrsBuffer *stream) return err; } -int SrsFMLEStartResPacket::get_prefer_cid() -{ - return RTMP_CID_OverConnection; -} - int SrsFMLEStartResPacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -3768,11 +3712,6 @@ srs_error_t SrsPublishPacket::decode(SrsBuffer *stream) return err; } -int SrsPublishPacket::get_prefer_cid() -{ - return RTMP_CID_OverStream; -} - int SrsPublishPacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -3927,11 +3866,6 @@ srs_error_t SrsPlayPacket::decode(SrsBuffer *stream) return err; } -int SrsPlayPacket::get_prefer_cid() -{ - return RTMP_CID_OverStream; -} - int SrsPlayPacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -4017,11 +3951,6 @@ void SrsPlayResPacket::set_desc(SrsAmf0Object *v) desc = v; } -int SrsPlayResPacket::get_prefer_cid() -{ - return RTMP_CID_OverStream; -} - int SrsPlayResPacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -4073,11 +4002,6 @@ void SrsOnBWDonePacket::set_args(SrsAmf0Any *v) args = v; } -int SrsOnBWDonePacket::get_prefer_cid() -{ - return RTMP_CID_OverConnection; -} - int SrsOnBWDonePacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -4133,11 +4057,6 @@ void SrsOnStatusCallPacket::set_data(SrsAmf0Object *v) data = v; } -int SrsOnStatusCallPacket::get_prefer_cid() -{ - return RTMP_CID_OverStream; -} - int SrsOnStatusCallPacket::get_message_type() { return RTMP_MSG_AMF0CommandMessage; @@ -4188,11 +4107,6 @@ void SrsOnStatusDataPacket::set_data(SrsAmf0Object *v) data = v; } -int SrsOnStatusDataPacket::get_prefer_cid() -{ - return RTMP_CID_OverStream; -} - int SrsOnStatusDataPacket::get_message_type() { return RTMP_MSG_AMF0DataMessage; @@ -4218,33 +4132,28 @@ srs_error_t SrsOnStatusDataPacket::encode_packet(SrsBuffer *stream) return err; } -SrsSampleAccessPacket::SrsSampleAccessPacket() +SrsNaluSampleAccessPacket::SrsNaluSampleAccessPacket() { command_name = RTMP_AMF0_DATA_SAMPLE_ACCESS; video_sample_access = false; audio_sample_access = false; } -SrsSampleAccessPacket::~SrsSampleAccessPacket() +SrsNaluSampleAccessPacket::~SrsNaluSampleAccessPacket() { } -int SrsSampleAccessPacket::get_prefer_cid() -{ - return RTMP_CID_OverStream; -} - -int SrsSampleAccessPacket::get_message_type() +int SrsNaluSampleAccessPacket::get_message_type() { return RTMP_MSG_AMF0DataMessage; } -int SrsSampleAccessPacket::get_size() +int SrsNaluSampleAccessPacket::get_size() { return SrsAmf0Size::str(command_name) + SrsAmf0Size::boolean() + SrsAmf0Size::boolean(); } -srs_error_t SrsSampleAccessPacket::encode_packet(SrsBuffer *stream) +srs_error_t SrsNaluSampleAccessPacket::encode_packet(SrsBuffer *stream) { srs_error_t err = srs_success; @@ -4326,11 +4235,6 @@ srs_error_t SrsOnMetaDataPacket::decode(SrsBuffer *stream) return err; } -int SrsOnMetaDataPacket::get_prefer_cid() -{ - return RTMP_CID_OverConnection2; -} - int SrsOnMetaDataPacket::get_message_type() { return RTMP_MSG_AMF0DataMessage; @@ -4378,11 +4282,6 @@ srs_error_t SrsSetWindowAckSizePacket::decode(SrsBuffer *stream) return err; } -int SrsSetWindowAckSizePacket::get_prefer_cid() -{ - return RTMP_CID_ProtocolControl; -} - int SrsSetWindowAckSizePacket::get_message_type() { return RTMP_MSG_WindowAcknowledgementSize; @@ -4428,11 +4327,6 @@ srs_error_t SrsAcknowledgementPacket::decode(SrsBuffer *stream) return err; } -int SrsAcknowledgementPacket::get_prefer_cid() -{ - return RTMP_CID_ProtocolControl; -} - int SrsAcknowledgementPacket::get_message_type() { return RTMP_MSG_Acknowledgement; @@ -4478,11 +4372,6 @@ srs_error_t SrsSetChunkSizePacket::decode(SrsBuffer *stream) return err; } -int SrsSetChunkSizePacket::get_prefer_cid() -{ - return RTMP_CID_ProtocolControl; -} - int SrsSetChunkSizePacket::get_message_type() { return RTMP_MSG_SetChunkSize; @@ -4516,11 +4405,6 @@ SrsSetPeerBandwidthPacket::~SrsSetPeerBandwidthPacket() { } -int SrsSetPeerBandwidthPacket::get_prefer_cid() -{ - return RTMP_CID_ProtocolControl; -} - int SrsSetPeerBandwidthPacket::get_message_type() { return RTMP_MSG_SetPeerBandwidth; @@ -4588,11 +4472,6 @@ srs_error_t SrsUserControlPacket::decode(SrsBuffer *stream) return err; } -int SrsUserControlPacket::get_prefer_cid() -{ - return RTMP_CID_ProtocolControl; -} - int SrsUserControlPacket::get_message_type() { return RTMP_MSG_UserControlMessage; diff --git a/trunk/src/protocol/srs_protocol_rtmp_stack.hpp b/trunk/src/protocol/srs_protocol_rtmp_stack.hpp index ea0306d8e..f53db5aa0 100644 --- a/trunk/src/protocol/srs_protocol_rtmp_stack.hpp +++ b/trunk/src/protocol/srs_protocol_rtmp_stack.hpp @@ -28,7 +28,7 @@ class SrsBuffer; class SrsAmf0Any; class SrsMessageHeader; class SrsChunkStream; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsProtocol; class ISrsProtocolReader; @@ -39,7 +39,7 @@ class SrsPublishPacket; class SrsOnMetaDataPacket; class SrsPlayPacket; class SrsCommonMessage; -class SrsPacket; +class SrsRtmpCommand; class SrsAmf0Object; class IMergeReadHandler; class SrsCallPacket; @@ -86,17 +86,17 @@ class SrsCallPacket; #define StatusCodeDataStart "NetStream.Data.Start" #define StatusCodeUnpublishSuccess "NetStream.Unpublish.Success" -// The decoded message payload. +// The message payload is decoded as RTMP packet. // @remark we seperate the packet from message, // for the packet focus on logic and domain data, // the message bind to the protocol and focus on protocol, such as header. // we can merge the message and packet, using OOAD hierachy, packet extends from message, // it's better for me to use components -- the message use the packet as payload. -class SrsPacket +class SrsRtmpCommand { public: - SrsPacket(); - virtual ~SrsPacket(); + SrsRtmpCommand(); + virtual ~SrsRtmpCommand(); public: // Covert packet to common message. @@ -115,11 +115,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - // The cid(chunk id) specifies the chunk to send data over. - // Generally, each message prefer some cid, for example, - // all protocol control messages prefer RTMP_CID_ProtocolControl, - // SrsSetWindowAckSizePacket is protocol control message. - virtual int get_prefer_cid(); // The subpacket must override to provide the right message type. // The message type set the RTMP message type in header. virtual int get_message_type(); @@ -182,7 +177,7 @@ private: // default to true for it's very easy to use the protocol stack. bool auto_response_when_recv; // When not auto response message, manual flush the messages in queue. - std::vector manual_response_queue; + std::vector manual_response_queue; // For peer out private: // Cache for multiple messages send, @@ -266,26 +261,26 @@ public: // @param ppacket, output decoded packet, // always NULL if error, never NULL if success. // @return error when unknown packet, error when decode failed. - virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsPacket **ppacket); + virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket); // Send the RTMP message and always free it. // user must never free or use the msg after this method, // For it will always free the msg. // @param msg, the msg to send out, never be NULL. // @param stream_id, the stream id of packet to send over, 0 for control message. - virtual srs_error_t send_and_free_message(SrsSharedPtrMessage *msg, int stream_id); + virtual srs_error_t send_and_free_message(SrsMediaPacket *msg, int stream_id); // Send the RTMP message and always free it. // user must never free or use the msg after this method, // For it will always free the msg. // @param msgs, the msgs to send out, never be NULL. // @param nb_msgs, the size of msgs to send out. // @param stream_id, the stream id of packet to send over, 0 for control message. - virtual srs_error_t send_and_free_messages(SrsSharedPtrMessage **msgs, int nb_msgs, int stream_id); + virtual srs_error_t send_and_free_messages(SrsMediaPacket **msgs, int nb_msgs, int stream_id); // Send the RTMP packet and always free it. // user must never free or use the packet after this method, // For it will always free the packet. // @param packet, the packet to send out, never be NULL. // @param stream_id, the stream id of packet to send over, 0 for control message. - virtual srs_error_t send_and_free_packet(SrsPacket *packet, int stream_id); + virtual srs_error_t send_and_free_packet(SrsRtmpCommand *packet, int stream_id); public: // Expect a specified message, drop others util got specified one. @@ -317,7 +312,7 @@ public: return srs_error_wrap(err, "recv message"); } - SrsPacket *packet = NULL; + SrsRtmpCommand *packet = NULL; if ((err = decode_message(msg, &packet)) != srs_success) { srs_freep(msg); srs_freep(packet); @@ -342,13 +337,13 @@ public: private: // Send out the messages, donot free it, // The caller must free the param msgs. - virtual srs_error_t do_send_messages(SrsSharedPtrMessage **msgs, int nb_msgs); + virtual srs_error_t do_send_messages(SrsMediaPacket **msgs, int nb_msgs); // Send iovs. send multiple times if exceed limits. virtual srs_error_t do_iovs_send(iovec *iovs, int size); // The underlayer api for send and free packet. - virtual srs_error_t do_send_and_free_packet(SrsPacket *packet, int stream_id); + virtual srs_error_t do_send_and_free_packet(SrsRtmpCommand *packet, int stream_id); // The imp for decode_message - virtual srs_error_t do_decode_message(SrsMessageHeader &header, SrsBuffer *stream, SrsPacket **ppacket); + virtual srs_error_t do_decode_message(SrsMessageHeader &header, SrsBuffer *stream, SrsRtmpCommand **ppacket); // Recv bytes oriented RTMP message from protocol stack. // return error if error occur and nerver set the pmsg, // return success and pmsg set to NULL if no entire message got, @@ -366,7 +361,7 @@ private: // When recv message, update the context. virtual srs_error_t on_recv_message(SrsCommonMessage *msg); // When message sentout, update the context. - virtual srs_error_t on_send_packet(SrsMessageHeader *mh, SrsPacket *packet); + virtual srs_error_t on_send_packet(SrsMessageHeader *mh, SrsRtmpCommand *packet); private: // Auto response the ack message. @@ -604,10 +599,10 @@ public: virtual int64_t get_recv_bytes(); virtual int64_t get_send_bytes(); virtual srs_error_t recv_message(SrsCommonMessage **pmsg); - virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsPacket **ppacket); - virtual srs_error_t send_and_free_message(SrsSharedPtrMessage *msg, int stream_id); - virtual srs_error_t send_and_free_messages(SrsSharedPtrMessage **msgs, int nb_msgs, int stream_id); - virtual srs_error_t send_and_free_packet(SrsPacket *packet, int stream_id); + virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket); + virtual srs_error_t send_and_free_message(SrsMediaPacket *msg, int stream_id); + virtual srs_error_t send_and_free_messages(SrsMediaPacket **msgs, int nb_msgs, int stream_id); + virtual srs_error_t send_and_free_packet(SrsRtmpCommand *packet, int stream_id); public: // handshake with server, try complex, then simple handshake. @@ -717,13 +712,13 @@ public: // @param ppacket, output decoded packet, // always NULL if error, never NULL if success. // @return error when unknown packet, error when decode failed. - virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsPacket **ppacket); + virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsRtmpCommand **ppacket); // Send the RTMP message and always free it. // user must never free or use the msg after this method, // For it will always free the msg. // @param msg, the msg to send out, never be NULL. // @param stream_id, the stream id of packet to send over, 0 for control message. - virtual srs_error_t send_and_free_message(SrsSharedPtrMessage *msg, int stream_id); + virtual srs_error_t send_and_free_message(SrsMediaPacket *msg, int stream_id); // Send the RTMP message and always free it. // user must never free or use the msg after this method, // For it will always free the msg. @@ -732,13 +727,13 @@ public: // @param stream_id, the stream id of packet to send over, 0 for control message. // // @remark performance issue, to support 6k+ 250kbps client, - virtual srs_error_t send_and_free_messages(SrsSharedPtrMessage **msgs, int nb_msgs, int stream_id); + virtual srs_error_t send_and_free_messages(SrsMediaPacket **msgs, int nb_msgs, int stream_id); // Send the RTMP packet and always free it. // user must never free or use the packet after this method, // For it will always free the packet. // @param packet, the packet to send out, never be NULL. // @param stream_id, the stream id of packet to send over, 0 for control message. - virtual srs_error_t send_and_free_packet(SrsPacket *packet, int stream_id); + virtual srs_error_t send_and_free_packet(SrsRtmpCommand *packet, int stream_id); public: // Do handshake with client, try complex then simple. @@ -842,7 +837,7 @@ private: // 4.1.1. connect // The client sends the connect command to the server to request // connection to a server application instance. -class SrsConnectAppPacket : public SrsPacket +class SrsConnectAppPacket : public SrsRtmpCommand { public: // Name of the command. Set to "connect". @@ -866,7 +861,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -874,7 +868,7 @@ protected: virtual srs_error_t encode_packet(SrsBuffer *stream); }; // Response for SrsConnectAppPacket. -class SrsConnectAppResPacket : public SrsPacket +class SrsConnectAppResPacket : public SrsRtmpCommand { public: // The _result or _error; indicates whether the response is result or error. @@ -897,7 +891,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -909,7 +902,7 @@ protected: // The call method of the NetConnection object runs remote procedure // calls (RPC) at the receiving end. The called RPC name is passed as a // parameter to the call command. -class SrsCallPacket : public SrsPacket +class SrsCallPacket : public SrsRtmpCommand { public: // Name of the remote procedure that is called. @@ -932,7 +925,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -940,7 +932,7 @@ protected: virtual srs_error_t encode_packet(SrsBuffer *stream); }; // Response for SrsCallPacket. -class SrsCallResPacket : public SrsPacket +class SrsCallResPacket : public SrsRtmpCommand { public: // Name of the command. @@ -959,7 +951,6 @@ public: virtual ~SrsCallResPacket(); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -972,7 +963,7 @@ protected: // channel for message communication The publishing of audio, video, and // metadata is carried out over stream channel created using the // createStream command. -class SrsCreateStreamPacket : public SrsPacket +class SrsCreateStreamPacket : public SrsRtmpCommand { public: // Name of the command. Set to "createStream". @@ -993,7 +984,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1001,7 +991,7 @@ protected: virtual srs_error_t encode_packet(SrsBuffer *stream); }; // Response for SrsCreateStreamPacket. -class SrsCreateStreamResPacket : public SrsPacket +class SrsCreateStreamResPacket : public SrsRtmpCommand { public: // The _result or _error; indicates whether the response is result or error. @@ -1022,7 +1012,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1031,7 +1020,7 @@ protected: }; // client close stream packet. -class SrsCloseStreamPacket : public SrsPacket +class SrsCloseStreamPacket : public SrsRtmpCommand { public: // Name of the command, set to "closeStream". @@ -1050,7 +1039,7 @@ public: }; // FMLE start publish: ReleaseStream/PublishStream/FCPublish/FCUnpublish -class SrsFMLEStartPacket : public SrsPacket +class SrsFMLEStartPacket : public SrsRtmpCommand { public: // Name of the command @@ -1074,7 +1063,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1086,7 +1074,7 @@ public: static SrsFMLEStartPacket *create_FC_publish(std::string stream); }; // Response for SrsFMLEStartPacket. -class SrsFMLEStartResPacket : public SrsPacket +class SrsFMLEStartResPacket : public SrsRtmpCommand { public: // Name of the command @@ -1111,7 +1099,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1124,7 +1111,7 @@ protected: // The client sends the publish command to publish a named stream to the // server. Using this name, any client can play this stream and receive // The published audio, video, and data messages. -class SrsPublishPacket : public SrsPacket +class SrsPublishPacket : public SrsRtmpCommand { public: // Name of the command, set to "publish". @@ -1159,7 +1146,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1170,7 +1156,7 @@ protected: // 4.2.8. pause // The client sends the pause command to tell the server to pause or // start playing. -class SrsPausePacket : public SrsPacket +class SrsPausePacket : public SrsRtmpCommand { public: // Name of the command, set to "pause". @@ -1198,7 +1184,7 @@ public: // 4.2.1. play // The client sends this command to the server to play a stream. -class SrsPlayPacket : public SrsPacket +class SrsPlayPacket : public SrsRtmpCommand { public: // Name of the command. Set to "play". @@ -1253,7 +1239,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1263,7 +1248,7 @@ protected: // Response for SrsPlayPacket. // @remark, user must set the stream_id in header. -class SrsPlayResPacket : public SrsPacket +class SrsPlayResPacket : public SrsRtmpCommand { public: // Name of the command. If the play command is successful, the command @@ -1289,7 +1274,6 @@ public: void set_desc(SrsAmf0Object *v); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1298,7 +1282,7 @@ protected: }; // When bandwidth test done, notice client. -class SrsOnBWDonePacket : public SrsPacket +class SrsOnBWDonePacket : public SrsRtmpCommand { public: // Name of command. Set to "onBWDone" @@ -1316,7 +1300,6 @@ public: void set_args(SrsAmf0Any *v); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1326,7 +1309,7 @@ protected: // onStatus command, AMF0 Call // @remark, user must set the stream_id by SrsCommonMessage.set_packet(). -class SrsOnStatusCallPacket : public SrsPacket +class SrsOnStatusCallPacket : public SrsRtmpCommand { public: // Name of command. Set to "onStatus" @@ -1350,7 +1333,6 @@ public: void set_data(SrsAmf0Object *v); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1360,7 +1342,7 @@ protected: // onStatus data, AMF0 Data // @remark, user must set the stream_id by SrsCommonMessage.set_packet(). -class SrsOnStatusDataPacket : public SrsPacket +class SrsOnStatusDataPacket : public SrsRtmpCommand { public: // Name of command. Set to "onStatus" @@ -1379,7 +1361,6 @@ public: SrsAmf0Object *get_data(); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1389,7 +1370,7 @@ protected: // AMF0Data RtmpSampleAccess // @remark, user must set the stream_id by SrsCommonMessage.set_packet(). -class SrsSampleAccessPacket : public SrsPacket +class SrsNaluSampleAccessPacket : public SrsRtmpCommand { public: // Name of command. Set to "|RtmpSampleAccess". @@ -1402,11 +1383,10 @@ public: bool audio_sample_access; public: - SrsSampleAccessPacket(); - virtual ~SrsSampleAccessPacket(); + SrsNaluSampleAccessPacket(); + virtual ~SrsNaluSampleAccessPacket(); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1417,7 +1397,7 @@ protected: // The stream metadata. // FMLE: @setDataFrame // others: onMetaData -class SrsOnMetaDataPacket : public SrsPacket +class SrsOnMetaDataPacket : public SrsRtmpCommand { public: // Name of metadata. Set to "onMetaData" @@ -1437,7 +1417,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1448,7 +1427,7 @@ protected: // 5.5. Window Acknowledgement Size (5) // The client or the server sends this message to inform the peer which // window size to use when sending acknowledgment. -class SrsSetWindowAckSizePacket : public SrsPacket +class SrsSetWindowAckSizePacket : public SrsRtmpCommand { public: int32_t ackowledgement_window_size; @@ -1461,7 +1440,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1472,7 +1450,7 @@ protected: // 5.3. Acknowledgement (3) // The client or the server sends the acknowledgment to the peer after // receiving bytes equal to the window size. -class SrsAcknowledgementPacket : public SrsPacket +class SrsAcknowledgementPacket : public SrsRtmpCommand { public: uint32_t sequence_number; @@ -1485,7 +1463,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1496,7 +1473,7 @@ protected: // 7.1. Set Chunk Size // Protocol control message 1, Set Chunk Size, is used to notify the // peer about the new maximum chunk size. -class SrsSetChunkSizePacket : public SrsPacket +class SrsSetChunkSizePacket : public SrsRtmpCommand { public: // The maximum chunk size can be 65536 bytes. The chunk size is @@ -1511,7 +1488,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1531,7 +1507,7 @@ enum SrsPeerBandwidthType { // 5.6. Set Peer Bandwidth (6) // The client or the server sends this message to update the output // bandwidth of the peer. -class SrsSetPeerBandwidthPacket : public SrsPacket +class SrsSetPeerBandwidthPacket : public SrsRtmpCommand { public: int32_t bandwidth; @@ -1543,7 +1519,6 @@ public: virtual ~SrsSetPeerBandwidthPacket(); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: @@ -1634,7 +1609,7 @@ enum SrcPCUCEventType { // | Event Type ( 2- bytes ) | Event Data // +------------------------------+------------------------- // Figure 5 Pay load for the 'User Control Message'. -class SrsUserControlPacket : public SrsPacket +class SrsUserControlPacket : public SrsRtmpCommand { public: // Event type is followed by Event data. @@ -1655,7 +1630,6 @@ public: virtual srs_error_t decode(SrsBuffer *stream); // Encode functions for concrete packet to override. public: - virtual int get_prefer_cid(); virtual int get_message_type(); protected: diff --git a/trunk/src/protocol/srs_protocol_rtp.cpp b/trunk/src/protocol/srs_protocol_rtp.cpp index a6390d12b..5d82c7491 100644 --- a/trunk/src/protocol/srs_protocol_rtp.cpp +++ b/trunk/src/protocol/srs_protocol_rtp.cpp @@ -36,7 +36,7 @@ srs_error_t SrsRtpVideoBuilder::initialize(SrsFormat *format, uint32_t ssrc, uin return srs_success; } -srs_error_t SrsRtpVideoBuilder::package_stap_a(SrsSharedPtrMessage *msg, SrsRtpPacket *pkt) +srs_error_t SrsRtpVideoBuilder::package_stap_a(SrsMediaPacket *msg, SrsRtpPacket *pkt) { srs_error_t err = srs_success; @@ -86,7 +86,7 @@ srs_error_t SrsRtpVideoBuilder::package_stap_a(SrsSharedPtrMessage *msg, SrsRtpP for (vector *>::iterator it = params.begin(); it != params.end(); ++it) { vector *param = *it; - SrsSample *sample = new SrsSample(); + SrsNaluSample *sample = new SrsNaluSample(); sample->bytes = payload; sample->size = param->size(); if (format->vcodec->id == SrsVideoCodecIdHEVC) { @@ -102,7 +102,7 @@ srs_error_t SrsRtpVideoBuilder::package_stap_a(SrsSharedPtrMessage *msg, SrsRtpP return err; } -srs_error_t SrsRtpVideoBuilder::package_nalus(SrsSharedPtrMessage *msg, const vector &samples, vector &pkts) +srs_error_t SrsRtpVideoBuilder::package_nalus(SrsMediaPacket *msg, const vector &samples, vector &pkts) { srs_error_t err = srs_success; @@ -116,7 +116,7 @@ srs_error_t SrsRtpVideoBuilder::package_nalus(SrsSharedPtrMessage *msg, const ve uint8_t first_nalu_type = 0; for (int i = 0; i < (int)samples.size(); i++) { - SrsSample *sample = samples[i]; + SrsNaluSample *sample = samples[i]; if (!sample->size) { continue; @@ -212,7 +212,7 @@ srs_error_t SrsRtpVideoBuilder::package_nalus(SrsSharedPtrMessage *msg, const ve } // Single NAL Unit Packet @see https://tools.ietf.org/html/rfc6184#section-5.6 -srs_error_t SrsRtpVideoBuilder::package_single_nalu(SrsSharedPtrMessage *msg, SrsSample *sample, vector &pkts) +srs_error_t SrsRtpVideoBuilder::package_single_nalu(SrsMediaPacket *msg, SrsNaluSample *sample, vector &pkts) { srs_error_t err = srs_success; @@ -236,7 +236,7 @@ srs_error_t SrsRtpVideoBuilder::package_single_nalu(SrsSharedPtrMessage *msg, Sr return err; } -srs_error_t SrsRtpVideoBuilder::package_fu_a(SrsSharedPtrMessage *msg, SrsSample *sample, int fu_payload_size, vector &pkts) +srs_error_t SrsRtpVideoBuilder::package_fu_a(SrsMediaPacket *msg, SrsNaluSample *sample, int fu_payload_size, vector &pkts) { srs_error_t err = srs_success; diff --git a/trunk/src/protocol/srs_protocol_rtp.hpp b/trunk/src/protocol/srs_protocol_rtp.hpp index ee6b81362..b3a6b4a39 100644 --- a/trunk/src/protocol/srs_protocol_rtp.hpp +++ b/trunk/src/protocol/srs_protocol_rtp.hpp @@ -16,8 +16,8 @@ #include #include -class SrsSharedPtrMessage; -class SrsSample; +class SrsMediaPacket; +class SrsNaluSample; class SrsRtpPacket; class SrsFormat; @@ -36,10 +36,10 @@ public: public: srs_error_t initialize(SrsFormat *format, uint32_t ssrc, uint8_t payload_type); - srs_error_t package_stap_a(SrsSharedPtrMessage *msg, SrsRtpPacket *pkt); - srs_error_t package_nalus(SrsSharedPtrMessage *msg, const std::vector &samples, std::vector &pkts); - srs_error_t package_single_nalu(SrsSharedPtrMessage *msg, SrsSample *sample, std::vector &pkts); - srs_error_t package_fu_a(SrsSharedPtrMessage *msg, SrsSample *sample, int fu_payload_size, std::vector &pkts); + srs_error_t package_stap_a(SrsMediaPacket *msg, SrsRtpPacket *pkt); + srs_error_t package_nalus(SrsMediaPacket *msg, const std::vector &samples, std::vector &pkts); + srs_error_t package_single_nalu(SrsMediaPacket *msg, SrsNaluSample *sample, std::vector &pkts); + srs_error_t package_fu_a(SrsMediaPacket *msg, SrsNaluSample *sample, int fu_payload_size, std::vector &pkts); }; #endif diff --git a/trunk/src/protocol/srs_protocol_rtsp_stack.hpp b/trunk/src/protocol/srs_protocol_rtsp_stack.hpp index cb84d95df..588b5d0f5 100644 --- a/trunk/src/protocol/srs_protocol_rtsp_stack.hpp +++ b/trunk/src/protocol/srs_protocol_rtsp_stack.hpp @@ -15,7 +15,7 @@ class SrsBuffer; class SrsSimpleStream; -class SrsAudioFrame; +class SrsParsedAudioPacket; class ISrsProtocolReadWriter; // From rtsp specification diff --git a/trunk/src/protocol/srs_protocol_utility.cpp b/trunk/src/protocol/srs_protocol_utility.cpp index 3932fc940..80d558b39 100644 --- a/trunk/src/protocol/srs_protocol_utility.cpp +++ b/trunk/src/protocol/srs_protocol_utility.cpp @@ -283,19 +283,18 @@ string srs_net_url_encode_rtmp_url(string server, int port, string host, string return url; } -template -srs_error_t srs_do_rtmp_create_msg(char type, uint32_t timestamp, char *data, int size, int stream_id, T **ppmsg) +srs_error_t srs_do_rtmp_create_msg(char type, uint32_t timestamp, char *data, int size, int stream_id, SrsCommonMessage **ppmsg) { srs_error_t err = srs_success; *ppmsg = NULL; - T *msg = NULL; + SrsCommonMessage *msg = NULL; if (type == SrsFrameTypeAudio) { SrsMessageHeader header; header.initialize_audio(size, timestamp, stream_id); - msg = new T(); + msg = new SrsCommonMessage(); if ((err = msg->create(&header, data, size)) != srs_success) { srs_freep(msg); return srs_error_wrap(err, "create message"); @@ -304,7 +303,7 @@ srs_error_t srs_do_rtmp_create_msg(char type, uint32_t timestamp, char *data, in SrsMessageHeader header; header.initialize_video(size, timestamp, stream_id); - msg = new T(); + msg = new SrsCommonMessage(); if ((err = msg->create(&header, data, size)) != srs_success) { srs_freep(msg); return srs_error_wrap(err, "create message"); @@ -313,7 +312,7 @@ srs_error_t srs_do_rtmp_create_msg(char type, uint32_t timestamp, char *data, in SrsMessageHeader header; header.initialize_amf0_script(size, stream_id); - msg = new T(); + msg = new SrsCommonMessage(); if ((err = msg->create(&header, data, size)) != srs_success) { srs_freep(msg); return srs_error_wrap(err, "create message"); @@ -327,19 +326,6 @@ srs_error_t srs_do_rtmp_create_msg(char type, uint32_t timestamp, char *data, in return err; } -srs_error_t srs_rtmp_create_msg(char type, uint32_t timestamp, char *data, int size, int stream_id, SrsSharedPtrMessage **ppmsg) -{ - srs_error_t err = srs_success; - - // only when failed, we must free the data. - if ((err = srs_do_rtmp_create_msg(type, timestamp, data, size, stream_id, ppmsg)) != srs_success) { - srs_freepa(data); - return srs_error_wrap(err, "create message"); - } - - return err; -} - srs_error_t srs_rtmp_create_msg(char type, uint32_t timestamp, char *data, int size, int stream_id, SrsCommonMessage **ppmsg) { srs_error_t err = srs_success; diff --git a/trunk/src/protocol/srs_protocol_utility.hpp b/trunk/src/protocol/srs_protocol_utility.hpp index 9100f875d..d7a6a53a5 100644 --- a/trunk/src/protocol/srs_protocol_utility.hpp +++ b/trunk/src/protocol/srs_protocol_utility.hpp @@ -32,7 +32,7 @@ class ISrsHttpMessage; class SrsMessageHeader; -class SrsSharedPtrMessage; +class SrsMediaPacket; class SrsCommonMessage; class ISrsProtocolReadWriter; class ISrsReader; @@ -101,7 +101,6 @@ extern std::string srs_net_url_encode_rtmp_url(std::string server, int port, std * @param data the packet bytes. user should never free it. * @param ppmsg output the shared ptr message. user should free it. */ -extern srs_error_t srs_rtmp_create_msg(char type, uint32_t timestamp, char *data, int size, int stream_id, SrsSharedPtrMessage **ppmsg); extern srs_error_t srs_rtmp_create_msg(char type, uint32_t timestamp, char *data, int size, int stream_id, SrsCommonMessage **ppmsg); // write large numbers of iovs. diff --git a/trunk/src/utest/srs_utest_fmp4.cpp b/trunk/src/utest/srs_utest_fmp4.cpp index d102cc205..8c25253cd 100644 --- a/trunk/src/utest/srs_utest_fmp4.cpp +++ b/trunk/src/utest/srs_utest_fmp4.cpp @@ -54,25 +54,25 @@ public: virtual ~MockSrsFormat() {} }; -class MockSrsSharedPtrMessage : public SrsSharedPtrMessage +class MockSrsMediaPacket : public SrsMediaPacket { public: - MockSrsSharedPtrMessage(bool is_video_msg, uint32_t ts) + MockSrsMediaPacket(bool is_video_msg, uint32_t ts) { timestamp = ts; // Create sample payload char *payload = new char[1024]; memset(payload, 0x00, 1024); - SrsSharedPtrMessage::wrap(payload, 1024); + SrsMediaPacket::wrap(payload, 1024); if (is_video_msg) { - message_type = RTMP_MSG_VideoMessage; + message_type = SrsFrameTypeVideo; } else { - message_type = RTMP_MSG_AudioMessage; + message_type = SrsFrameTypeAudio; } } - virtual ~MockSrsSharedPtrMessage() {} + virtual ~MockSrsMediaPacket() {} }; VOID TEST(Fmp4Test, SrsInitMp4Segment_VideoOnly) @@ -165,11 +165,11 @@ VOID TEST(Fmp4Test, SrsHlsM4sSegment_Basic) // Write video sample MockSrsFormat fmt; - MockSrsSharedPtrMessage video_msg(true, 1000); + MockSrsMediaPacket video_msg(true, 1000); HELPER_ASSERT_SUCCESS(segment.write(&video_msg, &fmt)); // Write audio sample - MockSrsSharedPtrMessage audio_msg(false, 2000); // Different timestamp + MockSrsMediaPacket audio_msg(false, 2000); // Different timestamp HELPER_ASSERT_SUCCESS(segment.write(&audio_msg, &fmt)); // Test duration - should be > 0 after writing samples with different timestamps @@ -199,10 +199,10 @@ VOID TEST(Fmp4Test, SrsHlsM4sSegment_WithEncryption) // Write samples with different timestamps to create duration MockSrsFormat fmt; - MockSrsSharedPtrMessage video_msg1(true, 1000); + MockSrsMediaPacket video_msg1(true, 1000); HELPER_ASSERT_SUCCESS(segment.write(&video_msg1, &fmt)); - MockSrsSharedPtrMessage video_msg2(true, 2000); + MockSrsMediaPacket video_msg2(true, 2000); HELPER_ASSERT_SUCCESS(segment.write(&video_msg2, &fmt)); // Test that segment has content @@ -330,19 +330,19 @@ VOID TEST(Fmp4Test, SrsHlsFmp4Muxer_WriteMedia) HELPER_ASSERT_SUCCESS(muxer.write_init_mp4(&fmt, true, true)); // Write video samples - MockSrsSharedPtrMessage video_msg(true, 1000); + MockSrsMediaPacket video_msg(true, 1000); HELPER_ASSERT_SUCCESS(muxer.write_video(&video_msg, &fmt)); // Write audio samples - MockSrsSharedPtrMessage audio_msg(false, 1000); + MockSrsMediaPacket audio_msg(false, 1000); HELPER_ASSERT_SUCCESS(muxer.write_audio(&audio_msg, &fmt)); // Write more samples with time progression to accumulate duration for (int i = 1; i <= 5; i++) { - MockSrsSharedPtrMessage video_msg2(true, 1000 + i * 1000); // 1 second increments + MockSrsMediaPacket video_msg2(true, 1000 + i * 1000); // 1 second increments HELPER_ASSERT_SUCCESS(muxer.write_video(&video_msg2, &fmt)); - MockSrsSharedPtrMessage audio_msg2(false, 1000 + i * 1000); + MockSrsMediaPacket audio_msg2(false, 1000 + i * 1000); HELPER_ASSERT_SUCCESS(muxer.write_audio(&audio_msg2, &fmt)); } @@ -385,17 +385,17 @@ VOID TEST(Fmp4Test, SrsHlsMp4Controller_PublishWorkflow) // Handle sequence headers MockSrsFormat fmt; - MockSrsSharedPtrMessage video_sh(true, 0); + MockSrsMediaPacket video_sh(true, 0); HELPER_ASSERT_SUCCESS(controller.on_sequence_header(&video_sh, &fmt)); - MockSrsSharedPtrMessage audio_sh(false, 0); + MockSrsMediaPacket audio_sh(false, 0); HELPER_ASSERT_SUCCESS(controller.on_sequence_header(&audio_sh, &fmt)); // Write media samples - MockSrsSharedPtrMessage video_msg(true, 1000); + MockSrsMediaPacket video_msg(true, 1000); HELPER_ASSERT_SUCCESS(controller.write_video(&video_msg, &fmt)); - MockSrsSharedPtrMessage audio_msg(false, 1000); + MockSrsMediaPacket audio_msg(false, 1000); HELPER_ASSERT_SUCCESS(controller.write_audio(&audio_msg, &fmt)); // Unpublish @@ -601,13 +601,13 @@ VOID TEST(Fmp4Test, Integration_FullEncryptionWorkflow) m4s_segment.config_cipher(seg_key, seg_iv); // Write samples to encrypted segment with time progression - MockSrsSharedPtrMessage video_msg1(true, 2000); + MockSrsMediaPacket video_msg1(true, 2000); HELPER_ASSERT_SUCCESS(m4s_segment.write(&video_msg1, &fmt)); - MockSrsSharedPtrMessage audio_msg1(false, 2500); + MockSrsMediaPacket audio_msg1(false, 2500); HELPER_ASSERT_SUCCESS(m4s_segment.write(&audio_msg1, &fmt)); - MockSrsSharedPtrMessage video_msg2(true, 3000); + MockSrsMediaPacket video_msg2(true, 3000); HELPER_ASSERT_SUCCESS(m4s_segment.write(&video_msg2, &fmt)); // Should have duration from timestamp progression @@ -720,11 +720,11 @@ VOID TEST(Fmp4Test, Configuration_TrackIdManagement) HELPER_ASSERT_SUCCESS(controller.on_publish(&req)); MockSrsFormat fmt; - MockSrsSharedPtrMessage video_sh(true, 0); + MockSrsMediaPacket video_sh(true, 0); HELPER_ASSERT_SUCCESS(controller.on_sequence_header(&video_sh, &fmt)); EXPECT_TRUE(controller.has_video_sh_); - MockSrsSharedPtrMessage audio_sh(false, 0); + MockSrsMediaPacket audio_sh(false, 0); HELPER_ASSERT_SUCCESS(controller.on_sequence_header(&audio_sh, &fmt)); EXPECT_TRUE(controller.has_audio_sh_); @@ -740,7 +740,7 @@ VOID TEST(Fmp4Test, Configuration_SequenceHeaderValidation) // Test sequence header without request (should fail) MockSrsFormat fmt; - MockSrsSharedPtrMessage video_sh(true, 0); + MockSrsMediaPacket video_sh(true, 0); HELPER_EXPECT_FAILED(controller.on_sequence_header(&video_sh, &fmt)); // Set request and try again @@ -765,14 +765,14 @@ VOID TEST(Fmp4Test, CodecDetection_AudioCodecUpdate) MockSrsFormat fmt; fmt.acodec = new SrsAudioCodecConfig(); fmt.acodec->id = SrsAudioCodecIdAAC; - fmt.audio = new SrsAudioFrame(); + fmt.audio = new SrsParsedAudioPacket(); fmt.audio->codec = fmt.acodec; // Initial codec should be forbidden (not set) EXPECT_EQ(SrsAudioCodecIdForbidden, controller.muxer_->latest_acodec()); // Write audio frame - should detect and update codec - MockSrsSharedPtrMessage audio_msg(false, 1000); + MockSrsMediaPacket audio_msg(false, 1000); HELPER_ASSERT_SUCCESS(controller.write_audio(&audio_msg, &fmt)); // Codec should now be detected as AAC @@ -804,14 +804,14 @@ VOID TEST(Fmp4Test, CodecDetection_VideoCodecUpdate) MockSrsFormat fmt; fmt.vcodec = new SrsVideoCodecConfig(); fmt.vcodec->id = SrsVideoCodecIdAVC; - fmt.video = new SrsVideoFrame(); + fmt.video = new SrsParsedVideoPacket(); fmt.video->codec = fmt.vcodec; // Initial codec should be forbidden (not set) EXPECT_EQ(SrsVideoCodecIdForbidden, controller.muxer_->latest_vcodec()); // Write video frame - should detect and update codec - MockSrsSharedPtrMessage video_msg(true, 1000); + MockSrsMediaPacket video_msg(true, 1000); HELPER_ASSERT_SUCCESS(controller.write_video(&video_msg, &fmt)); // Codec should now be detected as H.264 @@ -847,11 +847,11 @@ VOID TEST(Fmp4Test, Performance_MultipleSegments) // Write many samples to create multiple segments for (int i = 0; i < 500; i++) { - MockSrsSharedPtrMessage video_msg(true, i * 40); + MockSrsMediaPacket video_msg(true, i * 40); HELPER_ASSERT_SUCCESS(muxer.write_video(&video_msg, &fmt)); if (i % 2 == 0) { // Write audio less frequently - MockSrsSharedPtrMessage audio_msg(false, i * 40); + MockSrsMediaPacket audio_msg(false, i * 40); HELPER_ASSERT_SUCCESS(muxer.write_audio(&audio_msg, &fmt)); } } @@ -876,13 +876,13 @@ VOID TEST(Fmp4Test, Compatibility_SequenceHeaderIgnore) MockSrsFormat fmt; // Create audio sequence header message - MockSrsSharedPtrMessage audio_sh(false, 0); + MockSrsMediaPacket audio_sh(false, 0); // Should ignore sequence headers in write_audio HELPER_ASSERT_SUCCESS(controller.write_audio(&audio_sh, &fmt)); // Regular audio message should be processed - MockSrsSharedPtrMessage audio_msg(false, 1000); + MockSrsMediaPacket audio_msg(false, 1000); HELPER_ASSERT_SUCCESS(controller.write_audio(&audio_msg, &fmt)); controller.dispose(); diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp index 3408331e4..c3eac541a 100644 --- a/trunk/src/utest/srs_utest_kernel.cpp +++ b/trunk/src/utest/srs_utest_kernel.cpp @@ -966,10 +966,12 @@ VOID TEST(KernelFLVTest, CoverWriterErrorCase) SrsMessageHeader h; h.initialize_video(10, 30, 20); - SrsSharedPtrMessage msg; - HELPER_EXPECT_SUCCESS(msg.create(&h, new char[1], 1)); + SrsMediaPacket msg; + SrsCommonMessage common_msg; + HELPER_EXPECT_SUCCESS(common_msg.create(&h, new char[1], 1)); + common_msg.to_msg(&msg); - SrsSharedPtrMessage *msgs = &msg; + SrsMediaPacket *msgs = &msg; HELPER_EXPECT_FAILED(m.write_tags(&msgs, 1)); } @@ -983,10 +985,12 @@ VOID TEST(KernelFLVTest, CoverWriterErrorCase) SrsMessageHeader h; h.initialize_audio(10, 30, 20); - SrsSharedPtrMessage msg; - HELPER_EXPECT_SUCCESS(msg.create(&h, new char[1], 1)); + SrsMediaPacket msg; + SrsCommonMessage common_msg; + HELPER_EXPECT_SUCCESS(common_msg.create(&h, new char[1], 1)); + common_msg.to_msg(&msg); - SrsSharedPtrMessage *msgs = &msg; + SrsMediaPacket *msgs = &msg; HELPER_EXPECT_FAILED(m.write_tags(&msgs, 1)); } @@ -1000,10 +1004,12 @@ VOID TEST(KernelFLVTest, CoverWriterErrorCase) SrsMessageHeader h; h.initialize_amf0_script(10, 20); - SrsSharedPtrMessage msg; - HELPER_EXPECT_SUCCESS(msg.create(&h, new char[1], 1)); + SrsMediaPacket msg; + SrsCommonMessage common_msg; + HELPER_EXPECT_SUCCESS(common_msg.create(&h, new char[1], 1)); + common_msg.to_msg(&msg); - SrsSharedPtrMessage *msgs = &msg; + SrsMediaPacket *msgs = &msg; HELPER_EXPECT_FAILED(m.write_tags(&msgs, 1)); } } @@ -3483,7 +3489,7 @@ VOID TEST(KernelCodecTest, AVFrame) srs_error_t err; if (true) { - SrsAudioFrame f; + SrsParsedAudioPacket f; SrsAudioCodecConfig *cc = new SrsAudioCodecConfig(); SrsUniquePtr cc_uptr(cc); HELPER_EXPECT_SUCCESS(f.initialize(cc)); @@ -3501,7 +3507,7 @@ VOID TEST(KernelCodecTest, AVFrame) } if (true) { - SrsAudioFrame f; + SrsParsedAudioPacket f; EXPECT_TRUE(0 == f.nb_samples); HELPER_EXPECT_SUCCESS(f.add_sample((char *)1, 0)); @@ -3512,7 +3518,7 @@ VOID TEST(KernelCodecTest, AVFrame) } if (true) { - SrsAudioFrame f; + SrsParsedAudioPacket f; for (int i = 0; i < SrsMaxNbSamples; i++) { HELPER_EXPECT_SUCCESS(f.add_sample((char *)(int64_t)(i + 1), i * 10 + 1)); } @@ -3522,7 +3528,7 @@ VOID TEST(KernelCodecTest, AVFrame) } if (true) { - SrsVideoFrame f; + SrsParsedVideoPacket f; SrsVideoCodecConfig *cc = new SrsVideoCodecConfig(); SrsUniquePtr cc_uptr(cc); HELPER_EXPECT_SUCCESS(f.initialize(cc)); @@ -3534,7 +3540,7 @@ VOID TEST(KernelCodecTest, AVFrame) } if (true) { - SrsVideoFrame f; + SrsParsedVideoPacket f; SrsVideoCodecConfig *cc = new SrsVideoCodecConfig(); SrsUniquePtr cc_uptr(cc); HELPER_EXPECT_SUCCESS(f.initialize(cc)); @@ -3545,7 +3551,7 @@ VOID TEST(KernelCodecTest, AVFrame) } if (true) { - SrsVideoFrame f; + SrsParsedVideoPacket f; SrsVideoCodecConfig *cc = new SrsVideoCodecConfig(); SrsUniquePtr cc_uptr(cc); HELPER_EXPECT_SUCCESS(f.initialize(cc)); @@ -3556,7 +3562,7 @@ VOID TEST(KernelCodecTest, AVFrame) } if (true) { - SrsVideoFrame f; + SrsParsedVideoPacket f; SrsVideoCodecConfig *cc = new SrsVideoCodecConfig(); SrsUniquePtr cc_uptr(cc); HELPER_EXPECT_SUCCESS(f.initialize(cc)); @@ -3567,7 +3573,7 @@ VOID TEST(KernelCodecTest, AVFrame) } if (true) { - SrsVideoFrame f; + SrsParsedVideoPacket f; SrsVideoCodecConfig *cc = new SrsVideoCodecConfig(); SrsUniquePtr cc_uptr(cc); HELPER_EXPECT_SUCCESS(f.initialize(cc)); @@ -3587,12 +3593,12 @@ VOID TEST(KernelCodecTest, AVFrameNoConfig) srs_error_t err; if (true) { - SrsAudioFrame f; + SrsParsedAudioPacket f; HELPER_EXPECT_SUCCESS(f.add_sample((char *)1, 10)); } if (true) { - SrsVideoFrame f; + SrsParsedVideoPacket f; HELPER_EXPECT_SUCCESS(f.add_sample((char *)"\x05", 1)); } } @@ -3604,39 +3610,39 @@ VOID TEST(KernelCodecTest, VideoFrameH264_ParseNaluType) if (true) { // I Frame uint8_t data[] = {0x05, 0x00, 0x00, 0x00}; - SrsSample sample((char *)data, sizeof(data)); + SrsNaluSample sample((char *)data, sizeof(data)); SrsAvcNaluType nalu_type = SrsAvcNaluTypeForbidden; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_nalu_type(&sample, nalu_type)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_nalu_type(&sample, nalu_type)); EXPECT_EQ(nalu_type, SrsAvcNaluTypeIDR); // P Frame uint8_t data2[] = {0x01, 0x00, 0x00, 0x00}; - SrsSample sample2((char *)data2, sizeof(data2)); + SrsNaluSample sample2((char *)data2, sizeof(data2)); nalu_type = SrsAvcNaluTypeForbidden; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_nalu_type(&sample2, nalu_type)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_nalu_type(&sample2, nalu_type)); EXPECT_EQ(nalu_type, SrsAvcNaluTypeNonIDR); // SPS uint8_t data3[] = {0x07, 0x00, 0x00, 0x00}; - SrsSample sample3((char *)data3, sizeof(data3)); + SrsNaluSample sample3((char *)data3, sizeof(data3)); nalu_type = SrsAvcNaluTypeForbidden; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_nalu_type(&sample3, nalu_type)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_nalu_type(&sample3, nalu_type)); EXPECT_EQ(nalu_type, SrsAvcNaluTypeSPS); // PPS uint8_t data4[] = {0x08, 0x00, 0x00, 0x00}; - SrsSample sample4((char *)data4, sizeof(data4)); + SrsNaluSample sample4((char *)data4, sizeof(data4)); nalu_type = SrsAvcNaluTypeForbidden; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_nalu_type(&sample4, nalu_type)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_nalu_type(&sample4, nalu_type)); EXPECT_EQ(nalu_type, SrsAvcNaluTypePPS); // Empty Sample - SrsSample empty_sample(NULL, 0); - HELPER_EXPECT_FAILED(SrsVideoFrame::parse_avc_nalu_type(&empty_sample, nalu_type)); + SrsNaluSample empty_sample(NULL, 0); + HELPER_EXPECT_FAILED(SrsParsedVideoPacket::parse_avc_nalu_type(&empty_sample, nalu_type)); } } @@ -3649,53 +3655,53 @@ VOID TEST(KernelCodecTest, VideoFrameH264_BFrameDetection_AllowedNaluTypes) // NonIDR NALU (type 1) with B-frame slice_type=1 uint8_t data_b1[] = {0x01, 0xA8, 0x00, 0x00}; // NALU type 1, slice_type=1 (B) - SrsSample sample_b1((char *)data_b1, sizeof(data_b1)); + SrsNaluSample sample_b1((char *)data_b1, sizeof(data_b1)); bool is_b_frame = false; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_b1, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_b1, is_b_frame)); EXPECT_TRUE(is_b_frame); // Test that the function correctly processes NALU type 1 (the main case) // NonIDR NALU (type 1) with P-frame slice_type=0 uint8_t data_p1[] = {0x01, 0x88, 0x00, 0x00}; // NALU type 1, slice_type=0 (P) - SrsSample sample_p1((char *)data_p1, sizeof(data_p1)); + SrsNaluSample sample_p1((char *)data_p1, sizeof(data_p1)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_p1, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_p1, is_b_frame)); EXPECT_FALSE(is_b_frame); // NonIDR NALU (type 1) with I-frame slice_type=2 uint8_t data_i1[] = {0x01, 0x98, 0x00, 0x00}; // NALU type 1, slice_type=2 (I) - SrsSample sample_i1((char *)data_i1, sizeof(data_i1)); + SrsNaluSample sample_i1((char *)data_i1, sizeof(data_i1)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_i1, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_i1, is_b_frame)); EXPECT_FALSE(is_b_frame); // DataPartitionA NALU (type 2) with B-frame slice_type=1 uint8_t data_dpa_b[] = {0x02, 0xA8, 0x00, 0x00}; // NALU type 2, slice_type=1 (B) - SrsSample sample_dpa_b((char *)data_dpa_b, sizeof(data_dpa_b)); + SrsNaluSample sample_dpa_b((char *)data_dpa_b, sizeof(data_dpa_b)); is_b_frame = false; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_dpa_b, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_dpa_b, is_b_frame)); EXPECT_TRUE(is_b_frame); // DataPartitionA NALU (type 2) with P-frame slice_type=0 uint8_t data_dpa_p[] = {0x02, 0x88, 0x00, 0x00}; // NALU type 2, slice_type=0 (P) - SrsSample sample_dpa_p((char *)data_dpa_p, sizeof(data_dpa_p)); + SrsNaluSample sample_dpa_p((char *)data_dpa_p, sizeof(data_dpa_p)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_dpa_p, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_dpa_p, is_b_frame)); EXPECT_FALSE(is_b_frame); // DataPartitionB NALU (type 3) with B-frame slice_type=1 uint8_t data_dpb_b[] = {0x03, 0xA8, 0x00, 0x00}; // NALU type 3, slice_type=1 (B) - SrsSample sample_dpb_b((char *)data_dpb_b, sizeof(data_dpb_b)); + SrsNaluSample sample_dpb_b((char *)data_dpb_b, sizeof(data_dpb_b)); is_b_frame = false; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_dpb_b, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_dpb_b, is_b_frame)); EXPECT_TRUE(is_b_frame); // DataPartitionC NALU (type 4) with B-frame slice_type=1 uint8_t data_dpc_b[] = {0x04, 0xA8, 0x00, 0x00}; // NALU type 4, slice_type=1 (B) - SrsSample sample_dpc_b((char *)data_dpc_b, sizeof(data_dpc_b)); + SrsNaluSample sample_dpc_b((char *)data_dpc_b, sizeof(data_dpc_b)); is_b_frame = false; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_dpc_b, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_dpc_b, is_b_frame)); EXPECT_TRUE(is_b_frame); } } @@ -3709,93 +3715,93 @@ VOID TEST(KernelCodecTest, VideoFrameH264_BFrameDetection_ForbiddenNaluTypes) // IDR NALU (type 5) - cannot contain B-frames by definition uint8_t data_idr[] = {0x05, 0xA8, 0x00, 0x00}; // NALU type 5, any slice data - SrsSample sample_idr((char *)data_idr, sizeof(data_idr)); + SrsNaluSample sample_idr((char *)data_idr, sizeof(data_idr)); bool is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_idr, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_idr, is_b_frame)); EXPECT_FALSE(is_b_frame); // SEI NALU (type 6) - cannot contain B-frames uint8_t data_sei[] = {0x06, 0xA8, 0x00, 0x00}; // NALU type 6 - SrsSample sample_sei((char *)data_sei, sizeof(data_sei)); + SrsNaluSample sample_sei((char *)data_sei, sizeof(data_sei)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_sei, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_sei, is_b_frame)); EXPECT_FALSE(is_b_frame); // SPS NALU (type 7) - cannot contain B-frames uint8_t data_sps[] = {0x07, 0xA8, 0x00, 0x00}; // NALU type 7 - SrsSample sample_sps((char *)data_sps, sizeof(data_sps)); + SrsNaluSample sample_sps((char *)data_sps, sizeof(data_sps)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_sps, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_sps, is_b_frame)); EXPECT_FALSE(is_b_frame); // PPS NALU (type 8) - cannot contain B-frames uint8_t data_pps[] = {0x08, 0xA8, 0x00, 0x00}; // NALU type 8 - SrsSample sample_pps((char *)data_pps, sizeof(data_pps)); + SrsNaluSample sample_pps((char *)data_pps, sizeof(data_pps)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_pps, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_pps, is_b_frame)); EXPECT_FALSE(is_b_frame); // AUD NALU (type 9) - cannot contain B-frames uint8_t data_aud[] = {0x09, 0xA8, 0x00, 0x00}; // NALU type 9 - SrsSample sample_aud((char *)data_aud, sizeof(data_aud)); + SrsNaluSample sample_aud((char *)data_aud, sizeof(data_aud)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_aud, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_aud, is_b_frame)); EXPECT_FALSE(is_b_frame); // End of Sequence NALU (type 10) - cannot contain B-frames uint8_t data_eos[] = {0x0A, 0xA8, 0x00, 0x00}; // NALU type 10 - SrsSample sample_eos((char *)data_eos, sizeof(data_eos)); + SrsNaluSample sample_eos((char *)data_eos, sizeof(data_eos)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_eos, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_eos, is_b_frame)); EXPECT_FALSE(is_b_frame); // End of Stream NALU (type 11) - cannot contain B-frames uint8_t data_eost[] = {0x0B, 0xA8, 0x00, 0x00}; // NALU type 11 - SrsSample sample_eost((char *)data_eost, sizeof(data_eost)); + SrsNaluSample sample_eost((char *)data_eost, sizeof(data_eost)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_eost, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_eost, is_b_frame)); EXPECT_FALSE(is_b_frame); // Filler Data NALU (type 12) - cannot contain B-frames uint8_t data_filler[] = {0x0C, 0xA8, 0x00, 0x00}; // NALU type 12 - SrsSample sample_filler((char *)data_filler, sizeof(data_filler)); + SrsNaluSample sample_filler((char *)data_filler, sizeof(data_filler)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_filler, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_filler, is_b_frame)); EXPECT_FALSE(is_b_frame); // SPS Extension NALU (type 13) - cannot contain B-frames uint8_t data_sps_ext[] = {0x0D, 0xA8, 0x00, 0x00}; // NALU type 13 - SrsSample sample_sps_ext((char *)data_sps_ext, sizeof(data_sps_ext)); + SrsNaluSample sample_sps_ext((char *)data_sps_ext, sizeof(data_sps_ext)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_sps_ext, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_sps_ext, is_b_frame)); EXPECT_FALSE(is_b_frame); // Prefix NALU (type 14) - cannot contain B-frames uint8_t data_prefix[] = {0x0E, 0xA8, 0x00, 0x00}; // NALU type 14 - SrsSample sample_prefix((char *)data_prefix, sizeof(data_prefix)); + SrsNaluSample sample_prefix((char *)data_prefix, sizeof(data_prefix)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_prefix, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_prefix, is_b_frame)); EXPECT_FALSE(is_b_frame); // Subset SPS NALU (type 15) - cannot contain B-frames uint8_t data_subset_sps[] = {0x0F, 0xA8, 0x00, 0x00}; // NALU type 15 - SrsSample sample_subset_sps((char *)data_subset_sps, sizeof(data_subset_sps)); + SrsNaluSample sample_subset_sps((char *)data_subset_sps, sizeof(data_subset_sps)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_subset_sps, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_subset_sps, is_b_frame)); EXPECT_FALSE(is_b_frame); // Layer Without Partition NALU (type 19) - cannot contain B-frames uint8_t data_layer[] = {0x13, 0xA8, 0x00, 0x00}; // NALU type 19 - SrsSample sample_layer((char *)data_layer, sizeof(data_layer)); + SrsNaluSample sample_layer((char *)data_layer, sizeof(data_layer)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_layer, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_layer, is_b_frame)); EXPECT_FALSE(is_b_frame); // Coded Slice Extension NALU (type 20) - cannot contain B-frames uint8_t data_slice_ext[] = {0x14, 0xA8, 0x00, 0x00}; // NALU type 20 - SrsSample sample_slice_ext((char *)data_slice_ext, sizeof(data_slice_ext)); + SrsNaluSample sample_slice_ext((char *)data_slice_ext, sizeof(data_slice_ext)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_slice_ext, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_slice_ext, is_b_frame)); EXPECT_FALSE(is_b_frame); } } @@ -3808,129 +3814,129 @@ VOID TEST(KernelCodecTest, VideoFrameH264_BFrameDetection_EdgeCases) if (true) { // IDR NALU (type 5) - cannot contain B-frames by definition uint8_t data_idr[] = {0x05, 0xA8, 0x00, 0x00}; // NALU type 5, any slice data - SrsSample sample_idr((char *)data_idr, sizeof(data_idr)); + SrsNaluSample sample_idr((char *)data_idr, sizeof(data_idr)); bool is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_idr, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_idr, is_b_frame)); EXPECT_FALSE(is_b_frame); // SEI NALU (type 6) - cannot contain B-frames uint8_t data_sei[] = {0x06, 0xA8, 0x00, 0x00}; // NALU type 6 - SrsSample sample_sei((char *)data_sei, sizeof(data_sei)); + SrsNaluSample sample_sei((char *)data_sei, sizeof(data_sei)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_sei, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_sei, is_b_frame)); EXPECT_FALSE(is_b_frame); // SPS NALU (type 7) - cannot contain B-frames uint8_t data_sps[] = {0x07, 0xA8, 0x00, 0x00}; // NALU type 7 - SrsSample sample_sps((char *)data_sps, sizeof(data_sps)); + SrsNaluSample sample_sps((char *)data_sps, sizeof(data_sps)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_sps, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_sps, is_b_frame)); EXPECT_FALSE(is_b_frame); // PPS NALU (type 8) - cannot contain B-frames uint8_t data_pps[] = {0x08, 0xA8, 0x00, 0x00}; // NALU type 8 - SrsSample sample_pps((char *)data_pps, sizeof(data_pps)); + SrsNaluSample sample_pps((char *)data_pps, sizeof(data_pps)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_pps, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_pps, is_b_frame)); EXPECT_FALSE(is_b_frame); // AUD NALU (type 9) - cannot contain B-frames uint8_t data_aud[] = {0x09, 0xA8, 0x00, 0x00}; // NALU type 9 - SrsSample sample_aud((char *)data_aud, sizeof(data_aud)); + SrsNaluSample sample_aud((char *)data_aud, sizeof(data_aud)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_aud, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_aud, is_b_frame)); EXPECT_FALSE(is_b_frame); // End of Sequence NALU (type 10) - cannot contain B-frames uint8_t data_eos[] = {0x0A, 0xA8, 0x00, 0x00}; // NALU type 10 - SrsSample sample_eos((char *)data_eos, sizeof(data_eos)); + SrsNaluSample sample_eos((char *)data_eos, sizeof(data_eos)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_eos, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_eos, is_b_frame)); EXPECT_FALSE(is_b_frame); // End of Stream NALU (type 11) - cannot contain B-frames uint8_t data_eost[] = {0x0B, 0xA8, 0x00, 0x00}; // NALU type 11 - SrsSample sample_eost((char *)data_eost, sizeof(data_eost)); + SrsNaluSample sample_eost((char *)data_eost, sizeof(data_eost)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_eost, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_eost, is_b_frame)); EXPECT_FALSE(is_b_frame); // Filler Data NALU (type 12) - cannot contain B-frames uint8_t data_filler[] = {0x0C, 0xA8, 0x00, 0x00}; // NALU type 12 - SrsSample sample_filler((char *)data_filler, sizeof(data_filler)); + SrsNaluSample sample_filler((char *)data_filler, sizeof(data_filler)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_filler, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_filler, is_b_frame)); EXPECT_FALSE(is_b_frame); // SPS Extension NALU (type 13) - cannot contain B-frames uint8_t data_sps_ext[] = {0x0D, 0xA8, 0x00, 0x00}; // NALU type 13 - SrsSample sample_sps_ext((char *)data_sps_ext, sizeof(data_sps_ext)); + SrsNaluSample sample_sps_ext((char *)data_sps_ext, sizeof(data_sps_ext)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_sps_ext, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_sps_ext, is_b_frame)); EXPECT_FALSE(is_b_frame); // Prefix NALU (type 14) - cannot contain B-frames uint8_t data_prefix[] = {0x0E, 0xA8, 0x00, 0x00}; // NALU type 14 - SrsSample sample_prefix((char *)data_prefix, sizeof(data_prefix)); + SrsNaluSample sample_prefix((char *)data_prefix, sizeof(data_prefix)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_prefix, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_prefix, is_b_frame)); EXPECT_FALSE(is_b_frame); // Subset SPS NALU (type 15) - cannot contain B-frames uint8_t data_subset_sps[] = {0x0F, 0xA8, 0x00, 0x00}; // NALU type 15 - SrsSample sample_subset_sps((char *)data_subset_sps, sizeof(data_subset_sps)); + SrsNaluSample sample_subset_sps((char *)data_subset_sps, sizeof(data_subset_sps)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_subset_sps, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_subset_sps, is_b_frame)); EXPECT_FALSE(is_b_frame); // Layer Without Partition NALU (type 19) - cannot contain B-frames uint8_t data_layer[] = {0x13, 0xA8, 0x00, 0x00}; // NALU type 19 - SrsSample sample_layer((char *)data_layer, sizeof(data_layer)); + SrsNaluSample sample_layer((char *)data_layer, sizeof(data_layer)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_layer, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_layer, is_b_frame)); EXPECT_FALSE(is_b_frame); // Coded Slice Extension NALU (type 20) - cannot contain B-frames uint8_t data_slice_ext[] = {0x14, 0xA8, 0x00, 0x00}; // NALU type 20 - SrsSample sample_slice_ext((char *)data_slice_ext, sizeof(data_slice_ext)); + SrsNaluSample sample_slice_ext((char *)data_slice_ext, sizeof(data_slice_ext)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_slice_ext, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_slice_ext, is_b_frame)); EXPECT_FALSE(is_b_frame); } // Test edge cases and error conditions if (true) { // Empty Sample - should fail - SrsSample empty_sample(NULL, 0); + SrsNaluSample empty_sample(NULL, 0); bool is_b_frame = false; - HELPER_EXPECT_FAILED(SrsVideoFrame::parse_avc_bframe(&empty_sample, is_b_frame)); + HELPER_EXPECT_FAILED(SrsParsedVideoPacket::parse_avc_bframe(&empty_sample, is_b_frame)); // Sample too small for slice parsing (only NALU header) - should fail for slice types uint8_t data_small[] = {0x01}; // NALU type 1, but no slice data - SrsSample sample_small((char *)data_small, sizeof(data_small)); + SrsNaluSample sample_small((char *)data_small, sizeof(data_small)); is_b_frame = false; - HELPER_EXPECT_FAILED(SrsVideoFrame::parse_avc_bframe(&sample_small, is_b_frame)); + HELPER_EXPECT_FAILED(SrsParsedVideoPacket::parse_avc_bframe(&sample_small, is_b_frame)); // Test basic slice types for NonIDR NALU using known working patterns // P frame (slice_type=0) uint8_t data_p[] = {0x01, 0x88, 0x00, 0x00}; // slice_type=0 - SrsSample sample_p((char *)data_p, sizeof(data_p)); + SrsNaluSample sample_p((char *)data_p, sizeof(data_p)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_p, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_p, is_b_frame)); EXPECT_FALSE(is_b_frame); // B frame (slice_type=1) uint8_t data_b[] = {0x01, 0xA8, 0x00, 0x00}; // slice_type=1 - SrsSample sample_b((char *)data_b, sizeof(data_b)); + SrsNaluSample sample_b((char *)data_b, sizeof(data_b)); is_b_frame = false; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_b, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_b, is_b_frame)); EXPECT_TRUE(is_b_frame); // I frame (slice_type=2) uint8_t data_i[] = {0x01, 0x98, 0x00, 0x00}; // slice_type=2 - SrsSample sample_i((char *)data_i, sizeof(data_i)); + SrsNaluSample sample_i((char *)data_i, sizeof(data_i)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_avc_bframe(&sample_i, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_avc_bframe(&sample_i, is_b_frame)); EXPECT_FALSE(is_b_frame); } } @@ -3942,47 +3948,47 @@ VOID TEST(KernelCodecTest, VideoFrameH265) if (true) { // I Frame uint8_t data[] = {0x26, 0x01, 0x00, 0x00}; - SrsSample sample((char *)data, sizeof(data)); + SrsNaluSample sample((char *)data, sizeof(data)); SrsHevcNaluType nalu_type = SrsHevcNaluType_INVALID; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_hevc_nalu_type(&sample, nalu_type)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_hevc_nalu_type(&sample, nalu_type)); EXPECT_EQ(nalu_type, SrsHevcNaluType_CODED_SLICE_IDR); // P Frame uint8_t data2[] = {0x02, 0x01, 0x00, 0x00}; - SrsSample sample2((char *)data2, sizeof(data2)); + SrsNaluSample sample2((char *)data2, sizeof(data2)); nalu_type = SrsHevcNaluType_INVALID; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_hevc_nalu_type(&sample2, nalu_type)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_hevc_nalu_type(&sample2, nalu_type)); EXPECT_EQ(nalu_type, SrsHevcNaluType_CODED_SLICE_TRAIL_R); // VPS uint8_t data3[] = {0x40, 0x01, 0x00, 0x00}; - SrsSample sample3((char *)data3, sizeof(data3)); + SrsNaluSample sample3((char *)data3, sizeof(data3)); nalu_type = SrsHevcNaluType_INVALID; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_hevc_nalu_type(&sample3, nalu_type)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_hevc_nalu_type(&sample3, nalu_type)); EXPECT_EQ(nalu_type, SrsHevcNaluType_VPS); // SPS uint8_t data4[] = {0x42, 0x01, 0x00, 0x00}; - SrsSample sample4((char *)data4, sizeof(data4)); + SrsNaluSample sample4((char *)data4, sizeof(data4)); nalu_type = SrsHevcNaluType_INVALID; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_hevc_nalu_type(&sample4, nalu_type)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_hevc_nalu_type(&sample4, nalu_type)); EXPECT_EQ(nalu_type, SrsHevcNaluType_SPS); // PPS uint8_t data5[] = {0x44, 0x01, 0x00, 0x00}; - SrsSample sample5((char *)data5, sizeof(data5)); + SrsNaluSample sample5((char *)data5, sizeof(data5)); nalu_type = SrsHevcNaluType_INVALID; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_hevc_nalu_type(&sample5, nalu_type)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_hevc_nalu_type(&sample5, nalu_type)); EXPECT_EQ(nalu_type, SrsHevcNaluType_PPS); // Empty Sample - SrsSample empty_sample(NULL, 0); - HELPER_EXPECT_FAILED(SrsVideoFrame::parse_hevc_nalu_type(&empty_sample, nalu_type)); + SrsNaluSample empty_sample(NULL, 0); + HELPER_EXPECT_FAILED(SrsParsedVideoPacket::parse_hevc_nalu_type(&empty_sample, nalu_type)); } if (true) { @@ -3991,55 +3997,55 @@ VOID TEST(KernelCodecTest, VideoFrameH265) // B Frame, slice_type=0(B Frame) uint8_t data[] = {0x02, 0x01, 0xE0, 0x44}; - SrsSample sample((char *)data, sizeof(data)); + SrsNaluSample sample((char *)data, sizeof(data)); bool is_b_frame = false; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_hevc_bframe(&sample, &format, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_hevc_bframe(&sample, &format, is_b_frame)); EXPECT_TRUE(is_b_frame); // Non-B Frame, slice_type=1(P Frame) uint8_t data2[] = {0x02, 0x01, 0xD0, 0x30}; - SrsSample sample2((char *)data2, sizeof(data2)); + SrsNaluSample sample2((char *)data2, sizeof(data2)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_hevc_bframe(&sample2, &format, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_hevc_bframe(&sample2, &format, is_b_frame)); EXPECT_FALSE(is_b_frame); // VPS uint8_t data3[] = {0x40, 0x01, 0xE0, 0x44}; - SrsSample sample3((char *)data3, sizeof(data3)); + SrsNaluSample sample3((char *)data3, sizeof(data3)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_hevc_bframe(&sample3, &format, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_hevc_bframe(&sample3, &format, is_b_frame)); EXPECT_FALSE(is_b_frame); // SPS uint8_t data4[] = {0x42, 0x01, 0xE0, 0x44}; - SrsSample sample4((char *)data4, sizeof(data4)); + SrsNaluSample sample4((char *)data4, sizeof(data4)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_hevc_bframe(&sample4, &format, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_hevc_bframe(&sample4, &format, is_b_frame)); EXPECT_FALSE(is_b_frame); // PPS uint8_t data5[] = {0x44, 0x01, 0xE0, 0x44}; - SrsSample sample5((char *)data5, sizeof(data5)); + SrsNaluSample sample5((char *)data5, sizeof(data5)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_hevc_bframe(&sample5, &format, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_hevc_bframe(&sample5, &format, is_b_frame)); EXPECT_FALSE(is_b_frame); // IDR uint8_t data6[] = {0x26, 0x01, 0xE0, 0x44}; - SrsSample sample6((char *)data6, sizeof(data6)); + SrsNaluSample sample6((char *)data6, sizeof(data6)); is_b_frame = true; - HELPER_EXPECT_SUCCESS(SrsVideoFrame::parse_hevc_bframe(&sample6, &format, is_b_frame)); + HELPER_EXPECT_SUCCESS(SrsParsedVideoPacket::parse_hevc_bframe(&sample6, &format, is_b_frame)); EXPECT_FALSE(is_b_frame); // Empty Sample - SrsSample empty_sample(NULL, 0); - HELPER_EXPECT_FAILED(SrsVideoFrame::parse_hevc_bframe(&empty_sample, &format, is_b_frame)); + SrsNaluSample empty_sample(NULL, 0); + HELPER_EXPECT_FAILED(SrsParsedVideoPacket::parse_hevc_bframe(&empty_sample, &format, is_b_frame)); } } @@ -4050,7 +4056,7 @@ VOID TEST(KernelCodecTest, IsSequenceHeaderSpecial) EXPECT_FALSE(f.is_avc_sequence_header()); f.vcodec = new SrsVideoCodecConfig(); - f.video = new SrsVideoFrame(); + f.video = new SrsParsedVideoPacket(); EXPECT_FALSE(f.is_avc_sequence_header()); f.vcodec->id = SrsVideoCodecIdAVC; @@ -4065,7 +4071,7 @@ VOID TEST(KernelCodecTest, IsSequenceHeaderSpecial) EXPECT_FALSE(f.is_avc_sequence_header()); f.vcodec = new SrsVideoCodecConfig(); - f.video = new SrsVideoFrame(); + f.video = new SrsParsedVideoPacket(); EXPECT_FALSE(f.is_avc_sequence_header()); f.vcodec->id = SrsVideoCodecIdHEVC; @@ -5289,8 +5295,8 @@ VOID TEST(KernelFLVTest, CoverAll) EXPECT_EQ(30, m.header.timestamp_delta); EXPECT_EQ(30, m.header.timestamp); - SrsSharedPtrMessage s; - HELPER_EXPECT_SUCCESS(s.create(&m)); + SrsMediaPacket s; + m.to_msg(&s); EXPECT_TRUE(s.is_av()); EXPECT_TRUE(!s.is_audio()); EXPECT_TRUE(s.is_video()); @@ -5304,10 +5310,12 @@ VOID TEST(KernelFLVTest, CoverAll) SrsMessageHeader h; h.initialize_video(10, 30, 20); - SrsSharedPtrMessage m; - HELPER_EXPECT_SUCCESS(m.create(&h, new char[1], 1)); + SrsMediaPacket m; + SrsCommonMessage common_msg; + HELPER_EXPECT_SUCCESS(common_msg.create(&h, new char[1], 1)); + common_msg.to_msg(&m); - SrsSharedPtrMessage *msgs = &m; + SrsMediaPacket *msgs = &m; HELPER_EXPECT_SUCCESS(mux.write_tags(&msgs, 1)); EXPECT_EQ(16, f.tellg()); @@ -5320,28 +5328,34 @@ VOID TEST(KernelFLVTest, CoverSharedPtrMessage) if (true) { SrsMessageHeader h; - SrsSharedPtrMessage m; - HELPER_EXPECT_SUCCESS(m.create(&h, new char[1], 1)); + SrsMediaPacket m; + SrsCommonMessage common_msg; + HELPER_EXPECT_SUCCESS(common_msg.create(&h, new char[1], 1)); + common_msg.to_msg(&m); } if (true) { SrsMessageHeader h; - SrsSharedPtrMessage m; - HELPER_EXPECT_SUCCESS(m.create(&h, NULL, 0)); + SrsMediaPacket m; + SrsCommonMessage common_msg; + HELPER_EXPECT_SUCCESS(common_msg.create(&h, NULL, 0)); + common_msg.to_msg(&m); } if (true) { SrsMessageHeader h; - SrsSharedPtrMessage m; - HELPER_EXPECT_FAILED(m.create(&h, NULL, -1)); + SrsMediaPacket m; + SrsCommonMessage common_msg; + HELPER_EXPECT_FAILED(common_msg.create(&h, NULL, -1)); } if (true) { SrsMessageHeader h; - h.prefer_cid = 1; - SrsSharedPtrMessage m; - HELPER_EXPECT_SUCCESS(m.create(&h, NULL, 0)); + SrsMediaPacket m; + SrsCommonMessage common_msg; + HELPER_EXPECT_SUCCESS(common_msg.create(&h, NULL, 0)); + common_msg.to_msg(&m); EXPECT_FALSE(m.check(1)); EXPECT_TRUE(m.check(1)); diff --git a/trunk/src/utest/srs_utest_protocol.cpp b/trunk/src/utest/srs_utest_protocol.cpp index d28a7b39a..298f3e45f 100644 --- a/trunk/src/utest/srs_utest_protocol.cpp +++ b/trunk/src/utest/srs_utest_protocol.cpp @@ -896,9 +896,11 @@ VOID TEST(ProtocolMsgArrayTest, MessageArray) srs_error_t err = srs_success; SrsMessageHeader header; - SrsSharedPtrMessage msg; + SrsMediaPacket msg; char *payload = new char[1024]; - HELPER_EXPECT_SUCCESS(msg.create(&header, payload, 1024)); + SrsCommonMessage common_msg; + HELPER_EXPECT_SUCCESS(common_msg.create(&header, payload, 1024)); + common_msg.to_msg(&msg); if (true) { SrsMessageArray arr(3); @@ -1012,9 +1014,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvMessage) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt = NULL; + SrsRtmpCommand *pkt = NULL; HELPER_EXPECT_SUCCESS(proto.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); SrsConnectAppPacket *spkt = dynamic_cast(pkt); ASSERT_TRUE(NULL != spkt); @@ -1049,9 +1051,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvMessageBug98) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt = NULL; + SrsRtmpCommand *pkt = NULL; HELPER_EXPECT_SUCCESS(proto.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); SrsUserControlPacket *spkt = dynamic_cast(pkt); ASSERT_TRUE(NULL != spkt); @@ -1085,9 +1087,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvAckSizeMessage) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt = NULL; + SrsRtmpCommand *pkt = NULL; HELPER_EXPECT_SUCCESS(proto.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); SrsSetWindowAckSizePacket *spkt = dynamic_cast(pkt); ASSERT_TRUE(NULL != spkt); @@ -3765,8 +3767,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid1BNormal) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); EXPECT_TRUE(msg->header.is_video()); - // 1B cid(6bits), cid in 2-63 - EXPECT_EQ(0x09, msg->header.prefer_cid); } /** @@ -3817,8 +3817,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid1BMax) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); EXPECT_TRUE(msg->header.is_video()); - // 1B cid(6bits), max is 63 - EXPECT_EQ(0x3F, msg->header.prefer_cid); } /** @@ -3869,8 +3867,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid2BMin) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); EXPECT_TRUE(msg->header.is_video()); - // 2B cid(8bits), min is 64 - EXPECT_EQ(64, msg->header.prefer_cid); } /** @@ -3921,8 +3917,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid2BNormal) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); EXPECT_TRUE(msg->header.is_video()); - // 2B cid(8bits), cid in 64-319 - EXPECT_EQ(0x10 + 64, msg->header.prefer_cid); } /** @@ -3973,8 +3967,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid2BNormal2) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); EXPECT_TRUE(msg->header.is_video()); - // 2B cid(8bits), cid in 64-319 - EXPECT_EQ(0x11 + 64, msg->header.prefer_cid); } /** @@ -4025,8 +4017,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid2BMax) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); EXPECT_TRUE(msg->header.is_video()); - // 2B cid(68bits), max is 319 - EXPECT_EQ(319, msg->header.prefer_cid); } /** @@ -4077,8 +4067,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BMin) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); EXPECT_TRUE(msg->header.is_video()); - // 3B cid(16bits), min is 64 - EXPECT_EQ(64, msg->header.prefer_cid); } /** @@ -4129,8 +4117,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); EXPECT_TRUE(msg->header.is_video()); - // 3B cid(16bits), cid in 64-65599 - EXPECT_EQ(0x10 * 256 + 64, msg->header.prefer_cid); } /** @@ -4181,8 +4167,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal2) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); EXPECT_TRUE(msg->header.is_video()); - // 3B cid(16bits), cid in 64-65599 - EXPECT_EQ(0x01 + (0x10 * 256) + 64, msg->header.prefer_cid); } /** @@ -4233,8 +4217,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal3) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); EXPECT_TRUE(msg->header.is_video()); - // 3B cid(16bits), cid in 64-65599 - EXPECT_EQ(0xFF + (0x10 * 256) + 64, msg->header.prefer_cid); } /** @@ -4285,8 +4267,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal4) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); EXPECT_TRUE(msg->header.is_video()); - // 3B cid(16bits), cid in 64-65599 - EXPECT_EQ(0x02 + (0x10 * 256) + 64, msg->header.prefer_cid); } /** @@ -4337,8 +4317,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BMax) HELPER_ASSERT_SUCCESS(proto.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); EXPECT_TRUE(msg->header.is_video()); - // 2B cid(16bits), max is 65599 - EXPECT_EQ(65599, msg->header.prefer_cid); } /** @@ -4397,8 +4375,8 @@ VOID TEST(ProtocolStackTest, ProtocolSendVMessage) msg->create_payload(sizeof(data)); memcpy(msg->payload(), data, sizeof(data)); - SrsSharedPtrMessage m; - HELPER_ASSERT_SUCCESS(m.create(msg)); + SrsMediaPacket m; + msg->to_msg(&m); HELPER_EXPECT_SUCCESS(proto.send_and_free_message(m.copy(), 0)); EXPECT_EQ(16, bio.out_buffer.length()); @@ -4427,7 +4405,7 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsCallPacket) HELPER_EXPECT_SUCCESS(proto.send_and_free_packet(pkt, 0)); char buf[] = { - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x14, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x14, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x6d, 0x79, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, @@ -4470,7 +4448,7 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsCallResPacket) HELPER_EXPECT_SUCCESS(proto.send_and_free_packet(pkt, 0)); char buf[] = { - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x14, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x14, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, @@ -4505,7 +4483,7 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsCreateStreamPacket) HELPER_EXPECT_SUCCESS(proto.send_and_free_packet(pkt, 0)); char buf[] = { - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x14, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x14, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, @@ -4530,7 +4508,7 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsFMLEStartPacket) HELPER_EXPECT_SUCCESS(proto.send_and_free_packet(pkt, 0)); char buf[] = { - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x14, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x14, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0x46, 0x4d, 0x4c, 0x45, 0x53, 0x74, 0x61, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -4561,7 +4539,7 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsFMLEStartResPacket) HELPER_EXPECT_SUCCESS(proto.send_and_free_packet(pkt, 0)); uint8_t buf[] = { - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x14, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x14, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0x46, 0x4d, 0x4c, 0x45, 0x53, 0x74, 0x61, 0x72, 0x74, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -4648,7 +4626,7 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsOnBWDonePacket) HELPER_EXPECT_SUCCESS(proto.send_and_free_packet(pkt, 0)); char buf[] = { - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x14, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x14, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x6f, 0x6e, 0x42, 0x57, 0x44, 0x6f, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -4724,16 +4702,16 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsOnStatusDataPacket) } /** - * send a SrsSampleAccessPacket packet + * send a SrsNaluSampleAccessPacket packet */ -VOID TEST(ProtocolStackTest, ProtocolSendSrsSampleAccessPacket) +VOID TEST(ProtocolStackTest, ProtocolSendSrsNaluSampleAccessPacket) { srs_error_t err = srs_success; MockBufferIO bio; SrsProtocol proto(&bio); - SrsSampleAccessPacket *pkt = new SrsSampleAccessPacket(); + SrsNaluSampleAccessPacket *pkt = new SrsNaluSampleAccessPacket(); pkt->command_name = "|RtmpSampleAccess"; pkt->video_sample_access = true; pkt->audio_sample_access = true; @@ -4769,7 +4747,7 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsOnMetaDataPacket) HELPER_EXPECT_SUCCESS(proto.send_and_free_packet(pkt, 0)); uint8_t buf[] = { - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x12, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x12, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x03, 0x00, 0x05, 0x77, 0x69, 0x64, 0x74, @@ -4795,7 +4773,7 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsSetWindowAckSizePacket) HELPER_EXPECT_SUCCESS(proto.send_and_free_packet(pkt, 0)); uint8_t buf[] = { - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x90, 0x00}; EXPECT_TRUE(srs_bytes_equal(bio.out_buffer.bytes(), (char *)buf, sizeof(buf))); } @@ -4815,7 +4793,7 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsAcknowledgementPacket) HELPER_EXPECT_SUCCESS(proto.send_and_free_packet(pkt, 0)); char buf[] = { - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00}; EXPECT_TRUE(srs_bytes_equal(bio.out_buffer.bytes(), buf, sizeof(buf))); } @@ -4835,7 +4813,7 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsSetChunkSizePacket) HELPER_EXPECT_SUCCESS(proto.send_and_free_packet(pkt, 0)); char buf[] = { - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00}; EXPECT_TRUE(srs_bytes_equal(bio.out_buffer.bytes(), buf, sizeof(buf))); } @@ -4856,7 +4834,7 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsSetPeerBandwidthPacket) HELPER_EXPECT_SUCCESS(proto.send_and_free_packet(pkt, 0)); char buf[] = { - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01}; EXPECT_TRUE(srs_bytes_equal(bio.out_buffer.bytes(), buf, sizeof(buf))); @@ -4879,7 +4857,7 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsUserControlPacket) HELPER_EXPECT_SUCCESS(proto.send_and_free_packet(pkt, 0)); char buf[] = { - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10}; @@ -4961,8 +4939,8 @@ VOID TEST(ProtocolStackTest, ProtocolAckSizeFlow) msg->header.message_type = 9; EXPECT_TRUE(msg->header.is_video()); - SrsSharedPtrMessage m; - HELPER_ASSERT_SUCCESS(m.create(msg)); + SrsMediaPacket m; + msg->to_msg(&m); HELPER_EXPECT_SUCCESS(proto.send_and_free_message(m.copy(), 1)); } @@ -5011,8 +4989,8 @@ VOID TEST(ProtocolStackTest, ProtocolAckSizeFlow) msg->header.message_type = 9; EXPECT_TRUE(msg->header.is_video()); - SrsSharedPtrMessage m; - HELPER_ASSERT_SUCCESS(m.create(msg)); + SrsMediaPacket m; + msg->to_msg(&m); HELPER_EXPECT_SUCCESS(proto.send_and_free_message(m.copy(), 1)); } @@ -5086,9 +5064,9 @@ VOID TEST(ProtocolStackTest, ProtocolPingFlow) SrsUniquePtr msg_uptr(msg); ASSERT_TRUE(msg->header.is_user_control_message()); - SrsPacket *pkt = NULL; + SrsRtmpCommand *pkt = NULL; HELPER_ASSERT_SUCCESS(proto.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); SrsUserControlPacket *spkt = dynamic_cast(pkt); ASSERT_TRUE(spkt != NULL); diff --git a/trunk/src/utest/srs_utest_protocol2.cpp b/trunk/src/utest/srs_utest_protocol2.cpp index 873b386bd..ff877bfd9 100644 --- a/trunk/src/utest/srs_utest_protocol2.cpp +++ b/trunk/src/utest/srs_utest_protocol2.cpp @@ -4269,8 +4269,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid1BMin) SrsUniquePtr msg(msg_raw); EXPECT_TRUE(msg->header.is_video()); - // 1B cid(6bits), min is 2 - EXPECT_EQ(0x02, msg->header.prefer_cid); } VOID TEST(ProtocolKbpsTest, Connections) diff --git a/trunk/src/utest/srs_utest_rtc.cpp b/trunk/src/utest/srs_utest_rtc.cpp index 702cb7f24..a3406910a 100644 --- a/trunk/src/utest/srs_utest_rtc.cpp +++ b/trunk/src/utest/srs_utest_rtc.cpp @@ -2344,21 +2344,21 @@ VOID TEST(KernelRTCTest, H265RtpSTAPPayload) SrsRtpSTAPPayloadHevc stap; // Create sample VPS NALU - SrsSample *vps = new SrsSample(); + SrsNaluSample *vps = new SrsNaluSample(); uint8_t vps_data[] = {0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x90, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x3d, 0x95, 0x98, 0x09}; vps->bytes = (char *)vps_data; vps->size = sizeof(vps_data); stap.nalus.push_back(vps); // Create sample SPS NALU - SrsSample *sps = new SrsSample(); + SrsNaluSample *sps = new SrsNaluSample(); uint8_t sps_data[] = {0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x90, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x3d, 0xa0, 0x02, 0x80, 0x80, 0x2d, 0x16, 0x59, 0x59, 0xa4, 0x93, 0x2b, 0xc0, 0x5a, 0x70, 0x80, 0x80, 0x80, 0x82}; sps->bytes = (char *)sps_data; sps->size = sizeof(sps_data); stap.nalus.push_back(sps); // Create sample PPS NALU - SrsSample *pps = new SrsSample(); + SrsNaluSample *pps = new SrsNaluSample(); uint8_t pps_data[] = {0x44, 0x01, 0xc1, 0x72, 0xb4, 0x62, 0x40}; pps->bytes = (char *)pps_data; pps->size = sizeof(pps_data); @@ -2383,17 +2383,17 @@ VOID TEST(KernelRTCTest, H265RtpSTAPPayload) EXPECT_EQ(3, (int)decode_stap.nalus.size()); // Check VPS - SrsSample *decoded_vps = decode_stap.get_vps(); + SrsNaluSample *decoded_vps = decode_stap.get_vps(); EXPECT_TRUE(decoded_vps != NULL); EXPECT_EQ(sizeof(vps_data), (size_t)decoded_vps->size); // Check SPS - SrsSample *decoded_sps = decode_stap.get_sps(); + SrsNaluSample *decoded_sps = decode_stap.get_sps(); EXPECT_TRUE(decoded_sps != NULL); EXPECT_EQ(sizeof(sps_data), (size_t)decoded_sps->size); // Check PPS - SrsSample *decoded_pps = decode_stap.get_pps(); + SrsNaluSample *decoded_pps = decode_stap.get_pps(); EXPECT_TRUE(decoded_pps != NULL); EXPECT_EQ(sizeof(pps_data), (size_t)decoded_pps->size); @@ -2443,7 +2443,7 @@ VOID TEST(KernelRTCTest, H265RtpFUAPayload) fua.nalu_type = SrsHevcNaluType_CODED_SLICE_IDR; // Create sample payload data - SrsSample *sample = new SrsSample(); + SrsNaluSample *sample = new SrsNaluSample(); uint8_t payload_data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; sample->bytes = (char *)payload_data; sample->size = sizeof(payload_data); @@ -2576,7 +2576,7 @@ VOID TEST(KernelRTCTest, H265RtpPacketKeyframe) pkt.set_payload(stap_payload, SrsRtpPacketPayloadTypeSTAPHevc); // Create VPS NALU - SrsSample *vps = new SrsSample(); + SrsNaluSample *vps = new SrsNaluSample(); uint8_t vps_data[] = {0x40, 0x01}; // VPS NALU header vps->bytes = (char *)vps_data; vps->size = sizeof(vps_data); @@ -2624,7 +2624,7 @@ VOID TEST(KernelRTCTest, H265RtpRawNALUsSkipBytes) SrsRtpRawNALUs raw_nalus; // Create sample HEVC NALU - SrsSample *sample = new SrsSample(); + SrsNaluSample *sample = new SrsNaluSample(); uint8_t nalu_data[] = {0x26, 0x01, 0x12, 0x34, 0x56, 0x78}; // IDR slice sample->bytes = (char *)nalu_data; sample->size = sizeof(nalu_data); @@ -2635,7 +2635,7 @@ VOID TEST(KernelRTCTest, H265RtpRawNALUsSkipBytes) EXPECT_EQ(0x26, header); // Should return first byte // Verify remaining data - std::vector samples; + std::vector samples; HELPER_EXPECT_SUCCESS(raw_nalus.read_samples(samples, 4)); EXPECT_EQ(1, (int)samples.size()); EXPECT_EQ(4, samples[0]->size); @@ -2655,7 +2655,7 @@ VOID TEST(KernelRTCTest, H265RtpRawNALUsSkipBytes) SrsRtpRawNALUs raw_nalus; // Create sample H.264 NALU - SrsSample *sample = new SrsSample(); + SrsNaluSample *sample = new SrsNaluSample(); uint8_t nalu_data[] = {0x65, 0x12, 0x34, 0x56}; // IDR slice sample->bytes = (char *)nalu_data; sample->size = sizeof(nalu_data); @@ -2666,7 +2666,7 @@ VOID TEST(KernelRTCTest, H265RtpRawNALUsSkipBytes) EXPECT_EQ(0x65, header); // Should return first byte // Verify remaining data - std::vector samples; + std::vector samples; HELPER_EXPECT_SUCCESS(raw_nalus.read_samples(samples, 3)); EXPECT_EQ(1, (int)samples.size()); EXPECT_EQ(3, samples[0]->size); diff --git a/trunk/src/utest/srs_utest_rtc2.cpp b/trunk/src/utest/srs_utest_rtc2.cpp index ebdca443c..dc1c93bb1 100644 --- a/trunk/src/utest/srs_utest_rtc2.cpp +++ b/trunk/src/utest/srs_utest_rtc2.cpp @@ -1543,7 +1543,7 @@ public: return srs_success; } - virtual srs_error_t on_frame(SrsSharedPtrMessage *frame) + virtual srs_error_t on_frame(SrsMediaPacket *frame) { frame_count++; return srs_success; diff --git a/trunk/src/utest/srs_utest_rtmp.cpp b/trunk/src/utest/srs_utest_rtmp.cpp index 0f9109337..40bb2cf04 100644 --- a/trunk/src/utest/srs_utest_rtmp.cpp +++ b/trunk/src/utest/srs_utest_rtmp.cpp @@ -22,7 +22,7 @@ using namespace std; -class MockPacket : public SrsPacket +class MockPacket : public SrsRtmpCommand { public: int size; @@ -89,8 +89,7 @@ VOID TEST(ProtocolRTMPTest, PacketEncode) } if (true) { - SrsPacket pkt; - EXPECT_EQ(0, pkt.get_prefer_cid()); + SrsRtmpCommand pkt; EXPECT_EQ(0, pkt.get_message_type()); EXPECT_EQ(0, pkt.get_size()); } @@ -230,7 +229,7 @@ VOID TEST(ProtocolRTMPTest, SendPacketsError) MockBufferIO io; SrsProtocol p(&io); - SrsPacket *pkt = new SrsPacket(); + SrsRtmpCommand *pkt = new SrsRtmpCommand(); HELPER_EXPECT_SUCCESS(p.send_and_free_packet(pkt, 1)); } @@ -251,11 +250,11 @@ VOID TEST(ProtocolRTMPTest, SendPacketsError) pkt.header.initialize_audio(200, 1000, 1); pkt.create_payload(256); - SrsSharedPtrMessage *msg = new SrsSharedPtrMessage(); - msg->create(&pkt); - SrsUniquePtr msg_uptr(msg); + SrsMediaPacket *msg = new SrsMediaPacket(); + pkt.to_msg(msg); + SrsUniquePtr msg_uptr(msg); - SrsSharedPtrMessage *msgs[10240]; + SrsMediaPacket *msgs[10240]; for (int i = 0; i < 10240; i++) { msgs[i] = msg->copy(); } @@ -320,16 +319,16 @@ VOID TEST(ProtocolRTMPTest, SendZeroMessages) if (true) { MockBufferIO io; SrsProtocol p(&io); - SrsSharedPtrMessage *msg = new SrsSharedPtrMessage(); + SrsMediaPacket *msg = new SrsMediaPacket(); HELPER_EXPECT_SUCCESS(p.send_and_free_message(msg, 1)); } if (true) { MockBufferIO io; SrsProtocol p(&io); - SrsSharedPtrMessage *msgs[1024]; + SrsMediaPacket *msgs[1024]; for (int i = 0; i < 1024; i++) { - msgs[i] = new SrsSharedPtrMessage(); + msgs[i] = new SrsMediaPacket(); } HELPER_EXPECT_SUCCESS(p.send_and_free_messages(msgs, 1024, 0)); } @@ -346,8 +345,8 @@ VOID TEST(ProtocolRTMPTest, HugeMessages) pkt.header.initialize_audio(200, 1000, 1); pkt.create_payload(256); - SrsSharedPtrMessage *msg = new SrsSharedPtrMessage(); - msg->create(&pkt); + SrsMediaPacket *msg = new SrsMediaPacket(); + pkt.to_msg(msg); HELPER_EXPECT_SUCCESS(p.send_and_free_message(msg, 1)); EXPECT_EQ(269, io.out_buffer.length()); @@ -361,11 +360,11 @@ VOID TEST(ProtocolRTMPTest, HugeMessages) pkt.header.initialize_audio(200, 1000, 1); pkt.create_payload(256); - SrsSharedPtrMessage *msg = new SrsSharedPtrMessage(); - msg->create(&pkt); - SrsUniquePtr msg_uptr(msg); + SrsMediaPacket *msg = new SrsMediaPacket(); + pkt.to_msg(msg); + SrsUniquePtr msg_uptr(msg); - SrsSharedPtrMessage *msgs[1024]; + SrsMediaPacket *msgs[1024]; for (int i = 0; i < 1024; i++) { msgs[i] = msg->copy(); } @@ -382,11 +381,11 @@ VOID TEST(ProtocolRTMPTest, HugeMessages) pkt.header.initialize_audio(200, 1000, 1); pkt.create_payload(256); - SrsSharedPtrMessage *msg = new SrsSharedPtrMessage(); - msg->create(&pkt); - SrsUniquePtr msg_uptr(msg); + SrsMediaPacket *msg = new SrsMediaPacket(); + pkt.to_msg(msg); + SrsUniquePtr msg_uptr(msg); - SrsSharedPtrMessage *msgs[10240]; + SrsMediaPacket *msgs[10240]; for (int i = 0; i < 10240; i++) { msgs[i] = msg->copy(); } @@ -409,7 +408,7 @@ VOID TEST(ProtocolRTMPTest, DecodeMessages) msg.header.initialize_amf0_script(1, 1); msg.create_payload(1); - SrsPacket *pkt; + SrsRtmpCommand *pkt; HELPER_EXPECT_FAILED(p.decode_message(&msg, &pkt)); } } @@ -467,9 +466,9 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages2) SrsUniquePtr msg_uptr(msg); msg->header.message_type = RTMP_MSG_AMF3CommandMessage; - SrsPacket *pkt; + SrsRtmpCommand *pkt; HELPER_EXPECT_SUCCESS(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); SrsCallPacket *call = (SrsCallPacket *)pkt; EXPECT_STREQ("s", call->command_name.c_str()); @@ -484,9 +483,9 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages2) SrsUniquePtr msg_uptr(msg); msg->header.message_type = RTMP_MSG_AMF3CommandMessage; - SrsPacket *pkt; + SrsRtmpCommand *pkt; HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -498,9 +497,9 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages2) SrsUniquePtr msg_uptr(msg); msg->header.message_type = 0xff; - SrsPacket *pkt; + SrsRtmpCommand *pkt; HELPER_EXPECT_SUCCESS(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -512,9 +511,9 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages2) SrsUniquePtr msg_uptr(msg); msg->header.message_type = RTMP_MSG_AMF0DataMessage; - SrsPacket *pkt; + SrsRtmpCommand *pkt; HELPER_EXPECT_SUCCESS(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } } @@ -531,10 +530,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages3) SrsUniquePtr msg_uptr(msg); msg->header.message_type = RTMP_MSG_AMF0DataMessage; - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Decode the response failed, no transaction ID was set by request. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -546,10 +545,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages3) SrsUniquePtr msg_uptr(msg); msg->header.message_type = RTMP_MSG_AMF3DataMessage; - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Decode the response failed, no transaction ID was set by request. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -561,10 +560,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages3) SrsUniquePtr msg_uptr(msg); msg->header.message_type = RTMP_MSG_AMF3CommandMessage; - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Decode the response failed, no transaction ID was set by request. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -579,10 +578,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages3) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the response packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -597,10 +596,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages3) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the response packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -615,10 +614,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages3) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the response packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -633,10 +632,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages3) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the response packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -652,10 +651,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages3) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the response packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -671,10 +670,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages3) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the response packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } } @@ -690,10 +689,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages4) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the request packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -704,10 +703,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages4) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the request packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -718,10 +717,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages4) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the request packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -732,10 +731,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages4) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the request packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -746,10 +745,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages4) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the request packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -760,10 +759,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages4) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the request packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -774,10 +773,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages4) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the request packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -788,10 +787,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages4) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the request packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -802,10 +801,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages4) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the request packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -816,9 +815,9 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages4) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; HELPER_EXPECT_SUCCESS(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -829,10 +828,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages4) SrsCommonMessage *msg = _create_amf0((char *)bytes, sizeof(bytes), 1); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the request packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } if (true) { @@ -844,10 +843,10 @@ VOID TEST(ProtocolRTMPTest, OnDecodeMessages4) msg->header.message_type = RTMP_MSG_AMF0CommandMessage; SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt; + SrsRtmpCommand *pkt; // Without enough data, it fail when decoding the request packet. HELPER_EXPECT_FAILED(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } } @@ -2134,7 +2133,7 @@ VOID TEST(ProtocolRTMPTest, ServerResponseCommands) srs_freep(pkt); // onStatus(NetStream.Data.Start) - SrsPacket *bpkt = NULL; + SrsRtmpCommand *bpkt = NULL; HELPER_ASSERT_SUCCESS(p.expect_message(&msg, &bpkt)); srs_freep(msg); srs_freep(bpkt); @@ -2682,9 +2681,9 @@ VOID TEST(ProtocolRTMPTest, AgentMessageCodec) HELPER_ASSERT_SUCCESS(p.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt = NULL; + SrsRtmpCommand *pkt = NULL; HELPER_EXPECT_SUCCESS(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } } @@ -2720,14 +2719,14 @@ VOID TEST(ProtocolRTMPTest, AgentMessageCodec) HELPER_ASSERT_SUCCESS(p.recv_message(&msg)); SrsUniquePtr msg_uptr(msg); - SrsPacket *pkt = NULL; + SrsRtmpCommand *pkt = NULL; HELPER_EXPECT_SUCCESS(p.decode_message(msg, &pkt)); - SrsUniquePtr pkt_uptr(pkt); + SrsUniquePtr pkt_uptr(pkt); } } } -srs_error_t _mock_packet_to_shared_msg(SrsPacket *packet, int stream_id, SrsSharedPtrMessage *shared_msg) +srs_error_t _mock_packet_to_shared_msg(SrsRtmpCommand *packet, int stream_id, SrsMediaPacket *shared_msg) { srs_error_t err = srs_success; @@ -2739,9 +2738,7 @@ srs_error_t _mock_packet_to_shared_msg(SrsPacket *packet, int stream_id, SrsShar return err; } - if ((err = shared_msg->create(msg)) != srs_success) { - return err; - } + msg->to_msg(shared_msg); return err; } @@ -2755,18 +2752,18 @@ VOID TEST(ProtocolRTMPTest, CheckStreamID) SrsRtmpClient p(&io); if (true) { - SrsSharedPtrMessage *shared_msgs[2]; + SrsMediaPacket *shared_msgs[2]; SrsConnectAppPacket *res = new SrsConnectAppPacket(); SrsUniquePtr res_uptr(res); if (true) { - SrsSharedPtrMessage *shared_msg = new SrsSharedPtrMessage(); + SrsMediaPacket *shared_msg = new SrsMediaPacket(); HELPER_ASSERT_SUCCESS(_mock_packet_to_shared_msg(res, 1, shared_msg)); shared_msgs[0] = shared_msg; } if (true) { - SrsSharedPtrMessage *shared_msg = new SrsSharedPtrMessage(); + SrsMediaPacket *shared_msg = new SrsMediaPacket(); HELPER_ASSERT_SUCCESS(_mock_packet_to_shared_msg(res, 2, shared_msg)); shared_msgs[1] = shared_msg; } @@ -2800,7 +2797,7 @@ VOID TEST(ProtocolRTMPTest, AgentMessageTransform) SrsRtmpClient p(&io); if (true) { - SrsSharedPtrMessage *shared_msg = new SrsSharedPtrMessage(); + SrsMediaPacket *shared_msg = new SrsMediaPacket(); SrsConnectAppPacket *res = new SrsConnectAppPacket(); HELPER_ASSERT_SUCCESS(_mock_packet_to_shared_msg(res, 1, shared_msg)); srs_freep(res); @@ -2821,7 +2818,7 @@ VOID TEST(ProtocolRTMPTest, AgentMessageTransform) SrsRtmpClient p(&io); if (true) { - SrsSharedPtrMessage *shared_msg = new SrsSharedPtrMessage(); + SrsMediaPacket *shared_msg = new SrsMediaPacket(); SrsConnectAppPacket *res = new SrsConnectAppPacket(); HELPER_ASSERT_SUCCESS(_mock_packet_to_shared_msg(res, 1, shared_msg)); srs_freep(res); @@ -2842,7 +2839,7 @@ VOID TEST(ProtocolRTMPTest, AgentMessageTransform) SrsRtmpServer p(&io); if (true) { - SrsSharedPtrMessage *shared_msg = new SrsSharedPtrMessage(); + SrsMediaPacket *shared_msg = new SrsMediaPacket(); SrsConnectAppPacket *res = new SrsConnectAppPacket(); HELPER_ASSERT_SUCCESS(_mock_packet_to_shared_msg(res, 1, shared_msg)); srs_freep(res); @@ -2863,7 +2860,7 @@ VOID TEST(ProtocolRTMPTest, AgentMessageTransform) SrsRtmpServer p(&io); if (true) { - SrsSharedPtrMessage *shared_msg = new SrsSharedPtrMessage(); + SrsMediaPacket *shared_msg = new SrsMediaPacket(); SrsConnectAppPacket *res = new SrsConnectAppPacket(); HELPER_ASSERT_SUCCESS(_mock_packet_to_shared_msg(res, 1, shared_msg)); srs_freep(res); @@ -2929,7 +2926,7 @@ VOID TEST(ProtocolRTMPTest, CreateRTMPMessage) // Invalid message type. if (true) { - SrsSharedPtrMessage *msg = NULL; + SrsCommonMessage *msg = NULL; HELPER_EXPECT_FAILED(srs_rtmp_create_msg(SrsFrameTypeForbidden, 0, _strcpy("Hello"), 5, 0, &msg)); EXPECT_TRUE(NULL == msg); } @@ -2941,7 +2938,7 @@ VOID TEST(ProtocolRTMPTest, CreateRTMPMessage) // Normal script message. if (true) { - SrsSharedPtrMessage *msg = NULL; + SrsCommonMessage *msg = NULL; HELPER_EXPECT_SUCCESS(srs_rtmp_create_msg(SrsFrameTypeScript, 0, _strcpy("Hello"), 5, 0, &msg)); EXPECT_STREQ("Hello", msg->payload()); srs_freep(msg); @@ -2949,7 +2946,7 @@ VOID TEST(ProtocolRTMPTest, CreateRTMPMessage) // Normal video message. if (true) { - SrsSharedPtrMessage *msg = NULL; + SrsCommonMessage *msg = NULL; HELPER_EXPECT_SUCCESS(srs_rtmp_create_msg(SrsFrameTypeVideo, 0, _strcpy("Hello"), 5, 0, &msg)); EXPECT_STREQ("Hello", msg->payload()); srs_freep(msg); @@ -2957,7 +2954,7 @@ VOID TEST(ProtocolRTMPTest, CreateRTMPMessage) // Normal audio message. if (true) { - SrsSharedPtrMessage *msg = NULL; + SrsCommonMessage *msg = NULL; HELPER_EXPECT_SUCCESS(srs_rtmp_create_msg(SrsFrameTypeAudio, 0, _strcpy("Hello"), 5, 0, &msg)); EXPECT_STREQ("Hello", msg->payload()); srs_freep(msg); @@ -3046,8 +3043,8 @@ VOID TEST(ProtocolRTMPTest, OthersAll) SrsMessageArray *parr = &h; SrsUniquePtr parr2(parr, srs_utest_free_message_array); - h.msgs[0] = new SrsSharedPtrMessage(); - h.msgs[1] = new SrsSharedPtrMessage(); + h.msgs[0] = new SrsMediaPacket(); + h.msgs[1] = new SrsMediaPacket(); EXPECT_TRUE(NULL != h.msgs[0]); EXPECT_TRUE(NULL != h.msgs[1]);