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
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)
...
@@ -1185,6 +1185,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
decoded_frame
->
pts
=
av_rescale_q
(
decoded_frame
->
pts
,
decoded_frame
->
pts
=
av_rescale_q
(
decoded_frame
->
pts
,
ist
->
st
->
time_base
,
ist
->
st
->
time_base
,
(
AVRational
){
1
,
avctx
->
sample_rate
});
(
AVRational
){
1
,
avctx
->
sample_rate
});
ist
->
nb_samples
=
decoded_frame
->
nb_samples
;
for
(
i
=
0
;
i
<
ist
->
nb_filters
;
i
++
)
{
for
(
i
=
0
;
i
<
ist
->
nb_filters
;
i
++
)
{
if
(
i
<
ist
->
nb_filters
-
1
)
{
if
(
i
<
ist
->
nb_filters
-
1
)
{
f
=
ist
->
filter_frame
;
f
=
ist
->
filter_frame
;
...
@@ -1323,7 +1324,7 @@ static int send_filter_eof(InputStream *ist)
...
@@ -1323,7 +1324,7 @@ static int send_filter_eof(InputStream *ist)
}
}
/* pkt = NULL means EOF (needed to flush decoder buffers) */
/* 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
i
;
int
got_output
;
int
got_output
;
...
@@ -1402,7 +1403,8 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt)
...
@@ -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 */
/* 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
);
int
ret
=
send_filter_eof
(
ist
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
av_log
(
NULL
,
AV_LOG_FATAL
,
"Error marking filters as finished
\n
"
);
av_log
(
NULL
,
AV_LOG_FATAL
,
"Error marking filters as finished
\n
"
);
...
@@ -2270,6 +2272,86 @@ static void reset_eagain(void)
...
@@ -2270,6 +2272,86 @@ static void reset_eagain(void)
input_files
[
i
]
->
eagain
=
0
;
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
* Read one packet from an input file and send it for
* - decoding -> lavfi (audio/video)
* - decoding -> lavfi (audio/video)
...
@@ -2289,6 +2371,7 @@ static int process_input(void)
...
@@ -2289,6 +2371,7 @@ static int process_input(void)
InputStream
*
ist
;
InputStream
*
ist
;
AVPacket
pkt
;
AVPacket
pkt
;
int
ret
,
i
,
j
;
int
ret
,
i
,
j
;
int64_t
duration
;
/* select the stream that we must read now */
/* select the stream that we must read now */
ifile
=
select_input_file
();
ifile
=
select_input_file
();
...
@@ -2310,6 +2393,11 @@ static int process_input(void)
...
@@ -2310,6 +2393,11 @@ static int process_input(void)
ifile
->
eagain
=
1
;
ifile
->
eagain
=
1
;
return
ret
;
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
<
0
)
{
if
(
ret
!=
AVERROR_EOF
)
{
if
(
ret
!=
AVERROR_EOF
)
{
print_error
(
is
->
filename
,
ret
);
print_error
(
is
->
filename
,
ret
);
...
@@ -2321,7 +2409,7 @@ static int process_input(void)
...
@@ -2321,7 +2409,7 @@ static int process_input(void)
for
(
i
=
0
;
i
<
ifile
->
nb_streams
;
i
++
)
{
for
(
i
=
0
;
i
<
ifile
->
nb_streams
;
i
++
)
{
ist
=
input_streams
[
ifile
->
ist_index
+
i
];
ist
=
input_streams
[
ifile
->
ist_index
+
i
];
if
(
ist
->
decoding_needed
)
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 */
/* mark all outputs that don't go through lavfi as finished */
for
(
j
=
0
;
j
<
nb_output_streams
;
j
++
)
{
for
(
j
=
0
;
j
<
nb_output_streams
;
j
++
)
{
...
@@ -2400,8 +2488,17 @@ static int process_input(void)
...
@@ -2400,8 +2488,17 @@ static int process_input(void)
pkt
.
pts
-=
av_rescale_q
(
delta
,
AV_TIME_BASE_Q
,
ist
->
st
->
time_base
);
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:
discard_packet:
av_free_packet
(
&
pkt
);
av_free_packet
(
&
pkt
);
...
@@ -2472,7 +2569,7 @@ static int transcode(void)
...
@@ -2472,7 +2569,7 @@ static int transcode(void)
for
(
i
=
0
;
i
<
nb_input_streams
;
i
++
)
{
for
(
i
=
0
;
i
<
nb_input_streams
;
i
++
)
{
ist
=
input_streams
[
i
];
ist
=
input_streams
[
i
];
if
(
!
input_files
[
ist
->
file_index
]
->
eof_reached
&&
ist
->
decoding_needed
)
{
if
(
!
input_files
[
ist
->
file_index
]
->
eof_reached
&&
ist
->
decoding_needed
)
{
process_input_packet
(
ist
,
NULL
);
process_input_packet
(
ist
,
NULL
,
0
);
}
}
}
}
poll_filters
();
poll_filters
();
...
...
avconv.h
View file @
16b0c929
...
@@ -102,6 +102,7 @@ typedef struct OptionsContext {
...
@@ -102,6 +102,7 @@ typedef struct OptionsContext {
/* input options */
/* input options */
int64_t
input_ts_offset
;
int64_t
input_ts_offset
;
int
loop
;
int
rate_emu
;
int
rate_emu
;
int
accurate_seek
;
int
accurate_seek
;
...
@@ -233,6 +234,9 @@ typedef struct InputStream {
...
@@ -233,6 +234,9 @@ typedef struct InputStream {
int64_t
next_dts
;
int64_t
next_dts
;
/* dts of the last packet read for this stream */
/* dts of the last packet read for this stream */
int64_t
last_dts
;
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
;
PtsCorrectionContext
pts_ctx
;
double
ts_scale
;
double
ts_scale
;
int
showed_multi_packet_warning
;
int
showed_multi_packet_warning
;
...
@@ -282,6 +286,10 @@ typedef struct InputFile {
...
@@ -282,6 +286,10 @@ typedef struct InputFile {
int
eof_reached
;
/* true if eof reached */
int
eof_reached
;
/* true if eof reached */
int
eagain
;
/* true if last read attempt returned EAGAIN */
int
eagain
;
/* true if last read attempt returned EAGAIN */
int
ist_index
;
/* index of first stream in ist_table */
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
ts_offset
;
int64_t
start_time
;
/* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
int64_t
start_time
;
/* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
int64_t
recording_time
;
int64_t
recording_time
;
...
...
avconv_opt.c
View file @
16b0c929
...
@@ -498,6 +498,9 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
...
@@ -498,6 +498,9 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
ist
->
file_index
=
nb_input_files
;
ist
->
file_index
=
nb_input_files
;
ist
->
discard
=
1
;
ist
->
discard
=
1
;
st
->
discard
=
AVDISCARD_ALL
;
st
->
discard
=
AVDISCARD_ALL
;
ist
->
nb_samples
=
0
;
ist
->
min_pts
=
INT64_MAX
;
ist
->
max_pts
=
INT64_MIN
;
ist
->
ts_scale
=
1
.
0
;
ist
->
ts_scale
=
1
.
0
;
MATCH_PER_STREAM_OPT
(
ts_scale
,
dbl
,
ist
->
ts_scale
,
ic
,
st
);
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)
...
@@ -783,6 +786,9 @@ static int open_input_file(OptionsContext *o, const char *filename)
f
->
nb_streams
=
ic
->
nb_streams
;
f
->
nb_streams
=
ic
->
nb_streams
;
f
->
rate_emu
=
o
->
rate_emu
;
f
->
rate_emu
=
o
->
rate_emu
;
f
->
accurate_seek
=
o
->
accurate_seek
;
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 */
/* check if all codec options have been used */
unused_opts
=
strip_specifiers
(
o
->
g
->
codec_opts
);
unused_opts
=
strip_specifiers
(
o
->
g
->
codec_opts
);
...
@@ -2391,6 +2397,8 @@ const OptionDef options[] = {
...
@@ -2391,6 +2397,8 @@ const OptionDef options[] = {
{
"dump_attachment"
,
HAS_ARG
|
OPT_STRING
|
OPT_SPEC
|
{
"dump_attachment"
,
HAS_ARG
|
OPT_STRING
|
OPT_SPEC
|
OPT_EXPERT
|
OPT_INPUT
,
{
.
off
=
OFFSET
(
dump_attachment
)
},
OPT_EXPERT
|
OPT_INPUT
,
{
.
off
=
OFFSET
(
dump_attachment
)
},
"extract an attachment into a file"
,
"filename"
},
"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 */
/* video options */
{
"vframes"
,
OPT_VIDEO
|
HAS_ARG
|
OPT_PERFILE
|
OPT_OUTPUT
,
{
.
func_arg
=
opt_video_frames
},
{
"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.
...
@@ -253,6 +253,9 @@ Overwrite output files without asking.
@item -n (@emph
{
global
}
)
@item -n (@emph
{
global
}
)
Immediately exit when output files already exist.
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
}
)
@item -c[:@var
{
stream
_
specifier
}
] @var
{
codec
}
(@emph
{
input/output,per-stream
}
)
@itemx -codec[:@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
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