Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
ba71ebbb
Commit
ba71ebbb
authored
Nov 30, 2018
by
Steven Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avformat/dashdec: add subtitle stream support
Signed-off-by:
Steven Liu
<
lq@chinaffmpeg.org
>
parent
b87063c0
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
90 additions
and
7 deletions
+90
-7
dashdec.c
libavformat/dashdec.c
+90
-7
No files found.
libavformat/dashdec.c
View file @
ba71ebbb
...
@@ -140,6 +140,8 @@ typedef struct DASHContext {
...
@@ -140,6 +140,8 @@ typedef struct DASHContext {
struct
representation
**
videos
;
struct
representation
**
videos
;
int
n_audios
;
int
n_audios
;
struct
representation
**
audios
;
struct
representation
**
audios
;
int
n_subtitles
;
struct
representation
**
subtitles
;
/* MediaPresentationDescription Attribute */
/* MediaPresentationDescription Attribute */
uint64_t
media_presentation_duration
;
uint64_t
media_presentation_duration
;
...
@@ -394,6 +396,17 @@ static void free_audio_list(DASHContext *c)
...
@@ -394,6 +396,17 @@ static void free_audio_list(DASHContext *c)
c
->
n_audios
=
0
;
c
->
n_audios
=
0
;
}
}
static
void
free_subtitle_list
(
DASHContext
*
c
)
{
int
i
;
for
(
i
=
0
;
i
<
c
->
n_subtitles
;
i
++
)
{
struct
representation
*
pls
=
c
->
subtitles
[
i
];
free_representation
(
pls
);
}
av_freep
(
&
c
->
subtitles
);
c
->
n_subtitles
=
0
;
}
static
int
open_url
(
AVFormatContext
*
s
,
AVIOContext
**
pb
,
const
char
*
url
,
static
int
open_url
(
AVFormatContext
*
s
,
AVIOContext
**
pb
,
const
char
*
url
,
AVDictionary
*
opts
,
AVDictionary
*
opts2
,
int
*
is_http
)
AVDictionary
*
opts
,
AVDictionary
*
opts2
,
int
*
is_http
)
{
{
...
@@ -565,6 +578,8 @@ static enum AVMediaType get_content_type(xmlNodePtr node)
...
@@ -565,6 +578,8 @@ static enum AVMediaType get_content_type(xmlNodePtr node)
type
=
AVMEDIA_TYPE_VIDEO
;
type
=
AVMEDIA_TYPE_VIDEO
;
}
else
if
(
av_stristr
((
const
char
*
)
val
,
"audio"
))
{
}
else
if
(
av_stristr
((
const
char
*
)
val
,
"audio"
))
{
type
=
AVMEDIA_TYPE_AUDIO
;
type
=
AVMEDIA_TYPE_AUDIO
;
}
else
if
(
av_stristr
((
const
char
*
)
val
,
"text"
))
{
type
=
AVMEDIA_TYPE_SUBTITLE
;
}
}
xmlFree
(
val
);
xmlFree
(
val
);
}
}
...
@@ -818,6 +833,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
...
@@ -818,6 +833,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
xmlNodePtr
adaptionset_supplementalproperty_node
)
xmlNodePtr
adaptionset_supplementalproperty_node
)
{
{
int32_t
ret
=
0
;
int32_t
ret
=
0
;
int32_t
subtitle_rep_idx
=
0
;
int32_t
audio_rep_idx
=
0
;
int32_t
audio_rep_idx
=
0
;
int32_t
video_rep_idx
=
0
;
int32_t
video_rep_idx
=
0
;
DASHContext
*
c
=
s
->
priv_data
;
DASHContext
*
c
=
s
->
priv_data
;
...
@@ -854,7 +870,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
...
@@ -854,7 +870,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
type
=
get_content_type
(
adaptionset_node
);
type
=
get_content_type
(
adaptionset_node
);
if
(
type
==
AVMEDIA_TYPE_UNKNOWN
)
{
if
(
type
==
AVMEDIA_TYPE_UNKNOWN
)
{
av_log
(
s
,
AV_LOG_VERBOSE
,
"Parsing '%s' - skipp not supported representation type
\n
"
,
url
);
av_log
(
s
,
AV_LOG_VERBOSE
,
"Parsing '%s' - skipp not supported representation type
\n
"
,
url
);
}
else
if
(
type
==
AVMEDIA_TYPE_VIDEO
||
type
==
AVMEDIA_TYPE_AUDIO
)
{
}
else
if
(
type
==
AVMEDIA_TYPE_VIDEO
||
type
==
AVMEDIA_TYPE_AUDIO
||
type
==
AVMEDIA_TYPE_SUBTITLE
)
{
// convert selected representation to our internal struct
// convert selected representation to our internal struct
rep
=
av_mallocz
(
sizeof
(
struct
representation
));
rep
=
av_mallocz
(
sizeof
(
struct
representation
));
if
(
!
rep
)
{
if
(
!
rep
)
{
...
@@ -1048,18 +1064,29 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
...
@@ -1048,18 +1064,29 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
av_log
(
s
,
AV_LOG_VERBOSE
,
"Ignoring invalid frame rate '%s'
\n
"
,
rep_framerate_val
);
av_log
(
s
,
AV_LOG_VERBOSE
,
"Ignoring invalid frame rate '%s'
\n
"
,
rep_framerate_val
);
}
}
if
(
type
==
AVMEDIA_TYPE_VIDEO
)
{
switch
(
type
)
{
rep
->
rep_idx
=
video_rep_idx
;
case
AVMEDIA_TYPE_VIDEO
:
dynarray_add
(
&
c
->
videos
,
&
c
->
n_videos
,
rep
);
rep
->
rep_idx
=
video_rep_idx
;
}
else
{
dynarray_add
(
&
c
->
videos
,
&
c
->
n_videos
,
rep
);
rep
->
rep_idx
=
audio_rep_idx
;
break
;
dynarray_add
(
&
c
->
audios
,
&
c
->
n_audios
,
rep
);
case
AVMEDIA_TYPE_AUDIO
:
rep
->
rep_idx
=
audio_rep_idx
;
dynarray_add
(
&
c
->
audios
,
&
c
->
n_audios
,
rep
);
break
;
case
AVMEDIA_TYPE_SUBTITLE
:
rep
->
rep_idx
=
subtitle_rep_idx
;
dynarray_add
(
&
c
->
subtitles
,
&
c
->
n_subtitles
,
rep
);
break
;
default:
av_log
(
s
,
AV_LOG_WARNING
,
"Unsupported the stream type %d
\n
"
,
type
);
break
;
}
}
}
}
}
}
video_rep_idx
+=
type
==
AVMEDIA_TYPE_VIDEO
;
video_rep_idx
+=
type
==
AVMEDIA_TYPE_VIDEO
;
audio_rep_idx
+=
type
==
AVMEDIA_TYPE_AUDIO
;
audio_rep_idx
+=
type
==
AVMEDIA_TYPE_AUDIO
;
subtitle_rep_idx
+=
type
==
AVMEDIA_TYPE_SUBTITLE
;
end:
end:
if
(
rep_id_val
)
if
(
rep_id_val
)
...
@@ -1441,6 +1468,8 @@ static int refresh_manifest(AVFormatContext *s)
...
@@ -1441,6 +1468,8 @@ static int refresh_manifest(AVFormatContext *s)
struct
representation
**
videos
=
c
->
videos
;
struct
representation
**
videos
=
c
->
videos
;
int
n_audios
=
c
->
n_audios
;
int
n_audios
=
c
->
n_audios
;
struct
representation
**
audios
=
c
->
audios
;
struct
representation
**
audios
=
c
->
audios
;
int
n_subtitles
=
c
->
n_subtitles
;
struct
representation
**
subtitles
=
c
->
subtitles
;
char
*
base_url
=
c
->
base_url
;
char
*
base_url
=
c
->
base_url
;
c
->
base_url
=
NULL
;
c
->
base_url
=
NULL
;
...
@@ -1448,6 +1477,8 @@ static int refresh_manifest(AVFormatContext *s)
...
@@ -1448,6 +1477,8 @@ static int refresh_manifest(AVFormatContext *s)
c
->
videos
=
NULL
;
c
->
videos
=
NULL
;
c
->
n_audios
=
0
;
c
->
n_audios
=
0
;
c
->
audios
=
NULL
;
c
->
audios
=
NULL
;
c
->
n_subtitles
=
0
;
c
->
subtitles
=
NULL
;
ret
=
parse_manifest
(
s
,
s
->
url
,
NULL
);
ret
=
parse_manifest
(
s
,
s
->
url
,
NULL
);
if
(
ret
)
if
(
ret
)
goto
finish
;
goto
finish
;
...
@@ -1464,6 +1495,12 @@ static int refresh_manifest(AVFormatContext *s)
...
@@ -1464,6 +1495,12 @@ static int refresh_manifest(AVFormatContext *s)
n_audios
,
c
->
n_audios
);
n_audios
,
c
->
n_audios
);
return
AVERROR_INVALIDDATA
;
return
AVERROR_INVALIDDATA
;
}
}
if
(
c
->
n_subtitles
!=
n_subtitles
)
{
av_log
(
c
,
AV_LOG_ERROR
,
"new manifest has mismatched no. of subtitles representations, %d -> %d
\n
"
,
n_subtitles
,
c
->
n_subtitles
);
return
AVERROR_INVALIDDATA
;
}
for
(
i
=
0
;
i
<
n_videos
;
i
++
)
{
for
(
i
=
0
;
i
<
n_videos
;
i
++
)
{
struct
representation
*
cur_video
=
videos
[
i
];
struct
representation
*
cur_video
=
videos
[
i
];
...
@@ -1504,10 +1541,16 @@ finish:
...
@@ -1504,10 +1541,16 @@ finish:
av_free
(
base_url
);
av_free
(
base_url
);
else
else
c
->
base_url
=
base_url
;
c
->
base_url
=
base_url
;
if
(
c
->
subtitles
)
free_subtitle_list
(
c
);
if
(
c
->
audios
)
if
(
c
->
audios
)
free_audio_list
(
c
);
free_audio_list
(
c
);
if
(
c
->
videos
)
if
(
c
->
videos
)
free_video_list
(
c
);
free_video_list
(
c
);
c
->
n_subtitles
=
n_subtitles
;
c
->
subtitles
=
subtitles
;
c
->
n_audios
=
n_audios
;
c
->
n_audios
=
n_audios
;
c
->
audios
=
audios
;
c
->
audios
=
audios
;
c
->
n_videos
=
n_videos
;
c
->
n_videos
=
n_videos
;
...
@@ -2001,6 +2044,23 @@ static int dash_read_header(AVFormatContext *s)
...
@@ -2001,6 +2044,23 @@ static int dash_read_header(AVFormatContext *s)
++
stream_index
;
++
stream_index
;
}
}
if
(
c
->
n_subtitles
)
c
->
is_init_section_common_audio
=
is_common_init_section_exist
(
c
->
subtitles
,
c
->
n_subtitles
);
for
(
i
=
0
;
i
<
c
->
n_subtitles
;
i
++
)
{
struct
representation
*
cur_subtitle
=
c
->
subtitles
[
i
];
if
(
i
>
0
&&
c
->
is_init_section_common_audio
)
{
copy_init_section
(
cur_subtitle
,
c
->
subtitles
[
0
]);
}
ret
=
open_demux_for_component
(
s
,
cur_subtitle
);
if
(
ret
)
goto
fail
;
cur_subtitle
->
stream_index
=
stream_index
;
++
stream_index
;
}
if
(
!
stream_index
)
{
if
(
!
stream_index
)
{
ret
=
AVERROR_INVALIDDATA
;
ret
=
AVERROR_INVALIDDATA
;
goto
fail
;
goto
fail
;
...
@@ -2034,6 +2094,14 @@ static int dash_read_header(AVFormatContext *s)
...
@@ -2034,6 +2094,14 @@ static int dash_read_header(AVFormatContext *s)
if
(
pls
->
id
[
0
])
if
(
pls
->
id
[
0
])
av_dict_set
(
&
pls
->
assoc_stream
->
metadata
,
"id"
,
pls
->
id
,
0
);
av_dict_set
(
&
pls
->
assoc_stream
->
metadata
,
"id"
,
pls
->
id
,
0
);
}
}
for
(
i
=
0
;
i
<
c
->
n_subtitles
;
i
++
)
{
struct
representation
*
pls
=
c
->
subtitles
[
i
];
av_program_add_stream_index
(
s
,
0
,
pls
->
stream_index
);
pls
->
assoc_stream
=
s
->
streams
[
pls
->
stream_index
];
if
(
pls
->
id
[
0
])
av_dict_set
(
&
pls
->
assoc_stream
->
metadata
,
"id"
,
pls
->
id
,
0
);
}
}
}
return
0
;
return
0
;
...
@@ -2076,6 +2144,7 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
...
@@ -2076,6 +2144,7 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
recheck_discard_flags
(
s
,
c
->
videos
,
c
->
n_videos
);
recheck_discard_flags
(
s
,
c
->
videos
,
c
->
n_videos
);
recheck_discard_flags
(
s
,
c
->
audios
,
c
->
n_audios
);
recheck_discard_flags
(
s
,
c
->
audios
,
c
->
n_audios
);
recheck_discard_flags
(
s
,
c
->
subtitles
,
c
->
n_subtitles
);
for
(
i
=
0
;
i
<
c
->
n_videos
;
i
++
)
{
for
(
i
=
0
;
i
<
c
->
n_videos
;
i
++
)
{
struct
representation
*
pls
=
c
->
videos
[
i
];
struct
representation
*
pls
=
c
->
videos
[
i
];
...
@@ -2096,6 +2165,16 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
...
@@ -2096,6 +2165,16 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
}
}
}
}
for
(
i
=
0
;
i
<
c
->
n_subtitles
;
i
++
)
{
struct
representation
*
pls
=
c
->
subtitles
[
i
];
if
(
!
pls
->
ctx
)
continue
;
if
(
!
cur
||
pls
->
cur_timestamp
<
mints
)
{
cur
=
pls
;
mints
=
pls
->
cur_timestamp
;
}
}
if
(
!
cur
)
{
if
(
!
cur
)
{
return
AVERROR_INVALIDDATA
;
return
AVERROR_INVALIDDATA
;
}
}
...
@@ -2215,6 +2294,10 @@ static int dash_read_seek(AVFormatContext *s, int stream_index, int64_t timestam
...
@@ -2215,6 +2294,10 @@ static int dash_read_seek(AVFormatContext *s, int stream_index, int64_t timestam
if
(
!
ret
)
if
(
!
ret
)
ret
=
dash_seek
(
s
,
c
->
audios
[
i
],
seek_pos_msec
,
flags
,
!
c
->
audios
[
i
]
->
ctx
);
ret
=
dash_seek
(
s
,
c
->
audios
[
i
],
seek_pos_msec
,
flags
,
!
c
->
audios
[
i
]
->
ctx
);
}
}
for
(
i
=
0
;
i
<
c
->
n_subtitles
;
i
++
)
{
if
(
!
ret
)
ret
=
dash_seek
(
s
,
c
->
subtitles
[
i
],
seek_pos_msec
,
flags
,
!
c
->
subtitles
[
i
]
->
ctx
);
}
return
ret
;
return
ret
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment