Opened 11 months ago

Last modified 11 months ago

#9126 new defect

404 when playing back DASH

Reported by: hjmallon Owned by:
Priority: normal Component: avformat
Version: git-master Keywords: dash
Cc: liuqi05@kuaishou.com Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:
How to reproduce:

% ffprobe http://192.168.1.18:8080/live/manifest.mpd
ffprobe version 4.3.2 Copyright (c) 2007-2021 the FFmpeg developers
  built with Apple clang version 12.0.0 (clang-1200.0.32.29)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.2 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
[http @ 0x7f849d805580] HTTP error 404 Not Found
[dash @ 0x7f849e00c000] Failed to open an initialization section in playlist 0
[dash @ 0x7f849e00c000] Error when loading first fragment, playlist 0
http://192.168.1.18:8080/live/manifest.mpd: Server returned 404 Not Found

This DASH manifest plays back in VLC OK. I have tracked the problem down to BaseURL handling in resolve_content_path. The manifest has a BaseURL in the AdaptationSet and another in the Representation.

e.g.
URL - http://192.168.1.18:8080/live/manifest.mpd
AdaptationSet/BaseURL - video/
Representation/BaseURL - v_34_10000/

The assets are under http://192.168.1.18:8080/live/video/v_34_10000/ but ffmpeg only concatenates the BaseURL with the Root URL (i.e. http://192.168.1.18:8080/live/v_34_10000/), rather than all the parent BaseURLs. I do not have access to the relevant standard so I don't know if concat parents is the expected behaviour (but that seems to be what VLC does).

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" id="1614186048" profiles="urn:mpeg:dash:profile:full:2011" type="dynamic" availabilityStartTime="2021-02-24T17:00:49Z" publishTime="2021-02-24T18:02:43Z" minimumUpdatePeriod="PT2S" timeShiftBufferDepth="PT20S" minBufferTime="PT2S">
	<Period id="p0" start="PT0S">
		<AdaptationSet contentType="video" segmentAlignment="true" mimeType="video/mp4" par="16:9" maxWidth="1920" maxHeight="1080" maxFrameRate="30.00/1001">
			<BaseURL>video/</BaseURL>
			<Representation id="v_34_10000" bandwidth="10000000" width="1920" height="1080" sar="1:1" frameRate="30.00/1001" codecs="hvc1.1.60000000.L93.B0.00.00.00.00.00" startWithSAP="1">
				<BaseURL>v_34_10000/</BaseURL>
				<SegmentTemplate timescale="30030" duration="84084" startNumber="1" media="1614186048_$Number$.m4s" initialization="1614186048_init.mp4"/>
			</Representation>
		</AdaptationSet>
		<AdaptationSet contentType="audio" lang="und" segmentAlignment="true" mimeType="audio/mp4">
			<BaseURL>audio/</BaseURL>
			<Representation id="a_35_SAMPLE_RATE_48000" bandwidth="128000" audioSamplingRate="SAMPLE_RATE_48000" codecs="mp4a.40.2" startWithSAP="1">
				<BaseURL>a_35_SAMPLE_RATE_48000/</BaseURL>
				<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="1"></AudioChannelConfiguration>
				<SegmentTemplate timescale="48000" duration="134400" startNumber="1" media="1614186048_$Number$.m4s" initialization="1614186048_init.mp4"/>
			</Representation>
		</AdaptationSet>
	</Period>
</MPD>

Change History (4)

comment:1 by Carl Eugen Hoyos, 11 months ago

Keywords: 404 removed

Is the issue reproducible with current FFmpeg git head, the only version supported on this bug tracker?

comment:2 by Steven Liu, 11 months ago

Cc: liuqi05@kuaishou.com added

Can you provide how to create that mpd or leave the usable mpd url here? let me test and debug that. :D

comment:3 by hjmallon, 11 months ago

Is the issue reproducible with current FFmpeg git head, the only version supported on this bug tracker?

