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
398f015f
Commit
398f015f
authored
May 23, 2016
by
Anton Khirnov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avconv: buffer the packets written while the muxer is not initialized
parent
1c169782
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
85 additions
and
18 deletions
+85
-18
avconv.c
avconv.c
+58
-18
avconv.h
avconv.h
+7
-0
avconv_opt.c
avconv_opt.c
+11
-0
avconv.texi
doc/avconv.texi
+9
-0
No files found.
avconv.c
View file @
398f015f
...
...
@@ -192,6 +192,13 @@ static void avconv_cleanup(int ret)
avcodec_free_context
(
&
ost
->
enc_ctx
);
while
(
av_fifo_size
(
ost
->
muxing_queue
))
{
AVPacket
pkt
;
av_fifo_generic_read
(
ost
->
muxing_queue
,
&
pkt
,
sizeof
(
pkt
),
NULL
);
av_packet_unref
(
&
pkt
);
}
av_fifo_free
(
ost
->
muxing_queue
);
av_freep
(
&
output_streams
[
i
]);
}
for
(
i
=
0
;
i
<
nb_input_files
;
i
++
)
{
...
...
@@ -255,11 +262,33 @@ static void abort_codec_experimental(AVCodec *c, int encoder)
exit_program
(
1
);
}
static
void
write_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
,
OutputStream
*
ost
)
static
void
write_packet
(
OutputFile
*
of
,
AVPacket
*
pkt
,
OutputStream
*
ost
)
{
AVFormatContext
*
s
=
of
->
ctx
;
AVStream
*
st
=
ost
->
st
;
int
ret
;
if
(
!
of
->
header_written
)
{
AVPacket
tmp_pkt
;
/* the muxer is not initialized yet, buffer the packet */
if
(
!
av_fifo_space
(
ost
->
muxing_queue
))
{
int
new_size
=
FFMIN
(
2
*
av_fifo_size
(
ost
->
muxing_queue
),
ost
->
max_muxing_queue_size
);
if
(
new_size
<=
av_fifo_size
(
ost
->
muxing_queue
))
{
av_log
(
NULL
,
AV_LOG_ERROR
,
"Too many packets buffered for output stream %d:%d.
\n
"
,
ost
->
file_index
,
ost
->
st
->
index
);
exit_program
(
1
);
}
ret
=
av_fifo_realloc2
(
ost
->
muxing_queue
,
new_size
);
if
(
ret
<
0
)
exit_program
(
1
);
}
av_packet_move_ref
(
&
tmp_pkt
,
pkt
);
av_fifo_generic_write
(
ost
->
muxing_queue
,
&
tmp_pkt
,
sizeof
(
tmp_pkt
),
NULL
);
return
;
}
/*
* Audio encoders may split the packets -- #frames in != #packets out.
* But there is no reordering, so we can limit the number of output packets
...
...
@@ -315,7 +344,7 @@ static void write_packet(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
}
}
static
void
output_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
,
OutputStream
*
ost
)
static
void
output_packet
(
OutputFile
*
of
,
AVPacket
*
pkt
,
OutputStream
*
ost
)
{
int
ret
=
0
;
...
...
@@ -345,10 +374,10 @@ static void output_packet(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
goto
finish
;
idx
++
;
}
else
write_packet
(
s
,
pkt
,
ost
);
write_packet
(
of
,
pkt
,
ost
);
}
}
else
write_packet
(
s
,
pkt
,
ost
);
write_packet
(
of
,
pkt
,
ost
);
finish:
if
(
ret
<
0
&&
ret
!=
AVERROR_EOF
)
{
...
...
@@ -371,7 +400,7 @@ static int check_recording_time(OutputStream *ost)
return
1
;
}
static
void
do_audio_out
(
AVFormatContext
*
s
,
OutputStream
*
ost
,
static
void
do_audio_out
(
OutputFile
*
of
,
OutputStream
*
ost
,
AVFrame
*
frame
)
{
AVCodecContext
*
enc
=
ost
->
enc_ctx
;
...
...
@@ -401,7 +430,7 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost,
goto
error
;
av_packet_rescale_ts
(
&
pkt
,
enc
->
time_base
,
ost
->
st
->
time_base
);
output_packet
(
s
,
&
pkt
,
ost
);
output_packet
(
of
,
&
pkt
,
ost
);
}
return
;
...
...
@@ -410,7 +439,7 @@ error:
exit_program
(
1
);
}
static
void
do_subtitle_out
(
AVFormatContext
*
s
,
static
void
do_subtitle_out
(
OutputFile
*
of
,
OutputStream
*
ost
,
InputStream
*
ist
,
AVSubtitle
*
sub
,
...
...
@@ -475,11 +504,11 @@ static void do_subtitle_out(AVFormatContext *s,
else
pkt
.
pts
+=
90
*
sub
->
end_display_time
;
}
output_packet
(
s
,
&
pkt
,
ost
);
output_packet
(
of
,
&
pkt
,
ost
);
}
}
static
void
do_video_out
(
AVFormatContext
*
s
,
static
void
do_video_out
(
OutputFile
*
of
,
OutputStream
*
ost
,
AVFrame
*
in_picture
,
int
*
frame_size
)
...
...
@@ -492,8 +521,8 @@ static void do_video_out(AVFormatContext *s,
format_video_sync
=
video_sync_method
;
if
(
format_video_sync
==
VSYNC_AUTO
)
format_video_sync
=
(
s
->
oformat
->
flags
&
AVFMT_NOTIMESTAMPS
)
?
VSYNC_PASSTHROUGH
:
(
s
->
oformat
->
flags
&
AVFMT_VARIABLE_FPS
)
?
VSYNC_VFR
:
VSYNC_CFR
;
format_video_sync
=
(
of
->
ctx
->
oformat
->
flags
&
AVFMT_NOTIMESTAMPS
)
?
VSYNC_PASSTHROUGH
:
(
of
->
ctx
->
oformat
->
flags
&
AVFMT_VARIABLE_FPS
)
?
VSYNC_VFR
:
VSYNC_CFR
;
if
(
format_video_sync
!=
VSYNC_PASSTHROUGH
&&
ost
->
frame_number
&&
in_picture
->
pts
!=
AV_NOPTS_VALUE
&&
...
...
@@ -552,7 +581,7 @@ static void do_video_out(AVFormatContext *s,
goto
error
;
av_packet_rescale_ts
(
&
pkt
,
enc
->
time_base
,
ost
->
st
->
time_base
);
output_packet
(
s
,
&
pkt
,
ost
);
output_packet
(
of
,
&
pkt
,
ost
);
*
frame_size
=
pkt
.
size
;
/* if two pass, output log */
...
...
@@ -662,12 +691,12 @@ static int poll_filter(OutputStream *ost)
if
(
!
ost
->
frame_aspect_ratio
)
ost
->
enc_ctx
->
sample_aspect_ratio
=
filtered_frame
->
sample_aspect_ratio
;
do_video_out
(
of
->
ctx
,
ost
,
filtered_frame
,
&
frame_size
);
do_video_out
(
of
,
ost
,
filtered_frame
,
&
frame_size
);
if
(
vstats_filename
&&
frame_size
)
do_video_stats
(
ost
,
frame_size
);
break
;
case
AVMEDIA_TYPE_AUDIO
:
do_audio_out
(
of
->
ctx
,
ost
,
filtered_frame
);
do_audio_out
(
of
,
ost
,
filtered_frame
);
break
;
default:
// TODO support subtitle filters
...
...
@@ -975,7 +1004,7 @@ static void flush_encoders(void)
for
(
i
=
0
;
i
<
nb_output_streams
;
i
++
)
{
OutputStream
*
ost
=
output_streams
[
i
];
AVCodecContext
*
enc
=
ost
->
enc_ctx
;
AVFormatContext
*
os
=
output_files
[
ost
->
file_index
]
->
ctx
;
OutputFile
*
of
=
output_files
[
ost
->
file_index
]
;
int
stop_encoding
=
0
;
if
(
!
ost
->
encoding_needed
)
...
...
@@ -1022,7 +1051,7 @@ static void flush_encoders(void)
break
;
}
av_packet_rescale_ts
(
&
pkt
,
enc
->
time_base
,
ost
->
st
->
time_base
);
output_packet
(
o
s
,
&
pkt
,
ost
);
output_packet
(
o
f
,
&
pkt
,
ost
);
}
if
(
stop_encoding
)
...
...
@@ -1115,7 +1144,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
opkt
.
size
=
pkt
->
size
;
}
output_packet
(
of
->
ctx
,
&
opkt
,
ost
);
output_packet
(
of
,
&
opkt
,
ost
);
}
// This does not quite work like avcodec_decode_audio4/avcodec_decode_video2.
...
...
@@ -1353,7 +1382,7 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
if
(
!
check_output_constraints
(
ist
,
ost
)
||
!
ost
->
encoding_needed
)
continue
;
do_subtitle_out
(
output_files
[
ost
->
file_index
]
->
ctx
,
ost
,
ist
,
&
subtitle
,
pkt
->
pts
);
do_subtitle_out
(
output_files
[
ost
->
file_index
],
ost
,
ist
,
&
subtitle
,
pkt
->
pts
);
}
avsubtitle_free
(
&
subtitle
);
...
...
@@ -1657,6 +1686,17 @@ static int check_init_output_file(OutputFile *of, int file_index)
if
(
want_sdp
)
print_sdp
();
/* flush the muxing queues */
for
(
i
=
0
;
i
<
of
->
ctx
->
nb_streams
;
i
++
)
{
OutputStream
*
ost
=
output_streams
[
of
->
ost_index
+
i
];
while
(
av_fifo_size
(
ost
->
muxing_queue
))
{
AVPacket
pkt
;
av_fifo_generic_read
(
ost
->
muxing_queue
,
&
pkt
,
sizeof
(
pkt
),
NULL
);
write_packet
(
of
,
&
pkt
,
ost
);
}
}
return
0
;
}
...
...
avconv.h
View file @
398f015f
...
...
@@ -190,6 +190,8 @@ typedef struct OptionsContext {
int
nb_pass
;
SpecifierOpt
*
passlogfiles
;
int
nb_passlogfiles
;
SpecifierOpt
*
max_muxing_queue_size
;
int
nb_max_muxing_queue_size
;
}
OptionsContext
;
typedef
struct
InputFilter
{
...
...
@@ -391,6 +393,11 @@ typedef struct OutputStream {
/* packet quality factor */
int
quality
;
int
max_muxing_queue_size
;
/* the packets are buffered here until the muxer is ready to be initialized */
AVFifoBuffer
*
muxing_queue
;
}
OutputStream
;
typedef
struct
OutputFile
{
...
...
avconv_opt.c
View file @
398f015f
...
...
@@ -1073,6 +1073,10 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
ost
->
enc_ctx
->
global_quality
=
FF_QP2LAMBDA
*
qscale
;
}
ost
->
max_muxing_queue_size
=
128
;
MATCH_PER_STREAM_OPT
(
max_muxing_queue_size
,
i
,
ost
->
max_muxing_queue_size
,
oc
,
st
);
ost
->
max_muxing_queue_size
*=
sizeof
(
AVPacket
);
if
(
oc
->
oformat
->
flags
&
AVFMT_GLOBALHEADER
)
ost
->
enc_ctx
->
flags
|=
AV_CODEC_FLAG_GLOBAL_HEADER
;
...
...
@@ -1083,6 +1087,10 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
ost
->
pix_fmts
[
0
]
=
ost
->
pix_fmts
[
1
]
=
AV_PIX_FMT_NONE
;
ost
->
last_mux_dts
=
AV_NOPTS_VALUE
;
ost
->
muxing_queue
=
av_fifo_alloc
(
8
*
sizeof
(
AVPacket
));
if
(
!
ost
->
muxing_queue
)
exit_program
(
1
);
return
ost
;
}
...
...
@@ -2648,6 +2656,9 @@ const OptionDef options[] = {
{
"bsf"
,
HAS_ARG
|
OPT_STRING
|
OPT_SPEC
|
OPT_EXPERT
|
OPT_OUTPUT
,
{
.
off
=
OFFSET
(
bitstream_filters
)
},
"A comma-separated list of bitstream filters"
,
"bitstream_filters"
},
{
"max_muxing_queue_size"
,
HAS_ARG
|
OPT_INT
|
OPT_SPEC
|
OPT_EXPERT
|
OPT_OUTPUT
,
{
.
off
=
OFFSET
(
max_muxing_queue_size
)
},
"maximum number of packets that can be buffered while waiting for all streams to initialize"
,
"packets"
},
/* data codec support */
{
"dcodec"
,
HAS_ARG
|
OPT_DATA
|
OPT_PERFILE
|
OPT_EXPERT
|
OPT_INPUT
|
OPT_OUTPUT
,
{
.
func_arg
=
opt_data_codec
},
"force data codec ('copy' to copy stream)"
,
"codec"
},
...
...
doc/avconv.texi
View file @
398f015f
...
...
@@ -956,6 +956,15 @@ This option enables or disables accurate seeking in input files with the
transcoding. Use @option
{
-noaccurate
_
seek
}
to disable it, which may be useful
e.g. when copying some streams and transcoding the others.
@item -max
_
muxing
_
queue
_
size @var
{
packets
}
(@emph
{
output,per-stream
}
)
When transcoding audio and/or video streams, avconv will not begin writing into
the output until it has one packet for each such stream. While waiting for that
to happen, packets for other streams are buffered. This option sets the size of
this buffer, in packets, for the matching output stream.
The default value of this option should be high enough for most uses, so only
touch this option if you are sure that you need it.
@end table
@c man end OPTIONS
...
...
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