SRT2RTMP: fix srt bridge hevc to rtmp error. v7.0.84 (#4446)
try to fix #4428. ## Cause rtmp do not support hevc, rtmp enhanced do. ## How to reproduce 1. start srs. `./objs/srs -c conf/srt.conf` 2. publish hevc (h.265) stream to srs by srt. `ffmpeg -re -i ./doc/source.flv -c:v libx265 -crf 28 -preset medium -c:a copy -pes_payload_size 0 -f mpegts 'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish'` 3. probe the rtmp stream `ffprobe rtmp://localhost/live/livestream` ## About the Failed BlackBox test The failed blackbox test: `TestSlow_SrtPublish_RtmpPlay_HEVC_Basic` `TestSlow_SrtPublish_HttpFlvPlay_HEVC_Basic` ### Cause: The ffmpeg 5 is used to record a piece of video (DRV), the ffmpeg will transcode the enhanced flv format to TS format, but ffmpeg 5 don't support enhanced rtmp (or flv) in this case. The solution is to replace the ffmpeg to version 7 in those 2 test cases. ### why not upgrade ffmpeg to version 7? The black tests dependency on ffmpeg 5 will fail, and there are a few of them are not easy to resolve in ffmpeg 7. --------- Co-authored-by: winlin <winlinvip@gmail.com>
This commit is contained in:
parent
3a29e5c550
commit
a6d14eb09a
|
|
@ -709,6 +709,8 @@ func TestSlow_SrtPublish_RtmpPlay_HEVC_Basic(t *testing.T) {
|
|||
v.dvrFile = path.Join(svr.WorkDir(), "objs", fmt.Sprintf("srs-ffprobe-%v.ts", streamID))
|
||||
v.streamURL = fmt.Sprintf("rtmp://localhost:%v/live/%v", svr.RTMPPort(), streamID)
|
||||
v.duration, v.timeout = duration, time.Duration(*srsFFprobeTimeout)*time.Millisecond
|
||||
v.ffmpegCmdName = "ffmpeg7" // ffmpeg 5 don't support enhanced rtmp, so use ffmpeg 7 instead.
|
||||
v.ffprobeCmdName = "ffprobe7"
|
||||
})
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
|
|
@ -807,6 +809,8 @@ func TestSlow_SrtPublish_HttpFlvPlay_HEVC_Basic(t *testing.T) {
|
|||
v.dvrFile = path.Join(svr.WorkDir(), "objs", fmt.Sprintf("srs-ffprobe-%v.ts", streamID))
|
||||
v.streamURL = fmt.Sprintf("http://localhost:%v/live/%v.flv", svr.HTTPPort(), streamID)
|
||||
v.duration, v.timeout = duration, time.Duration(*srsFFprobeTimeout)*time.Millisecond
|
||||
v.ffmpegCmdName = "ffmpeg7" // ffmpeg 5 don't support enhanced rtmp, so use ffmpeg 7 instead.
|
||||
v.ffprobeCmdName = "ffprobe7"
|
||||
})
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
|
|
|
|||
19
trunk/3rdparty/srs-bench/blackbox/util.go
vendored
19
trunk/3rdparty/srs-bench/blackbox/util.go
vendored
|
|
@ -666,6 +666,8 @@ type ffmpegClient struct {
|
|||
// The backend service process.
|
||||
process *backendService
|
||||
|
||||
// FFmpeg cmd name
|
||||
ffmpegCmdName string
|
||||
// FFmpeg cli args, without ffmpeg binary.
|
||||
args []string
|
||||
// Let the process quit, do not cancel the case.
|
||||
|
|
@ -678,6 +680,7 @@ func NewFFmpeg(opts ...func(v *ffmpegClient)) FFmpegClient {
|
|||
v := &ffmpegClient{
|
||||
process: newBackendService(),
|
||||
cancelCaseWhenQuit: true,
|
||||
ffmpegCmdName: *srsFFmpeg,
|
||||
}
|
||||
|
||||
// Do cleanup.
|
||||
|
|
@ -702,7 +705,7 @@ func (v *ffmpegClient) ReadyCtx() context.Context {
|
|||
func (v *ffmpegClient) Run(ctx context.Context, cancel context.CancelFunc) error {
|
||||
logger.Tf(ctx, "Starting FFmpeg by %v", strings.Join(v.args, " "))
|
||||
|
||||
v.process.name = *srsFFmpeg
|
||||
v.process.name = v.ffmpegCmdName
|
||||
v.process.args = v.args
|
||||
v.process.env = os.Environ()
|
||||
v.process.duration = v.ffmpegDuration
|
||||
|
|
@ -746,6 +749,10 @@ type ffprobeClient struct {
|
|||
// The timeout to wait for task to done.
|
||||
timeout time.Duration
|
||||
|
||||
// the FFprobe cmd name
|
||||
ffprobeCmdName string
|
||||
// the ffmpeg cmd name
|
||||
ffmpegCmdName string
|
||||
// Whether do DVR by FFmpeg, if using SRS DVR, please set to false.
|
||||
dvrByFFmpeg bool
|
||||
// The stream to DVR for probing. Ignore if not DVR by ffmpeg
|
||||
|
|
@ -764,8 +771,10 @@ type ffprobeClient struct {
|
|||
|
||||
func NewFFprobe(opts ...func(v *ffprobeClient)) FFprobeClient {
|
||||
v := &ffprobeClient{
|
||||
metadata: &ffprobeObject{},
|
||||
dvrByFFmpeg: true,
|
||||
metadata: &ffprobeObject{},
|
||||
dvrByFFmpeg: true,
|
||||
ffprobeCmdName: *srsFFprobe,
|
||||
ffmpegCmdName: *srsFFmpeg,
|
||||
}
|
||||
v.doneCtx, v.doneCancel = context.WithCancel(context.Background())
|
||||
|
||||
|
|
@ -842,7 +851,7 @@ func (v *ffprobeClient) doDVR(ctx context.Context) error {
|
|||
}
|
||||
|
||||
process := newBackendService()
|
||||
process.name = *srsFFmpeg
|
||||
process.name = v.ffmpegCmdName
|
||||
process.args = []string{
|
||||
"-t", fmt.Sprintf("%v", int64(v.duration/time.Second)),
|
||||
"-i", v.streamURL, "-c", "copy", "-y", v.dvrFile,
|
||||
|
|
@ -869,7 +878,7 @@ func (v *ffprobeClient) doDVR(ctx context.Context) error {
|
|||
|
||||
func (v *ffprobeClient) doProbe(ctx context.Context, cancel context.CancelFunc) error {
|
||||
process := newBackendService()
|
||||
process.name = *srsFFprobe
|
||||
process.name = v.ffprobeCmdName
|
||||
process.args = []string{
|
||||
"-show_error", "-show_private_data", "-v", "quiet", "-find_stream_info",
|
||||
"-analyzeduration", fmt.Sprintf("%v", int64(v.duration/time.Microsecond)),
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ The changelog for SRS.
|
|||
<a name="v7-changes"></a>
|
||||
|
||||
## SRS 7.0 Changelog
|
||||
* v7.0, 2025-09-09, Merge [#4446](https://github.com/ossrs/srs/pull/4446): SRT2RTMP: fix srt bridge hevc to rtmp error. v7.0.84 (#4446)
|
||||
* v7.0, 2025-09-09, Merge [#4482](https://github.com/ossrs/srs/pull/4482): AI: Fix naming issue for protocol module. v7.0.83 (#4482)
|
||||
* v7.0, 2025-09-07, Merge [#4479](https://github.com/ossrs/srs/pull/4479): AI: Fix naming problem in kernel module. v7.0.82 (#4479)
|
||||
* v7.0, 2025-09-06, Merge [#4478](https://github.com/ossrs/srs/pull/4478): AI: Add more utests for kernel module. v7.0.81 (#4478)
|
||||
|
|
|
|||
|
|
@ -671,6 +671,7 @@ srs_error_t SrsSrtFrameBuilder::check_vps_sps_pps_change(SrsTsMessage *msg)
|
|||
|
||||
// ts tbn to flv tbn.
|
||||
uint32_t dts = (uint32_t)(msg->dts_ / 90);
|
||||
uint32_t pts = (uint32_t)(msg->pts_ / 90);
|
||||
|
||||
std::string sh;
|
||||
SrsUniquePtr<SrsRawHEVCStream> hevc(new SrsRawHEVCStream());
|
||||
|
|
@ -682,8 +683,14 @@ srs_error_t SrsSrtFrameBuilder::check_vps_sps_pps_change(SrsTsMessage *msg)
|
|||
// h265 packet to flv packet.
|
||||
char *flv = NULL;
|
||||
int nb_flv = 0;
|
||||
if ((err = hevc->mux_avc2flv(sh, SrsVideoAvcFrameTypeKeyFrame, SrsVideoAvcFrameTraitSequenceHeader, dts, dts, &flv, &nb_flv)) != srs_success) {
|
||||
return srs_error_wrap(err, "avc to flv");
|
||||
if ((err = hevc->mux_avc2flv_enhanced(sh,
|
||||
SrsVideoAvcFrameTypeKeyFrame,
|
||||
SrsVideoHEVCFrameTraitPacketTypeSequenceStart,
|
||||
dts,
|
||||
pts,
|
||||
&flv,
|
||||
&nb_flv)) != srs_success) {
|
||||
return srs_error_wrap(err, "hevc sh to flv");
|
||||
}
|
||||
|
||||
SrsMessageHeader header;
|
||||
|
|
@ -713,8 +720,6 @@ srs_error_t SrsSrtFrameBuilder::on_hevc_frame(SrsTsMessage *msg, vector<pair<cha
|
|||
|
||||
// ts tbn to flv tbn.
|
||||
uint32_t dts = (uint32_t)(msg->dts_ / 90);
|
||||
uint32_t pts = (uint32_t)(msg->pts_ / 90);
|
||||
int32_t cts = pts - dts;
|
||||
|
||||
// for IDR frame, the frame is keyframe.
|
||||
SrsVideoAvcFrameType frame_type = SrsVideoAvcFrameTypeInterFrame;
|
||||
|
|
@ -736,16 +741,9 @@ srs_error_t SrsSrtFrameBuilder::on_hevc_frame(SrsTsMessage *msg, vector<pair<cha
|
|||
SrsBuffer payload(rtmp.payload(), rtmp.size());
|
||||
|
||||
// Write 5bytes video tag header.
|
||||
|
||||
// @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
|
||||
// Frame Type, Type of video frame.
|
||||
// CodecID, Codec Identifier.
|
||||
// set the rtmp header
|
||||
payload.write_1bytes((frame_type << 4) | SrsVideoCodecIdHEVC);
|
||||
// hevc_type: nalu
|
||||
payload.write_1bytes(0x01);
|
||||
// composition time
|
||||
payload.write_3bytes(cts);
|
||||
// @see: https://veovera.org/docs/enhanced/enhanced-rtmp-v1.pdf, page 8
|
||||
payload.write_1bytes(SRS_FLV_IS_EX_HEADER | (frame_type << 4) | SrsVideoHEVCFrameTraitPacketTypeCodedFramesX);
|
||||
payload.write_4bytes(0x68766331); // 'h' 'v' 'c' '1'
|
||||
|
||||
// Write video nalus.
|
||||
for (size_t i = 0; i != ipb_frames.size(); ++i) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 7
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 83
|
||||
#define VERSION_REVISION 84
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user