I can reproduce it on HEAD (d3d99a0a / "lavc/lscrdec: use ff_reget_buffer()").

Can you provide how to create that mpd or leave the usable mpd url here?

Hmm, the manifest is made by a live video encoder (one of these https://videon-central.com/) so I don't have a web link. With the manifest like above the layout of files is:

  • http://192.168.1.18:8080/live/
    • manifest.mpd
    • video/
      • v_34_10000/
        • 1614186048_init.mp4
        • 1614186048_123456.m4s
    • audio/
      • a_35_SAMPLE_RATE_48000/
        • 1614186048_init.mp4
        • 1614186048_123456.m4s

The 404 is generated when ffprobe looks for "http://192.168.1.18:8080/live/v_34_10000/1614186048_init.mp4" (without the video/ part).

I have been able to fix the issue with a patch as follows (I wouldn't say I know enough about DASH to say that the patch is correct):

diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
index b82805c9ce..5abc914c68 100644
--- a/libavformat/dashdec.c
+++ b/libavformat/dashdec.c
@@ -777,14 +777,14 @@ static int resolve_content_path(AVFormatContext *s, const char *url, int *max_ur
         size += 2;
     }

+    memset(tmp_str, 0, strlen(tmp_str));
     for (i = 0; i < n_baseurl_nodes; ++i) {
         if (i == rootId) {
             continue;
         }
         text = xmlNodeGetContent(baseurl_nodes[i]);
         if (text && !av_strstart(text, "/", NULL)) {
-            memset(tmp_str, 0, strlen(tmp_str));
-            if (!ishttp(text) && isRootHttp) {
+            if (!ishttp(tmp_str) && !ishttp(text) && isRootHttp) {
                 av_strlcpy(tmp_str, root_url, size + 1);
             }
             start = (text[0] == token);

in reply to:  3 comment:4 by Steven Liu, 11 months ago

Replying to hjmallon:

Is the issue reproducible with current FFmpeg git head, the only version supported on this bug tracker?

I can reproduce it on HEAD (d3d99a0a / "lavc/lscrdec: use ff_reget_buffer()").

Can you provide how to create that mpd or leave the usable mpd url here?

Hmm, the manifest is made by a live video encoder (one of these https://videon-central.com/) so I don't have a web link. With the manifest like above the layout of files is:

  • http://192.168.1.18:8080/live/
    • manifest.mpd
    • video/
      • v_34_10000/
        • 1614186048_init.mp4
        • 1614186048_123456.m4s
    • audio/
      • a_35_SAMPLE_RATE_48000/
        • 1614186048_init.mp4
        • 1614186048_123456.m4s

The 404 is generated when ffprobe looks for "http://192.168.1.18:8080/live/v_34_10000/1614186048_init.mp4" (without the video/ part).

I have been able to fix the issue with a patch as follows (I wouldn't say I know enough about DASH to say that the patch is correct):

diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
index b82805c9ce..5abc914c68 100644
--- a/libavformat/dashdec.c
+++ b/libavformat/dashdec.c
@@ -777,14 +777,14 @@ static int resolve_content_path(AVFormatContext *s, const char *url, int *max_ur
         size += 2;
     }

+    memset(tmp_str, 0, strlen(tmp_str));
     for (i = 0; i < n_baseurl_nodes; ++i) {
         if (i == rootId) {
             continue;
         }
         text = xmlNodeGetContent(baseurl_nodes[i]);
         if (text && !av_strstart(text, "/", NULL)) {
-            memset(tmp_str, 0, strlen(tmp_str));
-            if (!ishttp(text) && isRootHttp) {
+            if (!ishttp(tmp_str) && !ishttp(text) && isRootHttp) {
                 av_strlcpy(tmp_str, root_url, size + 1);
             }
             start = (text[0] == token);

Can you send this patch to maillist?

Note: See TracTickets for help on using tickets.