sergey-dryabzhinsky / nginx-rtmp-module

NGINX-based Media Streaming Server
http://nginx-rtmp.blogspot.com
BSD 2-Clause "Simplified" License
1.02k stars 215 forks source link

DASH timeShiftBufferDepth and suggestedPresentationDelay #243

Open codegastudio opened 7 years ago

codegastudio commented 7 years ago

Hello,

I stream rtsp camera ip which is redirect to rtmp server for dash and hls. Dash manifest is played with dash.js and hls with vlc.

    application dash {
        live on;

        dash on;
        dash_nested on;
        dash_path /tmp/dash;

        dash_fragment 1s;
        dash_playlist_length 2s;

        allow publish 127.0.0.1;
        deny publish all;
    }
ffmpeg -f rtsp -re -rtsp_transport tcp -i ${RTSP_INPUT} -c copy -force_key_frames "expr:gte(t,n_forced*1)" -f flv rtmp://localhost:1935/dash/movie

All work fine but i would like to know if it's possible to reduce suggestedPresentationDelay in dash manifest to limit stream delay at just the timeShiftBufferDepth.

When i see the video in dash.js client the delay is approximately the sum of this two values (suggestedPresentationDelay+ timeShiftBufferDepth) -> 9s delay.

After many tests on dash_fragment and dash_playlist_length, it seems to be not possible to down under dash_fragment 1s. dash_playlist_length cannot be set under 2 * dash_fragment duration. manifest.mpd is not created on server so player can't get him to play video. dash_fragment 1s and dash_playlist_length 2s generate a stable timeShiftBufferDepth of 4s.

sergey-dryabzhinsky nginx-rtmp-module Stream working

ngx_rtmp_dash_module.c line 455

   update_period = dacf->fraglen;

    for (i = 0; i < ctx->nfrags; i++) {
        f = ngx_rtmp_dash_get_frag(s, i);
        if (f->duration > update_period) {
            update_period = f->duration;
        }
    }

    // Reasonable delay for streaming
    presentation_delay = update_period * 2 + 1000;
    presentation_delay_msec = presentation_delay % 1000;
    presentation_delay -= presentation_delay_msec;
    presentation_delay /= 1000;

    // Calculate msec part and seconds
    update_period_msec = update_period % 1000;
    update_period -= update_period_msec;
    update_period /= 1000;

    // Buffer length by default fragment length
    buffer_time = dacf->fraglen;
    buffer_time_msec = buffer_time % 1000;
    buffer_time -= buffer_time_msec;
    buffer_time /= 1000;

    // Fill DASH header
    p = ngx_slprintf(buffer, last, NGX_RTMP_DASH_MANIFEST_HEADER,
                     // availabilityStartTime
                     avaliable_time,
                     // publishTime
                     publish_time,
                     // minimumUpdatePeriod
                     update_period, update_period_msec,
                     // minBufferTime
                     buffer_time, buffer_time_msec,
                     // timeShiftBufferDepth
                     buffer_depth,
                     // suggestedPresentationDelay
                     presentation_delay, presentation_delay_msec
                     );

fraglen is dash_fragment in milliseconds. set dash_fragment 1s -> fraglen 1000ms .

  • minimumUpdatePeriod should be 1s -> 2s written .
  • minBufferTime 1s.
  • timeShiftBufferDepth should be 1s -> 4s written
  • suggestedPresentationDelay should be 3s -> 5s written

with sergey-dryabzhinsky nginx-rtmp-module

<?xml version="1.0"?>
<MPD
    type="dynamic"
    xmlns="urn:mpeg:dash:schema:mpd:2011"
    availabilityStartTime="2017-05-12T14:09:53Z"
    publishTime="2017-05-12T14:09:53Z"
    minimumUpdatePeriod="PT2.000S"
    minBufferTime="PT1.000S"
    timeShiftBufferDepth="P0Y00M00DT0H00M04.000S"
    suggestedPresentationDelay="PT5.000S"
    profiles="urn:hbbtv:dash:profile:isoff-live:2012,urn:mpeg:dash:profile:isoff-live:2011"
    xmlns:xsi="http://www.w3.org/2011/XMLSchema-instance"
    xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd">
  <Period start="PT0S" id="dash">
    <AdaptationSet
        id="1"
        startWithSAP="1"
        segmentAlignment="true"
        maxWidth="704"
        maxHeight="576"
        maxFrameRate="12"
        par="11:9">
      <Representation
          id="movie_H264"
          mimeType="video/mp4"
          codecs="avc1.4d401e"
          width="704"
          height="576"
          frameRate="12"
          sar="1:1"
          bandwidth="0">
        <SegmentTemplate
            presentationTimeOffset="0"
            timescale="1000"
            media="$Time$.m4v"
            initialization="init.m4v">
          <SegmentTimeline>
             <S t="35170" d="2000"/>
             <S t="37170" d="2000"/>
          </SegmentTimeline>
        </SegmentTemplate>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

