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
16b0c929
Commit
16b0c929
authored
Oct 09, 2015
by
Alexandra Hájková
Committed by
Anton Khirnov
Oct 13, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avconv: Add loop option.
Signed-off-by:
Anton Khirnov
<
anton@khirnov.net
>
parent
11c5f438
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
121 additions
and
5 deletions
+121
-5
avconv.c
avconv.c
+102
-5
avconv.h
avconv.h
+8
-0
avconv_opt.c
avconv_opt.c
+8
-0
avconv.texi
doc/avconv.texi
+3
-0
No files found.
avconv.c
View file @
16b0c929
...
...
@@ -1185,6 +1185,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
decoded_frame
->
pts
=
av_rescale_q
(
decoded_frame
->
pts
,
ist
->
st
->
time_base
,
(
AVRational
){
1
,
avctx
->
sample_rate
});
ist
->
nb_samples
=
decoded_frame
->
nb_samples
;
for
(
i
=
0
;
i
<
ist
->
nb_filters
;
i
++
)
{
if
(
i
<
ist
->
nb_filters
-
1
)
{
f
=
ist
->
filter_frame
;
...
...
@@ -1323,7 +1324,7 @@ static int send_filter_eof(InputStream *ist)
}
/* pkt = NULL means EOF (needed to flush decoder buffers) */
static
void
process_input_packet
(
InputStream
*
ist
,
const
AVPacket
*
pkt
)
static
void
process_input_packet
(
InputStream
*
ist
,
const
AVPacket
*
pkt
,
int
no_eof
)
{
int
i
;
int
got_output
;
...
...
@@ -1402,7 +1403,8 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt)
}
/* after flushing, send an EOF on all the filter inputs attached to the stream */
if
(
!
pkt
&&
ist
->
decoding_needed
)
{
/* except when looping we need to flush but not to send an EOF */
if
(
!
pkt
&&
ist
->
decoding_needed
&&
!
no_eof
)
{
int
ret
=
send_filter_eof
(
ist
);
if
(
ret
<
0
)
{
av_log
(
NULL
,
AV_LOG_FATAL
,
"Error marking filters as finished
\n
"
);
...
...
@@ -2270,6 +2272,86 @@ static void reset_eagain(void)
input_files
[
i
]
->
eagain
=
0
;
}
// set duration to max(tmp, duration) in a proper time base and return duration's time_base
static
AVRational
duration_max
(
int64_t
tmp
,
int64_t
*
duration
,
AVRational
tmp_time_base
,
AVRational
time_base
)
{
int
ret
;
if
(
!*
duration
)
{
*
duration
=
tmp
;
return
tmp_time_base
;
}
ret
=
av_compare_ts
(
*
duration
,
time_base
,
tmp
,
tmp_time_base
);
if
(
ret
<
0
)
{
*
duration
=
tmp
;
return
tmp_time_base
;
}
return
time_base
;
}
static
int
seek_to_start
(
InputFile
*
ifile
,
AVFormatContext
*
is
)
{
InputStream
*
ist
;
AVCodecContext
*
avctx
;
int
i
,
ret
,
has_audio
=
0
;
int64_t
duration
=
0
;
ret
=
av_seek_frame
(
is
,
-
1
,
is
->
start_time
,
0
);
if
(
ret
<
0
)
return
ret
;
for
(
i
=
0
;
i
<
ifile
->
nb_streams
;
i
++
)
{
ist
=
input_streams
[
ifile
->
ist_index
+
i
];
avctx
=
ist
->
dec_ctx
;
// flush decoders
if
(
ist
->
decoding_needed
)
{
process_input_packet
(
ist
,
NULL
,
1
);
avcodec_flush_buffers
(
avctx
);
}
/* duration is the length of the last frame in a stream
* when audio stream is present we don't care about
* last video frame length because it's not defined exactly */
if
(
avctx
->
codec_type
==
AVMEDIA_TYPE_AUDIO
&&
ist
->
nb_samples
)
has_audio
=
1
;
}
for
(
i
=
0
;
i
<
ifile
->
nb_streams
;
i
++
)
{
ist
=
input_streams
[
ifile
->
ist_index
+
i
];
avctx
=
ist
->
dec_ctx
;
if
(
has_audio
)
{
if
(
avctx
->
codec_type
==
AVMEDIA_TYPE_AUDIO
&&
ist
->
nb_samples
)
{
AVRational
sample_rate
=
{
1
,
avctx
->
sample_rate
};
duration
=
av_rescale_q
(
ist
->
nb_samples
,
sample_rate
,
ist
->
st
->
time_base
);
}
else
continue
;
}
else
{
if
(
ist
->
framerate
.
num
)
{
duration
=
av_rescale_q
(
1
,
ist
->
framerate
,
ist
->
st
->
time_base
);
}
else
if
(
ist
->
st
->
avg_frame_rate
.
num
)
{
duration
=
av_rescale_q
(
1
,
ist
->
st
->
avg_frame_rate
,
ist
->
st
->
time_base
);
}
else
duration
=
1
;
}
if
(
!
ifile
->
duration
)
ifile
->
time_base
=
ist
->
st
->
time_base
;
/* the total duration of the stream, max_pts - min_pts is
* the duration of the stream without the last frame */
duration
+=
ist
->
max_pts
-
ist
->
min_pts
;
ifile
->
time_base
=
duration_max
(
duration
,
&
ifile
->
duration
,
ist
->
st
->
time_base
,
ifile
->
time_base
);
}
ifile
->
loop
--
;
return
ret
;
}
/*
* Read one packet from an input file and send it for
* - decoding -> lavfi (audio/video)
...
...
@@ -2289,6 +2371,7 @@ static int process_input(void)
InputStream
*
ist
;
AVPacket
pkt
;
int
ret
,
i
,
j
;
int64_t
duration
;
/* select the stream that we must read now */
ifile
=
select_input_file
();
...
...
@@ -2310,6 +2393,11 @@ static int process_input(void)
ifile
->
eagain
=
1
;
return
ret
;
}
if
((
ret
<
0
)
&&
(
ifile
->
loop
>
1
))
{
if
((
ret
=
seek_to_start
(
ifile
,
is
))
<
0
)
return
ret
;
ret
=
get_input_packet
(
ifile
,
&
pkt
);
}
if
(
ret
<
0
)
{
if
(
ret
!=
AVERROR_EOF
)
{
print_error
(
is
->
filename
,
ret
);
...
...
@@ -2321,7 +2409,7 @@ static int process_input(void)
for
(
i
=
0
;
i
<
ifile
->
nb_streams
;
i
++
)
{
ist
=
input_streams
[
ifile
->
ist_index
+
i
];
if
(
ist
->
decoding_needed
)
process_input_packet
(
ist
,
NULL
);
process_input_packet
(
ist
,
NULL
,
0
);
/* mark all outputs that don't go through lavfi as finished */
for
(
j
=
0
;
j
<
nb_output_streams
;
j
++
)
{
...
...
@@ -2400,8 +2488,17 @@ static int process_input(void)
pkt
.
pts
-=
av_rescale_q
(
delta
,
AV_TIME_BASE_Q
,
ist
->
st
->
time_base
);
}
}
duration
=
av_rescale_q
(
ifile
->
duration
,
ifile
->
time_base
,
ist
->
st
->
time_base
);
if
(
pkt
.
pts
!=
AV_NOPTS_VALUE
)
{
pkt
.
pts
+=
duration
;
ist
->
max_pts
=
FFMAX
(
pkt
.
pts
,
ist
->
max_pts
);
ist
->
min_pts
=
FFMIN
(
pkt
.
pts
,
ist
->
min_pts
);
}
if
(
pkt
.
dts
!=
AV_NOPTS_VALUE
)
pkt
.
dts
+=
duration
;
process_input_packet
(
ist
,
&
pkt
);
process_input_packet
(
ist
,
&
pkt
,
0
);
discard_packet:
av_free_packet
(
&
pkt
);
...
...
@@ -2472,7 +2569,7 @@ static int transcode(void)
for
(
i
=
0
;
i
<
nb_input_streams
;
i
++
)
{
ist
=
input_streams
[
i
];
if
(
!
input_files
[
ist
->
file_index
]
->
eof_reached
&&
ist
->
decoding_needed
)
{
process_input_packet
(
ist
,
NULL
);
process_input_packet
(
ist
,
NULL
,
0
);
}
}
poll_filters
();
...
...
avconv.h
View file @
16b0c929
...
...
@@ -102,6 +102,7 @@ typedef struct OptionsContext {
/* input options */
int64_t
input_ts_offset
;
int
loop
;
int
rate_emu
;
int
accurate_seek
;
...
...
@@ -233,6 +234,9 @@ typedef struct InputStream {
int64_t
next_dts
;
/* dts of the last packet read for this stream */
int64_t
last_dts
;
int64_t
min_pts
;
/* pts with the smallest value in a current stream */
int64_t
max_pts
;
/* pts with the higher value in a current stream */
int64_t
nb_samples
;
/* number of samples in the last decoded audio frame before looping */
PtsCorrectionContext
pts_ctx
;
double
ts_scale
;
int
showed_multi_packet_warning
;
...
...
@@ -282,6 +286,10 @@ typedef struct InputFile {
int
eof_reached
;
/* true if eof reached */
int
eagain
;
/* true if last read attempt returned EAGAIN */
int
ist_index
;
/* index of first stream in ist_table */
int
loop
;
/* set number of times input stream should be looped */
int64_t
duration
;
/* actual duration of the longest stream in a file
at the moment when looping happens */
AVRational
time_base
;
/* time base of the duration */
int64_t
ts_offset
;
int64_t
start_time
;
/* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
int64_t
recording_time
;
...
...
avconv_opt.c
View file @
16b0c929
...
...
@@ -498,6 +498,9 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
ist
->
file_index
=
nb_input_files
;
ist
->
discard
=
1
;
st
->
discard
=
AVDISCARD_ALL
;
ist
->
nb_samples
=
0
;
ist
->
min_pts
=
INT64_MAX
;
ist
->
max_pts
=
INT64_MIN
;
ist
->
ts_scale
=
1
.
0
;
MATCH_PER_STREAM_OPT
(
ts_scale
,
dbl
,
ist
->
ts_scale
,
ic
,
st
);
...
...
@@ -783,6 +786,9 @@ static int open_input_file(OptionsContext *o, const char *filename)
f
->
nb_streams
=
ic
->
nb_streams
;
f
->
rate_emu
=
o
->
rate_emu
;
f
->
accurate_seek
=
o
->
accurate_seek
;
f
->
loop
=
o
->
loop
;
f
->
duration
=
0
;
f
->
time_base
=
(
AVRational
){
1
,
1
};
/* check if all codec options have been used */
unused_opts
=
strip_specifiers
(
o
->
g
->
codec_opts
);
...
...
@@ -2391,6 +2397,8 @@ const OptionDef options[] = {
{
"dump_attachment"
,
HAS_ARG
|
OPT_STRING
|
OPT_SPEC
|
OPT_EXPERT
|
OPT_INPUT
,
{
.
off
=
OFFSET
(
dump_attachment
)
},
"extract an attachment into a file"
,
"filename"
},
{
"loop"
,
OPT_INT
|
HAS_ARG
|
OPT_EXPERT
|
OPT_INPUT
|
OPT_OFFSET
,
{
.
off
=
OFFSET
(
loop
)
},
"set number of times input stream shall be looped"
,
"loop count"
},
/* video options */
{
"vframes"
,
OPT_VIDEO
|
HAS_ARG
|
OPT_PERFILE
|
OPT_OUTPUT
,
{
.
func_arg
=
opt_video_frames
},
...
...
doc/avconv.texi
View file @
16b0c929
...
...
@@ -253,6 +253,9 @@ Overwrite output files without asking.
@item -n (@emph
{
global
}
)
Immediately exit when output files already exist.
@item -loop @var
{
number
}
(@emph
{
input
}
)
Set number of times input stream shall be looped.
@item -c[:@var
{
stream
_
specifier
}
] @var
{
codec
}
(@emph
{
input/output,per-stream
}
)
@itemx -codec[:@var
{
stream
_
specifier
}
] @var
{
codec
}
(@emph
{
input/output,per-stream
}
)
Select an encoder (when used before an output file) or a decoder (when used
...
...
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