Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
32aedebd
Commit
32aedebd
authored
Aug 22, 2012
by
Nicolas George
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavf: add a concat demuxer.
parent
c3fa6add
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
256 additions
and
1 deletion
+256
-1
Changelog
Changelog
+1
-0
demuxers.texi
doc/demuxers.texi
+31
-0
Makefile
libavformat/Makefile
+1
-0
allformats.c
libavformat/allformats.c
+1
-0
concatdec.c
libavformat/concatdec.c
+221
-0
version.h
libavformat/version.h
+1
-1
No files found.
Changelog
View file @
32aedebd
...
...
@@ -36,6 +36,7 @@ version <next>:
- subtitles filter
- IRCAM muxer/demuxer
- Paris Audio File demuxer
- Virtual concatenation demuxer
version 1.0:
...
...
doc/demuxers.texi
View file @
32aedebd
...
...
@@ -184,4 +184,35 @@ the script is directly played, the actual times will match the absolute
timestamps up to the sound controller's clock accuracy, but if the user
somehow pauses the playback or seeks, all times will be shifted accordingly.
@section concat
Virtual concatenation script demuxer.
This demuxer reads a list of files and other directives from a text file and
demuxes them one after the other, as if all their packet had been muxed
together.
The timestamps in the files are adjusted so that the first file starts at 0
and each next file starts where the previous one finishes. Note that it is
done globally and may cause gaps if all streams do not have exactly the same
length.
All files must have the same streams (same codecs, same time base, etc.).
This script format can currently not be probed, it must be specified explicitly.
@subsection Syntax
The script is a text file in extended-ASCII, with one directive per line.
Empty lines, leading spaces and lines starting with '#' are ignored. The
following directive is recognized:
@table @option
@item @code{file @var{path}}
Path to a file to read; special characters and spaces must be escaped with
backslash or single quotes.
@end table
@c man end INPUT DEVICES
libavformat/Makefile
View file @
32aedebd
...
...
@@ -96,6 +96,7 @@ OBJS-$(CONFIG_CAVSVIDEO_DEMUXER) += cavsvideodec.o rawdec.o
OBJS-$(CONFIG_CAVSVIDEO_MUXER)
+=
rawenc.o
OBJS-$(CONFIG_CDG_DEMUXER)
+=
cdg.o
OBJS-$(CONFIG_CDXL_DEMUXER)
+=
cdxl.o
OBJS-$(CONFIG_CONCAT_DEMUXER)
+=
concatdec.o
OBJS-$(CONFIG_CRC_MUXER)
+=
crcenc.o
OBJS-$(CONFIG_DAUD_DEMUXER)
+=
daud.o
OBJS-$(CONFIG_DAUD_MUXER)
+=
daud.o
...
...
libavformat/allformats.c
View file @
32aedebd
...
...
@@ -85,6 +85,7 @@ void av_register_all(void)
REGISTER_MUXDEMUX
(
CAVSVIDEO
,
cavsvideo
);
REGISTER_DEMUXER
(
CDG
,
cdg
);
REGISTER_DEMUXER
(
CDXL
,
cdxl
);
REGISTER_DEMUXER
(
CONCAT
,
concat
);
REGISTER_MUXER
(
CRC
,
crc
);
REGISTER_MUXDEMUX
(
DAUD
,
daud
);
REGISTER_DEMUXER
(
DFA
,
dfa
);
...
...
libavformat/concatdec.c
0 → 100644
View file @
32aedebd
/*
* Copyright (c) 2012 Nicolas George
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/avstring.h"
#include "avformat.h"
#include "internal.h"
typedef
struct
{
char
*
url
;
int64_t
start_time
;
int64_t
duration
;
}
ConcatFile
;
typedef
struct
{
ConcatFile
*
files
;
ConcatFile
*
cur_file
;
unsigned
nb_files
;
AVFormatContext
*
avf
;
}
ConcatContext
;
static
int
concat_probe
(
AVProbeData
*
probe
)
{
return
0
;
}
static
char
*
get_keyword
(
uint8_t
**
cursor
)
{
char
*
ret
=
*
cursor
+=
strspn
(
*
cursor
,
SPACE_CHARS
);
*
cursor
+=
strcspn
(
*
cursor
,
SPACE_CHARS
);
if
(
**
cursor
)
{
*
((
*
cursor
)
++
)
=
0
;
*
cursor
+=
strspn
(
*
cursor
,
SPACE_CHARS
);
}
return
ret
;
}
#define FAIL(retcode) do { ret = (retcode); goto fail; } while(0)
static
int
add_file
(
AVFormatContext
*
avf
,
char
*
filename
,
ConcatFile
**
rfile
,
unsigned
*
nb_files_alloc
)
{
ConcatContext
*
cat
=
avf
->
priv_data
;
ConcatFile
*
file
;
char
*
url
;
size_t
url_len
;
url_len
=
strlen
(
avf
->
filename
)
+
strlen
(
filename
)
+
16
;
if
(
!
(
url
=
av_malloc
(
url_len
)))
return
AVERROR
(
ENOMEM
);
ff_make_absolute_url
(
url
,
url_len
,
avf
->
filename
,
filename
);
av_free
(
filename
);
if
(
cat
->
nb_files
>=
*
nb_files_alloc
)
{
unsigned
n
=
FFMAX
(
*
nb_files_alloc
*
2
,
16
);
if
(
n
<=
cat
->
nb_files
||
!
(
cat
->
files
=
av_realloc_f
(
cat
->
files
,
n
,
sizeof
(
*
cat
->
files
))))
return
AVERROR
(
ENOMEM
);
*
nb_files_alloc
=
n
;
}
file
=
&
cat
->
files
[
cat
->
nb_files
++
];
memset
(
file
,
0
,
sizeof
(
*
file
));
*
rfile
=
file
;
file
->
url
=
url
;
file
->
start_time
=
AV_NOPTS_VALUE
;
file
->
duration
=
AV_NOPTS_VALUE
;
return
0
;
}
static
int
open_file
(
AVFormatContext
*
avf
,
unsigned
fileno
)
{
ConcatContext
*
cat
=
avf
->
priv_data
;
ConcatFile
*
file
=
&
cat
->
files
[
fileno
];
int
ret
;
if
((
ret
=
avformat_open_input
(
&
cat
->
avf
,
file
->
url
,
NULL
,
NULL
))
<
0
||
(
ret
=
avformat_find_stream_info
(
cat
->
avf
,
NULL
))
<
0
)
{
av_log
(
avf
,
AV_LOG_ERROR
,
"Impossible to open '%s'
\n
"
,
file
->
url
);
return
ret
;
}
cat
->
cur_file
=
file
;
if
(
file
->
start_time
==
AV_NOPTS_VALUE
)
file
->
start_time
=
!
fileno
?
0
:
cat
->
files
[
fileno
-
1
].
start_time
+
cat
->
files
[
fileno
-
1
].
duration
;
return
0
;
}
static
int
concat_read_close
(
AVFormatContext
*
avf
)
{
ConcatContext
*
cat
=
avf
->
priv_data
;
unsigned
i
;
if
(
cat
->
avf
)
avformat_close_input
(
&
cat
->
avf
);
for
(
i
=
0
;
i
<
cat
->
nb_files
;
i
++
)
av_freep
(
&
cat
->
files
[
i
].
url
);
av_freep
(
&
cat
->
files
);
return
0
;
}
static
int
concat_read_header
(
AVFormatContext
*
avf
)
{
ConcatContext
*
cat
=
avf
->
priv_data
;
uint8_t
buf
[
4096
];
uint8_t
*
cursor
,
*
keyword
;
int
ret
,
line
=
0
,
i
;
unsigned
nb_files_alloc
=
0
;
ConcatFile
*
file
=
NULL
;
AVStream
*
st
,
*
source_st
;
while
(
1
)
{
if
((
ret
=
ff_get_line
(
avf
->
pb
,
buf
,
sizeof
(
buf
)))
<=
0
)
break
;
line
++
;
cursor
=
buf
;
keyword
=
get_keyword
(
&
cursor
);
if
(
!*
keyword
||
*
keyword
==
'#'
)
continue
;
if
(
!
strcmp
(
keyword
,
"file"
))
{
char
*
filename
=
av_get_token
((
const
char
**
)
&
cursor
,
SPACE_CHARS
);
if
(
!
filename
)
{
av_log
(
avf
,
AV_LOG_ERROR
,
"Line %d: filename required
\n
"
,
line
);
FAIL
(
AVERROR_INVALIDDATA
);
}
if
((
ret
=
add_file
(
avf
,
filename
,
&
file
,
&
nb_files_alloc
))
<
0
)
FAIL
(
ret
);
}
else
{
av_log
(
avf
,
AV_LOG_ERROR
,
"Line %d: unknown keyword '%s'
\n
"
,
line
,
keyword
);
FAIL
(
AVERROR_INVALIDDATA
);
}
}
if
(
ret
<
0
)
FAIL
(
ret
);
if
((
ret
=
open_file
(
avf
,
0
))
<
0
)
FAIL
(
ret
);
for
(
i
=
0
;
i
<
cat
->
avf
->
nb_streams
;
i
++
)
{
if
(
!
(
st
=
avformat_new_stream
(
avf
,
NULL
)))
FAIL
(
AVERROR
(
ENOMEM
));
source_st
=
cat
->
avf
->
streams
[
i
];
if
((
ret
=
avcodec_copy_context
(
st
->
codec
,
source_st
->
codec
))
<
0
)
FAIL
(
ret
);
st
->
r_frame_rate
=
source_st
->
r_frame_rate
;
st
->
avg_frame_rate
=
source_st
->
avg_frame_rate
;
st
->
time_base
=
source_st
->
time_base
;
st
->
sample_aspect_ratio
=
source_st
->
sample_aspect_ratio
;
}
return
0
;
fail:
concat_read_close
(
avf
);
return
ret
;
}
static
int
open_next_file
(
AVFormatContext
*
avf
)
{
ConcatContext
*
cat
=
avf
->
priv_data
;
unsigned
fileno
=
cat
->
cur_file
-
cat
->
files
;
if
(
cat
->
cur_file
->
duration
==
AV_NOPTS_VALUE
)
cat
->
cur_file
->
duration
=
cat
->
avf
->
duration
;
if
(
++
fileno
>=
cat
->
nb_files
)
return
AVERROR_EOF
;
avformat_close_input
(
&
cat
->
avf
);
return
open_file
(
avf
,
fileno
);
}
static
int
concat_read_packet
(
AVFormatContext
*
avf
,
AVPacket
*
pkt
)
{
ConcatContext
*
cat
=
avf
->
priv_data
;
int
ret
;
int64_t
delta
;
while
(
1
)
{
if
((
ret
=
av_read_frame
(
cat
->
avf
,
pkt
))
!=
AVERROR_EOF
||
(
ret
=
open_next_file
(
avf
))
<
0
)
break
;
}
delta
=
av_rescale_q
(
cat
->
cur_file
->
start_time
-
cat
->
avf
->
start_time
,
AV_TIME_BASE_Q
,
cat
->
avf
->
streams
[
pkt
->
stream_index
]
->
time_base
);
if
(
pkt
->
pts
!=
AV_NOPTS_VALUE
)
pkt
->
pts
+=
delta
;
if
(
pkt
->
dts
!=
AV_NOPTS_VALUE
)
pkt
->
dts
+=
delta
;
return
ret
;
}
AVInputFormat
ff_concat_demuxer
=
{
.
name
=
"concat"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"Virtual concatenation script"
),
.
priv_data_size
=
sizeof
(
ConcatContext
),
.
read_probe
=
concat_probe
,
.
read_header
=
concat_read_header
,
.
read_packet
=
concat_read_packet
,
.
read_close
=
concat_read_close
,
};
libavformat/version.h
View file @
32aedebd
...
...
@@ -30,7 +30,7 @@
#include "libavutil/avutil.h"
#define LIBAVFORMAT_VERSION_MAJOR 54
#define LIBAVFORMAT_VERSION_MINOR 4
6
#define LIBAVFORMAT_VERSION_MINOR 4
7
#define LIBAVFORMAT_VERSION_MICRO 100
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
...
...
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