arut nginx-rtmp-module Stream not working

ngx_rtmp_dash_module.c line 256

#define NGX_RTMP_DASH_MANIFEST_HEADER                                          \
    "<?xml version=\"1.0\"?>\n"                                                \
    "<MPD\n"                                                                   \
    "    type=\"dynamic\"\n"                                                   \
    "    xmlns=\"urn:mpeg:dash:schema:mpd:2011\"\n"                            \
    "    availabilityStartTime=\"%s\"\n"                                       \
    "    availabilityEndTime=\"%s\"\n"                                         \
    "    minimumUpdatePeriod=\"PT%uiS\"\n"                                     \
    "    minBufferTime=\"PT%uiS\"\n"                                           \
    "    timeShiftBufferDepth=\"PT0H0M0.00S\"\n"                               \
    "    suggestedPresentationDelay=\"PT%uiS\"\n"                              \
    "    profiles=\"urn:hbbtv:dash:profile:isoff-live:2012,"                   \
                   "urn:mpeg:dash:profile:isoff-live:2011\"\n"                 \
    "    xmlns:xsi=\"http://www.w3.org/2011/XMLSchema-instance\"\n"            \
    "    xsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd\">\n" \
    "  <Period start=\"PT0S\" id=\"dash\">\n"

ngx_rtmp_dash_module.c line 370

p = ngx_slprintf(buffer, last, NGX_RTMP_DASH_MANIFEST_HEADER,
                   start_time,
                   end_time,
                   (ngx_uint_t) (dacf->fraglen / 1000), // minimumUpdatePeriod
                   (ngx_uint_t) (dacf->fraglen / 1000), // minBufferTime
                   (ngx_uint_t) (dacf->fraglen / 500)); // suggestedPresentationDelay

fraglen is dash_fragment in milliseconds. set dash_fragment 1s -> fraglen 1000ms .

  • minimumUpdatePeriod 1s .
  • minBufferTime 1s.
  • timeShiftBufferDepth 0s. -> hard coded ! Reason of non playing stream in dash.js player ?
  • suggestedPresentationDelay 2s.

with arut nginx-rtmp-module

<?xml version="1.0"?>
<MPD
    type="dynamic"
    xmlns="urn:mpeg:dash:schema:mpd:2011"
    availabilityStartTime="2017-05-12T17:42:35+02:00"
    availabilityEndTime="2017-05-12T17:42:39+02:00"
    minimumUpdatePeriod="PT1S"
    minBufferTime="PT1S"
    timeShiftBufferDepth="PT0H0M0.00S"
    suggestedPresentationDelay="PT2S"
    profiles="urn:hbbtv:dash:profile:isoff-live:2012,urn:mpeg:dash:profile:isoff-live:2011"
    xmlns:xsi="http://www.w3.org/2011/XMLSchema-instance"
    xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd">
  <Period start="PT0S" id="dash">
    <AdaptationSet
        id="1"
        segmentAlignment="true"
        maxWidth="704"
        maxHeight="576"
        maxFrameRate="12">
      <Representation
          id="movie_H264"
          mimeType="video/mp4"
          codecs="avc1.4d401e"
          width="704"
          height="576"
          frameRate="12"
          sar="1:1"
          startWithSAP="1"
          bandwidth="0">
        <SegmentTemplate
            presentationTimeOffset="0"
            timescale="1000"
            media="$Time$.m4v"
            initialization="init.m4v">
          <SegmentTimeline>
             <S t="2000" d="2000"/>
             <S t="4000" d="2000"/>
          </SegmentTimeline>
        </SegmentTemplate>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

Why so big differences about header calcul values ?

This will be wonderfull if we can decrease timeShiftBufferDepth and or suggestedPresentationDelay for live. Let me know if this is a possible way or if DASH can't do better than 10sec of delay.

Best regards and thanks a lot for your job !

codegastudio commented 7 years ago

Any comment will be appreciated :/

matansag commented 7 years ago

+1