Update ffmpeg 2.1.3 -> 5.0.1
Old ffmpeg has a lot of vulnerabilities that have been fixed in newer versions, see https://www.cvedetails.com/vulnerability-list/vendor_id-3611/Ffmpeg.html.
This commit is contained in:
Vendored
+3565
File diff suppressed because it is too large
Load Diff
Vendored
+2359
File diff suppressed because it is too large
Load Diff
Vendored
+154
@@ -0,0 +1,154 @@
|
||||
LIBRARIES-$(CONFIG_AVUTIL) += libavutil
|
||||
LIBRARIES-$(CONFIG_SWSCALE) += libswscale
|
||||
LIBRARIES-$(CONFIG_SWRESAMPLE) += libswresample
|
||||
LIBRARIES-$(CONFIG_AVCODEC) += libavcodec
|
||||
LIBRARIES-$(CONFIG_AVFORMAT) += libavformat
|
||||
LIBRARIES-$(CONFIG_AVDEVICE) += libavdevice
|
||||
LIBRARIES-$(CONFIG_AVFILTER) += libavfilter
|
||||
|
||||
COMPONENTS-$(CONFIG_AVUTIL) += ffmpeg-utils
|
||||
COMPONENTS-$(CONFIG_SWSCALE) += ffmpeg-scaler
|
||||
COMPONENTS-$(CONFIG_SWRESAMPLE) += ffmpeg-resampler
|
||||
COMPONENTS-$(CONFIG_AVCODEC) += ffmpeg-codecs ffmpeg-bitstream-filters
|
||||
COMPONENTS-$(CONFIG_AVFORMAT) += ffmpeg-formats ffmpeg-protocols
|
||||
COMPONENTS-$(CONFIG_AVDEVICE) += ffmpeg-devices
|
||||
COMPONENTS-$(CONFIG_AVFILTER) += ffmpeg-filters
|
||||
|
||||
MANPAGES1 = $(AVPROGS-yes:%=doc/%.1) $(AVPROGS-yes:%=doc/%-all.1) $(COMPONENTS-yes:%=doc/%.1)
|
||||
MANPAGES3 = $(LIBRARIES-yes:%=doc/%.3)
|
||||
MANPAGES = $(MANPAGES1) $(MANPAGES3)
|
||||
PODPAGES = $(AVPROGS-yes:%=doc/%.pod) $(AVPROGS-yes:%=doc/%-all.pod) $(COMPONENTS-yes:%=doc/%.pod) $(LIBRARIES-yes:%=doc/%.pod)
|
||||
HTMLPAGES = $(AVPROGS-yes:%=doc/%.html) $(AVPROGS-yes:%=doc/%-all.html) $(COMPONENTS-yes:%=doc/%.html) $(LIBRARIES-yes:%=doc/%.html) \
|
||||
doc/developer.html \
|
||||
doc/faq.html \
|
||||
doc/fate.html \
|
||||
doc/general.html \
|
||||
doc/git-howto.html \
|
||||
doc/mailing-list-faq.html \
|
||||
doc/nut.html \
|
||||
doc/platform.html \
|
||||
|
||||
TXTPAGES = doc/fate.txt \
|
||||
|
||||
|
||||
DOCS-$(CONFIG_HTMLPAGES) += $(HTMLPAGES)
|
||||
DOCS-$(CONFIG_PODPAGES) += $(PODPAGES)
|
||||
DOCS-$(CONFIG_MANPAGES) += $(MANPAGES)
|
||||
DOCS-$(CONFIG_TXTPAGES) += $(TXTPAGES)
|
||||
DOCS = $(DOCS-yes)
|
||||
|
||||
all-$(CONFIG_DOC): doc
|
||||
|
||||
doc: documentation
|
||||
|
||||
apidoc: doc/doxy/html
|
||||
documentation: $(DOCS)
|
||||
|
||||
TEXIDEP = perl $(SRC_PATH)/doc/texidep.pl $(SRC_PATH) $< $@ >$(@:%=%.d)
|
||||
|
||||
doc/%.txt: TAG = TXT
|
||||
doc/%.txt: doc/%.texi
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)makeinfo --force --no-headers -o $@ $< 2>/dev/null
|
||||
|
||||
GENTEXI = format codec
|
||||
GENTEXI := $(GENTEXI:%=doc/avoptions_%.texi)
|
||||
|
||||
$(GENTEXI): TAG = GENTEXI
|
||||
$(GENTEXI): doc/avoptions_%.texi: doc/print_options$(HOSTEXESUF)
|
||||
$(M)doc/print_options $* > $@
|
||||
|
||||
doc/%.html: TAG = HTML
|
||||
doc/%-all.html: TAG = HTML
|
||||
|
||||
ifdef HAVE_MAKEINFO_HTML
|
||||
doc/%.html: doc/%.texi $(SRC_PATH)/doc/t2h.pm $(GENTEXI)
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)makeinfo --html -I doc --no-split -D config-not-all --init-file=$(SRC_PATH)/doc/t2h.pm --output $@ $<
|
||||
|
||||
doc/%-all.html: doc/%.texi $(SRC_PATH)/doc/t2h.pm $(GENTEXI)
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)makeinfo --html -I doc --no-split -D config-all --init-file=$(SRC_PATH)/doc/t2h.pm --output $@ $<
|
||||
else
|
||||
doc/%.html: doc/%.texi $(SRC_PATH)/doc/t2h.init $(GENTEXI)
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)texi2html -I doc -monolithic --D=config-not-all --init-file $(SRC_PATH)/doc/t2h.init --output $@ $<
|
||||
|
||||
doc/%-all.html: doc/%.texi $(SRC_PATH)/doc/t2h.init $(GENTEXI)
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)texi2html -I doc -monolithic --D=config-all --init-file $(SRC_PATH)/doc/t2h.init --output $@ $<
|
||||
endif
|
||||
|
||||
doc/%.pod: TAG = POD
|
||||
doc/%.pod: doc/%.texi $(SRC_PATH)/doc/texi2pod.pl $(GENTEXI)
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)perl $(SRC_PATH)/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc $< $@
|
||||
|
||||
doc/%-all.pod: TAG = POD
|
||||
doc/%-all.pod: doc/%.texi $(SRC_PATH)/doc/texi2pod.pl $(GENTEXI)
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)perl $(SRC_PATH)/doc/texi2pod.pl -Dconfig-all=yes -Idoc $< $@
|
||||
|
||||
doc/%.1 doc/%.3: TAG = MAN
|
||||
doc/%.1: doc/%.pod $(GENTEXI)
|
||||
$(M)pod2man --section=1 --center=" " --release=" " --date=" " $< > $@
|
||||
doc/%.3: doc/%.pod $(GENTEXI)
|
||||
$(M)pod2man --section=3 --center=" " --release=" " --date=" " $< > $@
|
||||
|
||||
$(DOCS) doc/doxy/html: | doc/
|
||||
|
||||
DOXY_INPUT = $(INSTHEADERS)
|
||||
DOXY_INPUT_DEPS = $(addprefix $(SRC_PATH)/, $(DOXY_INPUT)) ffbuild/config.mak
|
||||
|
||||
doc/doxy/html: TAG = DOXY
|
||||
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(SRC_PATH)/doc/doxy-wrapper.sh $(DOXY_INPUT_DEPS)
|
||||
$(M)$(SRC_PATH)/doc/doxy-wrapper.sh $$PWD/doc/doxy $(SRC_PATH) doc/Doxyfile $(DOXYGEN) $(DOXY_INPUT);
|
||||
|
||||
install-doc: install-html install-man
|
||||
|
||||
install-html:
|
||||
|
||||
install-man:
|
||||
|
||||
ifdef CONFIG_HTMLPAGES
|
||||
install-progs-$(CONFIG_DOC): install-html
|
||||
|
||||
install-html: $(HTMLPAGES)
|
||||
$(Q)mkdir -p "$(DOCDIR)"
|
||||
$(INSTALL) -m 644 $(HTMLPAGES) "$(DOCDIR)"
|
||||
endif
|
||||
|
||||
ifdef CONFIG_MANPAGES
|
||||
install-progs-$(CONFIG_DOC): install-man
|
||||
|
||||
install-man: $(MANPAGES)
|
||||
$(Q)mkdir -p "$(MANDIR)/man1"
|
||||
$(INSTALL) -m 644 $(MANPAGES1) "$(MANDIR)/man1"
|
||||
$(Q)mkdir -p "$(MANDIR)/man3"
|
||||
$(INSTALL) -m 644 $(MANPAGES3) "$(MANDIR)/man3"
|
||||
endif
|
||||
|
||||
uninstall: uninstall-doc
|
||||
|
||||
uninstall-doc: uninstall-html uninstall-man
|
||||
|
||||
uninstall-html:
|
||||
$(RM) -r "$(DOCDIR)"
|
||||
|
||||
uninstall-man:
|
||||
$(RM) $(addprefix "$(MANDIR)/man1/",$(AVPROGS-yes:%=%.1) $(AVPROGS-yes:%=%-all.1) $(COMPONENTS-yes:%=%.1))
|
||||
$(RM) $(addprefix "$(MANDIR)/man3/",$(LIBRARIES-yes:%=%.3))
|
||||
|
||||
clean:: docclean
|
||||
|
||||
distclean:: docclean
|
||||
$(RM) doc/config.texi
|
||||
|
||||
docclean::
|
||||
$(RM) $(CLEANSUFFIXES:%=doc/%)
|
||||
$(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 doc/*.3 doc/avoptions_*.texi
|
||||
$(RM) -r doc/doxy/html
|
||||
|
||||
-include $(wildcard $(DOCS:%=%.d))
|
||||
|
||||
.PHONY: apidoc doc documentation
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
@chapter Authors
|
||||
|
||||
The FFmpeg developers.
|
||||
|
||||
For details about the authorship, see the Git history of the project
|
||||
(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
@command{git log} in the FFmpeg source directory, or browsing the
|
||||
online repository at @url{http://source.ffmpeg.org}.
|
||||
|
||||
Maintainers for the specific components are listed in the file
|
||||
@file{MAINTAINERS} in the source code tree.
|
||||
+854
@@ -0,0 +1,854 @@
|
||||
@chapter Bitstream Filters
|
||||
@c man begin BITSTREAM FILTERS
|
||||
|
||||
When you configure your FFmpeg build, all the supported bitstream
|
||||
filters are enabled by default. You can list all available ones using
|
||||
the configure option @code{--list-bsfs}.
|
||||
|
||||
You can disable all the bitstream filters using the configure option
|
||||
@code{--disable-bsfs}, and selectively enable any bitstream filter using
|
||||
the option @code{--enable-bsf=BSF}, or you can disable a particular
|
||||
bitstream filter using the option @code{--disable-bsf=BSF}.
|
||||
|
||||
The option @code{-bsfs} of the ff* tools will display the list of
|
||||
all the supported bitstream filters included in your build.
|
||||
|
||||
The ff* tools have a -bsf option applied per stream, taking a
|
||||
comma-separated list of filters, whose parameters follow the filter
|
||||
name after a '='.
|
||||
|
||||
@example
|
||||
ffmpeg -i INPUT -c:v copy -bsf:v filter1[=opt1=str1:opt2=str2][,filter2] OUTPUT
|
||||
@end example
|
||||
|
||||
Below is a description of the currently available bitstream filters,
|
||||
with their parameters, if any.
|
||||
|
||||
@section aac_adtstoasc
|
||||
|
||||
Convert MPEG-2/4 AAC ADTS to an MPEG-4 Audio Specific Configuration
|
||||
bitstream.
|
||||
|
||||
This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4
|
||||
ADTS header and removes the ADTS header.
|
||||
|
||||
This filter is required for example when copying an AAC stream from a
|
||||
raw ADTS AAC or an MPEG-TS container to MP4A-LATM, to an FLV file, or
|
||||
to MOV/MP4 files and related formats such as 3GP or M4A. Please note
|
||||
that it is auto-inserted for MP4A-LATM and MOV/MP4 and related formats.
|
||||
|
||||
@section av1_metadata
|
||||
|
||||
Modify metadata embedded in an AV1 stream.
|
||||
|
||||
@table @option
|
||||
@item td
|
||||
Insert or remove temporal delimiter OBUs in all temporal units of the
|
||||
stream.
|
||||
|
||||
@table @samp
|
||||
@item insert
|
||||
Insert a TD at the beginning of every TU which does not already have one.
|
||||
@item remove
|
||||
Remove the TD from the beginning of every TU which has one.
|
||||
@end table
|
||||
|
||||
@item color_primaries
|
||||
@item transfer_characteristics
|
||||
@item matrix_coefficients
|
||||
Set the color description fields in the stream (see AV1 section 6.4.2).
|
||||
|
||||
@item color_range
|
||||
Set the color range in the stream (see AV1 section 6.4.2; note that
|
||||
this cannot be set for streams using BT.709 primaries, sRGB transfer
|
||||
characteristic and identity (RGB) matrix coefficients).
|
||||
@table @samp
|
||||
@item tv
|
||||
Limited range.
|
||||
@item pc
|
||||
Full range.
|
||||
@end table
|
||||
|
||||
@item chroma_sample_position
|
||||
Set the chroma sample location in the stream (see AV1 section 6.4.2).
|
||||
This can only be set for 4:2:0 streams.
|
||||
|
||||
@table @samp
|
||||
@item vertical
|
||||
Left position (matching the default in MPEG-2 and H.264).
|
||||
@item colocated
|
||||
Top-left position.
|
||||
@end table
|
||||
|
||||
@item tick_rate
|
||||
Set the tick rate (@emph{time_scale / num_units_in_display_tick}) in
|
||||
the timing info in the sequence header.
|
||||
@item num_ticks_per_picture
|
||||
Set the number of ticks in each picture, to indicate that the stream
|
||||
has a fixed framerate. Ignored if @option{tick_rate} is not also set.
|
||||
|
||||
@item delete_padding
|
||||
Deletes Padding OBUs.
|
||||
|
||||
@end table
|
||||
|
||||
@section chomp
|
||||
|
||||
Remove zero padding at the end of a packet.
|
||||
|
||||
@section dca_core
|
||||
|
||||
Extract the core from a DCA/DTS stream, dropping extensions such as
|
||||
DTS-HD.
|
||||
|
||||
@section dump_extra
|
||||
|
||||
Add extradata to the beginning of the filtered packets except when
|
||||
said packets already exactly begin with the extradata that is intended
|
||||
to be added.
|
||||
|
||||
@table @option
|
||||
@item freq
|
||||
The additional argument specifies which packets should be filtered.
|
||||
It accepts the values:
|
||||
@table @samp
|
||||
@item k
|
||||
@item keyframe
|
||||
add extradata to all key packets
|
||||
|
||||
@item e
|
||||
@item all
|
||||
add extradata to all packets
|
||||
@end table
|
||||
@end table
|
||||
|
||||
If not specified it is assumed @samp{k}.
|
||||
|
||||
For example the following @command{ffmpeg} command forces a global
|
||||
header (thus disabling individual packet headers) in the H.264 packets
|
||||
generated by the @code{libx264} encoder, but corrects them by adding
|
||||
the header stored in extradata to the key packets:
|
||||
@example
|
||||
ffmpeg -i INPUT -map 0 -flags:v +global_header -c:v libx264 -bsf:v dump_extra out.ts
|
||||
@end example
|
||||
|
||||
@section eac3_core
|
||||
|
||||
Extract the core from a E-AC-3 stream, dropping extra channels.
|
||||
|
||||
@section extract_extradata
|
||||
|
||||
Extract the in-band extradata.
|
||||
|
||||
Certain codecs allow the long-term headers (e.g. MPEG-2 sequence headers,
|
||||
or H.264/HEVC (VPS/)SPS/PPS) to be transmitted either "in-band" (i.e. as a part
|
||||
of the bitstream containing the coded frames) or "out of band" (e.g. on the
|
||||
container level). This latter form is called "extradata" in FFmpeg terminology.
|
||||
|
||||
This bitstream filter detects the in-band headers and makes them available as
|
||||
extradata.
|
||||
|
||||
@table @option
|
||||
@item remove
|
||||
When this option is enabled, the long-term headers are removed from the
|
||||
bitstream after extraction.
|
||||
@end table
|
||||
|
||||
@section filter_units
|
||||
|
||||
Remove units with types in or not in a given set from the stream.
|
||||
|
||||
@table @option
|
||||
@item pass_types
|
||||
List of unit types or ranges of unit types to pass through while removing
|
||||
all others. This is specified as a '|'-separated list of unit type values
|
||||
or ranges of values with '-'.
|
||||
|
||||
@item remove_types
|
||||
Identical to @option{pass_types}, except the units in the given set
|
||||
removed and all others passed through.
|
||||
@end table
|
||||
|
||||
Extradata is unchanged by this transformation, but note that if the stream
|
||||
contains inline parameter sets then the output may be unusable if they are
|
||||
removed.
|
||||
|
||||
For example, to remove all non-VCL NAL units from an H.264 stream:
|
||||
@example
|
||||
ffmpeg -i INPUT -c:v copy -bsf:v 'filter_units=pass_types=1-5' OUTPUT
|
||||
@end example
|
||||
|
||||
To remove all AUDs, SEI and filler from an H.265 stream:
|
||||
@example
|
||||
ffmpeg -i INPUT -c:v copy -bsf:v 'filter_units=remove_types=35|38-40' OUTPUT
|
||||
@end example
|
||||
|
||||
@section hapqa_extract
|
||||
|
||||
Extract Rgb or Alpha part of an HAPQA file, without recompression, in order to create an HAPQ or an HAPAlphaOnly file.
|
||||
|
||||
@table @option
|
||||
@item texture
|
||||
Specifies the texture to keep.
|
||||
|
||||
@table @option
|
||||
@item color
|
||||
@item alpha
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
Convert HAPQA to HAPQ
|
||||
@example
|
||||
ffmpeg -i hapqa_inputfile.mov -c copy -bsf:v hapqa_extract=texture=color -tag:v HapY -metadata:s:v:0 encoder="HAPQ" hapq_file.mov
|
||||
@end example
|
||||
|
||||
Convert HAPQA to HAPAlphaOnly
|
||||
@example
|
||||
ffmpeg -i hapqa_inputfile.mov -c copy -bsf:v hapqa_extract=texture=alpha -tag:v HapA -metadata:s:v:0 encoder="HAPAlpha Only" hapalphaonly_file.mov
|
||||
@end example
|
||||
|
||||
@section h264_metadata
|
||||
|
||||
Modify metadata embedded in an H.264 stream.
|
||||
|
||||
@table @option
|
||||
@item aud
|
||||
Insert or remove AUD NAL units in all access units of the stream.
|
||||
|
||||
@table @samp
|
||||
@item insert
|
||||
@item remove
|
||||
@end table
|
||||
|
||||
@item sample_aspect_ratio
|
||||
Set the sample aspect ratio of the stream in the VUI parameters.
|
||||
|
||||
@item overscan_appropriate_flag
|
||||
Set whether the stream is suitable for display using overscan
|
||||
or not (see H.264 section E.2.1).
|
||||
|
||||
@item video_format
|
||||
@item video_full_range_flag
|
||||
Set the video format in the stream (see H.264 section E.2.1 and
|
||||
table E-2).
|
||||
|
||||
@item colour_primaries
|
||||
@item transfer_characteristics
|
||||
@item matrix_coefficients
|
||||
Set the colour description in the stream (see H.264 section E.2.1
|
||||
and tables E-3, E-4 and E-5).
|
||||
|
||||
@item chroma_sample_loc_type
|
||||
Set the chroma sample location in the stream (see H.264 section
|
||||
E.2.1 and figure E-1).
|
||||
|
||||
@item tick_rate
|
||||
Set the tick rate (time_scale / num_units_in_tick) in the VUI
|
||||
parameters. This is the smallest time unit representable in the
|
||||
stream, and in many cases represents the field rate of the stream
|
||||
(double the frame rate).
|
||||
@item fixed_frame_rate_flag
|
||||
Set whether the stream has fixed framerate - typically this indicates
|
||||
that the framerate is exactly half the tick rate, but the exact
|
||||
meaning is dependent on interlacing and the picture structure (see
|
||||
H.264 section E.2.1 and table E-6).
|
||||
@item zero_new_constraint_set_flags
|
||||
Zero constraint_set4_flag and constraint_set5_flag in the SPS. These
|
||||
bits were reserved in a previous version of the H.264 spec, and thus
|
||||
some hardware decoders require these to be zero. The result of zeroing
|
||||
this is still a valid bitstream.
|
||||
|
||||
@item crop_left
|
||||
@item crop_right
|
||||
@item crop_top
|
||||
@item crop_bottom
|
||||
Set the frame cropping offsets in the SPS. These values will replace
|
||||
the current ones if the stream is already cropped.
|
||||
|
||||
These fields are set in pixels. Note that some sizes may not be
|
||||
representable if the chroma is subsampled or the stream is interlaced
|
||||
(see H.264 section 7.4.2.1.1).
|
||||
|
||||
@item sei_user_data
|
||||
Insert a string as SEI unregistered user data. The argument must
|
||||
be of the form @emph{UUID+string}, where the UUID is as hex digits
|
||||
possibly separated by hyphens, and the string can be anything.
|
||||
|
||||
For example, @samp{086f3693-b7b3-4f2c-9653-21492feee5b8+hello} will
|
||||
insert the string ``hello'' associated with the given UUID.
|
||||
|
||||
@item delete_filler
|
||||
Deletes both filler NAL units and filler SEI messages.
|
||||
|
||||
@item level
|
||||
Set the level in the SPS. Refer to H.264 section A.3 and tables A-1
|
||||
to A-5.
|
||||
|
||||
The argument must be the name of a level (for example, @samp{4.2}), a
|
||||
level_idc value (for example, @samp{42}), or the special name @samp{auto}
|
||||
indicating that the filter should attempt to guess the level from the
|
||||
input stream properties.
|
||||
|
||||
@end table
|
||||
|
||||
@section h264_mp4toannexb
|
||||
|
||||
Convert an H.264 bitstream from length prefixed mode to start code
|
||||
prefixed mode (as defined in the Annex B of the ITU-T H.264
|
||||
specification).
|
||||
|
||||
This is required by some streaming formats, typically the MPEG-2
|
||||
transport stream format (muxer @code{mpegts}).
|
||||
|
||||
For example to remux an MP4 file containing an H.264 stream to mpegts
|
||||
format with @command{ffmpeg}, you can use the command:
|
||||
|
||||
@example
|
||||
ffmpeg -i INPUT.mp4 -codec copy -bsf:v h264_mp4toannexb OUTPUT.ts
|
||||
@end example
|
||||
|
||||
Please note that this filter is auto-inserted for MPEG-TS (muxer
|
||||
@code{mpegts}) and raw H.264 (muxer @code{h264}) output formats.
|
||||
|
||||
@section h264_redundant_pps
|
||||
|
||||
This applies a specific fixup to some Blu-ray streams which contain
|
||||
redundant PPSs modifying irrelevant parameters of the stream which
|
||||
confuse other transformations which require correct extradata.
|
||||
|
||||
A new single global PPS is created, and all of the redundant PPSs
|
||||
within the stream are removed.
|
||||
|
||||
@section hevc_metadata
|
||||
|
||||
Modify metadata embedded in an HEVC stream.
|
||||
|
||||
@table @option
|
||||
@item aud
|
||||
Insert or remove AUD NAL units in all access units of the stream.
|
||||
|
||||
@table @samp
|
||||
@item insert
|
||||
@item remove
|
||||
@end table
|
||||
|
||||
@item sample_aspect_ratio
|
||||
Set the sample aspect ratio in the stream in the VUI parameters.
|
||||
|
||||
@item video_format
|
||||
@item video_full_range_flag
|
||||
Set the video format in the stream (see H.265 section E.3.1 and
|
||||
table E.2).
|
||||
|
||||
@item colour_primaries
|
||||
@item transfer_characteristics
|
||||
@item matrix_coefficients
|
||||
Set the colour description in the stream (see H.265 section E.3.1
|
||||
and tables E.3, E.4 and E.5).
|
||||
|
||||
@item chroma_sample_loc_type
|
||||
Set the chroma sample location in the stream (see H.265 section
|
||||
E.3.1 and figure E.1).
|
||||
|
||||
@item tick_rate
|
||||
Set the tick rate in the VPS and VUI parameters (time_scale /
|
||||
num_units_in_tick). Combined with @option{num_ticks_poc_diff_one}, this can
|
||||
set a constant framerate in the stream. Note that it is likely to be
|
||||
overridden by container parameters when the stream is in a container.
|
||||
|
||||
@item num_ticks_poc_diff_one
|
||||
Set poc_proportional_to_timing_flag in VPS and VUI and use this value
|
||||
to set num_ticks_poc_diff_one_minus1 (see H.265 sections 7.4.3.1 and
|
||||
E.3.1). Ignored if @option{tick_rate} is not also set.
|
||||
|
||||
@item crop_left
|
||||
@item crop_right
|
||||
@item crop_top
|
||||
@item crop_bottom
|
||||
Set the conformance window cropping offsets in the SPS. These values
|
||||
will replace the current ones if the stream is already cropped.
|
||||
|
||||
These fields are set in pixels. Note that some sizes may not be
|
||||
representable if the chroma is subsampled (H.265 section 7.4.3.2.1).
|
||||
|
||||
@item level
|
||||
Set the level in the VPS and SPS. See H.265 section A.4 and tables
|
||||
A.6 and A.7.
|
||||
|
||||
The argument must be the name of a level (for example, @samp{5.1}), a
|
||||
@emph{general_level_idc} value (for example, @samp{153} for level 5.1),
|
||||
or the special name @samp{auto} indicating that the filter should
|
||||
attempt to guess the level from the input stream properties.
|
||||
|
||||
@end table
|
||||
|
||||
@section hevc_mp4toannexb
|
||||
|
||||
Convert an HEVC/H.265 bitstream from length prefixed mode to start code
|
||||
prefixed mode (as defined in the Annex B of the ITU-T H.265
|
||||
specification).
|
||||
|
||||
This is required by some streaming formats, typically the MPEG-2
|
||||
transport stream format (muxer @code{mpegts}).
|
||||
|
||||
For example to remux an MP4 file containing an HEVC stream to mpegts
|
||||
format with @command{ffmpeg}, you can use the command:
|
||||
|
||||
@example
|
||||
ffmpeg -i INPUT.mp4 -codec copy -bsf:v hevc_mp4toannexb OUTPUT.ts
|
||||
@end example
|
||||
|
||||
Please note that this filter is auto-inserted for MPEG-TS (muxer
|
||||
@code{mpegts}) and raw HEVC/H.265 (muxer @code{h265} or
|
||||
@code{hevc}) output formats.
|
||||
|
||||
@section imxdump
|
||||
|
||||
Modifies the bitstream to fit in MOV and to be usable by the Final Cut
|
||||
Pro decoder. This filter only applies to the mpeg2video codec, and is
|
||||
likely not needed for Final Cut Pro 7 and newer with the appropriate
|
||||
@option{-tag:v}.
|
||||
|
||||
For example, to remux 30 MB/sec NTSC IMX to MOV:
|
||||
|
||||
@example
|
||||
ffmpeg -i input.mxf -c copy -bsf:v imxdump -tag:v mx3n output.mov
|
||||
@end example
|
||||
|
||||
@section mjpeg2jpeg
|
||||
|
||||
Convert MJPEG/AVI1 packets to full JPEG/JFIF packets.
|
||||
|
||||
MJPEG is a video codec wherein each video frame is essentially a
|
||||
JPEG image. The individual frames can be extracted without loss,
|
||||
e.g. by
|
||||
|
||||
@example
|
||||
ffmpeg -i ../some_mjpeg.avi -c:v copy frames_%d.jpg
|
||||
@end example
|
||||
|
||||
Unfortunately, these chunks are incomplete JPEG images, because
|
||||
they lack the DHT segment required for decoding. Quoting from
|
||||
@url{http://www.digitalpreservation.gov/formats/fdd/fdd000063.shtml}:
|
||||
|
||||
Avery Lee, writing in the rec.video.desktop newsgroup in 2001,
|
||||
commented that "MJPEG, or at least the MJPEG in AVIs having the
|
||||
MJPG fourcc, is restricted JPEG with a fixed -- and *omitted* --
|
||||
Huffman table. The JPEG must be YCbCr colorspace, it must be 4:2:2,
|
||||
and it must use basic Huffman encoding, not arithmetic or
|
||||
progressive. . . . You can indeed extract the MJPEG frames and
|
||||
decode them with a regular JPEG decoder, but you have to prepend
|
||||
the DHT segment to them, or else the decoder won't have any idea
|
||||
how to decompress the data. The exact table necessary is given in
|
||||
the OpenDML spec."
|
||||
|
||||
This bitstream filter patches the header of frames extracted from an MJPEG
|
||||
stream (carrying the AVI1 header ID and lacking a DHT segment) to
|
||||
produce fully qualified JPEG images.
|
||||
|
||||
@example
|
||||
ffmpeg -i mjpeg-movie.avi -c:v copy -bsf:v mjpeg2jpeg frame_%d.jpg
|
||||
exiftran -i -9 frame*.jpg
|
||||
ffmpeg -i frame_%d.jpg -c:v copy rotated.avi
|
||||
@end example
|
||||
|
||||
@section mjpegadump
|
||||
|
||||
Add an MJPEG A header to the bitstream, to enable decoding by
|
||||
Quicktime.
|
||||
|
||||
@anchor{mov2textsub}
|
||||
@section mov2textsub
|
||||
|
||||
Extract a representable text file from MOV subtitles, stripping the
|
||||
metadata header from each subtitle packet.
|
||||
|
||||
See also the @ref{text2movsub} filter.
|
||||
|
||||
@section mp3decomp
|
||||
|
||||
Decompress non-standard compressed MP3 audio headers.
|
||||
|
||||
@section mpeg2_metadata
|
||||
|
||||
Modify metadata embedded in an MPEG-2 stream.
|
||||
|
||||
@table @option
|
||||
@item display_aspect_ratio
|
||||
Set the display aspect ratio in the stream.
|
||||
|
||||
The following fixed values are supported:
|
||||
@table @option
|
||||
@item 4/3
|
||||
@item 16/9
|
||||
@item 221/100
|
||||
@end table
|
||||
Any other value will result in square pixels being signalled instead
|
||||
(see H.262 section 6.3.3 and table 6-3).
|
||||
|
||||
@item frame_rate
|
||||
Set the frame rate in the stream. This is constructed from a table
|
||||
of known values combined with a small multiplier and divisor - if
|
||||
the supplied value is not exactly representable, the nearest
|
||||
representable value will be used instead (see H.262 section 6.3.3
|
||||
and table 6-4).
|
||||
|
||||
@item video_format
|
||||
Set the video format in the stream (see H.262 section 6.3.6 and
|
||||
table 6-6).
|
||||
|
||||
@item colour_primaries
|
||||
@item transfer_characteristics
|
||||
@item matrix_coefficients
|
||||
Set the colour description in the stream (see H.262 section 6.3.6
|
||||
and tables 6-7, 6-8 and 6-9).
|
||||
|
||||
@end table
|
||||
|
||||
@section mpeg4_unpack_bframes
|
||||
|
||||
Unpack DivX-style packed B-frames.
|
||||
|
||||
DivX-style packed B-frames are not valid MPEG-4 and were only a
|
||||
workaround for the broken Video for Windows subsystem.
|
||||
They use more space, can cause minor AV sync issues, require more
|
||||
CPU power to decode (unless the player has some decoded picture queue
|
||||
to compensate the 2,0,2,0 frame per packet style) and cause
|
||||
trouble if copied into a standard container like mp4 or mpeg-ps/ts,
|
||||
because MPEG-4 decoders may not be able to decode them, since they are
|
||||
not valid MPEG-4.
|
||||
|
||||
For example to fix an AVI file containing an MPEG-4 stream with
|
||||
DivX-style packed B-frames using @command{ffmpeg}, you can use the command:
|
||||
|
||||
@example
|
||||
ffmpeg -i INPUT.avi -codec copy -bsf:v mpeg4_unpack_bframes OUTPUT.avi
|
||||
@end example
|
||||
|
||||
@section noise
|
||||
|
||||
Damages the contents of packets or simply drops them without damaging the
|
||||
container. Can be used for fuzzing or testing error resilience/concealment.
|
||||
|
||||
Parameters:
|
||||
@table @option
|
||||
@item amount
|
||||
Accepts an expression whose evaluation per-packet determines how often bytes in that
|
||||
packet will be modified. A value below 0 will result in a variable frequency.
|
||||
Default is 0 which results in no modification. However, if neither amount nor drop is specified,
|
||||
amount will be set to @var{-1}. See below for accepted variables.
|
||||
@item drop
|
||||
Accepts an expression evaluated per-packet whose value determines whether that packet is dropped.
|
||||
Evaluation to a positive value results in the packet being dropped. Evaluation to a negative
|
||||
value results in a variable chance of it being dropped, roughly inverse in proportion to the magnitude
|
||||
of the value. Default is 0 which results in no drops. See below for accepted variables.
|
||||
@item dropamount
|
||||
Accepts a non-negative integer, which assigns a variable chance of it being dropped, roughly inverse
|
||||
in proportion to the value. Default is 0 which results in no drops. This option is kept for backwards
|
||||
compatibility and is equivalent to setting drop to a negative value with the same magnitude
|
||||
i.e. @code{dropamount=4} is the same as @code{drop=-4}. Ignored if drop is also specified.
|
||||
@end table
|
||||
|
||||
Both @code{amount} and @code{drop} accept expressions containing the following variables:
|
||||
|
||||
@table @samp
|
||||
@item n
|
||||
The index of the packet, starting from zero.
|
||||
@item tb
|
||||
The timebase for packet timestamps.
|
||||
@item pts
|
||||
Packet presentation timestamp.
|
||||
@item dts
|
||||
Packet decoding timestamp.
|
||||
@item nopts
|
||||
Constant representing AV_NOPTS_VALUE.
|
||||
@item startpts
|
||||
First non-AV_NOPTS_VALUE PTS seen in the stream.
|
||||
@item startdts
|
||||
First non-AV_NOPTS_VALUE DTS seen in the stream.
|
||||
@item duration
|
||||
@itemx d
|
||||
Packet duration, in timebase units.
|
||||
@item pos
|
||||
Packet position in input; may be -1 when unknown or not set.
|
||||
@item size
|
||||
Packet size, in bytes.
|
||||
@item key
|
||||
Whether packet is marked as a keyframe.
|
||||
@item state
|
||||
A pseudo random integer, primarily derived from the content of packet payload.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
Apply modification to every byte but don't drop any packets.
|
||||
@example
|
||||
ffmpeg -i INPUT -c copy -bsf noise=1 output.mkv
|
||||
@end example
|
||||
|
||||
Drop every video packet not marked as a keyframe after timestamp 30s but do not
|
||||
modify any of the remaining packets.
|
||||
@example
|
||||
ffmpeg -i INPUT -c copy -bsf:v noise=drop='gt(t\,30)*not(key)' output.mkv
|
||||
@end example
|
||||
|
||||
Drop one second of audio every 10 seconds and add some random noise to the rest.
|
||||
@example
|
||||
ffmpeg -i INPUT -c copy -bsf:a noise=amount=-1:drop='between(mod(t\,10)\,9\,10)' output.mkv
|
||||
@end example
|
||||
|
||||
@section null
|
||||
This bitstream filter passes the packets through unchanged.
|
||||
|
||||
@section pcm_rechunk
|
||||
|
||||
Repacketize PCM audio to a fixed number of samples per packet or a fixed packet
|
||||
rate per second. This is similar to the @ref{asetnsamples,,asetnsamples audio
|
||||
filter,ffmpeg-filters} but works on audio packets instead of audio frames.
|
||||
|
||||
@table @option
|
||||
@item nb_out_samples, n
|
||||
Set the number of samples per each output audio packet. The number is intended
|
||||
as the number of samples @emph{per each channel}. Default value is 1024.
|
||||
|
||||
@item pad, p
|
||||
If set to 1, the filter will pad the last audio packet with silence, so that it
|
||||
will contain the same number of samples (or roughly the same number of samples,
|
||||
see @option{frame_rate}) as the previous ones. Default value is 1.
|
||||
|
||||
@item frame_rate, r
|
||||
This option makes the filter output a fixed number of packets per second instead
|
||||
of a fixed number of samples per packet. If the audio sample rate is not
|
||||
divisible by the frame rate then the number of samples will not be constant but
|
||||
will vary slightly so that each packet will start as close to the frame
|
||||
boundary as possible. Using this option has precedence over @option{nb_out_samples}.
|
||||
@end table
|
||||
|
||||
You can generate the well known 1602-1601-1602-1601-1602 pattern of 48kHz audio
|
||||
for NTSC frame rate using the @option{frame_rate} option.
|
||||
@example
|
||||
ffmpeg -f lavfi -i sine=r=48000:d=1 -c pcm_s16le -bsf pcm_rechunk=r=30000/1001 -f framecrc -
|
||||
@end example
|
||||
|
||||
@section prores_metadata
|
||||
|
||||
Modify color property metadata embedded in prores stream.
|
||||
|
||||
@table @option
|
||||
@item color_primaries
|
||||
Set the color primaries.
|
||||
Available values are:
|
||||
|
||||
@table @samp
|
||||
@item auto
|
||||
Keep the same color primaries property (default).
|
||||
|
||||
@item unknown
|
||||
@item bt709
|
||||
@item bt470bg
|
||||
BT601 625
|
||||
|
||||
@item smpte170m
|
||||
BT601 525
|
||||
|
||||
@item bt2020
|
||||
@item smpte431
|
||||
DCI P3
|
||||
|
||||
@item smpte432
|
||||
P3 D65
|
||||
|
||||
@end table
|
||||
|
||||
@item transfer_characteristics
|
||||
Set the color transfer.
|
||||
Available values are:
|
||||
|
||||
@table @samp
|
||||
@item auto
|
||||
Keep the same transfer characteristics property (default).
|
||||
|
||||
@item unknown
|
||||
@item bt709
|
||||
BT 601, BT 709, BT 2020
|
||||
@item smpte2084
|
||||
SMPTE ST 2084
|
||||
@item arib-std-b67
|
||||
ARIB STD-B67
|
||||
@end table
|
||||
|
||||
|
||||
@item matrix_coefficients
|
||||
Set the matrix coefficient.
|
||||
Available values are:
|
||||
|
||||
@table @samp
|
||||
@item auto
|
||||
Keep the same colorspace property (default).
|
||||
|
||||
@item unknown
|
||||
@item bt709
|
||||
@item smpte170m
|
||||
BT 601
|
||||
|
||||
@item bt2020nc
|
||||
@end table
|
||||
@end table
|
||||
|
||||
Set Rec709 colorspace for each frame of the file
|
||||
@example
|
||||
ffmpeg -i INPUT -c copy -bsf:v prores_metadata=color_primaries=bt709:color_trc=bt709:colorspace=bt709 output.mov
|
||||
@end example
|
||||
|
||||
Set Hybrid Log-Gamma parameters for each frame of the file
|
||||
@example
|
||||
ffmpeg -i INPUT -c copy -bsf:v prores_metadata=color_primaries=bt2020:color_trc=arib-std-b67:colorspace=bt2020nc output.mov
|
||||
@end example
|
||||
|
||||
@section remove_extra
|
||||
|
||||
Remove extradata from packets.
|
||||
|
||||
It accepts the following parameter:
|
||||
@table @option
|
||||
@item freq
|
||||
Set which frame types to remove extradata from.
|
||||
|
||||
@table @samp
|
||||
@item k
|
||||
Remove extradata from non-keyframes only.
|
||||
|
||||
@item keyframe
|
||||
Remove extradata from keyframes only.
|
||||
|
||||
@item e, all
|
||||
Remove extradata from all frames.
|
||||
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@section setts
|
||||
Set PTS and DTS in packets.
|
||||
|
||||
It accepts the following parameters:
|
||||
@table @option
|
||||
@item ts
|
||||
@item pts
|
||||
@item dts
|
||||
Set expressions for PTS, DTS or both.
|
||||
@end table
|
||||
|
||||
The expressions are evaluated through the eval API and can contain the following
|
||||
constants:
|
||||
|
||||
@table @option
|
||||
@item N
|
||||
The count of the input packet. Starting from 0.
|
||||
|
||||
@item TS
|
||||
The demux timestamp in input in case of @code{ts} or @code{dts} option or presentation
|
||||
timestamp in case of @code{pts} option.
|
||||
|
||||
@item POS
|
||||
The original position in the file of the packet, or undefined if undefined
|
||||
for the current packet
|
||||
|
||||
@item DTS
|
||||
The demux timestamp in input.
|
||||
|
||||
@item PTS
|
||||
The presentation timestamp in input.
|
||||
|
||||
@item STARTDTS
|
||||
The DTS of the first packet.
|
||||
|
||||
@item STARTPTS
|
||||
The PTS of the first packet.
|
||||
|
||||
@item PREV_INDTS
|
||||
The previous input DTS.
|
||||
|
||||
@item PREV_INPTS
|
||||
The previous input PTS.
|
||||
|
||||
@item PREV_OUTDTS
|
||||
The previous output DTS.
|
||||
|
||||
@item PREV_OUTPTS
|
||||
The previous output PTS.
|
||||
|
||||
@item TB
|
||||
The timebase of stream packet belongs.
|
||||
|
||||
@item SR
|
||||
The sample rate of stream packet belongs.
|
||||
|
||||
@item NOPTS
|
||||
The AV_NOPTS_VALUE constant.
|
||||
@end table
|
||||
|
||||
@anchor{text2movsub}
|
||||
@section text2movsub
|
||||
|
||||
Convert text subtitles to MOV subtitles (as used by the @code{mov_text}
|
||||
codec) with metadata headers.
|
||||
|
||||
See also the @ref{mov2textsub} filter.
|
||||
|
||||
@section trace_headers
|
||||
|
||||
Log trace output containing all syntax elements in the coded stream
|
||||
headers (everything above the level of individual coded blocks).
|
||||
This can be useful for debugging low-level stream issues.
|
||||
|
||||
Supports AV1, H.264, H.265, (M)JPEG, MPEG-2 and VP9, but depending
|
||||
on the build only a subset of these may be available.
|
||||
|
||||
@section truehd_core
|
||||
|
||||
Extract the core from a TrueHD stream, dropping ATMOS data.
|
||||
|
||||
@section vp9_metadata
|
||||
|
||||
Modify metadata embedded in a VP9 stream.
|
||||
|
||||
@table @option
|
||||
@item color_space
|
||||
Set the color space value in the frame header. Note that any frame
|
||||
set to RGB will be implicitly set to PC range and that RGB is
|
||||
incompatible with profiles 0 and 2.
|
||||
@table @samp
|
||||
@item unknown
|
||||
@item bt601
|
||||
@item bt709
|
||||
@item smpte170
|
||||
@item smpte240
|
||||
@item bt2020
|
||||
@item rgb
|
||||
@end table
|
||||
|
||||
@item color_range
|
||||
Set the color range value in the frame header. Note that any value
|
||||
imposed by the color space will take precedence over this value.
|
||||
@table @samp
|
||||
@item tv
|
||||
@item pc
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@section vp9_superframe
|
||||
|
||||
Merge VP9 invisible (alt-ref) frames back into VP9 superframes. This
|
||||
fixes merging of split/segmented VP9 streams where the alt-ref frame
|
||||
was split from its visible counterpart.
|
||||
|
||||
@section vp9_superframe_split
|
||||
|
||||
Split VP9 superframes into single frames.
|
||||
|
||||
@section vp9_raw_reorder
|
||||
|
||||
Given a VP9 stream with correct timestamps but possibly out of order,
|
||||
insert additional show-existing-frame packets to correct the ordering.
|
||||
|
||||
@c man end BITSTREAM FILTERS
|
||||
Vendored
+5
File diff suppressed because one or more lines are too long
Vendored
+66
@@ -0,0 +1,66 @@
|
||||
FFmpeg currently uses a custom build system, this text attempts to document
|
||||
some of its obscure features and options.
|
||||
|
||||
Makefile variables:
|
||||
|
||||
V
|
||||
Disable the default terse mode, the full command issued by make and its
|
||||
output will be shown on the screen.
|
||||
|
||||
DBG
|
||||
Preprocess x86 external assembler files to a .dbg.asm file in the object
|
||||
directory, which then gets compiled. Helps in developing those assembler
|
||||
files.
|
||||
|
||||
DESTDIR
|
||||
Destination directory for the install targets, useful to prepare packages
|
||||
or install FFmpeg in cross-environments.
|
||||
|
||||
GEN
|
||||
Set to ‘1’ to generate the missing or mismatched references.
|
||||
|
||||
Makefile targets:
|
||||
|
||||
all
|
||||
Default target, builds all the libraries and the executables.
|
||||
|
||||
fate
|
||||
Run the fate test suite, note that you must have installed it.
|
||||
|
||||
fate-list
|
||||
List all fate/regression test targets.
|
||||
|
||||
install
|
||||
Install headers, libraries and programs.
|
||||
|
||||
examples
|
||||
Build all examples located in doc/examples.
|
||||
|
||||
checkheaders
|
||||
Check headers dependencies.
|
||||
|
||||
alltools
|
||||
Build all tools in tools directory.
|
||||
|
||||
config
|
||||
Reconfigure the project with the current configuration.
|
||||
|
||||
tools/target_dec_<decoder>_fuzzer
|
||||
Build fuzzer to fuzz the specified decoder.
|
||||
|
||||
tools/target_bsf_<filter>_fuzzer
|
||||
Build fuzzer to fuzz the specified bitstream filter.
|
||||
|
||||
Useful standard make commands:
|
||||
make -t <target>
|
||||
Touch all files that otherwise would be built, this is useful to reduce
|
||||
unneeded rebuilding when changing headers, but note that you must force rebuilds
|
||||
of files that actually need it by hand then.
|
||||
|
||||
make -j<num>
|
||||
Rebuild with multiple jobs at the same time. Faster on multi processor systems.
|
||||
|
||||
make -k
|
||||
Continue build in case of errors, this is useful for the regression tests
|
||||
sometimes but note that it will still not run all reg tests.
|
||||
|
||||
Vendored
+1031
File diff suppressed because it is too large
Load Diff
Vendored
+406
@@ -0,0 +1,406 @@
|
||||
@chapter Decoders
|
||||
@c man begin DECODERS
|
||||
|
||||
Decoders are configured elements in FFmpeg which allow the decoding of
|
||||
multimedia streams.
|
||||
|
||||
When you configure your FFmpeg build, all the supported native decoders
|
||||
are enabled by default. Decoders requiring an external library must be enabled
|
||||
manually via the corresponding @code{--enable-lib} option. You can list all
|
||||
available decoders using the configure option @code{--list-decoders}.
|
||||
|
||||
You can disable all the decoders with the configure option
|
||||
@code{--disable-decoders} and selectively enable / disable single decoders
|
||||
with the options @code{--enable-decoder=@var{DECODER}} /
|
||||
@code{--disable-decoder=@var{DECODER}}.
|
||||
|
||||
The option @code{-decoders} of the ff* tools will display the list of
|
||||
enabled decoders.
|
||||
|
||||
@c man end DECODERS
|
||||
|
||||
@chapter Video Decoders
|
||||
@c man begin VIDEO DECODERS
|
||||
|
||||
A description of some of the currently available video decoders
|
||||
follows.
|
||||
|
||||
@section av1
|
||||
|
||||
AOMedia Video 1 (AV1) decoder.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item operating_point
|
||||
Select an operating point of a scalable AV1 bitstream (0 - 31). Default is 0.
|
||||
|
||||
@end table
|
||||
|
||||
@section rawvideo
|
||||
|
||||
Raw video decoder.
|
||||
|
||||
This decoder decodes rawvideo streams.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item top @var{top_field_first}
|
||||
Specify the assumed field type of the input video.
|
||||
@table @option
|
||||
@item -1
|
||||
the video is assumed to be progressive (default)
|
||||
@item 0
|
||||
bottom-field-first is assumed
|
||||
@item 1
|
||||
top-field-first is assumed
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@section libdav1d
|
||||
|
||||
dav1d AV1 decoder.
|
||||
|
||||
libdav1d allows libavcodec to decode the AOMedia Video 1 (AV1) codec.
|
||||
Requires the presence of the libdav1d headers and library during configuration.
|
||||
You need to explicitly configure the build with @code{--enable-libdav1d}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following options are supported by the libdav1d wrapper.
|
||||
|
||||
@table @option
|
||||
|
||||
@item framethreads
|
||||
Set amount of frame threads to use during decoding. The default value is 0 (autodetect).
|
||||
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
|
||||
global option @code{threads} instead.
|
||||
|
||||
@item tilethreads
|
||||
Set amount of tile threads to use during decoding. The default value is 0 (autodetect).
|
||||
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
|
||||
global option @code{threads} instead.
|
||||
|
||||
@item filmgrain
|
||||
Apply film grain to the decoded video if present in the bitstream. Defaults to the
|
||||
internal default of the library.
|
||||
This option is deprecated and will be removed in the future. See the global option
|
||||
@code{export_side_data} to export Film Grain parameters instead of applying it.
|
||||
|
||||
@item oppoint
|
||||
Select an operating point of a scalable AV1 bitstream (0 - 31). Defaults to the
|
||||
internal default of the library.
|
||||
|
||||
@item alllayers
|
||||
Output all spatial layers of a scalable AV1 bitstream. The default value is false.
|
||||
|
||||
@end table
|
||||
|
||||
@section libdavs2
|
||||
|
||||
AVS2-P2/IEEE1857.4 video decoder wrapper.
|
||||
|
||||
This decoder allows libavcodec to decode AVS2 streams with davs2 library.
|
||||
|
||||
@c man end VIDEO DECODERS
|
||||
|
||||
@section libuavs3d
|
||||
|
||||
AVS3-P2/IEEE1857.10 video decoder.
|
||||
|
||||
libuavs3d allows libavcodec to decode AVS3 streams.
|
||||
Requires the presence of the libuavs3d headers and library during configuration.
|
||||
You need to explicitly configure the build with @code{--enable-libuavs3d}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following option is supported by the libuavs3d wrapper.
|
||||
|
||||
@table @option
|
||||
|
||||
@item frame_threads
|
||||
Set amount of frame threads to use during decoding. The default value is 0 (autodetect).
|
||||
|
||||
@end table
|
||||
|
||||
@c man end VIDEO DECODERS
|
||||
|
||||
@chapter Audio Decoders
|
||||
@c man begin AUDIO DECODERS
|
||||
|
||||
A description of some of the currently available audio decoders
|
||||
follows.
|
||||
|
||||
@section ac3
|
||||
|
||||
AC-3 audio decoder.
|
||||
|
||||
This decoder implements part of ATSC A/52:2010 and ETSI TS 102 366, as well as
|
||||
the undocumented RealAudio 3 (a.k.a. dnet).
|
||||
|
||||
@subsection AC-3 Decoder Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item -drc_scale @var{value}
|
||||
Dynamic Range Scale Factor. The factor to apply to dynamic range values
|
||||
from the AC-3 stream. This factor is applied exponentially. The default value is 1.
|
||||
There are 3 notable scale factor ranges:
|
||||
@table @option
|
||||
@item drc_scale == 0
|
||||
DRC disabled. Produces full range audio.
|
||||
@item 0 < drc_scale <= 1
|
||||
DRC enabled. Applies a fraction of the stream DRC value.
|
||||
Audio reproduction is between full range and full compression.
|
||||
@item drc_scale > 1
|
||||
DRC enabled. Applies drc_scale asymmetrically.
|
||||
Loud sounds are fully compressed. Soft sounds are enhanced.
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@section flac
|
||||
|
||||
FLAC audio decoder.
|
||||
|
||||
This decoder aims to implement the complete FLAC specification from Xiph.
|
||||
|
||||
@subsection FLAC Decoder options
|
||||
|
||||
@table @option
|
||||
|
||||
@item -use_buggy_lpc
|
||||
The lavc FLAC encoder used to produce buggy streams with high lpc values
|
||||
(like the default value). This option makes it possible to decode such streams
|
||||
correctly by using lavc's old buggy lpc logic for decoding.
|
||||
|
||||
@end table
|
||||
|
||||
@section ffwavesynth
|
||||
|
||||
Internal wave synthesizer.
|
||||
|
||||
This decoder generates wave patterns according to predefined sequences. Its
|
||||
use is purely internal and the format of the data it accepts is not publicly
|
||||
documented.
|
||||
|
||||
@section libcelt
|
||||
|
||||
libcelt decoder wrapper.
|
||||
|
||||
libcelt allows libavcodec to decode the Xiph CELT ultra-low delay audio codec.
|
||||
Requires the presence of the libcelt headers and library during configuration.
|
||||
You need to explicitly configure the build with @code{--enable-libcelt}.
|
||||
|
||||
@section libgsm
|
||||
|
||||
libgsm decoder wrapper.
|
||||
|
||||
libgsm allows libavcodec to decode the GSM full rate audio codec. Requires
|
||||
the presence of the libgsm headers and library during configuration. You need
|
||||
to explicitly configure the build with @code{--enable-libgsm}.
|
||||
|
||||
This decoder supports both the ordinary GSM and the Microsoft variant.
|
||||
|
||||
@section libilbc
|
||||
|
||||
libilbc decoder wrapper.
|
||||
|
||||
libilbc allows libavcodec to decode the Internet Low Bitrate Codec (iLBC)
|
||||
audio codec. Requires the presence of the libilbc headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libilbc}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following option is supported by the libilbc wrapper.
|
||||
|
||||
@table @option
|
||||
@item enhance
|
||||
|
||||
Enable the enhancement of the decoded audio when set to 1. The default
|
||||
value is 0 (disabled).
|
||||
|
||||
@end table
|
||||
|
||||
@section libopencore-amrnb
|
||||
|
||||
libopencore-amrnb decoder wrapper.
|
||||
|
||||
libopencore-amrnb allows libavcodec to decode the Adaptive Multi-Rate
|
||||
Narrowband audio codec. Using it requires the presence of the
|
||||
libopencore-amrnb headers and library during configuration. You need to
|
||||
explicitly configure the build with @code{--enable-libopencore-amrnb}.
|
||||
|
||||
An FFmpeg native decoder for AMR-NB exists, so users can decode AMR-NB
|
||||
without this library.
|
||||
|
||||
@section libopencore-amrwb
|
||||
|
||||
libopencore-amrwb decoder wrapper.
|
||||
|
||||
libopencore-amrwb allows libavcodec to decode the Adaptive Multi-Rate
|
||||
Wideband audio codec. Using it requires the presence of the
|
||||
libopencore-amrwb headers and library during configuration. You need to
|
||||
explicitly configure the build with @code{--enable-libopencore-amrwb}.
|
||||
|
||||
An FFmpeg native decoder for AMR-WB exists, so users can decode AMR-WB
|
||||
without this library.
|
||||
|
||||
@section libopus
|
||||
|
||||
libopus decoder wrapper.
|
||||
|
||||
libopus allows libavcodec to decode the Opus Interactive Audio Codec.
|
||||
Requires the presence of the libopus headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libopus}.
|
||||
|
||||
An FFmpeg native decoder for Opus exists, so users can decode Opus
|
||||
without this library.
|
||||
|
||||
@c man end AUDIO DECODERS
|
||||
|
||||
@chapter Subtitles Decoders
|
||||
@c man begin SUBTILES DECODERS
|
||||
|
||||
@section libaribb24
|
||||
|
||||
ARIB STD-B24 caption decoder.
|
||||
|
||||
Implements profiles A and C of the ARIB STD-B24 standard.
|
||||
|
||||
@subsection libaribb24 Decoder Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item -aribb24-base-path @var{path}
|
||||
Sets the base path for the libaribb24 library. This is utilized for reading of
|
||||
configuration files (for custom unicode conversions), and for dumping of
|
||||
non-text symbols as images under that location.
|
||||
|
||||
Unset by default.
|
||||
|
||||
@item -aribb24-skip-ruby-text @var{boolean}
|
||||
Tells the decoder wrapper to skip text blocks that contain half-height ruby
|
||||
text.
|
||||
|
||||
Enabled by default.
|
||||
|
||||
@end table
|
||||
|
||||
@section dvbsub
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item compute_clut
|
||||
@table @option
|
||||
@item -2
|
||||
Compute clut once if no matching CLUT is in the stream.
|
||||
@item -1
|
||||
Compute clut if no matching CLUT is in the stream.
|
||||
@item 0
|
||||
Never compute CLUT
|
||||
@item 1
|
||||
Always compute CLUT and override the one provided in the stream.
|
||||
@end table
|
||||
@item dvb_substream
|
||||
Selects the dvb substream, or all substreams if -1 which is default.
|
||||
|
||||
@end table
|
||||
|
||||
@section dvdsub
|
||||
|
||||
This codec decodes the bitmap subtitles used in DVDs; the same subtitles can
|
||||
also be found in VobSub file pairs and in some Matroska files.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item palette
|
||||
Specify the global palette used by the bitmaps. When stored in VobSub, the
|
||||
palette is normally specified in the index file; in Matroska, the palette is
|
||||
stored in the codec extra-data in the same format as in VobSub. In DVDs, the
|
||||
palette is stored in the IFO file, and therefore not available when reading
|
||||
from dumped VOB files.
|
||||
|
||||
The format for this option is a string containing 16 24-bits hexadecimal
|
||||
numbers (without 0x prefix) separated by commas, for example @code{0d00ee,
|
||||
ee450d, 101010, eaeaea, 0ce60b, ec14ed, ebff0b, 0d617a, 7b7b7b, d1d1d1,
|
||||
7b2a0e, 0d950c, 0f007b, cf0dec, cfa80c, 7c127b}.
|
||||
|
||||
@item ifo_palette
|
||||
Specify the IFO file from which the global palette is obtained.
|
||||
(experimental)
|
||||
|
||||
@item forced_subs_only
|
||||
Only decode subtitle entries marked as forced. Some titles have forced
|
||||
and non-forced subtitles in the same track. Setting this flag to @code{1}
|
||||
will only keep the forced subtitles. Default value is @code{0}.
|
||||
@end table
|
||||
|
||||
@section libzvbi-teletext
|
||||
|
||||
Libzvbi allows libavcodec to decode DVB teletext pages and DVB teletext
|
||||
subtitles. Requires the presence of the libzvbi headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libzvbi}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item txt_page
|
||||
List of teletext page numbers to decode. Pages that do not match the specified
|
||||
list are dropped. You may use the special @code{*} string to match all pages,
|
||||
or @code{subtitle} to match all subtitle pages.
|
||||
Default value is *.
|
||||
@item txt_default_region
|
||||
Set default character set used for decoding, a value between 0 and 87 (see
|
||||
ETS 300 706, Section 15, Table 32). Default value is -1, which does not
|
||||
override the libzvbi default. This option is needed for some legacy level 1.0
|
||||
transmissions which cannot signal the proper charset.
|
||||
@item txt_chop_top
|
||||
Discards the top teletext line. Default value is 1.
|
||||
@item txt_format
|
||||
Specifies the format of the decoded subtitles.
|
||||
@table @option
|
||||
@item bitmap
|
||||
The default format, you should use this for teletext pages, because certain
|
||||
graphics and colors cannot be expressed in simple text or even ASS.
|
||||
@item text
|
||||
Simple text based output without formatting.
|
||||
@item ass
|
||||
Formatted ASS output, subtitle pages and teletext pages are returned in
|
||||
different styles, subtitle pages are stripped down to text, but an effort is
|
||||
made to keep the text alignment and the formatting.
|
||||
@end table
|
||||
@item txt_left
|
||||
X offset of generated bitmaps, default is 0.
|
||||
@item txt_top
|
||||
Y offset of generated bitmaps, default is 0.
|
||||
@item txt_chop_spaces
|
||||
Chops leading and trailing spaces and removes empty lines from the generated
|
||||
text. This option is useful for teletext based subtitles where empty spaces may
|
||||
be present at the start or at the end of the lines or empty lines may be
|
||||
present between the subtitle lines because of double-sized teletext characters.
|
||||
Default value is 1.
|
||||
@item txt_duration
|
||||
Sets the display duration of the decoded teletext pages or subtitles in
|
||||
milliseconds. Default value is -1 which means infinity or until the next
|
||||
subtitle event comes.
|
||||
@item txt_transparent
|
||||
Force transparent background of the generated teletext bitmaps. Default value
|
||||
is 0 which means an opaque background.
|
||||
@item txt_opacity
|
||||
Sets the opacity (0-255) of the teletext background. If
|
||||
@option{txt_transparent} is not set, it only affects characters between a start
|
||||
box and an end box, typically subtitles. Default value is 0 if
|
||||
@option{txt_transparent} is set, 255 otherwise.
|
||||
|
||||
@end table
|
||||
|
||||
@c man end SUBTILES DECODERS
|
||||
Vendored
+165
@@ -0,0 +1,165 @@
|
||||
a.summary-letter {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2D6198;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #884488;
|
||||
}
|
||||
|
||||
#banner {
|
||||
background-color: white;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#banner img {
|
||||
margin-bottom: 1px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#body {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #313131;
|
||||
margin: 0;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#container {
|
||||
background-color: white;
|
||||
color: #202020;
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
#footer {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 a, h2 a, h3 a, h4 a {
|
||||
text-decoration: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
padding-left: 0.4em;
|
||||
border-radius: 4px;
|
||||
padding-bottom: 0.25em;
|
||||
padding-top: 0.25em;
|
||||
border: 1px solid #6A996A;
|
||||
}
|
||||
|
||||
h1 {
|
||||
background-color: #7BB37B;
|
||||
color: #151515;
|
||||
font-size: 1.2em;
|
||||
padding-bottom: 0.3em;
|
||||
padding-top: 0.3em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #313131;
|
||||
font-size: 1.0em;
|
||||
background-color: #ABE3AB;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #313131;
|
||||
font-size: 0.9em;
|
||||
margin-bottom: -6px;
|
||||
background-color: #BBF3BB;
|
||||
}
|
||||
|
||||
h4 {
|
||||
color: #313131;
|
||||
font-size: 0.8em;
|
||||
margin-bottom: -8px;
|
||||
background-color: #D1FDD1;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#navbar {
|
||||
background-color: #738073;
|
||||
border-bottom: 1px solid #5C665C;
|
||||
border-top: 1px solid #5C665C;
|
||||
margin-top: 12px;
|
||||
padding: 0.3em;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#navbar a, #navbar_secondary a {
|
||||
color: white;
|
||||
padding: 0.3em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#navbar a:hover, #navbar_secondary a:hover {
|
||||
background-color: #313131;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#navbar_secondary {
|
||||
background-color: #738073;
|
||||
border-bottom: 1px solid #5C665C;
|
||||
border-left: 1px solid #5C665C;
|
||||
border-right: 1px solid #5C665C;
|
||||
padding: 0.3em;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-left: 3em;
|
||||
margin-right: 3em;
|
||||
padding: 0.3em;
|
||||
border: 1px solid #bbb;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
dl dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#proj_desc {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
#repos {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
border-collapse: collapse;
|
||||
border: solid 1px #6A996A;
|
||||
}
|
||||
|
||||
#repos th {
|
||||
background-color: #7BB37B;
|
||||
border: solid 1px #6A996A;
|
||||
}
|
||||
|
||||
#repos td {
|
||||
padding: 0.2em;
|
||||
border: solid 1px #6A996A;
|
||||
}
|
||||
Vendored
+891
@@ -0,0 +1,891 @@
|
||||
@chapter Demuxers
|
||||
@c man begin DEMUXERS
|
||||
|
||||
Demuxers are configured elements in FFmpeg that can read the
|
||||
multimedia streams from a particular type of file.
|
||||
|
||||
When you configure your FFmpeg build, all the supported demuxers
|
||||
are enabled by default. You can list all available ones using the
|
||||
configure option @code{--list-demuxers}.
|
||||
|
||||
You can disable all the demuxers using the configure option
|
||||
@code{--disable-demuxers}, and selectively enable a single demuxer with
|
||||
the option @code{--enable-demuxer=@var{DEMUXER}}, or disable it
|
||||
with the option @code{--disable-demuxer=@var{DEMUXER}}.
|
||||
|
||||
The option @code{-demuxers} of the ff* tools will display the list of
|
||||
enabled demuxers. Use @code{-formats} to view a combined list of
|
||||
enabled demuxers and muxers.
|
||||
|
||||
The description of some of the currently available demuxers follows.
|
||||
|
||||
@section aa
|
||||
|
||||
Audible Format 2, 3, and 4 demuxer.
|
||||
|
||||
This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files.
|
||||
|
||||
@section aac
|
||||
|
||||
Raw Audio Data Transport Stream AAC demuxer.
|
||||
|
||||
This demuxer is used to demux an ADTS input containing a single AAC stream
|
||||
alongwith any ID3v1/2 or APE tags in it.
|
||||
|
||||
@section apng
|
||||
|
||||
Animated Portable Network Graphics demuxer.
|
||||
|
||||
This demuxer is used to demux APNG files.
|
||||
All headers, but the PNG signature, up to (but not including) the first
|
||||
fcTL chunk are transmitted as extradata.
|
||||
Frames are then split as being all the chunks between two fcTL ones, or
|
||||
between the last fcTL and IEND chunks.
|
||||
|
||||
@table @option
|
||||
@item -ignore_loop @var{bool}
|
||||
Ignore the loop variable in the file if set. Default is enabled.
|
||||
|
||||
@item -max_fps @var{int}
|
||||
Maximum framerate in frames per second. Default of 0 imposes no limit.
|
||||
|
||||
@item -default_fps @var{int}
|
||||
Default framerate in frames per second when none is specified in the file
|
||||
(0 meaning as fast as possible). Default is 15.
|
||||
|
||||
@end table
|
||||
|
||||
@section asf
|
||||
|
||||
Advanced Systems Format demuxer.
|
||||
|
||||
This demuxer is used to demux ASF files and MMS network streams.
|
||||
|
||||
@table @option
|
||||
@item -no_resync_search @var{bool}
|
||||
Do not try to resynchronize by looking for a certain optional start code.
|
||||
@end table
|
||||
|
||||
@anchor{concat}
|
||||
@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 packets 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.).
|
||||
|
||||
The duration of each file is used to adjust the timestamps of the next file:
|
||||
if the duration is incorrect (because it was computed using the bit-rate or
|
||||
because the file is truncated, for example), it can cause artifacts. The
|
||||
@code{duration} directive can be used to override the duration stored in
|
||||
each file.
|
||||
|
||||
@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.
|
||||
|
||||
All subsequent file-related directives apply to that file.
|
||||
|
||||
@item @code{ffconcat version 1.0}
|
||||
Identify the script type and version.
|
||||
|
||||
To make FFmpeg recognize the format automatically, this directive must
|
||||
appear exactly as is (no extra space or byte-order-mark) on the very first
|
||||
line of the script.
|
||||
|
||||
@item @code{duration @var{dur}}
|
||||
Duration of the file. This information can be specified from the file;
|
||||
specifying it here may be more efficient or help if the information from the
|
||||
file is not available or accurate.
|
||||
|
||||
If the duration is set for all files, then it is possible to seek in the
|
||||
whole concatenated video.
|
||||
|
||||
@item @code{inpoint @var{timestamp}}
|
||||
In point of the file. When the demuxer opens the file it instantly seeks to the
|
||||
specified timestamp. Seeking is done so that all streams can be presented
|
||||
successfully at In point.
|
||||
|
||||
This directive works best with intra frame codecs, because for non-intra frame
|
||||
ones you will usually get extra packets before the actual In point and the
|
||||
decoded content will most likely contain frames before In point too.
|
||||
|
||||
For each file, packets before the file In point will have timestamps less than
|
||||
the calculated start timestamp of the file (negative in case of the first
|
||||
file), and the duration of the files (if not specified by the @code{duration}
|
||||
directive) will be reduced based on their specified In point.
|
||||
|
||||
Because of potential packets before the specified In point, packet timestamps
|
||||
may overlap between two concatenated files.
|
||||
|
||||
@item @code{outpoint @var{timestamp}}
|
||||
Out point of the file. When the demuxer reaches the specified decoding
|
||||
timestamp in any of the streams, it handles it as an end of file condition and
|
||||
skips the current and all the remaining packets from all streams.
|
||||
|
||||
Out point is exclusive, which means that the demuxer will not output packets
|
||||
with a decoding timestamp greater or equal to Out point.
|
||||
|
||||
This directive works best with intra frame codecs and formats where all streams
|
||||
are tightly interleaved. For non-intra frame codecs you will usually get
|
||||
additional packets with presentation timestamp after Out point therefore the
|
||||
decoded content will most likely contain frames after Out point too. If your
|
||||
streams are not tightly interleaved you may not get all the packets from all
|
||||
streams before Out point and you may only will be able to decode the earliest
|
||||
stream until Out point.
|
||||
|
||||
The duration of the files (if not specified by the @code{duration}
|
||||
directive) will be reduced based on their specified Out point.
|
||||
|
||||
@item @code{file_packet_metadata @var{key=value}}
|
||||
Metadata of the packets of the file. The specified metadata will be set for
|
||||
each file packet. You can specify this directive multiple times to add multiple
|
||||
metadata entries.
|
||||
This directive is deprecated, use @code{file_packet_meta} instead.
|
||||
|
||||
@item @code{file_packet_meta @var{key} @var{value}}
|
||||
Metadata of the packets of the file. The specified metadata will be set for
|
||||
each file packet. You can specify this directive multiple times to add multiple
|
||||
metadata entries.
|
||||
|
||||
@item @code{option @var{key} @var{value}}
|
||||
Option to access, open and probe the file.
|
||||
Can be present multiple times.
|
||||
|
||||
@item @code{stream}
|
||||
Introduce a stream in the virtual file.
|
||||
All subsequent stream-related directives apply to the last introduced
|
||||
stream.
|
||||
Some streams properties must be set in order to allow identifying the
|
||||
matching streams in the subfiles.
|
||||
If no streams are defined in the script, the streams from the first file are
|
||||
copied.
|
||||
|
||||
@item @code{exact_stream_id @var{id}}
|
||||
Set the id of the stream.
|
||||
If this directive is given, the string with the corresponding id in the
|
||||
subfiles will be used.
|
||||
This is especially useful for MPEG-PS (VOB) files, where the order of the
|
||||
streams is not reliable.
|
||||
|
||||
@item @code{stream_meta @var{key} @var{value}}
|
||||
Metadata for the stream.
|
||||
Can be present multiple times.
|
||||
|
||||
@item @code{stream_codec @var{value}}
|
||||
Codec for the stream.
|
||||
|
||||
@item @code{stream_extradata @var{hex_string}}
|
||||
Extradata for the string, encoded in hexadecimal.
|
||||
|
||||
@item @code{chapter @var{id} @var{start} @var{end}}
|
||||
Add a chapter. @var{id} is an unique identifier, possibly small and
|
||||
consecutive.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Options
|
||||
|
||||
This demuxer accepts the following option:
|
||||
|
||||
@table @option
|
||||
|
||||
@item safe
|
||||
If set to 1, reject unsafe file paths and directives.
|
||||
A file path is considered safe if it
|
||||
does not contain a protocol specification and is relative and all components
|
||||
only contain characters from the portable character set (letters, digits,
|
||||
period, underscore and hyphen) and have no period at the beginning of a
|
||||
component.
|
||||
|
||||
If set to 0, any file name is accepted.
|
||||
|
||||
The default is 1.
|
||||
|
||||
@item auto_convert
|
||||
If set to 1, try to perform automatic conversions on packet data to make the
|
||||
streams concatenable.
|
||||
The default is 1.
|
||||
|
||||
Currently, the only conversion is adding the h264_mp4toannexb bitstream
|
||||
filter to H.264 streams in MP4 format. This is necessary in particular if
|
||||
there are resolution changes.
|
||||
|
||||
@item segment_time_metadata
|
||||
If set to 1, every packet will contain the @var{lavf.concat.start_time} and the
|
||||
@var{lavf.concat.duration} packet metadata values which are the start_time and
|
||||
the duration of the respective file segments in the concatenated output
|
||||
expressed in microseconds. The duration metadata is only set if it is known
|
||||
based on the concat file.
|
||||
The default is 0.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Use absolute filenames and include some comments:
|
||||
@example
|
||||
# my first filename
|
||||
file /mnt/share/file-1.wav
|
||||
# my second filename including whitespace
|
||||
file '/mnt/share/file 2.wav'
|
||||
# my third filename including whitespace plus single quote
|
||||
file '/mnt/share/file 3'\''.wav'
|
||||
@end example
|
||||
|
||||
@item
|
||||
Allow for input format auto-probing, use safe filenames and set the duration of
|
||||
the first file:
|
||||
@example
|
||||
ffconcat version 1.0
|
||||
|
||||
file file-1.wav
|
||||
duration 20.0
|
||||
|
||||
file subdir/file-2.wav
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section dash
|
||||
|
||||
Dynamic Adaptive Streaming over HTTP demuxer.
|
||||
|
||||
This demuxer presents all AVStreams found in the manifest.
|
||||
By setting the discard flags on AVStreams the caller can decide
|
||||
which streams to actually receive.
|
||||
Each stream mirrors the @code{id} and @code{bandwidth} properties from the
|
||||
@code{<Representation>} as metadata keys named "id" and "variant_bitrate" respectively.
|
||||
|
||||
@section imf
|
||||
|
||||
Interoperable Master Format demuxer.
|
||||
|
||||
This demuxer presents audio and video streams found in an IMF Composition.
|
||||
|
||||
@section flv, live_flv, kux
|
||||
|
||||
Adobe Flash Video Format demuxer.
|
||||
|
||||
This demuxer is used to demux FLV files and RTMP network streams. In case of live network streams, if you force format, you may use live_flv option instead of flv to survive timestamp discontinuities.
|
||||
KUX is a flv variant used on the Youku platform.
|
||||
|
||||
@example
|
||||
ffmpeg -f flv -i myfile.flv ...
|
||||
ffmpeg -f live_flv -i rtmp://<any.server>/anything/key ....
|
||||
@end example
|
||||
|
||||
|
||||
@table @option
|
||||
@item -flv_metadata @var{bool}
|
||||
Allocate the streams according to the onMetaData array content.
|
||||
|
||||
@item -flv_ignore_prevtag @var{bool}
|
||||
Ignore the size of previous tag value.
|
||||
|
||||
@item -flv_full_metadata @var{bool}
|
||||
Output all context of the onMetadata.
|
||||
@end table
|
||||
|
||||
@section gif
|
||||
|
||||
Animated GIF demuxer.
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item min_delay
|
||||
Set the minimum valid delay between frames in hundredths of seconds.
|
||||
Range is 0 to 6000. Default value is 2.
|
||||
|
||||
@item max_gif_delay
|
||||
Set the maximum valid delay between frames in hundredth of seconds.
|
||||
Range is 0 to 65535. Default value is 65535 (nearly eleven minutes),
|
||||
the maximum value allowed by the specification.
|
||||
|
||||
@item default_delay
|
||||
Set the default delay between frames in hundredths of seconds.
|
||||
Range is 0 to 6000. Default value is 10.
|
||||
|
||||
@item ignore_loop
|
||||
GIF files can contain information to loop a certain number of times (or
|
||||
infinitely). If @option{ignore_loop} is set to 1, then the loop setting
|
||||
from the input will be ignored and looping will not occur. If set to 0,
|
||||
then looping will occur and will cycle the number of times according to
|
||||
the GIF. Default value is 1.
|
||||
@end table
|
||||
|
||||
For example, with the overlay filter, place an infinitely looping GIF
|
||||
over another video:
|
||||
@example
|
||||
ffmpeg -i input.mp4 -ignore_loop 0 -i input.gif -filter_complex overlay=shortest=1 out.mkv
|
||||
@end example
|
||||
|
||||
Note that in the above example the shortest option for overlay filter is
|
||||
used to end the output video at the length of the shortest input file,
|
||||
which in this case is @file{input.mp4} as the GIF in this example loops
|
||||
infinitely.
|
||||
|
||||
@section hls
|
||||
|
||||
HLS demuxer
|
||||
|
||||
Apple HTTP Live Streaming demuxer.
|
||||
|
||||
This demuxer presents all AVStreams from all variant streams.
|
||||
The id field is set to the bitrate variant index number. By setting
|
||||
the discard flags on AVStreams (by pressing 'a' or 'v' in ffplay),
|
||||
the caller can decide which variant streams to actually receive.
|
||||
The total bitrate of the variant that the stream belongs to is
|
||||
available in a metadata key named "variant_bitrate".
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item live_start_index
|
||||
segment index to start live streams at (negative values are from the end).
|
||||
|
||||
@item allowed_extensions
|
||||
',' separated list of file extensions that hls is allowed to access.
|
||||
|
||||
@item max_reload
|
||||
Maximum number of times a insufficient list is attempted to be reloaded.
|
||||
Default value is 1000.
|
||||
|
||||
@item m3u8_hold_counters
|
||||
The maximum number of times to load m3u8 when it refreshes without new segments.
|
||||
Default value is 1000.
|
||||
|
||||
@item http_persistent
|
||||
Use persistent HTTP connections. Applicable only for HTTP streams.
|
||||
Enabled by default.
|
||||
|
||||
@item http_multiple
|
||||
Use multiple HTTP connections for downloading HTTP segments.
|
||||
Enabled by default for HTTP/1.1 servers.
|
||||
|
||||
@item http_seekable
|
||||
Use HTTP partial requests for downloading HTTP segments.
|
||||
0 = disable, 1 = enable, -1 = auto, Default is auto.
|
||||
|
||||
@item seg_format_options
|
||||
Set options for the demuxer of media segments using a list of key=value pairs separated by @code{:}.
|
||||
@end table
|
||||
|
||||
@section image2
|
||||
|
||||
Image file demuxer.
|
||||
|
||||
This demuxer reads from a list of image files specified by a pattern.
|
||||
The syntax and meaning of the pattern is specified by the
|
||||
option @var{pattern_type}.
|
||||
|
||||
The pattern may contain a suffix which is used to automatically
|
||||
determine the format of the images contained in the files.
|
||||
|
||||
The size, the pixel format, and the format of each image must be the
|
||||
same for all the files in the sequence.
|
||||
|
||||
This demuxer accepts the following options:
|
||||
@table @option
|
||||
@item framerate
|
||||
Set the frame rate for the video stream. It defaults to 25.
|
||||
@item loop
|
||||
If set to 1, loop over the input. Default value is 0.
|
||||
@item pattern_type
|
||||
Select the pattern type used to interpret the provided filename.
|
||||
|
||||
@var{pattern_type} accepts one of the following values.
|
||||
@table @option
|
||||
@item none
|
||||
Disable pattern matching, therefore the video will only contain the specified
|
||||
image. You should use this option if you do not want to create sequences from
|
||||
multiple images and your filenames may contain special pattern characters.
|
||||
@item sequence
|
||||
Select a sequence pattern type, used to specify a sequence of files
|
||||
indexed by sequential numbers.
|
||||
|
||||
A sequence pattern may contain the string "%d" or "%0@var{N}d", which
|
||||
specifies the position of the characters representing a sequential
|
||||
number in each filename matched by the pattern. If the form
|
||||
"%d0@var{N}d" is used, the string representing the number in each
|
||||
filename is 0-padded and @var{N} is the total number of 0-padded
|
||||
digits representing the number. The literal character '%' can be
|
||||
specified in the pattern with the string "%%".
|
||||
|
||||
If the sequence pattern contains "%d" or "%0@var{N}d", the first filename of
|
||||
the file list specified by the pattern must contain a number
|
||||
inclusively contained between @var{start_number} and
|
||||
@var{start_number}+@var{start_number_range}-1, and all the following
|
||||
numbers must be sequential.
|
||||
|
||||
For example the pattern "img-%03d.bmp" will match a sequence of
|
||||
filenames of the form @file{img-001.bmp}, @file{img-002.bmp}, ...,
|
||||
@file{img-010.bmp}, etc.; the pattern "i%%m%%g-%d.jpg" will match a
|
||||
sequence of filenames of the form @file{i%m%g-1.jpg},
|
||||
@file{i%m%g-2.jpg}, ..., @file{i%m%g-10.jpg}, etc.
|
||||
|
||||
Note that the pattern must not necessarily contain "%d" or
|
||||
"%0@var{N}d", for example to convert a single image file
|
||||
@file{img.jpeg} you can employ the command:
|
||||
@example
|
||||
ffmpeg -i img.jpeg img.png
|
||||
@end example
|
||||
|
||||
@item glob
|
||||
Select a glob wildcard pattern type.
|
||||
|
||||
The pattern is interpreted like a @code{glob()} pattern. This is only
|
||||
selectable if libavformat was compiled with globbing support.
|
||||
|
||||
@item glob_sequence @emph{(deprecated, will be removed)}
|
||||
Select a mixed glob wildcard/sequence pattern.
|
||||
|
||||
If your version of libavformat was compiled with globbing support, and
|
||||
the provided pattern contains at least one glob meta character among
|
||||
@code{%*?[]@{@}} that is preceded by an unescaped "%", the pattern is
|
||||
interpreted like a @code{glob()} pattern, otherwise it is interpreted
|
||||
like a sequence pattern.
|
||||
|
||||
All glob special characters @code{%*?[]@{@}} must be prefixed
|
||||
with "%". To escape a literal "%" you shall use "%%".
|
||||
|
||||
For example the pattern @code{foo-%*.jpeg} will match all the
|
||||
filenames prefixed by "foo-" and terminating with ".jpeg", and
|
||||
@code{foo-%?%?%?.jpeg} will match all the filenames prefixed with
|
||||
"foo-", followed by a sequence of three characters, and terminating
|
||||
with ".jpeg".
|
||||
|
||||
This pattern type is deprecated in favor of @var{glob} and
|
||||
@var{sequence}.
|
||||
@end table
|
||||
|
||||
Default value is @var{glob_sequence}.
|
||||
@item pixel_format
|
||||
Set the pixel format of the images to read. If not specified the pixel
|
||||
format is guessed from the first image file in the sequence.
|
||||
@item start_number
|
||||
Set the index of the file matched by the image file pattern to start
|
||||
to read from. Default value is 0.
|
||||
@item start_number_range
|
||||
Set the index interval range to check when looking for the first image
|
||||
file in the sequence, starting from @var{start_number}. Default value
|
||||
is 5.
|
||||
@item ts_from_file
|
||||
If set to 1, will set frame timestamp to modification time of image file. Note
|
||||
that monotonity of timestamps is not provided: images go in the same order as
|
||||
without this option. Default value is 0.
|
||||
If set to 2, will set frame timestamp to the modification time of the image file in
|
||||
nanosecond precision.
|
||||
@item video_size
|
||||
Set the video size of the images to read. If not specified the video
|
||||
size is guessed from the first image file in the sequence.
|
||||
@item export_path_metadata
|
||||
If set to 1, will add two extra fields to the metadata found in input, making them
|
||||
also available for other filters (see @var{drawtext} filter for examples). Default
|
||||
value is 0. The extra fields are described below:
|
||||
@table @option
|
||||
@item lavf.image2dec.source_path
|
||||
Corresponds to the full path to the input file being read.
|
||||
@item lavf.image2dec.source_basename
|
||||
Corresponds to the name of the file being read.
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Use @command{ffmpeg} for creating a video from the images in the file
|
||||
sequence @file{img-001.jpeg}, @file{img-002.jpeg}, ..., assuming an
|
||||
input frame rate of 10 frames per second:
|
||||
@example
|
||||
ffmpeg -framerate 10 -i 'img-%03d.jpeg' out.mkv
|
||||
@end example
|
||||
|
||||
@item
|
||||
As above, but start by reading from a file with index 100 in the sequence:
|
||||
@example
|
||||
ffmpeg -framerate 10 -start_number 100 -i 'img-%03d.jpeg' out.mkv
|
||||
@end example
|
||||
|
||||
@item
|
||||
Read images matching the "*.png" glob pattern , that is all the files
|
||||
terminating with the ".png" suffix:
|
||||
@example
|
||||
ffmpeg -framerate 10 -pattern_type glob -i "*.png" out.mkv
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section libgme
|
||||
|
||||
The Game Music Emu library is a collection of video game music file emulators.
|
||||
|
||||
See @url{https://bitbucket.org/mpyne/game-music-emu/overview} for more information.
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
|
||||
@item track_index
|
||||
Set the index of which track to demux. The demuxer can only export one track.
|
||||
Track indexes start at 0. Default is to pick the first track. Number of tracks
|
||||
is exported as @var{tracks} metadata entry.
|
||||
|
||||
@item sample_rate
|
||||
Set the sampling rate of the exported track. Range is 1000 to 999999. Default is 44100.
|
||||
|
||||
@item max_size @emph{(bytes)}
|
||||
The demuxer buffers the entire file into memory. Adjust this value to set the maximum buffer size,
|
||||
which in turn, acts as a ceiling for the size of files that can be read.
|
||||
Default is 50 MiB.
|
||||
|
||||
@end table
|
||||
|
||||
@section libmodplug
|
||||
|
||||
ModPlug based module demuxer
|
||||
|
||||
See @url{https://github.com/Konstanty/libmodplug}
|
||||
|
||||
It will export one 2-channel 16-bit 44.1 kHz audio stream.
|
||||
Optionally, a @code{pal8} 16-color video stream can be exported with or without printed metadata.
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item noise_reduction
|
||||
Apply a simple low-pass filter. Can be 1 (on) or 0 (off). Default is 0.
|
||||
|
||||
@item reverb_depth
|
||||
Set amount of reverb. Range 0-100. Default is 0.
|
||||
|
||||
@item reverb_delay
|
||||
Set delay in ms, clamped to 40-250 ms. Default is 0.
|
||||
|
||||
@item bass_amount
|
||||
Apply bass expansion a.k.a. XBass or megabass. Range is 0 (quiet) to 100 (loud). Default is 0.
|
||||
|
||||
@item bass_range
|
||||
Set cutoff i.e. upper-bound for bass frequencies. Range is 10-100 Hz. Default is 0.
|
||||
|
||||
@item surround_depth
|
||||
Apply a Dolby Pro-Logic surround effect. Range is 0 (quiet) to 100 (heavy). Default is 0.
|
||||
|
||||
@item surround_delay
|
||||
Set surround delay in ms, clamped to 5-40 ms. Default is 0.
|
||||
|
||||
@item max_size
|
||||
The demuxer buffers the entire file into memory. Adjust this value to set the maximum buffer size,
|
||||
which in turn, acts as a ceiling for the size of files that can be read. Range is 0 to 100 MiB.
|
||||
0 removes buffer size limit (not recommended). Default is 5 MiB.
|
||||
|
||||
@item video_stream_expr
|
||||
String which is evaluated using the eval API to assign colors to the generated video stream.
|
||||
Variables which can be used are @code{x}, @code{y}, @code{w}, @code{h}, @code{t}, @code{speed},
|
||||
@code{tempo}, @code{order}, @code{pattern} and @code{row}.
|
||||
|
||||
@item video_stream
|
||||
Generate video stream. Can be 1 (on) or 0 (off). Default is 0.
|
||||
|
||||
@item video_stream_w
|
||||
Set video frame width in 'chars' where one char indicates 8 pixels. Range is 20-512. Default is 30.
|
||||
|
||||
@item video_stream_h
|
||||
Set video frame height in 'chars' where one char indicates 8 pixels. Range is 20-512. Default is 30.
|
||||
|
||||
@item video_stream_ptxt
|
||||
Print metadata on video stream. Includes @code{speed}, @code{tempo}, @code{order}, @code{pattern},
|
||||
@code{row} and @code{ts} (time in ms). Can be 1 (on) or 0 (off). Default is 1.
|
||||
|
||||
@end table
|
||||
|
||||
@section libopenmpt
|
||||
|
||||
libopenmpt based module demuxer
|
||||
|
||||
See @url{https://lib.openmpt.org/libopenmpt/} for more information.
|
||||
|
||||
Some files have multiple subsongs (tracks) this can be set with the @option{subsong}
|
||||
option.
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item subsong
|
||||
Set the subsong index. This can be either 'all', 'auto', or the index of the
|
||||
subsong. Subsong indexes start at 0. The default is 'auto'.
|
||||
|
||||
The default value is to let libopenmpt choose.
|
||||
|
||||
@item layout
|
||||
Set the channel layout. Valid values are 1, 2, and 4 channel layouts.
|
||||
The default value is STEREO.
|
||||
|
||||
@item sample_rate
|
||||
Set the sample rate for libopenmpt to output.
|
||||
Range is from 1000 to INT_MAX. The value default is 48000.
|
||||
@end table
|
||||
|
||||
@section mov/mp4/3gp
|
||||
|
||||
Demuxer for Quicktime File Format & ISO/IEC Base Media File Format (ISO/IEC 14496-12 or MPEG-4 Part 12, ISO/IEC 15444-12 or JPEG 2000 Part 12).
|
||||
|
||||
Registered extensions: mov, mp4, m4a, 3gp, 3g2, mj2, psp, m4b, ism, ismv, isma, f4v
|
||||
|
||||
@subsection Options
|
||||
|
||||
This demuxer accepts the following options:
|
||||
@table @option
|
||||
@item enable_drefs
|
||||
Enable loading of external tracks, disabled by default.
|
||||
Enabling this can theoretically leak information in some use cases.
|
||||
|
||||
@item use_absolute_path
|
||||
Allows loading of external tracks via absolute paths, disabled by default.
|
||||
Enabling this poses a security risk. It should only be enabled if the source
|
||||
is known to be non-malicious.
|
||||
|
||||
@item seek_streams_individually
|
||||
When seeking, identify the closest point in each stream individually and demux packets in
|
||||
that stream from identified point. This can lead to a different sequence of packets compared
|
||||
to demuxing linearly from the beginning. Default is true.
|
||||
|
||||
@item ignore_editlist
|
||||
Ignore any edit list atoms. The demuxer, by default, modifies the stream index to reflect the
|
||||
timeline described by the edit list. Default is false.
|
||||
|
||||
@item advanced_editlist
|
||||
Modify the stream index to reflect the timeline described by the edit list. @code{ignore_editlist}
|
||||
must be set to false for this option to be effective.
|
||||
If both @code{ignore_editlist} and this option are set to false, then only the
|
||||
start of the stream index is modified to reflect initial dwell time or starting timestamp
|
||||
described by the edit list. Default is true.
|
||||
|
||||
@item ignore_chapters
|
||||
Don't parse chapters. This includes GoPro 'HiLight' tags/moments. Note that chapters are
|
||||
only parsed when input is seekable. Default is false.
|
||||
|
||||
@item use_mfra_for
|
||||
For seekable fragmented input, set fragment's starting timestamp from media fragment random access box, if present.
|
||||
|
||||
Following options are available:
|
||||
@table @samp
|
||||
@item auto
|
||||
Auto-detect whether to set mfra timestamps as PTS or DTS @emph{(default)}
|
||||
|
||||
@item dts
|
||||
Set mfra timestamps as DTS
|
||||
|
||||
@item pts
|
||||
Set mfra timestamps as PTS
|
||||
|
||||
@item 0
|
||||
Don't use mfra box to set timestamps
|
||||
@end table
|
||||
|
||||
@item use_tfdt
|
||||
For fragmented input, set fragment's starting timestamp to @code{baseMediaDecodeTime} from the @code{tfdt} box.
|
||||
Default is enabled, which will prefer to use the @code{tfdt} box to set DTS. Disable to use the @code{earliest_presentation_time} from the @code{sidx} box.
|
||||
In either case, the timestamp from the @code{mfra} box will be used if it's available and @code{use_mfra_for} is
|
||||
set to pts or dts.
|
||||
|
||||
@item export_all
|
||||
Export unrecognized boxes within the @var{udta} box as metadata entries. The first four
|
||||
characters of the box type are set as the key. Default is false.
|
||||
|
||||
@item export_xmp
|
||||
Export entire contents of @var{XMP_} box and @var{uuid} box as a string with key @code{xmp}. Note that
|
||||
if @code{export_all} is set and this option isn't, the contents of @var{XMP_} box are still exported
|
||||
but with key @code{XMP_}. Default is false.
|
||||
|
||||
@item activation_bytes
|
||||
4-byte key required to decrypt Audible AAX and AAX+ files. See Audible AAX subsection below.
|
||||
|
||||
@item audible_fixed_key
|
||||
Fixed key used for handling Audible AAX/AAX+ files. It has been pre-set so should not be necessary to
|
||||
specify.
|
||||
|
||||
@item decryption_key
|
||||
16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
|
||||
|
||||
@item max_stts_delta
|
||||
Very high sample deltas written in a trak's stts box may occasionally be intended but usually they are written in
|
||||
error or used to store a negative value for dts correction when treated as signed 32-bit integers. This option lets
|
||||
the user set an upper limit, beyond which the delta is clamped to 1. Values greater than the limit if negative when
|
||||
cast to int32 are used to adjust onward dts.
|
||||
|
||||
Unit is the track time scale. Range is 0 to UINT_MAX. Default is @code{UINT_MAX - 48000*10} which allows upto
|
||||
a 10 second dts correction for 48 kHz audio streams while accommodating 99.9% of @code{uint32} range.
|
||||
@end table
|
||||
|
||||
@subsection Audible AAX
|
||||
|
||||
Audible AAX files are encrypted M4B files, and they can be decrypted by specifying a 4 byte activation secret.
|
||||
@example
|
||||
ffmpeg -activation_bytes 1CEB00DA -i test.aax -vn -c:a copy output.mp4
|
||||
@end example
|
||||
|
||||
@section mpegts
|
||||
|
||||
MPEG-2 transport stream demuxer.
|
||||
|
||||
This demuxer accepts the following options:
|
||||
@table @option
|
||||
@item resync_size
|
||||
Set size limit for looking up a new synchronization. Default value is
|
||||
65536.
|
||||
|
||||
@item skip_unknown_pmt
|
||||
Skip PMTs for programs not defined in the PAT. Default value is 0.
|
||||
|
||||
@item fix_teletext_pts
|
||||
Override teletext packet PTS and DTS values with the timestamps calculated
|
||||
from the PCR of the first program which the teletext stream is part of and is
|
||||
not discarded. Default value is 1, set this option to 0 if you want your
|
||||
teletext packet PTS and DTS values untouched.
|
||||
|
||||
@item ts_packetsize
|
||||
Output option carrying the raw packet size in bytes.
|
||||
Show the detected raw packet size, cannot be set by the user.
|
||||
|
||||
@item scan_all_pmts
|
||||
Scan and combine all PMTs. The value is an integer with value from -1
|
||||
to 1 (-1 means automatic setting, 1 means enabled, 0 means
|
||||
disabled). Default value is -1.
|
||||
|
||||
@item merge_pmt_versions
|
||||
Re-use existing streams when a PMT's version is updated and elementary
|
||||
streams move to different PIDs. Default value is 0.
|
||||
@end table
|
||||
|
||||
@section mpjpeg
|
||||
|
||||
MJPEG encapsulated in multi-part MIME demuxer.
|
||||
|
||||
This demuxer allows reading of MJPEG, where each frame is represented as a part of
|
||||
multipart/x-mixed-replace stream.
|
||||
@table @option
|
||||
|
||||
@item strict_mime_boundary
|
||||
Default implementation applies a relaxed standard to multi-part MIME boundary detection,
|
||||
to prevent regression with numerous existing endpoints not generating a proper MIME
|
||||
MJPEG stream. Turning this option on by setting it to 1 will result in a stricter check
|
||||
of the boundary value.
|
||||
@end table
|
||||
|
||||
@section rawvideo
|
||||
|
||||
Raw video demuxer.
|
||||
|
||||
This demuxer allows one to read raw video data. Since there is no header
|
||||
specifying the assumed video parameters, the user must specify them
|
||||
in order to be able to decode the data correctly.
|
||||
|
||||
This demuxer accepts the following options:
|
||||
@table @option
|
||||
|
||||
@item framerate
|
||||
Set input video frame rate. Default value is 25.
|
||||
|
||||
@item pixel_format
|
||||
Set the input video pixel format. Default value is @code{yuv420p}.
|
||||
|
||||
@item video_size
|
||||
Set the input video size. This value must be specified explicitly.
|
||||
@end table
|
||||
|
||||
For example to read a rawvideo file @file{input.raw} with
|
||||
@command{ffplay}, assuming a pixel format of @code{rgb24}, a video
|
||||
size of @code{320x240}, and a frame rate of 10 images per second, use
|
||||
the command:
|
||||
@example
|
||||
ffplay -f rawvideo -pixel_format rgb24 -video_size 320x240 -framerate 10 input.raw
|
||||
@end example
|
||||
|
||||
@section sbg
|
||||
|
||||
SBaGen script demuxer.
|
||||
|
||||
This demuxer reads the script language used by SBaGen
|
||||
@url{http://uazu.net/sbagen/} to generate binaural beats sessions. A SBG
|
||||
script looks like that:
|
||||
@example
|
||||
-SE
|
||||
a: 300-2.5/3 440+4.5/0
|
||||
b: 300-2.5/0 440+4.5/3
|
||||
off: -
|
||||
NOW == a
|
||||
+0:07:00 == b
|
||||
+0:14:00 == a
|
||||
+0:21:00 == b
|
||||
+0:30:00 off
|
||||
@end example
|
||||
|
||||
A SBG script can mix absolute and relative timestamps. If the script uses
|
||||
either only absolute timestamps (including the script start time) or only
|
||||
relative ones, then its layout is fixed, and the conversion is
|
||||
straightforward. On the other hand, if the script mixes both kind of
|
||||
timestamps, then the @var{NOW} reference for relative timestamps will be
|
||||
taken from the current time of day at the time the script is read, and the
|
||||
script layout will be frozen according to that reference. That means that if
|
||||
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 tedcaptions
|
||||
|
||||
JSON captions used for @url{http://www.ted.com/, TED Talks}.
|
||||
|
||||
TED does not provide links to the captions, but they can be guessed from the
|
||||
page. The file @file{tools/bookmarklets.html} from the FFmpeg source tree
|
||||
contains a bookmarklet to expose them.
|
||||
|
||||
This demuxer accepts the following option:
|
||||
@table @option
|
||||
@item start_time
|
||||
Set the start time of the TED talk, in milliseconds. The default is 15000
|
||||
(15s). It is used to sync the captions with the downloadable videos, because
|
||||
they include a 15s intro.
|
||||
@end table
|
||||
|
||||
Example: convert the captions to a format most players understand:
|
||||
@example
|
||||
ffmpeg -i http://www.ted.com/talks/subtitles/id/1/lang/en talk1-en.srt
|
||||
@end example
|
||||
|
||||
@section vapoursynth
|
||||
|
||||
Vapoursynth wrapper.
|
||||
|
||||
Due to security concerns, Vapoursynth scripts will not
|
||||
be autodetected so the input format has to be forced. For ff* CLI tools,
|
||||
add @code{-f vapoursynth} before the input @code{-i yourscript.vpy}.
|
||||
|
||||
This demuxer accepts the following option:
|
||||
@table @option
|
||||
@item max_script_size
|
||||
The demuxer buffers the entire script into memory. Adjust this value to set the maximum buffer size,
|
||||
which in turn, acts as a ceiling for the size of scripts that can be read.
|
||||
Default is 1 MiB.
|
||||
@end table
|
||||
|
||||
@c man end DEMUXERS
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
# FFmpeg project
|
||||
|
||||
## Organisation
|
||||
|
||||
The FFmpeg project is organized through a community working on global consensus.
|
||||
|
||||
Decisions are taken by the ensemble of active members, through voting and
|
||||
are aided by two committees.
|
||||
|
||||
## General Assembly
|
||||
|
||||
The ensemble of active members is called the General Assembly (GA).
|
||||
|
||||
The General Assembly is sovereign and legitimate for all its decisions
|
||||
regarding the FFmpeg project.
|
||||
|
||||
The General Assembly is made up of active contributors.
|
||||
|
||||
Contributors are considered "active contributors" if they have pushed more
|
||||
than 20 patches in the last 36 months in the main FFmpeg repository, or
|
||||
if they have been voted in by the GA.
|
||||
|
||||
Additional members are added to the General Assembly through a vote after
|
||||
proposal by a member of the General Assembly.
|
||||
They are part of the GA for two years, after which they need a confirmation by
|
||||
the GA.
|
||||
|
||||
## Voting
|
||||
|
||||
Voting is done using a ranked voting system, currently running on https://vote.ffmpeg.org/ .
|
||||
|
||||
Majority vote means more than 50% of the expressed ballots.
|
||||
|
||||
## Technical Committee
|
||||
|
||||
The Technical Committee (TC) is here to arbitrate and make decisions when
|
||||
technical conflicts occur in the project.
|
||||
They will consider the merits of all the positions, judge them and make a
|
||||
decision.
|
||||
|
||||
The TC resolves technical conflicts but is not a technical steering committee.
|
||||
|
||||
Decisions by the TC are binding for all the contributors.
|
||||
|
||||
Decisions made by the TC can be re-opened after 1 year or by a majority vote
|
||||
of the General Assembly, requested by one of the member of the GA.
|
||||
|
||||
The TC is elected by the General Assembly for a duration of 1 year, and
|
||||
is composed of 5 members.
|
||||
Members can be re-elected if they wish. A majority vote in the General Assembly
|
||||
can trigger a new election of the TC.
|
||||
|
||||
The members of the TC can be elected from outside of the GA.
|
||||
Candidates for election can either be suggested or self-nominated.
|
||||
|
||||
The conflict resolution process is detailed in the [resolution process](resolution_process.md) document.
|
||||
|
||||
## Community committee
|
||||
|
||||
The Community Committee (CC) is here to arbitrage and make decisions when
|
||||
inter-personal conflicts occur in the project. It will decide quickly and
|
||||
take actions, for the sake of the project.
|
||||
|
||||
The CC can remove privileges of offending members, including removal of
|
||||
commit access and temporary ban from the community.
|
||||
|
||||
Decisions made by the CC can be re-opened after 1 year or by a majority vote
|
||||
of the General Assembly. Indefinite bans from the community must be confirmed
|
||||
by the General Assembly, in a majority vote.
|
||||
|
||||
The CC is elected by the General Assembly for a duration of 1 year, and is
|
||||
composed of 5 members.
|
||||
Members can be re-elected if they wish. A majority vote in the General Assembly
|
||||
can trigger a new election of the CC.
|
||||
|
||||
The members of the CC can be elected from outside of the GA.
|
||||
Candidates for election can either be suggested or self-nominated.
|
||||
|
||||
The CC is governed by and responsible for enforcing the Code of Conduct.
|
||||
@@ -0,0 +1,91 @@
|
||||
# Technical Committee
|
||||
|
||||
_This document only makes sense with the rules from [the community document](community)_.
|
||||
|
||||
The Technical Committee (**TC**) is here to arbitrate and make decisions when
|
||||
technical conflicts occur in the project.
|
||||
|
||||
The TC main role is to resolve technical conflicts.
|
||||
It is therefore not a technical steering committee, but it is understood that
|
||||
some decisions might impact the future of the project.
|
||||
|
||||
# Process
|
||||
|
||||
## Seizing
|
||||
|
||||
The TC can take possession of any technical matter that it sees fit.
|
||||
|
||||
To involve the TC in a matter, email tc@ or CC them on an ongoing discussion.
|
||||
|
||||
As members of TC are developers, they also can email tc@ to raise an issue.
|
||||
|
||||
## Announcement
|
||||
|
||||
The TC, once seized, must announce itself on the main mailing list, with a _[TC]_ tag.
|
||||
|
||||
The TC has 2 modes of operation: a RFC one and an internal one.
|
||||
|
||||
If the TC thinks it needs the input from the larger community, the TC can call
|
||||
for a RFC. Else, it can decide by itself.
|
||||
|
||||
If the disagreement involves a member of the TC, that member should recuse
|
||||
themselves from the decision.
|
||||
|
||||
The decision to use a RFC process or an internal discussion is a discretionary
|
||||
decision of the TC.
|
||||
|
||||
The TC can also reject a seizure for a few reasons such as:
|
||||
the matter was not discussed enough previously; it lacks expertise to reach a
|
||||
beneficial decision on the matter; or the matter is too trivial.
|
||||
|
||||
### RFC call
|
||||
|
||||
In the RFC mode, one person from the TC posts on the mailing list the
|
||||
technical question and will request input from the community.
|
||||
|
||||
The mail will have the following specification:
|
||||
* a precise title
|
||||
* a specific tag [TC RFC]
|
||||
* a top-level email
|
||||
* contain a precise question that does not exceed 100 words and that is answerable by developers
|
||||
* may have an extra description, or a link to a previous discussion, if deemed necessary,
|
||||
* contain a precise end date for the answers.
|
||||
|
||||
The answers from the community must be on the main mailing list and must have
|
||||
the following specification:
|
||||
* keep the tag and the title unchanged
|
||||
* limited to 400 words
|
||||
* a first-level, answering directly to the main email
|
||||
* answering to the question.
|
||||
|
||||
Further replies to answers are permitted, as long as they conform to the
|
||||
community standards of politeness, they are limited to 100 words, and are not
|
||||
nested more than once. (max-depth=2)
|
||||
|
||||
After the end-date, mails on the thread will be ignored.
|
||||
|
||||
Violations of those rules will be escalated through the Community Committee.
|
||||
|
||||
After all the emails are in, the TC has 96 hours to give its final decision.
|
||||
Exceptionally, the TC can request an extra delay, that will be notified on the
|
||||
mailing list.
|
||||
|
||||
### Within TC
|
||||
|
||||
In the internal case, the TC has 96 hours to give its final decision.
|
||||
Exceptionally, the TC can request an extra delay.
|
||||
|
||||
|
||||
## Decisions
|
||||
|
||||
The decisions from the TC will be sent on the mailing list, with the _[TC]_ tag.
|
||||
|
||||
Internally, the TC should take decisions with a majority, or using
|
||||
ranked-choice voting.
|
||||
|
||||
The decision from the TC should be published with a summary of the reasons that
|
||||
lead to this decision.
|
||||
|
||||
The decisions from the TC are final, until the matters are reopened after
|
||||
no less than one year.
|
||||
|
||||
Vendored
-877
@@ -1,877 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : Developer </title>
|
||||
|
||||
<meta name="description" content="Developer Documentation: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : Developer ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">Developer Documentation</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Developers-Guide" href="#Developers-Guide">1. Developers Guide</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Notes-for-external-developers" href="#Notes-for-external-developers">1.1 Notes for external developers</a></li>
|
||||
<li><a name="toc-Contributing" href="#Contributing">1.2 Contributing</a></li>
|
||||
<li><a name="toc-Coding-Rules-1" href="#Coding-Rules-1">1.3 Coding Rules</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Code-formatting-conventions" href="#Code-formatting-conventions">1.3.1 Code formatting conventions</a></li>
|
||||
<li><a name="toc-Comments" href="#Comments">1.3.2 Comments</a></li>
|
||||
<li><a name="toc-C-language-features" href="#C-language-features">1.3.3 C language features</a></li>
|
||||
<li><a name="toc-Naming-conventions" href="#Naming-conventions">1.3.4 Naming conventions</a></li>
|
||||
<li><a name="toc-Miscellaneous-conventions" href="#Miscellaneous-conventions">1.3.5 Miscellaneous conventions</a></li>
|
||||
<li><a name="toc-Editor-configuration" href="#Editor-configuration">1.3.6 Editor configuration</a></li>
|
||||
</ul></li>
|
||||
<li><a name="toc-Development-Policy" href="#Development-Policy">1.4 Development Policy</a></li>
|
||||
<li><a name="toc-Submitting-patches-1" href="#Submitting-patches-1">1.5 Submitting patches</a></li>
|
||||
<li><a name="toc-New-codecs-or-formats-checklist" href="#New-codecs-or-formats-checklist">1.6 New codecs or formats checklist</a></li>
|
||||
<li><a name="toc-patch-submission-checklist" href="#patch-submission-checklist">1.7 patch submission checklist</a></li>
|
||||
<li><a name="toc-Patch-review-process" href="#Patch-review-process">1.8 Patch review process</a></li>
|
||||
<li><a name="toc-Regression-tests-1" href="#Regression-tests-1">1.9 Regression tests</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Adding-files-to-the-fate_002dsuite-dataset" href="#Adding-files-to-the-fate_002dsuite-dataset">1.9.1 Adding files to the fate-suite dataset</a></li>
|
||||
<li><a name="toc-Visualizing-Test-Coverage" href="#Visualizing-Test-Coverage">1.9.2 Visualizing Test Coverage</a></li>
|
||||
<li><a name="toc-Using-Valgrind" href="#Using-Valgrind">1.9.3 Using Valgrind</a></li>
|
||||
</ul></li>
|
||||
<li><a name="toc-Release-process-1" href="#Release-process-1">1.10 Release process</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Criteria-for-Point-Releases-1" href="#Criteria-for-Point-Releases-1">1.10.1 Criteria for Point Releases</a></li>
|
||||
<li><a name="toc-Release-Checklist" href="#Release-Checklist">1.10.2 Release Checklist</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="Developers-Guide"></a>
|
||||
<h1 class="chapter"><a href="developer.html#toc-Developers-Guide">1. Developers Guide</a></h1>
|
||||
|
||||
<a name="Notes-for-external-developers"></a>
|
||||
<h2 class="section"><a href="developer.html#toc-Notes-for-external-developers">1.1 Notes for external developers</a></h2>
|
||||
|
||||
<p>This document is mostly useful for internal FFmpeg developers.
|
||||
External developers who need to use the API in their application should
|
||||
refer to the API doxygen documentation in the public headers, and
|
||||
check the examples in ‘<tt>doc/examples</tt>’ and in the source code to
|
||||
see how the public API is employed.
|
||||
</p>
|
||||
<p>You can use the FFmpeg libraries in your commercial program, but you
|
||||
are encouraged to <em>publish any patch you make</em>. In this case the
|
||||
best way to proceed is to send your patches to the ffmpeg-devel
|
||||
mailing list following the guidelines illustrated in the remainder of
|
||||
this document.
|
||||
</p>
|
||||
<p>For more detailed legal information about the use of FFmpeg in
|
||||
external programs read the ‘<tt>LICENSE</tt>’ file in the source tree and
|
||||
consult <a href="http://ffmpeg.org/legal.html">http://ffmpeg.org/legal.html</a>.
|
||||
</p>
|
||||
<a name="Contributing"></a>
|
||||
<h2 class="section"><a href="developer.html#toc-Contributing">1.2 Contributing</a></h2>
|
||||
|
||||
<p>There are 3 ways by which code gets into ffmpeg.
|
||||
</p><ul>
|
||||
<li> Submitting Patches to the main developer mailing list
|
||||
see <a href="#Submitting-patches">Submitting patches</a> for details.
|
||||
</li><li> Directly committing changes to the main tree.
|
||||
</li><li> Committing changes to a git clone, for example on github.com or
|
||||
gitorious.org. And asking us to merge these changes.
|
||||
</li></ul>
|
||||
|
||||
<p>Whichever way, changes should be reviewed by the maintainer of the code
|
||||
before they are committed. And they should follow the <a href="#Coding-Rules">Coding Rules</a>.
|
||||
The developer making the commit and the author are responsible for their changes
|
||||
and should try to fix issues their commit causes.
|
||||
</p>
|
||||
<p><a name="Coding-Rules"></a>
|
||||
</p><a name="Coding-Rules-1"></a>
|
||||
<h2 class="section"><a href="developer.html#toc-Coding-Rules-1">1.3 Coding Rules</a></h2>
|
||||
|
||||
<a name="Code-formatting-conventions"></a>
|
||||
<h3 class="subsection"><a href="developer.html#toc-Code-formatting-conventions">1.3.1 Code formatting conventions</a></h3>
|
||||
|
||||
<p>There are the following guidelines regarding the indentation in files:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
Indent size is 4.
|
||||
|
||||
</li><li>
|
||||
The TAB character is forbidden outside of Makefiles as is any
|
||||
form of trailing whitespace. Commits containing either will be
|
||||
rejected by the git repository.
|
||||
|
||||
</li><li>
|
||||
You should try to limit your code lines to 80 characters; however, do so if
|
||||
and only if this improves readability.
|
||||
</li></ul>
|
||||
<p>The presentation is one inspired by ’indent -i4 -kr -nut’.
|
||||
</p>
|
||||
<p>The main priority in FFmpeg is simplicity and small code size in order to
|
||||
minimize the bug count.
|
||||
</p>
|
||||
<a name="Comments"></a>
|
||||
<h3 class="subsection"><a href="developer.html#toc-Comments">1.3.2 Comments</a></h3>
|
||||
<p>Use the JavaDoc/Doxygen format (see examples below) so that code documentation
|
||||
can be generated automatically. All nontrivial functions should have a comment
|
||||
above them explaining what the function does, even if it is just one sentence.
|
||||
All structures and their member variables should be documented, too.
|
||||
</p>
|
||||
<p>Avoid Qt-style and similar Doxygen syntax with <code>!</code> in it, i.e. replace
|
||||
<code>//!</code> with <code>///</code> and similar. Also @ syntax should be employed
|
||||
for markup commands, i.e. use <code>@param</code> and not <code>\param</code>.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">/**
|
||||
* @file
|
||||
* MPEG codec.
|
||||
* @author ...
|
||||
*/
|
||||
|
||||
/**
|
||||
* Summary sentence.
|
||||
* more text ...
|
||||
* ...
|
||||
*/
|
||||
typedef struct Foobar{
|
||||
int var1; /**< var1 description */
|
||||
int var2; ///< var2 description
|
||||
/** var3 description */
|
||||
int var3;
|
||||
} Foobar;
|
||||
|
||||
/**
|
||||
* Summary sentence.
|
||||
* more text ...
|
||||
* ...
|
||||
* @param my_parameter description of my_parameter
|
||||
* @return return value description
|
||||
*/
|
||||
int myfunc(int my_parameter)
|
||||
...
|
||||
</pre></td></tr></table>
|
||||
|
||||
<a name="C-language-features"></a>
|
||||
<h3 class="subsection"><a href="developer.html#toc-C-language-features">1.3.3 C language features</a></h3>
|
||||
|
||||
<p>FFmpeg is programmed in the ISO C90 language with a few additional
|
||||
features from ISO C99, namely:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
the ‘<samp>inline</samp>’ keyword;
|
||||
|
||||
</li><li>
|
||||
‘<samp>//</samp>’ comments;
|
||||
|
||||
</li><li>
|
||||
designated struct initializers (‘<samp>struct s x = { .i = 17 };</samp>’)
|
||||
|
||||
</li><li>
|
||||
compound literals (‘<samp>x = (struct s) { 17, 23 };</samp>’)
|
||||
</li></ul>
|
||||
|
||||
<p>These features are supported by all compilers we care about, so we will not
|
||||
accept patches to remove their use unless they absolutely do not impair
|
||||
clarity and performance.
|
||||
</p>
|
||||
<p>All code must compile with recent versions of GCC and a number of other
|
||||
currently supported compilers. To ensure compatibility, please do not use
|
||||
additional C99 features or GCC extensions. Especially watch out for:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
mixing statements and declarations;
|
||||
|
||||
</li><li>
|
||||
‘<samp>long long</samp>’ (use ‘<samp>int64_t</samp>’ instead);
|
||||
|
||||
</li><li>
|
||||
‘<samp>__attribute__</samp>’ not protected by ‘<samp>#ifdef __GNUC__</samp>’ or similar;
|
||||
|
||||
</li><li>
|
||||
GCC statement expressions (‘<samp>(x = ({ int y = 4; y; })</samp>’).
|
||||
</li></ul>
|
||||
|
||||
<a name="Naming-conventions"></a>
|
||||
<h3 class="subsection"><a href="developer.html#toc-Naming-conventions">1.3.4 Naming conventions</a></h3>
|
||||
<p>All names should be composed with underscores (_), not CamelCase. For example,
|
||||
‘<samp>avfilter_get_video_buffer</samp>’ is an acceptable function name and
|
||||
‘<samp>AVFilterGetVideo</samp>’ is not. The exception from this are type names, like
|
||||
for example structs and enums; they should always be in the CamelCase
|
||||
</p>
|
||||
<p>There are the following conventions for naming variables and functions:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
For local variables no prefix is required.
|
||||
|
||||
</li><li>
|
||||
For file-scope variables and functions declared as <code>static</code>, no prefix
|
||||
is required.
|
||||
|
||||
</li><li>
|
||||
For variables and functions visible outside of file scope, but only used
|
||||
internally by a library, an <code>ff_</code> prefix should be used,
|
||||
e.g. ‘<samp>ff_w64_demuxer</samp>’.
|
||||
|
||||
</li><li>
|
||||
For variables and functions visible outside of file scope, used internally
|
||||
across multiple libraries, use <code>avpriv_</code> as prefix, for example,
|
||||
‘<samp>avpriv_aac_parse_header</samp>’.
|
||||
|
||||
</li><li>
|
||||
Each library has its own prefix for public symbols, in addition to the
|
||||
commonly used <code>av_</code> (<code>avformat_</code> for libavformat,
|
||||
<code>avcodec_</code> for libavcodec, <code>swr_</code> for libswresample, etc).
|
||||
Check the existing code and choose names accordingly.
|
||||
Note that some symbols without these prefixes are also exported for
|
||||
retro-compatibility reasons. These exceptions are declared in the
|
||||
<code>lib<name>/lib<name>.v</code> files.
|
||||
</li></ul>
|
||||
|
||||
<p>Furthermore, name space reserved for the system should not be invaded.
|
||||
Identifiers ending in <code>_t</code> are reserved by
|
||||
<a href="http://pubs.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_02.html#tag_02_02_02">POSIX</a>.
|
||||
Also avoid names starting with <code>__</code> or <code>_</code> followed by an uppercase
|
||||
letter as they are reserved by the C standard. Names starting with <code>_</code>
|
||||
are reserved at the file level and may not be used for externally visible
|
||||
symbols. If in doubt, just avoid names starting with <code>_</code> altogether.
|
||||
</p>
|
||||
<a name="Miscellaneous-conventions"></a>
|
||||
<h3 class="subsection"><a href="developer.html#toc-Miscellaneous-conventions">1.3.5 Miscellaneous conventions</a></h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
fprintf and printf are forbidden in libavformat and libavcodec,
|
||||
please use av_log() instead.
|
||||
|
||||
</li><li>
|
||||
Casts should be used only when necessary. Unneeded parentheses
|
||||
should also be avoided if they don’t make the code easier to understand.
|
||||
</li></ul>
|
||||
|
||||
<a name="Editor-configuration"></a>
|
||||
<h3 class="subsection"><a href="developer.html#toc-Editor-configuration">1.3.6 Editor configuration</a></h3>
|
||||
<p>In order to configure Vim to follow FFmpeg formatting conventions, paste
|
||||
the following snippet into your ‘<tt>.vimrc</tt>’:
|
||||
</p><table><tr><td> </td><td><pre class="example">" indentation rules for FFmpeg: 4 spaces, no tabs
|
||||
set expandtab
|
||||
set shiftwidth=4
|
||||
set softtabstop=4
|
||||
set cindent
|
||||
set cinoptions=(0
|
||||
" Allow tabs in Makefiles.
|
||||
autocmd FileType make,automake set noexpandtab shiftwidth=8 softtabstop=8
|
||||
" Trailing whitespace and tabs are forbidden, so highlight them.
|
||||
highlight ForbiddenWhitespace ctermbg=red guibg=red
|
||||
match ForbiddenWhitespace /\s\+$\|\t/
|
||||
" Do not highlight spaces at the end of line while typing on that line.
|
||||
autocmd InsertEnter * match ForbiddenWhitespace /\t\|\s\+\%#\@<!$/
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>For Emacs, add these roughly equivalent lines to your ‘<tt>.emacs.d/init.el</tt>’:
|
||||
</p><table><tr><td> </td><td><pre class="example">(c-add-style "ffmpeg"
|
||||
'("k&r"
|
||||
(c-basic-offset . 4)
|
||||
(indent-tabs-mode . nil)
|
||||
(show-trailing-whitespace . t)
|
||||
(c-offsets-alist
|
||||
(statement-cont . (c-lineup-assignments +)))
|
||||
)
|
||||
)
|
||||
(setq c-default-style "ffmpeg")
|
||||
</pre></td></tr></table>
|
||||
|
||||
<a name="Development-Policy"></a>
|
||||
<h2 class="section"><a href="developer.html#toc-Development-Policy">1.4 Development Policy</a></h2>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Contributions should be licensed under the
|
||||
<a href="http://www.gnu.org/licenses/lgpl-2.1.html">LGPL 2.1</a>,
|
||||
including an "or any later version" clause, or, if you prefer
|
||||
a gift-style license, the
|
||||
<a href="http://www.isc.org/software/license/">ISC</a> or
|
||||
<a href="http://mit-license.org/">MIT</a> license.
|
||||
<a href="http://www.gnu.org/licenses/gpl-2.0.html">GPL 2</a> including
|
||||
an "or any later version" clause is also acceptable, but LGPL is
|
||||
preferred.
|
||||
If you add a new file, give it a proper license header. Do not copy and
|
||||
paste it from a random place, use an existing file as template.
|
||||
|
||||
</li><li>
|
||||
You must not commit code which breaks FFmpeg! (Meaning unfinished but
|
||||
enabled code which breaks compilation or compiles but does not work or
|
||||
breaks the regression tests)
|
||||
You can commit unfinished stuff (for testing etc), but it must be disabled
|
||||
(#ifdef etc) by default so it does not interfere with other developers’
|
||||
work.
|
||||
|
||||
</li><li>
|
||||
The commit message should have a short first line in the form of
|
||||
a ‘<samp>topic: short description</samp>’ as a header, separated by a newline
|
||||
from the body consisting of an explanation of why the change is necessary.
|
||||
If the commit fixes a known bug on the bug tracker, the commit message
|
||||
should include its bug ID. Referring to the issue on the bug tracker does
|
||||
not exempt you from writing an excerpt of the bug in the commit message.
|
||||
|
||||
</li><li>
|
||||
You do not have to over-test things. If it works for you, and you think it
|
||||
should work for others, then commit. If your code has problems
|
||||
(portability, triggers compiler bugs, unusual environment etc) they will be
|
||||
reported and eventually fixed.
|
||||
|
||||
</li><li>
|
||||
Do not commit unrelated changes together, split them into self-contained
|
||||
pieces. Also do not forget that if part B depends on part A, but A does not
|
||||
depend on B, then A can and should be committed first and separate from B.
|
||||
Keeping changes well split into self-contained parts makes reviewing and
|
||||
understanding them on the commit log mailing list easier. This also helps
|
||||
in case of debugging later on.
|
||||
Also if you have doubts about splitting or not splitting, do not hesitate to
|
||||
ask/discuss it on the developer mailing list.
|
||||
|
||||
</li><li>
|
||||
Do not change behavior of the programs (renaming options etc) or public
|
||||
API or ABI without first discussing it on the ffmpeg-devel mailing list.
|
||||
Do not remove functionality from the code. Just improve!
|
||||
|
||||
<p>Note: Redundant code can be removed.
|
||||
</p>
|
||||
</li><li>
|
||||
Do not commit changes to the build system (Makefiles, configure script)
|
||||
which change behavior, defaults etc, without asking first. The same
|
||||
applies to compiler warning fixes, trivial looking fixes and to code
|
||||
maintained by other developers. We usually have a reason for doing things
|
||||
the way we do. Send your changes as patches to the ffmpeg-devel mailing
|
||||
list, and if the code maintainers say OK, you may commit. This does not
|
||||
apply to files you wrote and/or maintain.
|
||||
|
||||
</li><li>
|
||||
We refuse source indentation and other cosmetic changes if they are mixed
|
||||
with functional changes, such commits will be rejected and removed. Every
|
||||
developer has his own indentation style, you should not change it. Of course
|
||||
if you (re)write something, you can use your own style, even though we would
|
||||
prefer if the indentation throughout FFmpeg was consistent (Many projects
|
||||
force a given indentation style - we do not.). If you really need to make
|
||||
indentation changes (try to avoid this), separate them strictly from real
|
||||
changes.
|
||||
|
||||
<p>NOTE: If you had to put if(){ .. } over a large (> 5 lines) chunk of code,
|
||||
then either do NOT change the indentation of the inner part within (do not
|
||||
move it to the right)! or do so in a separate commit
|
||||
</p>
|
||||
</li><li>
|
||||
Always fill out the commit log message. Describe in a few lines what you
|
||||
changed and why. You can refer to mailing list postings if you fix a
|
||||
particular bug. Comments such as "fixed!" or "Changed it." are unacceptable.
|
||||
Recommended format:
|
||||
area changed: Short 1 line description
|
||||
|
||||
<p>details describing what and why and giving references.
|
||||
</p>
|
||||
</li><li>
|
||||
Make sure the author of the commit is set correctly. (see git commit –author)
|
||||
If you apply a patch, send an
|
||||
answer to ffmpeg-devel (or wherever you got the patch from) saying that
|
||||
you applied the patch.
|
||||
|
||||
</li><li>
|
||||
When applying patches that have been discussed (at length) on the mailing
|
||||
list, reference the thread in the log message.
|
||||
|
||||
</li><li>
|
||||
Do NOT commit to code actively maintained by others without permission.
|
||||
Send a patch to ffmpeg-devel instead. If no one answers within a reasonable
|
||||
timeframe (12h for build failures and security fixes, 3 days small changes,
|
||||
1 week for big patches) then commit your patch if you think it is OK.
|
||||
Also note, the maintainer can simply ask for more time to review!
|
||||
|
||||
</li><li>
|
||||
Subscribe to the ffmpeg-cvslog mailing list. The diffs of all commits
|
||||
are sent there and reviewed by all the other developers. Bugs and possible
|
||||
improvements or general questions regarding commits are discussed there. We
|
||||
expect you to react if problems with your code are uncovered.
|
||||
|
||||
</li><li>
|
||||
Update the documentation if you change behavior or add features. If you are
|
||||
unsure how best to do this, send a patch to ffmpeg-devel, the documentation
|
||||
maintainer(s) will review and commit your stuff.
|
||||
|
||||
</li><li>
|
||||
Try to keep important discussions and requests (also) on the public
|
||||
developer mailing list, so that all developers can benefit from them.
|
||||
|
||||
</li><li>
|
||||
Never write to unallocated memory, never write over the end of arrays,
|
||||
always check values read from some untrusted source before using them
|
||||
as array index or other risky things.
|
||||
|
||||
</li><li>
|
||||
Remember to check if you need to bump versions for the specific libav*
|
||||
parts (libavutil, libavcodec, libavformat) you are changing. You need
|
||||
to change the version integer.
|
||||
Incrementing the first component means no backward compatibility to
|
||||
previous versions (e.g. removal of a function from the public API).
|
||||
Incrementing the second component means backward compatible change
|
||||
(e.g. addition of a function to the public API or extension of an
|
||||
existing data structure).
|
||||
Incrementing the third component means a noteworthy binary compatible
|
||||
change (e.g. encoder bug fix that matters for the decoder). The third
|
||||
component always starts at 100 to distinguish FFmpeg from Libav.
|
||||
|
||||
</li><li>
|
||||
Compiler warnings indicate potential bugs or code with bad style. If a type of
|
||||
warning always points to correct and clean code, that warning should
|
||||
be disabled, not the code changed.
|
||||
Thus the remaining warnings can either be bugs or correct code.
|
||||
If it is a bug, the bug has to be fixed. If it is not, the code should
|
||||
be changed to not generate a warning unless that causes a slowdown
|
||||
or obfuscates the code.
|
||||
|
||||
</li><li>
|
||||
Make sure that no parts of the codebase that you maintain are missing from the
|
||||
‘<tt>MAINTAINERS</tt>’ file. If something that you want to maintain is missing add it with
|
||||
your name after it.
|
||||
If at some point you no longer want to maintain some code, then please help
|
||||
finding a new maintainer and also don’t forget updating the ‘<tt>MAINTAINERS</tt>’ file.
|
||||
</li></ol>
|
||||
|
||||
<p>We think our rules are not too hard. If you have comments, contact us.
|
||||
</p>
|
||||
<p><a name="Submitting-patches"></a>
|
||||
</p><a name="Submitting-patches-1"></a>
|
||||
<h2 class="section"><a href="developer.html#toc-Submitting-patches-1">1.5 Submitting patches</a></h2>
|
||||
|
||||
<p>First, read the <a href="#Coding-Rules">Coding Rules</a> above if you did not yet, in particular
|
||||
the rules regarding patch submission.
|
||||
</p>
|
||||
<p>When you submit your patch, please use <code>git format-patch</code> or
|
||||
<code>git send-email</code>. We cannot read other diffs :-)
|
||||
</p>
|
||||
<p>Also please do not submit a patch which contains several unrelated changes.
|
||||
Split it into separate, self-contained pieces. This does not mean splitting
|
||||
file by file. Instead, make the patch as small as possible while still
|
||||
keeping it as a logical unit that contains an individual change, even
|
||||
if it spans multiple files. This makes reviewing your patches much easier
|
||||
for us and greatly increases your chances of getting your patch applied.
|
||||
</p>
|
||||
<p>Use the patcheck tool of FFmpeg to check your patch.
|
||||
The tool is located in the tools directory.
|
||||
</p>
|
||||
<p>Run the <a href="#Regression-tests">Regression tests</a> before submitting a patch in order to verify
|
||||
it does not cause unexpected problems.
|
||||
</p>
|
||||
<p>It also helps quite a bit if you tell us what the patch does (for example
|
||||
’replaces lrint by lrintf’), and why (for example ’*BSD isn’t C99 compliant
|
||||
and has no lrint()’)
|
||||
</p>
|
||||
<p>Also please if you send several patches, send each patch as a separate mail,
|
||||
do not attach several unrelated patches to the same mail.
|
||||
</p>
|
||||
<p>Patches should be posted to the
|
||||
<a href="http://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel">ffmpeg-devel</a>
|
||||
mailing list. Use <code>git send-email</code> when possible since it will properly
|
||||
send patches without requiring extra care. If you cannot, then send patches
|
||||
as base64-encoded attachments, so your patch is not trashed during
|
||||
transmission.
|
||||
</p>
|
||||
<p>Your patch will be reviewed on the mailing list. You will likely be asked
|
||||
to make some changes and are expected to send in an improved version that
|
||||
incorporates the requests from the review. This process may go through
|
||||
several iterations. Once your patch is deemed good enough, some developer
|
||||
will pick it up and commit it to the official FFmpeg tree.
|
||||
</p>
|
||||
<p>Give us a few days to react. But if some time passes without reaction,
|
||||
send a reminder by email. Your patch should eventually be dealt with.
|
||||
</p>
|
||||
|
||||
<a name="New-codecs-or-formats-checklist"></a>
|
||||
<h2 class="section"><a href="developer.html#toc-New-codecs-or-formats-checklist">1.6 New codecs or formats checklist</a></h2>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Did you use av_cold for codec initialization and close functions?
|
||||
|
||||
</li><li>
|
||||
Did you add a long_name under NULL_IF_CONFIG_SMALL to the AVCodec or
|
||||
AVInputFormat/AVOutputFormat struct?
|
||||
|
||||
</li><li>
|
||||
Did you bump the minor version number (and reset the micro version
|
||||
number) in ‘<tt>libavcodec/version.h</tt>’ or ‘<tt>libavformat/version.h</tt>’?
|
||||
|
||||
</li><li>
|
||||
Did you register it in ‘<tt>allcodecs.c</tt>’ or ‘<tt>allformats.c</tt>’?
|
||||
|
||||
</li><li>
|
||||
Did you add the AVCodecID to ‘<tt>avcodec.h</tt>’?
|
||||
When adding new codec IDs, also add an entry to the codec descriptor
|
||||
list in ‘<tt>libavcodec/codec_desc.c</tt>’.
|
||||
|
||||
</li><li>
|
||||
If it has a FourCC, did you add it to ‘<tt>libavformat/riff.c</tt>’,
|
||||
even if it is only a decoder?
|
||||
|
||||
</li><li>
|
||||
Did you add a rule to compile the appropriate files in the Makefile?
|
||||
Remember to do this even if you’re just adding a format to a file that is
|
||||
already being compiled by some other rule, like a raw demuxer.
|
||||
|
||||
</li><li>
|
||||
Did you add an entry to the table of supported formats or codecs in
|
||||
‘<tt>doc/general.texi</tt>’?
|
||||
|
||||
</li><li>
|
||||
Did you add an entry in the Changelog?
|
||||
|
||||
</li><li>
|
||||
If it depends on a parser or a library, did you add that dependency in
|
||||
configure?
|
||||
|
||||
</li><li>
|
||||
Did you <code>git add</code> the appropriate files before committing?
|
||||
|
||||
</li><li>
|
||||
Did you make sure it compiles standalone, i.e. with
|
||||
<code>configure --disable-everything --enable-decoder=foo</code>
|
||||
(or <code>--enable-demuxer</code> or whatever your component is)?
|
||||
</li></ol>
|
||||
|
||||
|
||||
<a name="patch-submission-checklist"></a>
|
||||
<h2 class="section"><a href="developer.html#toc-patch-submission-checklist">1.7 patch submission checklist</a></h2>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Does <code>make fate</code> pass with the patch applied?
|
||||
|
||||
</li><li>
|
||||
Was the patch generated with git format-patch or send-email?
|
||||
|
||||
</li><li>
|
||||
Did you sign off your patch? (git commit -s)
|
||||
See <a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob_plain;f=Documentation/SubmittingPatches">http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob_plain;f=Documentation/SubmittingPatches</a> for the meaning
|
||||
of sign off.
|
||||
|
||||
</li><li>
|
||||
Did you provide a clear git commit log message?
|
||||
|
||||
</li><li>
|
||||
Is the patch against latest FFmpeg git master branch?
|
||||
|
||||
</li><li>
|
||||
Are you subscribed to ffmpeg-devel?
|
||||
(the list is subscribers only due to spam)
|
||||
|
||||
</li><li>
|
||||
Have you checked that the changes are minimal, so that the same cannot be
|
||||
achieved with a smaller patch and/or simpler final code?
|
||||
|
||||
</li><li>
|
||||
If the change is to speed critical code, did you benchmark it?
|
||||
|
||||
</li><li>
|
||||
If you did any benchmarks, did you provide them in the mail?
|
||||
|
||||
</li><li>
|
||||
Have you checked that the patch does not introduce buffer overflows or
|
||||
other security issues?
|
||||
|
||||
</li><li>
|
||||
Did you test your decoder or demuxer against damaged data? If no, see
|
||||
tools/trasher, the noise bitstream filter, and
|
||||
<a href="http://caca.zoy.org/wiki/zzuf">zzuf</a>. Your decoder or demuxer
|
||||
should not crash, end in a (near) infinite loop, or allocate ridiculous
|
||||
amounts of memory when fed damaged data.
|
||||
|
||||
</li><li>
|
||||
Does the patch not mix functional and cosmetic changes?
|
||||
|
||||
</li><li>
|
||||
Did you add tabs or trailing whitespace to the code? Both are forbidden.
|
||||
|
||||
</li><li>
|
||||
Is the patch attached to the email you send?
|
||||
|
||||
</li><li>
|
||||
Is the mime type of the patch correct? It should be text/x-diff or
|
||||
text/x-patch or at least text/plain and not application/octet-stream.
|
||||
|
||||
</li><li>
|
||||
If the patch fixes a bug, did you provide a verbose analysis of the bug?
|
||||
|
||||
</li><li>
|
||||
If the patch fixes a bug, did you provide enough information, including
|
||||
a sample, so the bug can be reproduced and the fix can be verified?
|
||||
Note please do not attach samples >100k to mails but rather provide a
|
||||
URL, you can upload to ftp://upload.ffmpeg.org
|
||||
|
||||
</li><li>
|
||||
Did you provide a verbose summary about what the patch does change?
|
||||
|
||||
</li><li>
|
||||
Did you provide a verbose explanation why it changes things like it does?
|
||||
|
||||
</li><li>
|
||||
Did you provide a verbose summary of the user visible advantages and
|
||||
disadvantages if the patch is applied?
|
||||
|
||||
</li><li>
|
||||
Did you provide an example so we can verify the new feature added by the
|
||||
patch easily?
|
||||
|
||||
</li><li>
|
||||
If you added a new file, did you insert a license header? It should be
|
||||
taken from FFmpeg, not randomly copied and pasted from somewhere else.
|
||||
|
||||
</li><li>
|
||||
You should maintain alphabetical order in alphabetically ordered lists as
|
||||
long as doing so does not break API/ABI compatibility.
|
||||
|
||||
</li><li>
|
||||
Lines with similar content should be aligned vertically when doing so
|
||||
improves readability.
|
||||
|
||||
</li><li>
|
||||
Consider to add a regression test for your code.
|
||||
|
||||
</li><li>
|
||||
If you added YASM code please check that things still work with –disable-yasm
|
||||
|
||||
</li><li>
|
||||
Make sure you check the return values of function and return appropriate
|
||||
error codes. Especially memory allocation functions like <code>av_malloc()</code>
|
||||
are notoriously left unchecked, which is a serious problem.
|
||||
|
||||
</li><li>
|
||||
Test your code with valgrind and or Address Sanitizer to ensure it’s free
|
||||
of leaks, out of array accesses, etc.
|
||||
</li></ol>
|
||||
|
||||
<a name="Patch-review-process"></a>
|
||||
<h2 class="section"><a href="developer.html#toc-Patch-review-process">1.8 Patch review process</a></h2>
|
||||
|
||||
<p>All patches posted to ffmpeg-devel will be reviewed, unless they contain a
|
||||
clear note that the patch is not for the git master branch.
|
||||
Reviews and comments will be posted as replies to the patch on the
|
||||
mailing list. The patch submitter then has to take care of every comment,
|
||||
that can be by resubmitting a changed patch or by discussion. Resubmitted
|
||||
patches will themselves be reviewed like any other patch. If at some point
|
||||
a patch passes review with no comments then it is approved, that can for
|
||||
simple and small patches happen immediately while large patches will generally
|
||||
have to be changed and reviewed many times before they are approved.
|
||||
After a patch is approved it will be committed to the repository.
|
||||
</p>
|
||||
<p>We will review all submitted patches, but sometimes we are quite busy so
|
||||
especially for large patches this can take several weeks.
|
||||
</p>
|
||||
<p>If you feel that the review process is too slow and you are willing to try to
|
||||
take over maintainership of the area of code you change then just clone
|
||||
git master and maintain the area of code there. We will merge each area from
|
||||
where its best maintained.
|
||||
</p>
|
||||
<p>When resubmitting patches, please do not make any significant changes
|
||||
not related to the comments received during review. Such patches will
|
||||
be rejected. Instead, submit significant changes or new features as
|
||||
separate patches.
|
||||
</p>
|
||||
<p><a name="Regression-tests"></a>
|
||||
</p><a name="Regression-tests-1"></a>
|
||||
<h2 class="section"><a href="developer.html#toc-Regression-tests-1">1.9 Regression tests</a></h2>
|
||||
|
||||
<p>Before submitting a patch (or committing to the repository), you should at least
|
||||
test that you did not break anything.
|
||||
</p>
|
||||
<p>Running ’make fate’ accomplishes this, please see <a href="fate.html">fate.html</a> for details.
|
||||
</p>
|
||||
<p>[Of course, some patches may change the results of the regression tests. In
|
||||
this case, the reference results of the regression tests shall be modified
|
||||
accordingly].
|
||||
</p>
|
||||
<a name="Adding-files-to-the-fate_002dsuite-dataset"></a>
|
||||
<h3 class="subsection"><a href="developer.html#toc-Adding-files-to-the-fate_002dsuite-dataset">1.9.1 Adding files to the fate-suite dataset</a></h3>
|
||||
|
||||
<p>When there is no muxer or encoder available to generate test media for a
|
||||
specific test then the media has to be inlcuded in the fate-suite.
|
||||
First please make sure that the sample file is as small as possible to test the
|
||||
respective decoder or demuxer sufficiently. Large files increase network
|
||||
bandwidth and disk space requirements.
|
||||
Once you have a working fate test and fate sample, provide in the commit
|
||||
message or introductionary message for the patch series that you post to
|
||||
the ffmpeg-devel mailing list, a direct link to download the sample media.
|
||||
</p>
|
||||
|
||||
<a name="Visualizing-Test-Coverage"></a>
|
||||
<h3 class="subsection"><a href="developer.html#toc-Visualizing-Test-Coverage">1.9.2 Visualizing Test Coverage</a></h3>
|
||||
|
||||
<p>The FFmpeg build system allows visualizing the test coverage in an easy
|
||||
manner with the coverage tools <code>gcov</code>/<code>lcov</code>. This involves
|
||||
the following steps:
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
Configure to compile with instrumentation enabled:
|
||||
<code>configure --toolchain=gcov</code>.
|
||||
|
||||
</li><li>
|
||||
Run your test case, either manually or via FATE. This can be either
|
||||
the full FATE regression suite, or any arbitrary invocation of any
|
||||
front-end tool provided by FFmpeg, in any combination.
|
||||
|
||||
</li><li>
|
||||
Run <code>make lcov</code> to generate coverage data in HTML format.
|
||||
|
||||
</li><li>
|
||||
View <code>lcov/index.html</code> in your preferred HTML viewer.
|
||||
</li></ol>
|
||||
|
||||
<p>You can use the command <code>make lcov-reset</code> to reset the coverage
|
||||
measurements. You will need to rerun <code>make lcov</code> after running a
|
||||
new test.
|
||||
</p>
|
||||
<a name="Using-Valgrind"></a>
|
||||
<h3 class="subsection"><a href="developer.html#toc-Using-Valgrind">1.9.3 Using Valgrind</a></h3>
|
||||
|
||||
<p>The configure script provides a shortcut for using valgrind to spot bugs
|
||||
related to memory handling. Just add the option
|
||||
<code>--toolchain=valgrind-memcheck</code> or <code>--toolchain=valgrind-massif</code>
|
||||
to your configure line, and reasonable defaults will be set for running
|
||||
FATE under the supervision of either the <strong>memcheck</strong> or the
|
||||
<strong>massif</strong> tool of the valgrind suite.
|
||||
</p>
|
||||
<p>In case you need finer control over how valgrind is invoked, use the
|
||||
<code>--target-exec='valgrind <your_custom_valgrind_options></code> option in
|
||||
your configure line instead.
|
||||
</p>
|
||||
<p><a name="Release-process"></a>
|
||||
</p><a name="Release-process-1"></a>
|
||||
<h2 class="section"><a href="developer.html#toc-Release-process-1">1.10 Release process</a></h2>
|
||||
|
||||
<p>FFmpeg maintains a set of <strong>release branches</strong>, which are the
|
||||
recommended deliverable for system integrators and distributors (such as
|
||||
Linux distributions, etc.). At regular times, a <strong>release
|
||||
manager</strong> prepares, tests and publishes tarballs on the
|
||||
<a href="http://ffmpeg.org">http://ffmpeg.org</a> website.
|
||||
</p>
|
||||
<p>There are two kinds of releases:
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
<strong>Major releases</strong> always include the latest and greatest
|
||||
features and functionality.
|
||||
|
||||
</li><li>
|
||||
<strong>Point releases</strong> are cut from <strong>release</strong> branches,
|
||||
which are named <code>release/X</code>, with <code>X</code> being the release
|
||||
version number.
|
||||
</li></ol>
|
||||
|
||||
<p>Note that we promise to our users that shared libraries from any FFmpeg
|
||||
release never break programs that have been <strong>compiled</strong> against
|
||||
previous versions of <strong>the same release series</strong> in any case!
|
||||
</p>
|
||||
<p>However, from time to time, we do make API changes that require adaptations
|
||||
in applications. Such changes are only allowed in (new) major releases and
|
||||
require further steps such as bumping library version numbers and/or
|
||||
adjustments to the symbol versioning file. Please discuss such changes
|
||||
on the <strong>ffmpeg-devel</strong> mailing list in time to allow forward planning.
|
||||
</p>
|
||||
<p><a name="Criteria-for-Point-Releases"></a>
|
||||
</p><a name="Criteria-for-Point-Releases-1"></a>
|
||||
<h3 class="subsection"><a href="developer.html#toc-Criteria-for-Point-Releases-1">1.10.1 Criteria for Point Releases</a></h3>
|
||||
|
||||
<p>Changes that match the following criteria are valid candidates for
|
||||
inclusion into a point release:
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
Fixes a security issue, preferably identified by a <strong>CVE
|
||||
number</strong> issued by <a href="http://cve.mitre.org/">http://cve.mitre.org/</a>.
|
||||
|
||||
</li><li>
|
||||
Fixes a documented bug in <a href="https://trac.ffmpeg.org">https://trac.ffmpeg.org</a>.
|
||||
|
||||
</li><li>
|
||||
Improves the included documentation.
|
||||
|
||||
</li><li>
|
||||
Retains both source code and binary compatibility with previous
|
||||
point releases of the same release branch.
|
||||
</li></ol>
|
||||
|
||||
<p>The order for checking the rules is (1 OR 2 OR 3) AND 4.
|
||||
</p>
|
||||
|
||||
<a name="Release-Checklist"></a>
|
||||
<h3 class="subsection"><a href="developer.html#toc-Release-Checklist">1.10.2 Release Checklist</a></h3>
|
||||
|
||||
<p>The release process involves the following steps:
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
Ensure that the ‘<tt>RELEASE</tt>’ file contains the version number for
|
||||
the upcoming release.
|
||||
|
||||
</li><li>
|
||||
Add the release at <a href="https://trac.ffmpeg.org/admin/ticket/versions">https://trac.ffmpeg.org/admin/ticket/versions</a>.
|
||||
|
||||
</li><li>
|
||||
Announce the intent to do a release to the mailing list.
|
||||
|
||||
</li><li>
|
||||
Make sure all relevant security fixes have been backported. See
|
||||
<a href="https://ffmpeg.org/security.html">https://ffmpeg.org/security.html</a>.
|
||||
|
||||
</li><li>
|
||||
Ensure that the FATE regression suite still passes in the release
|
||||
branch on at least <strong>i386</strong> and <strong>amd64</strong>
|
||||
(cf. <a href="#Regression-tests">Regression tests</a>).
|
||||
|
||||
</li><li>
|
||||
Prepare the release tarballs in <code>bz2</code> and <code>gz</code> formats, and
|
||||
supplementing files that contain <code>gpg</code> signatures
|
||||
|
||||
</li><li>
|
||||
Publish the tarballs at <a href="http://ffmpeg.org/releases">http://ffmpeg.org/releases</a>. Create and
|
||||
push an annotated tag in the form <code>nX</code>, with <code>X</code>
|
||||
containing the version number.
|
||||
|
||||
</li><li>
|
||||
Propose and send a patch to the <strong>ffmpeg-devel</strong> mailing list
|
||||
with a news entry for the website.
|
||||
|
||||
</li><li>
|
||||
Publish the news entry.
|
||||
|
||||
</li><li>
|
||||
Send announcement to the mailing list.
|
||||
</li></ol>
|
||||
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+882
@@ -0,0 +1,882 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle Developer Documentation
|
||||
@titlepage
|
||||
@center @titlefont{Developer Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Notes for external developers
|
||||
|
||||
This document is mostly useful for internal FFmpeg developers.
|
||||
External developers who need to use the API in their application should
|
||||
refer to the API doxygen documentation in the public headers, and
|
||||
check the examples in @file{doc/examples} and in the source code to
|
||||
see how the public API is employed.
|
||||
|
||||
You can use the FFmpeg libraries in your commercial program, but you
|
||||
are encouraged to @emph{publish any patch you make}. In this case the
|
||||
best way to proceed is to send your patches to the ffmpeg-devel
|
||||
mailing list following the guidelines illustrated in the remainder of
|
||||
this document.
|
||||
|
||||
For more detailed legal information about the use of FFmpeg in
|
||||
external programs read the @file{LICENSE} file in the source tree and
|
||||
consult @url{https://ffmpeg.org/legal.html}.
|
||||
|
||||
@chapter Contributing
|
||||
|
||||
There are 2 ways by which code gets into FFmpeg:
|
||||
@itemize @bullet
|
||||
@item Submitting patches to the ffmpeg-devel mailing list.
|
||||
See @ref{Submitting patches} for details.
|
||||
@item Directly committing changes to the main tree.
|
||||
@end itemize
|
||||
|
||||
Whichever way, changes should be reviewed by the maintainer of the code
|
||||
before they are committed. And they should follow the @ref{Coding Rules}.
|
||||
The developer making the commit and the author are responsible for their changes
|
||||
and should try to fix issues their commit causes.
|
||||
|
||||
@anchor{Coding Rules}
|
||||
@chapter Coding Rules
|
||||
|
||||
@section Code formatting conventions
|
||||
|
||||
There are the following guidelines regarding the indentation in files:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Indent size is 4.
|
||||
|
||||
@item
|
||||
The TAB character is forbidden outside of Makefiles as is any
|
||||
form of trailing whitespace. Commits containing either will be
|
||||
rejected by the git repository.
|
||||
|
||||
@item
|
||||
You should try to limit your code lines to 80 characters; however, do so if
|
||||
and only if this improves readability.
|
||||
|
||||
@item
|
||||
K&R coding style is used.
|
||||
@end itemize
|
||||
The presentation is one inspired by 'indent -i4 -kr -nut'.
|
||||
|
||||
The main priority in FFmpeg is simplicity and small code size in order to
|
||||
minimize the bug count.
|
||||
|
||||
@section Comments
|
||||
Use the JavaDoc/Doxygen format (see examples below) so that code documentation
|
||||
can be generated automatically. All nontrivial functions should have a comment
|
||||
above them explaining what the function does, even if it is just one sentence.
|
||||
All structures and their member variables should be documented, too.
|
||||
|
||||
Avoid Qt-style and similar Doxygen syntax with @code{!} in it, i.e. replace
|
||||
@code{//!} with @code{///} and similar. Also @@ syntax should be employed
|
||||
for markup commands, i.e. use @code{@@param} and not @code{\param}.
|
||||
|
||||
@example
|
||||
/**
|
||||
* @@file
|
||||
* MPEG codec.
|
||||
* @@author ...
|
||||
*/
|
||||
|
||||
/**
|
||||
* Summary sentence.
|
||||
* more text ...
|
||||
* ...
|
||||
*/
|
||||
typedef struct Foobar @{
|
||||
int var1; /**< var1 description */
|
||||
int var2; ///< var2 description
|
||||
/** var3 description */
|
||||
int var3;
|
||||
@} Foobar;
|
||||
|
||||
/**
|
||||
* Summary sentence.
|
||||
* more text ...
|
||||
* ...
|
||||
* @@param my_parameter description of my_parameter
|
||||
* @@return return value description
|
||||
*/
|
||||
int myfunc(int my_parameter)
|
||||
...
|
||||
@end example
|
||||
|
||||
@section C language features
|
||||
|
||||
FFmpeg is programmed in the ISO C90 language with a few additional
|
||||
features from ISO C99, namely:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
the @samp{inline} keyword;
|
||||
|
||||
@item
|
||||
@samp{//} comments;
|
||||
|
||||
@item
|
||||
designated struct initializers (@samp{struct s x = @{ .i = 17 @};});
|
||||
|
||||
@item
|
||||
compound literals (@samp{x = (struct s) @{ 17, 23 @};}).
|
||||
|
||||
@item
|
||||
for loops with variable definition (@samp{for (int i = 0; i < 8; i++)});
|
||||
|
||||
@item
|
||||
Variadic macros (@samp{#define ARRAY(nb, ...) (int[nb + 1])@{ nb, __VA_ARGS__ @}});
|
||||
|
||||
@item
|
||||
Implementation defined behavior for signed integers is assumed to match the
|
||||
expected behavior for two's complement. Non representable values in integer
|
||||
casts are binary truncated. Shift right of signed values uses sign extension.
|
||||
@end itemize
|
||||
|
||||
These features are supported by all compilers we care about, so we will not
|
||||
accept patches to remove their use unless they absolutely do not impair
|
||||
clarity and performance.
|
||||
|
||||
All code must compile with recent versions of GCC and a number of other
|
||||
currently supported compilers. To ensure compatibility, please do not use
|
||||
additional C99 features or GCC extensions. Especially watch out for:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
mixing statements and declarations;
|
||||
|
||||
@item
|
||||
@samp{long long} (use @samp{int64_t} instead);
|
||||
|
||||
@item
|
||||
@samp{__attribute__} not protected by @samp{#ifdef __GNUC__} or similar;
|
||||
|
||||
@item
|
||||
GCC statement expressions (@samp{(x = (@{ int y = 4; y; @})}).
|
||||
@end itemize
|
||||
|
||||
@section Naming conventions
|
||||
All names should be composed with underscores (_), not CamelCase. For example,
|
||||
@samp{avfilter_get_video_buffer} is an acceptable function name and
|
||||
@samp{AVFilterGetVideo} is not. The exception from this are type names, like
|
||||
for example structs and enums; they should always be in CamelCase.
|
||||
|
||||
There are the following conventions for naming variables and functions:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
For local variables no prefix is required.
|
||||
|
||||
@item
|
||||
For file-scope variables and functions declared as @code{static}, no prefix
|
||||
is required.
|
||||
|
||||
@item
|
||||
For variables and functions visible outside of file scope, but only used
|
||||
internally by a library, an @code{ff_} prefix should be used,
|
||||
e.g. @samp{ff_w64_demuxer}.
|
||||
|
||||
@item
|
||||
For variables and functions visible outside of file scope, used internally
|
||||
across multiple libraries, use @code{avpriv_} as prefix, for example,
|
||||
@samp{avpriv_report_missing_feature}.
|
||||
|
||||
@item
|
||||
Each library has its own prefix for public symbols, in addition to the
|
||||
commonly used @code{av_} (@code{avformat_} for libavformat,
|
||||
@code{avcodec_} for libavcodec, @code{swr_} for libswresample, etc).
|
||||
Check the existing code and choose names accordingly.
|
||||
Note that some symbols without these prefixes are also exported for
|
||||
retro-compatibility reasons. These exceptions are declared in the
|
||||
@code{lib<name>/lib<name>.v} files.
|
||||
@end itemize
|
||||
|
||||
Furthermore, name space reserved for the system should not be invaded.
|
||||
Identifiers ending in @code{_t} are reserved by
|
||||
@url{http://pubs.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_02.html#tag_02_02_02, POSIX}.
|
||||
Also avoid names starting with @code{__} or @code{_} followed by an uppercase
|
||||
letter as they are reserved by the C standard. Names starting with @code{_}
|
||||
are reserved at the file level and may not be used for externally visible
|
||||
symbols. If in doubt, just avoid names starting with @code{_} altogether.
|
||||
|
||||
@section Miscellaneous conventions
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
fprintf and printf are forbidden in libavformat and libavcodec,
|
||||
please use av_log() instead.
|
||||
|
||||
@item
|
||||
Casts should be used only when necessary. Unneeded parentheses
|
||||
should also be avoided if they don't make the code easier to understand.
|
||||
@end itemize
|
||||
|
||||
@section Editor configuration
|
||||
In order to configure Vim to follow FFmpeg formatting conventions, paste
|
||||
the following snippet into your @file{.vimrc}:
|
||||
@example
|
||||
" indentation rules for FFmpeg: 4 spaces, no tabs
|
||||
set expandtab
|
||||
set shiftwidth=4
|
||||
set softtabstop=4
|
||||
set cindent
|
||||
set cinoptions=(0
|
||||
" Allow tabs in Makefiles.
|
||||
autocmd FileType make,automake set noexpandtab shiftwidth=8 softtabstop=8
|
||||
" Trailing whitespace and tabs are forbidden, so highlight them.
|
||||
highlight ForbiddenWhitespace ctermbg=red guibg=red
|
||||
match ForbiddenWhitespace /\s\+$\|\t/
|
||||
" Do not highlight spaces at the end of line while typing on that line.
|
||||
autocmd InsertEnter * match ForbiddenWhitespace /\t\|\s\+\%#\@@<!$/
|
||||
@end example
|
||||
|
||||
For Emacs, add these roughly equivalent lines to your @file{.emacs.d/init.el}:
|
||||
@lisp
|
||||
(c-add-style "ffmpeg"
|
||||
'("k&r"
|
||||
(c-basic-offset . 4)
|
||||
(indent-tabs-mode . nil)
|
||||
(show-trailing-whitespace . t)
|
||||
(c-offsets-alist
|
||||
(statement-cont . (c-lineup-assignments +)))
|
||||
)
|
||||
)
|
||||
(setq c-default-style "ffmpeg")
|
||||
@end lisp
|
||||
|
||||
@chapter Development Policy
|
||||
|
||||
@section Patches/Committing
|
||||
@subheading Licenses for patches must be compatible with FFmpeg.
|
||||
Contributions should be licensed under the
|
||||
@uref{http://www.gnu.org/licenses/lgpl-2.1.html, LGPL 2.1},
|
||||
including an "or any later version" clause, or, if you prefer
|
||||
a gift-style license, the
|
||||
@uref{http://opensource.org/licenses/isc-license.txt, ISC} or
|
||||
@uref{http://mit-license.org/, MIT} license.
|
||||
@uref{http://www.gnu.org/licenses/gpl-2.0.html, GPL 2} including
|
||||
an "or any later version" clause is also acceptable, but LGPL is
|
||||
preferred.
|
||||
If you add a new file, give it a proper license header. Do not copy and
|
||||
paste it from a random place, use an existing file as template.
|
||||
|
||||
@subheading You must not commit code which breaks FFmpeg!
|
||||
This means unfinished code which is enabled and breaks compilation,
|
||||
or compiles but does not work/breaks the regression tests. Code which
|
||||
is unfinished but disabled may be permitted under-circumstances, like
|
||||
missing samples or an implementation with a small subset of features.
|
||||
Always check the mailing list for any reviewers with issues and test
|
||||
FATE before you push.
|
||||
|
||||
@subheading Keep the main commit message short with an extended description below.
|
||||
The commit message should have a short first line in the form of
|
||||
a @samp{topic: short description} as a header, separated by a newline
|
||||
from the body consisting of an explanation of why the change is necessary.
|
||||
If the commit fixes a known bug on the bug tracker, the commit message
|
||||
should include its bug ID. Referring to the issue on the bug tracker does
|
||||
not exempt you from writing an excerpt of the bug in the commit message.
|
||||
|
||||
@subheading Testing must be adequate but not excessive.
|
||||
If it works for you, others, and passes FATE then it should be OK to commit
|
||||
it, provided it fits the other committing criteria. You should not worry about
|
||||
over-testing things. If your code has problems (portability, triggers
|
||||
compiler bugs, unusual environment etc) they will be reported and eventually
|
||||
fixed.
|
||||
|
||||
@subheading Do not commit unrelated changes together.
|
||||
They should be split them into self-contained pieces. Also do not forget
|
||||
that if part B depends on part A, but A does not depend on B, then A can
|
||||
and should be committed first and separate from B. Keeping changes well
|
||||
split into self-contained parts makes reviewing and understanding them on
|
||||
the commit log mailing list easier. This also helps in case of debugging
|
||||
later on.
|
||||
Also if you have doubts about splitting or not splitting, do not hesitate to
|
||||
ask/discuss it on the developer mailing list.
|
||||
|
||||
@subheading Ask before you change the build system (configure, etc).
|
||||
Do not commit changes to the build system (Makefiles, configure script)
|
||||
which change behavior, defaults etc, without asking first. The same
|
||||
applies to compiler warning fixes, trivial looking fixes and to code
|
||||
maintained by other developers. We usually have a reason for doing things
|
||||
the way we do. Send your changes as patches to the ffmpeg-devel mailing
|
||||
list, and if the code maintainers say OK, you may commit. This does not
|
||||
apply to files you wrote and/or maintain.
|
||||
|
||||
@subheading Cosmetic changes should be kept in separate patches.
|
||||
We refuse source indentation and other cosmetic changes if they are mixed
|
||||
with functional changes, such commits will be rejected and removed. Every
|
||||
developer has his own indentation style, you should not change it. Of course
|
||||
if you (re)write something, you can use your own style, even though we would
|
||||
prefer if the indentation throughout FFmpeg was consistent (Many projects
|
||||
force a given indentation style - we do not.). If you really need to make
|
||||
indentation changes (try to avoid this), separate them strictly from real
|
||||
changes.
|
||||
|
||||
NOTE: If you had to put if()@{ .. @} over a large (> 5 lines) chunk of code,
|
||||
then either do NOT change the indentation of the inner part within (do not
|
||||
move it to the right)! or do so in a separate commit
|
||||
|
||||
@subheading Commit messages should always be filled out properly.
|
||||
Always fill out the commit log message. Describe in a few lines what you
|
||||
changed and why. You can refer to mailing list postings if you fix a
|
||||
particular bug. Comments such as "fixed!" or "Changed it." are unacceptable.
|
||||
Recommended format:
|
||||
|
||||
@example
|
||||
area changed: Short 1 line description
|
||||
|
||||
details describing what and why and giving references.
|
||||
@end example
|
||||
|
||||
@subheading Credit the author of the patch.
|
||||
Make sure the author of the commit is set correctly. (see git commit --author)
|
||||
If you apply a patch, send an
|
||||
answer to ffmpeg-devel (or wherever you got the patch from) saying that
|
||||
you applied the patch.
|
||||
|
||||
@subheading Complex patches should refer to discussion surrounding them.
|
||||
When applying patches that have been discussed (at length) on the mailing
|
||||
list, reference the thread in the log message.
|
||||
|
||||
@subheading Always wait long enough before pushing changes
|
||||
Do NOT commit to code actively maintained by others without permission.
|
||||
Send a patch to ffmpeg-devel. If no one answers within a reasonable
|
||||
time-frame (12h for build failures and security fixes, 3 days small changes,
|
||||
1 week for big patches) then commit your patch if you think it is OK.
|
||||
Also note, the maintainer can simply ask for more time to review!
|
||||
|
||||
@section Code
|
||||
@subheading API/ABI changes should be discussed before they are made.
|
||||
Do not change behavior of the programs (renaming options etc) or public
|
||||
API or ABI without first discussing it on the ffmpeg-devel mailing list.
|
||||
Do not remove widely used functionality or features (redundant code can be removed).
|
||||
|
||||
@subheading Remember to check if you need to bump versions for libav*.
|
||||
Depending on the change, you may need to change the version integer.
|
||||
Incrementing the first component means no backward compatibility to
|
||||
previous versions (e.g. removal of a function from the public API).
|
||||
Incrementing the second component means backward compatible change
|
||||
(e.g. addition of a function to the public API or extension of an
|
||||
existing data structure).
|
||||
Incrementing the third component means a noteworthy binary compatible
|
||||
change (e.g. encoder bug fix that matters for the decoder). The third
|
||||
component always starts at 100 to distinguish FFmpeg from Libav.
|
||||
|
||||
@subheading Warnings for correct code may be disabled if there is no other option.
|
||||
Compiler warnings indicate potential bugs or code with bad style. If a type of
|
||||
warning always points to correct and clean code, that warning should
|
||||
be disabled, not the code changed.
|
||||
Thus the remaining warnings can either be bugs or correct code.
|
||||
If it is a bug, the bug has to be fixed. If it is not, the code should
|
||||
be changed to not generate a warning unless that causes a slowdown
|
||||
or obfuscates the code.
|
||||
|
||||
@subheading Check untrusted input properly.
|
||||
Never write to unallocated memory, never write over the end of arrays,
|
||||
always check values read from some untrusted source before using them
|
||||
as array index or other risky things.
|
||||
|
||||
@section Documentation/Other
|
||||
@subheading Subscribe to the ffmpeg-devel mailing list.
|
||||
It is important to be subscribed to the
|
||||
@uref{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel, ffmpeg-devel}
|
||||
mailing list. Almost any non-trivial patch is to be sent there for review.
|
||||
Other developers may have comments about your contribution. We expect you see
|
||||
those comments, and to improve it if requested. (N.B. Experienced committers
|
||||
have other channels, and may sometimes skip review for trivial fixes.) Also,
|
||||
discussion here about bug fixes and FFmpeg improvements by other developers may
|
||||
be helpful information for you. Finally, by being a list subscriber, your
|
||||
contribution will be posted immediately to the list, without the moderation
|
||||
hold which messages from non-subscribers experience.
|
||||
|
||||
However, it is more important to the project that we receive your patch than
|
||||
that you be subscribed to the ffmpeg-devel list. If you have a patch, and don't
|
||||
want to subscribe and discuss the patch, then please do send it to the list
|
||||
anyway.
|
||||
|
||||
@subheading Subscribe to the ffmpeg-cvslog mailing list.
|
||||
Diffs of all commits are sent to the
|
||||
@uref{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-cvslog, ffmpeg-cvslog}
|
||||
mailing list. Some developers read this list to review all code base changes
|
||||
from all sources. Subscribing to this list is not mandatory.
|
||||
|
||||
@subheading Keep the documentation up to date.
|
||||
Update the documentation if you change behavior or add features. If you are
|
||||
unsure how best to do this, send a patch to ffmpeg-devel, the documentation
|
||||
maintainer(s) will review and commit your stuff.
|
||||
|
||||
@subheading Important discussions should be accessible to all.
|
||||
Try to keep important discussions and requests (also) on the public
|
||||
developer mailing list, so that all developers can benefit from them.
|
||||
|
||||
@subheading Check your entries in MAINTAINERS.
|
||||
Make sure that no parts of the codebase that you maintain are missing from the
|
||||
@file{MAINTAINERS} file. If something that you want to maintain is missing add it with
|
||||
your name after it.
|
||||
If at some point you no longer want to maintain some code, then please help in
|
||||
finding a new maintainer and also don't forget to update the @file{MAINTAINERS} file.
|
||||
|
||||
We think our rules are not too hard. If you have comments, contact us.
|
||||
|
||||
@chapter Code of conduct
|
||||
|
||||
Be friendly and respectful towards others and third parties.
|
||||
Treat others the way you yourself want to be treated.
|
||||
|
||||
Be considerate. Not everyone shares the same viewpoint and priorities as you do.
|
||||
Different opinions and interpretations help the project.
|
||||
Looking at issues from a different perspective assists development.
|
||||
|
||||
Do not assume malice for things that can be attributed to incompetence. Even if
|
||||
it is malice, it's rarely good to start with that as initial assumption.
|
||||
|
||||
Stay friendly even if someone acts contrarily. Everyone has a bad day
|
||||
once in a while.
|
||||
If you yourself have a bad day or are angry then try to take a break and reply
|
||||
once you are calm and without anger if you have to.
|
||||
|
||||
Try to help other team members and cooperate if you can.
|
||||
|
||||
The goal of software development is to create technical excellence, not for any
|
||||
individual to be better and "win" against the others. Large software projects
|
||||
are only possible and successful through teamwork.
|
||||
|
||||
If someone struggles do not put them down. Give them a helping hand
|
||||
instead and point them in the right direction.
|
||||
|
||||
Finally, keep in mind the immortal words of Bill and Ted,
|
||||
"Be excellent to each other."
|
||||
|
||||
@anchor{Submitting patches}
|
||||
@chapter Submitting patches
|
||||
|
||||
First, read the @ref{Coding Rules} above if you did not yet, in particular
|
||||
the rules regarding patch submission.
|
||||
|
||||
When you submit your patch, please use @code{git format-patch} or
|
||||
@code{git send-email}. We cannot read other diffs :-).
|
||||
|
||||
Also please do not submit a patch which contains several unrelated changes.
|
||||
Split it into separate, self-contained pieces. This does not mean splitting
|
||||
file by file. Instead, make the patch as small as possible while still
|
||||
keeping it as a logical unit that contains an individual change, even
|
||||
if it spans multiple files. This makes reviewing your patches much easier
|
||||
for us and greatly increases your chances of getting your patch applied.
|
||||
|
||||
Use the patcheck tool of FFmpeg to check your patch.
|
||||
The tool is located in the tools directory.
|
||||
|
||||
Run the @ref{Regression tests} before submitting a patch in order to verify
|
||||
it does not cause unexpected problems.
|
||||
|
||||
It also helps quite a bit if you tell us what the patch does (for example
|
||||
'replaces lrint by lrintf'), and why (for example '*BSD isn't C99 compliant
|
||||
and has no lrint()')
|
||||
|
||||
Also please if you send several patches, send each patch as a separate mail,
|
||||
do not attach several unrelated patches to the same mail.
|
||||
|
||||
Patches should be posted to the
|
||||
@uref{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel, ffmpeg-devel}
|
||||
mailing list. Use @code{git send-email} when possible since it will properly
|
||||
send patches without requiring extra care. If you cannot, then send patches
|
||||
as base64-encoded attachments, so your patch is not trashed during
|
||||
transmission. Also ensure the correct mime type is used
|
||||
(text/x-diff or text/x-patch or at least text/plain) and that only one
|
||||
patch is inline or attached per mail.
|
||||
You can check @url{https://patchwork.ffmpeg.org}, if your patch does not show up, its mime type
|
||||
likely was wrong.
|
||||
|
||||
@subheading Sending patches from email clients
|
||||
Using @code{git send-email} might not be desirable for everyone. The
|
||||
following trick allows to send patches via email clients in a safe
|
||||
way. It has been tested with Outlook and Thunderbird (with X-Unsent
|
||||
extension) and might work with other applications.
|
||||
|
||||
Create your patch like this:
|
||||
|
||||
@verbatim
|
||||
git format-patch -s -o "outputfolder" --add-header "X-Unsent: 1" --suffix .eml --to [email protected] -1 1a2b3c4d
|
||||
@end verbatim
|
||||
|
||||
Now you'll just need to open the eml file with the email application
|
||||
and execute 'Send'.
|
||||
|
||||
@subheading Reviews
|
||||
Your patch will be reviewed on the mailing list. You will likely be asked
|
||||
to make some changes and are expected to send in an improved version that
|
||||
incorporates the requests from the review. This process may go through
|
||||
several iterations. Once your patch is deemed good enough, some developer
|
||||
will pick it up and commit it to the official FFmpeg tree.
|
||||
|
||||
Give us a few days to react. But if some time passes without reaction,
|
||||
send a reminder by email. Your patch should eventually be dealt with.
|
||||
|
||||
|
||||
@chapter New codecs or formats checklist
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Did you use av_cold for codec initialization and close functions?
|
||||
|
||||
@item
|
||||
Did you add a long_name under NULL_IF_CONFIG_SMALL to the AVCodec or
|
||||
AVInputFormat/AVOutputFormat struct?
|
||||
|
||||
@item
|
||||
Did you bump the minor version number (and reset the micro version
|
||||
number) in @file{libavcodec/version.h} or @file{libavformat/version.h}?
|
||||
|
||||
@item
|
||||
Did you register it in @file{allcodecs.c} or @file{allformats.c}?
|
||||
|
||||
@item
|
||||
Did you add the AVCodecID to @file{avcodec.h}?
|
||||
When adding new codec IDs, also add an entry to the codec descriptor
|
||||
list in @file{libavcodec/codec_desc.c}.
|
||||
|
||||
@item
|
||||
If it has a FourCC, did you add it to @file{libavformat/riff.c},
|
||||
even if it is only a decoder?
|
||||
|
||||
@item
|
||||
Did you add a rule to compile the appropriate files in the Makefile?
|
||||
Remember to do this even if you're just adding a format to a file that is
|
||||
already being compiled by some other rule, like a raw demuxer.
|
||||
|
||||
@item
|
||||
Did you add an entry to the table of supported formats or codecs in
|
||||
@file{doc/general.texi}?
|
||||
|
||||
@item
|
||||
Did you add an entry in the Changelog?
|
||||
|
||||
@item
|
||||
If it depends on a parser or a library, did you add that dependency in
|
||||
configure?
|
||||
|
||||
@item
|
||||
Did you @code{git add} the appropriate files before committing?
|
||||
|
||||
@item
|
||||
Did you make sure it compiles standalone, i.e. with
|
||||
@code{configure --disable-everything --enable-decoder=foo}
|
||||
(or @code{--enable-demuxer} or whatever your component is)?
|
||||
@end enumerate
|
||||
|
||||
|
||||
@chapter Patch submission checklist
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Does @code{make fate} pass with the patch applied?
|
||||
|
||||
@item
|
||||
Was the patch generated with git format-patch or send-email?
|
||||
|
||||
@item
|
||||
Did you sign-off your patch? (@code{git commit -s})
|
||||
See @uref{https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/process/submitting-patches.rst, Sign your work} for the meaning
|
||||
of @dfn{sign-off}.
|
||||
|
||||
@item
|
||||
Did you provide a clear git commit log message?
|
||||
|
||||
@item
|
||||
Is the patch against latest FFmpeg git master branch?
|
||||
|
||||
@item
|
||||
Are you subscribed to ffmpeg-devel?
|
||||
(the list is subscribers only due to spam)
|
||||
|
||||
@item
|
||||
Have you checked that the changes are minimal, so that the same cannot be
|
||||
achieved with a smaller patch and/or simpler final code?
|
||||
|
||||
@item
|
||||
If the change is to speed critical code, did you benchmark it?
|
||||
|
||||
@item
|
||||
If you did any benchmarks, did you provide them in the mail?
|
||||
|
||||
@item
|
||||
Have you checked that the patch does not introduce buffer overflows or
|
||||
other security issues?
|
||||
|
||||
@item
|
||||
Did you test your decoder or demuxer against damaged data? If no, see
|
||||
tools/trasher, the noise bitstream filter, and
|
||||
@uref{http://caca.zoy.org/wiki/zzuf, zzuf}. Your decoder or demuxer
|
||||
should not crash, end in a (near) infinite loop, or allocate ridiculous
|
||||
amounts of memory when fed damaged data.
|
||||
|
||||
@item
|
||||
Did you test your decoder or demuxer against sample files?
|
||||
Samples may be obtained at @url{https://samples.ffmpeg.org}.
|
||||
|
||||
@item
|
||||
Does the patch not mix functional and cosmetic changes?
|
||||
|
||||
@item
|
||||
Did you add tabs or trailing whitespace to the code? Both are forbidden.
|
||||
|
||||
@item
|
||||
Is the patch attached to the email you send?
|
||||
|
||||
@item
|
||||
Is the mime type of the patch correct? It should be text/x-diff or
|
||||
text/x-patch or at least text/plain and not application/octet-stream.
|
||||
|
||||
@item
|
||||
If the patch fixes a bug, did you provide a verbose analysis of the bug?
|
||||
|
||||
@item
|
||||
If the patch fixes a bug, did you provide enough information, including
|
||||
a sample, so the bug can be reproduced and the fix can be verified?
|
||||
Note please do not attach samples >100k to mails but rather provide a
|
||||
URL, you can upload to @url{https://streams.videolan.org/upload/}.
|
||||
|
||||
@item
|
||||
Did you provide a verbose summary about what the patch does change?
|
||||
|
||||
@item
|
||||
Did you provide a verbose explanation why it changes things like it does?
|
||||
|
||||
@item
|
||||
Did you provide a verbose summary of the user visible advantages and
|
||||
disadvantages if the patch is applied?
|
||||
|
||||
@item
|
||||
Did you provide an example so we can verify the new feature added by the
|
||||
patch easily?
|
||||
|
||||
@item
|
||||
If you added a new file, did you insert a license header? It should be
|
||||
taken from FFmpeg, not randomly copied and pasted from somewhere else.
|
||||
|
||||
@item
|
||||
You should maintain alphabetical order in alphabetically ordered lists as
|
||||
long as doing so does not break API/ABI compatibility.
|
||||
|
||||
@item
|
||||
Lines with similar content should be aligned vertically when doing so
|
||||
improves readability.
|
||||
|
||||
@item
|
||||
Consider adding a regression test for your code.
|
||||
|
||||
@item
|
||||
If you added YASM code please check that things still work with --disable-yasm.
|
||||
|
||||
@item
|
||||
Make sure you check the return values of function and return appropriate
|
||||
error codes. Especially memory allocation functions like @code{av_malloc()}
|
||||
are notoriously left unchecked, which is a serious problem.
|
||||
|
||||
@item
|
||||
Test your code with valgrind and or Address Sanitizer to ensure it's free
|
||||
of leaks, out of array accesses, etc.
|
||||
@end enumerate
|
||||
|
||||
@chapter Patch review process
|
||||
|
||||
All patches posted to ffmpeg-devel will be reviewed, unless they contain a
|
||||
clear note that the patch is not for the git master branch.
|
||||
Reviews and comments will be posted as replies to the patch on the
|
||||
mailing list. The patch submitter then has to take care of every comment,
|
||||
that can be by resubmitting a changed patch or by discussion. Resubmitted
|
||||
patches will themselves be reviewed like any other patch. If at some point
|
||||
a patch passes review with no comments then it is approved, that can for
|
||||
simple and small patches happen immediately while large patches will generally
|
||||
have to be changed and reviewed many times before they are approved.
|
||||
After a patch is approved it will be committed to the repository.
|
||||
|
||||
We will review all submitted patches, but sometimes we are quite busy so
|
||||
especially for large patches this can take several weeks.
|
||||
|
||||
If you feel that the review process is too slow and you are willing to try to
|
||||
take over maintainership of the area of code you change then just clone
|
||||
git master and maintain the area of code there. We will merge each area from
|
||||
where its best maintained.
|
||||
|
||||
When resubmitting patches, please do not make any significant changes
|
||||
not related to the comments received during review. Such patches will
|
||||
be rejected. Instead, submit significant changes or new features as
|
||||
separate patches.
|
||||
|
||||
Everyone is welcome to review patches. Also if you are waiting for your patch
|
||||
to be reviewed, please consider helping to review other patches, that is a great
|
||||
way to get everyone's patches reviewed sooner.
|
||||
|
||||
@anchor{Regression tests}
|
||||
@chapter Regression tests
|
||||
|
||||
Before submitting a patch (or committing to the repository), you should at least
|
||||
test that you did not break anything.
|
||||
|
||||
Running 'make fate' accomplishes this, please see @url{fate.html} for details.
|
||||
|
||||
[Of course, some patches may change the results of the regression tests. In
|
||||
this case, the reference results of the regression tests shall be modified
|
||||
accordingly].
|
||||
|
||||
@section Adding files to the fate-suite dataset
|
||||
|
||||
When there is no muxer or encoder available to generate test media for a
|
||||
specific test then the media has to be included in the fate-suite.
|
||||
First please make sure that the sample file is as small as possible to test the
|
||||
respective decoder or demuxer sufficiently. Large files increase network
|
||||
bandwidth and disk space requirements.
|
||||
Once you have a working fate test and fate sample, provide in the commit
|
||||
message or introductory message for the patch series that you post to
|
||||
the ffmpeg-devel mailing list, a direct link to download the sample media.
|
||||
|
||||
@section Visualizing Test Coverage
|
||||
|
||||
The FFmpeg build system allows visualizing the test coverage in an easy
|
||||
manner with the coverage tools @code{gcov}/@code{lcov}. This involves
|
||||
the following steps:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Configure to compile with instrumentation enabled:
|
||||
@code{configure --toolchain=gcov}.
|
||||
|
||||
@item
|
||||
Run your test case, either manually or via FATE. This can be either
|
||||
the full FATE regression suite, or any arbitrary invocation of any
|
||||
front-end tool provided by FFmpeg, in any combination.
|
||||
|
||||
@item
|
||||
Run @code{make lcov} to generate coverage data in HTML format.
|
||||
|
||||
@item
|
||||
View @code{lcov/index.html} in your preferred HTML viewer.
|
||||
@end enumerate
|
||||
|
||||
You can use the command @code{make lcov-reset} to reset the coverage
|
||||
measurements. You will need to rerun @code{make lcov} after running a
|
||||
new test.
|
||||
|
||||
@section Using Valgrind
|
||||
|
||||
The configure script provides a shortcut for using valgrind to spot bugs
|
||||
related to memory handling. Just add the option
|
||||
@code{--toolchain=valgrind-memcheck} or @code{--toolchain=valgrind-massif}
|
||||
to your configure line, and reasonable defaults will be set for running
|
||||
FATE under the supervision of either the @strong{memcheck} or the
|
||||
@strong{massif} tool of the valgrind suite.
|
||||
|
||||
In case you need finer control over how valgrind is invoked, use the
|
||||
@code{--target-exec='valgrind <your_custom_valgrind_options>} option in
|
||||
your configure line instead.
|
||||
|
||||
@anchor{Release process}
|
||||
@chapter Release process
|
||||
|
||||
FFmpeg maintains a set of @strong{release branches}, which are the
|
||||
recommended deliverable for system integrators and distributors (such as
|
||||
Linux distributions, etc.). At regular times, a @strong{release
|
||||
manager} prepares, tests and publishes tarballs on the
|
||||
@url{https://ffmpeg.org} website.
|
||||
|
||||
There are two kinds of releases:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
@strong{Major releases} always include the latest and greatest
|
||||
features and functionality.
|
||||
|
||||
@item
|
||||
@strong{Point releases} are cut from @strong{release} branches,
|
||||
which are named @code{release/X}, with @code{X} being the release
|
||||
version number.
|
||||
@end enumerate
|
||||
|
||||
Note that we promise to our users that shared libraries from any FFmpeg
|
||||
release never break programs that have been @strong{compiled} against
|
||||
previous versions of @strong{the same release series} in any case!
|
||||
|
||||
However, from time to time, we do make API changes that require adaptations
|
||||
in applications. Such changes are only allowed in (new) major releases and
|
||||
require further steps such as bumping library version numbers and/or
|
||||
adjustments to the symbol versioning file. Please discuss such changes
|
||||
on the @strong{ffmpeg-devel} mailing list in time to allow forward planning.
|
||||
|
||||
@anchor{Criteria for Point Releases}
|
||||
@section Criteria for Point Releases
|
||||
|
||||
Changes that match the following criteria are valid candidates for
|
||||
inclusion into a point release:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Fixes a security issue, preferably identified by a @strong{CVE
|
||||
number} issued by @url{http://cve.mitre.org/}.
|
||||
|
||||
@item
|
||||
Fixes a documented bug in @url{https://trac.ffmpeg.org}.
|
||||
|
||||
@item
|
||||
Improves the included documentation.
|
||||
|
||||
@item
|
||||
Retains both source code and binary compatibility with previous
|
||||
point releases of the same release branch.
|
||||
@end enumerate
|
||||
|
||||
The order for checking the rules is (1 OR 2 OR 3) AND 4.
|
||||
|
||||
|
||||
@section Release Checklist
|
||||
|
||||
The release process involves the following steps:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Ensure that the @file{RELEASE} file contains the version number for
|
||||
the upcoming release.
|
||||
|
||||
@item
|
||||
Add the release at @url{https://trac.ffmpeg.org/admin/ticket/versions}.
|
||||
|
||||
@item
|
||||
Announce the intent to do a release to the mailing list.
|
||||
|
||||
@item
|
||||
Make sure all relevant security fixes have been backported. See
|
||||
@url{https://ffmpeg.org/security.html}.
|
||||
|
||||
@item
|
||||
Ensure that the FATE regression suite still passes in the release
|
||||
branch on at least @strong{i386} and @strong{amd64}
|
||||
(cf. @ref{Regression tests}).
|
||||
|
||||
@item
|
||||
Prepare the release tarballs in @code{bz2} and @code{gz} formats, and
|
||||
supplementing files that contain @code{gpg} signatures
|
||||
|
||||
@item
|
||||
Publish the tarballs at @url{https://ffmpeg.org/releases}. Create and
|
||||
push an annotated tag in the form @code{nX}, with @code{X}
|
||||
containing the version number.
|
||||
|
||||
@item
|
||||
Propose and send a patch to the @strong{ffmpeg-devel} mailing list
|
||||
with a news entry for the website.
|
||||
|
||||
@item
|
||||
Publish the news entry.
|
||||
|
||||
@item
|
||||
Send an announcement to the mailing list.
|
||||
@end enumerate
|
||||
|
||||
@bye
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
@chapter Device Options
|
||||
@c man begin DEVICE OPTIONS
|
||||
|
||||
The libavdevice library provides the same interface as
|
||||
libavformat. Namely, an input device is considered like a demuxer, and
|
||||
an output device like a muxer, and the interface and generic device
|
||||
options are the same provided by libavformat (see the ffmpeg-formats
|
||||
manual).
|
||||
|
||||
In addition each input or output device may support so-called private
|
||||
options, which are specific for that component.
|
||||
|
||||
Options may be set by specifying -@var{option} @var{value} in the
|
||||
FFmpeg tools, or by setting the value explicitly in the device
|
||||
@code{AVFormatContext} options or using the @file{libavutil/opt.h} API
|
||||
for programmatic use.
|
||||
|
||||
@c man end DEVICE OPTIONS
|
||||
|
||||
@ifclear config-writeonly
|
||||
@include indevs.texi
|
||||
@end ifclear
|
||||
@ifclear config-readonly
|
||||
@include outdevs.texi
|
||||
@end ifclear
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
OUT_DIR="${1}"
|
||||
SRC_DIR="${2}"
|
||||
DOXYFILE="${3}"
|
||||
DOXYGEN="${4}"
|
||||
|
||||
shift 4
|
||||
|
||||
cd ${SRC_DIR}
|
||||
|
||||
if [ -e "VERSION" ]; then
|
||||
VERSION=`cat "VERSION"`
|
||||
else
|
||||
VERSION=`git describe`
|
||||
fi
|
||||
|
||||
$DOXYGEN - <<EOF
|
||||
@INCLUDE = ${DOXYFILE}
|
||||
INPUT = $@
|
||||
HTML_TIMESTAMP = NO
|
||||
PROJECT_NUMBER = $VERSION
|
||||
OUTPUT_DIRECTORY = $OUT_DIR
|
||||
EOF
|
||||
Vendored
+3535
File diff suppressed because it is too large
Load Diff
Vendored
+174
@@ -0,0 +1,174 @@
|
||||
The following table lists most error codes found in various operating
|
||||
systems supported by FFmpeg.
|
||||
|
||||
OS
|
||||
Code Std F LBMWwb Text (YMMV)
|
||||
|
||||
E2BIG POSIX ++++++ Argument list too long
|
||||
EACCES POSIX ++++++ Permission denied
|
||||
EADDRINUSE POSIX +++..+ Address in use
|
||||
EADDRNOTAVAIL POSIX +++..+ Cannot assign requested address
|
||||
EADV +..... Advertise error
|
||||
EAFNOSUPPORT POSIX +++..+ Address family not supported
|
||||
EAGAIN POSIX + ++++++ Resource temporarily unavailable
|
||||
EALREADY POSIX +++..+ Operation already in progress
|
||||
EAUTH .++... Authentication error
|
||||
EBADARCH ..+... Bad CPU type in executable
|
||||
EBADE +..... Invalid exchange
|
||||
EBADEXEC ..+... Bad executable
|
||||
EBADF POSIX ++++++ Bad file descriptor
|
||||
EBADFD +..... File descriptor in bad state
|
||||
EBADMACHO ..+... Malformed Macho file
|
||||
EBADMSG POSIX ++4... Bad message
|
||||
EBADR +..... Invalid request descriptor
|
||||
EBADRPC .++... RPC struct is bad
|
||||
EBADRQC +..... Invalid request code
|
||||
EBADSLT +..... Invalid slot
|
||||
EBFONT +..... Bad font file format
|
||||
EBUSY POSIX - ++++++ Device or resource busy
|
||||
ECANCELED POSIX +++... Operation canceled
|
||||
ECHILD POSIX ++++++ No child processes
|
||||
ECHRNG +..... Channel number out of range
|
||||
ECOMM +..... Communication error on send
|
||||
ECONNABORTED POSIX +++..+ Software caused connection abort
|
||||
ECONNREFUSED POSIX - +++ss+ Connection refused
|
||||
ECONNRESET POSIX +++..+ Connection reset
|
||||
EDEADLK POSIX ++++++ Resource deadlock avoided
|
||||
EDEADLOCK +..++. File locking deadlock error
|
||||
EDESTADDRREQ POSIX +++... Destination address required
|
||||
EDEVERR ..+... Device error
|
||||
EDOM C89 - ++++++ Numerical argument out of domain
|
||||
EDOOFUS .F.... Programming error
|
||||
EDOTDOT +..... RFS specific error
|
||||
EDQUOT POSIX +++... Disc quota exceeded
|
||||
EEXIST POSIX ++++++ File exists
|
||||
EFAULT POSIX - ++++++ Bad address
|
||||
EFBIG POSIX - ++++++ File too large
|
||||
EFTYPE .++... Inappropriate file type or format
|
||||
EHOSTDOWN +++... Host is down
|
||||
EHOSTUNREACH POSIX +++..+ No route to host
|
||||
EHWPOISON +..... Memory page has hardware error
|
||||
EIDRM POSIX +++... Identifier removed
|
||||
EILSEQ C99 ++++++ Illegal byte sequence
|
||||
EINPROGRESS POSIX - +++ss+ Operation in progress
|
||||
EINTR POSIX - ++++++ Interrupted system call
|
||||
EINVAL POSIX + ++++++ Invalid argument
|
||||
EIO POSIX + ++++++ I/O error
|
||||
EISCONN POSIX +++..+ Socket is already connected
|
||||
EISDIR POSIX ++++++ Is a directory
|
||||
EISNAM +..... Is a named type file
|
||||
EKEYEXPIRED +..... Key has expired
|
||||
EKEYREJECTED +..... Key was rejected by service
|
||||
EKEYREVOKED +..... Key has been revoked
|
||||
EL2HLT +..... Level 2 halted
|
||||
EL2NSYNC +..... Level 2 not synchronized
|
||||
EL3HLT +..... Level 3 halted
|
||||
EL3RST +..... Level 3 reset
|
||||
ELIBACC +..... Can not access a needed shared library
|
||||
ELIBBAD +..... Accessing a corrupted shared library
|
||||
ELIBEXEC +..... Cannot exec a shared library directly
|
||||
ELIBMAX +..... Too many shared libraries
|
||||
ELIBSCN +..... .lib section in a.out corrupted
|
||||
ELNRNG +..... Link number out of range
|
||||
ELOOP POSIX +++..+ Too many levels of symbolic links
|
||||
EMEDIUMTYPE +..... Wrong medium type
|
||||
EMFILE POSIX ++++++ Too many open files
|
||||
EMLINK POSIX ++++++ Too many links
|
||||
EMSGSIZE POSIX +++..+ Message too long
|
||||
EMULTIHOP POSIX ++4... Multihop attempted
|
||||
ENAMETOOLONG POSIX - ++++++ File name too long
|
||||
ENAVAIL +..... No XENIX semaphores available
|
||||
ENEEDAUTH .++... Need authenticator
|
||||
ENETDOWN POSIX +++..+ Network is down
|
||||
ENETRESET SUSv3 +++..+ Network dropped connection on reset
|
||||
ENETUNREACH POSIX +++..+ Network unreachable
|
||||
ENFILE POSIX ++++++ Too many open files in system
|
||||
ENOANO +..... No anode
|
||||
ENOATTR .++... Attribute not found
|
||||
ENOBUFS POSIX - +++..+ No buffer space available
|
||||
ENOCSI +..... No CSI structure available
|
||||
ENODATA XSR +N4... No message available
|
||||
ENODEV POSIX - ++++++ No such device
|
||||
ENOENT POSIX - ++++++ No such file or directory
|
||||
ENOEXEC POSIX ++++++ Exec format error
|
||||
ENOFILE ...++. No such file or directory
|
||||
ENOKEY +..... Required key not available
|
||||
ENOLCK POSIX ++++++ No locks available
|
||||
ENOLINK POSIX ++4... Link has been severed
|
||||
ENOMEDIUM +..... No medium found
|
||||
ENOMEM POSIX ++++++ Not enough space
|
||||
ENOMSG POSIX +++..+ No message of desired type
|
||||
ENONET +..... Machine is not on the network
|
||||
ENOPKG +..... Package not installed
|
||||
ENOPROTOOPT POSIX +++..+ Protocol not available
|
||||
ENOSPC POSIX ++++++ No space left on device
|
||||
ENOSR XSR +N4... No STREAM resources
|
||||
ENOSTR XSR +N4... Not a STREAM
|
||||
ENOSYS POSIX + ++++++ Function not implemented
|
||||
ENOTBLK +++... Block device required
|
||||
ENOTCONN POSIX +++..+ Socket is not connected
|
||||
ENOTDIR POSIX ++++++ Not a directory
|
||||
ENOTEMPTY POSIX ++++++ Directory not empty
|
||||
ENOTNAM +..... Not a XENIX named type file
|
||||
ENOTRECOVERABLE SUSv4 - +..... State not recoverable
|
||||
ENOTSOCK POSIX +++..+ Socket operation on non-socket
|
||||
ENOTSUP POSIX +++... Operation not supported
|
||||
ENOTTY POSIX ++++++ Inappropriate I/O control operation
|
||||
ENOTUNIQ +..... Name not unique on network
|
||||
ENXIO POSIX ++++++ No such device or address
|
||||
EOPNOTSUPP POSIX +++..+ Operation not supported (on socket)
|
||||
EOVERFLOW POSIX +++..+ Value too large to be stored in data type
|
||||
EOWNERDEAD SUSv4 +..... Owner died
|
||||
EPERM POSIX - ++++++ Operation not permitted
|
||||
EPFNOSUPPORT +++..+ Protocol family not supported
|
||||
EPIPE POSIX - ++++++ Broken pipe
|
||||
EPROCLIM .++... Too many processes
|
||||
EPROCUNAVAIL .++... Bad procedure for program
|
||||
EPROGMISMATCH .++... Program version wrong
|
||||
EPROGUNAVAIL .++... RPC prog. not avail
|
||||
EPROTO POSIX ++4... Protocol error
|
||||
EPROTONOSUPPORT POSIX - +++ss+ Protocol not supported
|
||||
EPROTOTYPE POSIX +++..+ Protocol wrong type for socket
|
||||
EPWROFF ..+... Device power is off
|
||||
ERANGE C89 - ++++++ Result too large
|
||||
EREMCHG +..... Remote address changed
|
||||
EREMOTE +++... Object is remote
|
||||
EREMOTEIO +..... Remote I/O error
|
||||
ERESTART +..... Interrupted system call should be restarted
|
||||
ERFKILL +..... Operation not possible due to RF-kill
|
||||
EROFS POSIX ++++++ Read-only file system
|
||||
ERPCMISMATCH .++... RPC version wrong
|
||||
ESHLIBVERS ..+... Shared library version mismatch
|
||||
ESHUTDOWN +++..+ Cannot send after socket shutdown
|
||||
ESOCKTNOSUPPORT +++... Socket type not supported
|
||||
ESPIPE POSIX ++++++ Illegal seek
|
||||
ESRCH POSIX ++++++ No such process
|
||||
ESRMNT +..... Srmount error
|
||||
ESTALE POSIX +++..+ Stale NFS file handle
|
||||
ESTRPIPE +..... Streams pipe error
|
||||
ETIME XSR +N4... Stream ioctl timeout
|
||||
ETIMEDOUT POSIX - +++ss+ Connection timed out
|
||||
ETOOMANYREFS +++... Too many references: cannot splice
|
||||
ETXTBSY POSIX +++... Text file busy
|
||||
EUCLEAN +..... Structure needs cleaning
|
||||
EUNATCH +..... Protocol driver not attached
|
||||
EUSERS +++... Too many users
|
||||
EWOULDBLOCK POSIX +++..+ Operation would block
|
||||
EXDEV POSIX ++++++ Cross-device link
|
||||
EXFULL +..... Exchange full
|
||||
|
||||
Notations:
|
||||
|
||||
F: used in FFmpeg (-: a few times, +: a lot)
|
||||
|
||||
SUSv3: Single Unix Specification, version 3
|
||||
SUSv4: Single Unix Specification, version 4
|
||||
XSR: XSI STREAMS (obsolete)
|
||||
|
||||
OS: availability on some supported operating systems
|
||||
L: GNU/Linux
|
||||
B: BSD (F: FreeBSD, N: NetBSD)
|
||||
M: MacOS X
|
||||
W: Microsoft Windows (s: emulated with winsock, see libavformat/network.h)
|
||||
w: Mingw32 (3.17) and Mingw64 (2.0.1)
|
||||
b: BeOS
|
||||
Vendored
+64
@@ -0,0 +1,64 @@
|
||||
EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
|
||||
EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
|
||||
EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio
|
||||
EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video
|
||||
EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
|
||||
EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio
|
||||
EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video
|
||||
EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs
|
||||
EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio
|
||||
EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio
|
||||
EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE) += filtering_video
|
||||
EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE) += http_multiclient
|
||||
EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
|
||||
EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata
|
||||
EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing
|
||||
EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec
|
||||
EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing
|
||||
EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio
|
||||
EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
|
||||
EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
|
||||
EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE) += transcoding
|
||||
EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE) += vaapi_encode
|
||||
EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE) += vaapi_transcode
|
||||
|
||||
EXAMPLES := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
||||
EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
|
||||
ALL_EXAMPLES := $(EXAMPLES) $(EXAMPLES-:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
||||
ALL_EXAMPLES_G := $(EXAMPLES_G) $(EXAMPLES-:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
|
||||
PROGS += $(EXAMPLES)
|
||||
|
||||
EXAMPLE_MAKEFILE := $(SRC_PATH)/doc/examples/Makefile
|
||||
EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/README $(EXAMPLE_MAKEFILE)
|
||||
|
||||
$(foreach P,$(EXAMPLES),$(eval OBJS-$(P:%$(PROGSSUF)$(EXESUF)=%) = $(P:%$(PROGSSUF)$(EXESUF)=%).o))
|
||||
$(EXAMPLES_G): %$(PROGSSUF)_g$(EXESUF): %.o
|
||||
|
||||
examples: $(EXAMPLES)
|
||||
|
||||
$(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.o): | doc/examples
|
||||
OUTDIRS += doc/examples
|
||||
|
||||
DOXY_INPUT += $(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.c)
|
||||
|
||||
install: install-examples
|
||||
|
||||
install-examples: $(EXAMPLES_FILES)
|
||||
$(Q)mkdir -p "$(DATADIR)/examples"
|
||||
$(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples"
|
||||
$(INSTALL) -m 644 $(EXAMPLE_MAKEFILE:%=%.example) "$(DATADIR)/examples/Makefile"
|
||||
|
||||
uninstall: uninstall-examples
|
||||
|
||||
uninstall-examples:
|
||||
$(RM) -r "$(DATADIR)/examples"
|
||||
|
||||
examplesclean:
|
||||
$(RM) $(ALL_EXAMPLES) $(ALL_EXAMPLES_G)
|
||||
$(RM) $(CLEANSUFFIXES:%=doc/examples/%)
|
||||
|
||||
docclean:: examplesclean
|
||||
|
||||
-include $(wildcard $(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.d))
|
||||
|
||||
.PHONY: examples
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
# use pkg-config for getting CFLAGS and LDLIBS
|
||||
FFMPEG_LIBS= libavdevice \
|
||||
libavformat \
|
||||
libavfilter \
|
||||
libavcodec \
|
||||
libswresample \
|
||||
libswscale \
|
||||
libavutil \
|
||||
|
||||
CFLAGS += -Wall -g
|
||||
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
|
||||
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
|
||||
|
||||
EXAMPLES= avio_list_dir \
|
||||
avio_reading \
|
||||
decode_audio \
|
||||
decode_video \
|
||||
demuxing_decoding \
|
||||
encode_audio \
|
||||
encode_video \
|
||||
extract_mvs \
|
||||
filtering_video \
|
||||
filtering_audio \
|
||||
http_multiclient \
|
||||
hw_decode \
|
||||
metadata \
|
||||
muxing \
|
||||
remuxing \
|
||||
resampling_audio \
|
||||
scaling_video \
|
||||
transcode_aac \
|
||||
transcoding \
|
||||
|
||||
OBJS=$(addsuffix .o,$(EXAMPLES))
|
||||
|
||||
# the following examples make explicit use of the math library
|
||||
avcodec: LDLIBS += -lm
|
||||
encode_audio: LDLIBS += -lm
|
||||
muxing: LDLIBS += -lm
|
||||
resampling_audio: LDLIBS += -lm
|
||||
|
||||
.phony: all clean-test clean
|
||||
|
||||
all: $(OBJS) $(EXAMPLES)
|
||||
|
||||
clean-test:
|
||||
$(RM) test*.pgm test.h264 test.mp2 test.sw test.mpg
|
||||
|
||||
clean: clean-test
|
||||
$(RM) $(EXAMPLES) $(OBJS)
|
||||
Vendored
+9
-4
@@ -5,14 +5,19 @@ Both following use cases rely on pkg-config and make, thus make sure
|
||||
that you have them installed and working on your system.
|
||||
|
||||
|
||||
1) Build the installed examples in a generic read/write user directory
|
||||
Method 1: build the installed examples in a generic read/write user directory
|
||||
|
||||
Copy to a read/write user directory and just use "make", it will link
|
||||
to the libraries on your system, assuming the PKG_CONFIG_PATH is
|
||||
correctly configured.
|
||||
|
||||
2) Build the examples in-tree
|
||||
Method 2: build the examples in-tree
|
||||
|
||||
Assuming you are in the source FFmpeg checkout directory, you need to build
|
||||
FFmpeg (no need to make install in any prefix). Then you can go into
|
||||
doc/examples and run a command such as PKG_CONFIG_PATH=pc-uninstalled make.
|
||||
FFmpeg (no need to make install in any prefix). Then just run "make examples".
|
||||
This will build the examples using the FFmpeg build system. You can clean those
|
||||
examples using "make examplesclean"
|
||||
|
||||
If you want to try the dedicated Makefile examples (to emulate the first
|
||||
method), go into doc/examples and run a command such as
|
||||
PKG_CONFIG_PATH=pc-uninstalled make.
|
||||
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Lukasz Marek
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavformat/avio.h>
|
||||
|
||||
static const char *type_string(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case AVIO_ENTRY_DIRECTORY:
|
||||
return "<DIR>";
|
||||
case AVIO_ENTRY_FILE:
|
||||
return "<FILE>";
|
||||
case AVIO_ENTRY_BLOCK_DEVICE:
|
||||
return "<BLOCK DEVICE>";
|
||||
case AVIO_ENTRY_CHARACTER_DEVICE:
|
||||
return "<CHARACTER DEVICE>";
|
||||
case AVIO_ENTRY_NAMED_PIPE:
|
||||
return "<PIPE>";
|
||||
case AVIO_ENTRY_SYMBOLIC_LINK:
|
||||
return "<LINK>";
|
||||
case AVIO_ENTRY_SOCKET:
|
||||
return "<SOCKET>";
|
||||
case AVIO_ENTRY_SERVER:
|
||||
return "<SERVER>";
|
||||
case AVIO_ENTRY_SHARE:
|
||||
return "<SHARE>";
|
||||
case AVIO_ENTRY_WORKGROUP:
|
||||
return "<WORKGROUP>";
|
||||
case AVIO_ENTRY_UNKNOWN:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "<UNKNOWN>";
|
||||
}
|
||||
|
||||
static int list_op(const char *input_dir)
|
||||
{
|
||||
AVIODirEntry *entry = NULL;
|
||||
AVIODirContext *ctx = NULL;
|
||||
int cnt, ret;
|
||||
char filemode[4], uid_and_gid[20];
|
||||
|
||||
if ((ret = avio_open_dir(&ctx, input_dir, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open directory: %s.\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
cnt = 0;
|
||||
for (;;) {
|
||||
if ((ret = avio_read_dir(ctx, &entry)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot list directory: %s.\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
if (!entry)
|
||||
break;
|
||||
if (entry->filemode == -1) {
|
||||
snprintf(filemode, 4, "???");
|
||||
} else {
|
||||
snprintf(filemode, 4, "%3"PRIo64, entry->filemode);
|
||||
}
|
||||
snprintf(uid_and_gid, 20, "%"PRId64"(%"PRId64")", entry->user_id, entry->group_id);
|
||||
if (cnt == 0)
|
||||
av_log(NULL, AV_LOG_INFO, "%-9s %12s %30s %10s %s %16s %16s %16s\n",
|
||||
"TYPE", "SIZE", "NAME", "UID(GID)", "UGO", "MODIFIED",
|
||||
"ACCESSED", "STATUS_CHANGED");
|
||||
av_log(NULL, AV_LOG_INFO, "%-9s %12"PRId64" %30s %10s %s %16"PRId64" %16"PRId64" %16"PRId64"\n",
|
||||
type_string(entry->type),
|
||||
entry->size,
|
||||
entry->name,
|
||||
uid_and_gid,
|
||||
filemode,
|
||||
entry->modification_timestamp,
|
||||
entry->access_timestamp,
|
||||
entry->status_change_timestamp);
|
||||
avio_free_directory_entry(&entry);
|
||||
cnt++;
|
||||
};
|
||||
|
||||
fail:
|
||||
avio_close_dir(&ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void usage(const char *program_name)
|
||||
{
|
||||
fprintf(stderr, "usage: %s input_dir\n"
|
||||
"API example program to show how to list files in directory "
|
||||
"accessed through AVIOContext.\n", program_name);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
av_log_set_level(AV_LOG_DEBUG);
|
||||
|
||||
if (argc < 2) {
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
avformat_network_init();
|
||||
|
||||
ret = list_op(argv[1]);
|
||||
|
||||
avformat_network_deinit();
|
||||
|
||||
return ret < 0 ? 1 : 0;
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Stefano Sabatini
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* libavformat AVIOContext API example.
|
||||
*
|
||||
* Make libavformat demuxer access media content through a custom
|
||||
* AVIOContext read callback.
|
||||
* @example avio_reading.c
|
||||
*/
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavformat/avio.h>
|
||||
#include <libavutil/file.h>
|
||||
|
||||
struct buffer_data {
|
||||
uint8_t *ptr;
|
||||
size_t size; ///< size left in the buffer
|
||||
};
|
||||
|
||||
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
|
||||
{
|
||||
struct buffer_data *bd = (struct buffer_data *)opaque;
|
||||
buf_size = FFMIN(buf_size, bd->size);
|
||||
|
||||
if (!buf_size)
|
||||
return AVERROR_EOF;
|
||||
printf("ptr:%p size:%zu\n", bd->ptr, bd->size);
|
||||
|
||||
/* copy internal buffer data to buf */
|
||||
memcpy(buf, bd->ptr, buf_size);
|
||||
bd->ptr += buf_size;
|
||||
bd->size -= buf_size;
|
||||
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
AVFormatContext *fmt_ctx = NULL;
|
||||
AVIOContext *avio_ctx = NULL;
|
||||
uint8_t *buffer = NULL, *avio_ctx_buffer = NULL;
|
||||
size_t buffer_size, avio_ctx_buffer_size = 4096;
|
||||
char *input_filename = NULL;
|
||||
int ret = 0;
|
||||
struct buffer_data bd = { 0 };
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s input_file\n"
|
||||
"API example program to show how to read from a custom buffer "
|
||||
"accessed through AVIOContext.\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
input_filename = argv[1];
|
||||
|
||||
/* slurp file content into buffer */
|
||||
ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
/* fill opaque structure used by the AVIOContext read callback */
|
||||
bd.ptr = buffer;
|
||||
bd.size = buffer_size;
|
||||
|
||||
if (!(fmt_ctx = avformat_alloc_context())) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
avio_ctx_buffer = av_malloc(avio_ctx_buffer_size);
|
||||
if (!avio_ctx_buffer) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,
|
||||
0, &bd, &read_packet, NULL, NULL);
|
||||
if (!avio_ctx) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
fmt_ctx->pb = avio_ctx;
|
||||
|
||||
ret = avformat_open_input(&fmt_ctx, NULL, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open input\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avformat_find_stream_info(fmt_ctx, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not find stream information\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
av_dump_format(fmt_ctx, 0, input_filename, 0);
|
||||
|
||||
end:
|
||||
avformat_close_input(&fmt_ctx);
|
||||
|
||||
/* note: the internal buffer could have changed, and be != avio_ctx_buffer */
|
||||
if (avio_ctx)
|
||||
av_freep(&avio_ctx->buffer);
|
||||
avio_context_free(&avio_ctx);
|
||||
|
||||
av_file_unmap(buffer, buffer_size);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* audio decoding with libavcodec API example
|
||||
*
|
||||
* @example decode_audio.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libavutil/frame.h>
|
||||
#include <libavutil/mem.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#define AUDIO_INBUF_SIZE 20480
|
||||
#define AUDIO_REFILL_THRESH 4096
|
||||
|
||||
static int get_format_from_sample_fmt(const char **fmt,
|
||||
enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
int i;
|
||||
struct sample_fmt_entry {
|
||||
enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
|
||||
} sample_fmt_entries[] = {
|
||||
{ AV_SAMPLE_FMT_U8, "u8", "u8" },
|
||||
{ AV_SAMPLE_FMT_S16, "s16be", "s16le" },
|
||||
{ AV_SAMPLE_FMT_S32, "s32be", "s32le" },
|
||||
{ AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
|
||||
{ AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
|
||||
};
|
||||
*fmt = NULL;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
|
||||
struct sample_fmt_entry *entry = &sample_fmt_entries[i];
|
||||
if (sample_fmt == entry->sample_fmt) {
|
||||
*fmt = AV_NE(entry->fmt_be, entry->fmt_le);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"sample format %s is not supported as output format\n",
|
||||
av_get_sample_fmt_name(sample_fmt));
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame,
|
||||
FILE *outfile)
|
||||
{
|
||||
int i, ch;
|
||||
int ret, data_size;
|
||||
|
||||
/* send the packet with the compressed data to the decoder */
|
||||
ret = avcodec_send_packet(dec_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error submitting the packet to the decoder\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* read all the output frames (in general there may be any number of them */
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);
|
||||
if (data_size < 0) {
|
||||
/* This should not occur, checking just for paranoia */
|
||||
fprintf(stderr, "Failed to calculate data size\n");
|
||||
exit(1);
|
||||
}
|
||||
for (i = 0; i < frame->nb_samples; i++)
|
||||
for (ch = 0; ch < dec_ctx->channels; ch++)
|
||||
fwrite(frame->data[ch] + data_size*i, 1, data_size, outfile);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *outfilename, *filename;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
AVCodecParserContext *parser = NULL;
|
||||
int len, ret;
|
||||
FILE *f, *outfile;
|
||||
uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
uint8_t *data;
|
||||
size_t data_size;
|
||||
AVPacket *pkt;
|
||||
AVFrame *decoded_frame = NULL;
|
||||
enum AVSampleFormat sfmt;
|
||||
int n_channels = 0;
|
||||
const char *fmt;
|
||||
|
||||
if (argc <= 2) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
filename = argv[1];
|
||||
outfilename = argv[2];
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
|
||||
/* find the MPEG audio decoder */
|
||||
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
parser = av_parser_init(codec->id);
|
||||
if (!parser) {
|
||||
fprintf(stderr, "Parser not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate audio codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
outfile = fopen(outfilename, "wb");
|
||||
if (!outfile) {
|
||||
av_free(c);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* decode until eof */
|
||||
data = inbuf;
|
||||
data_size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
||||
|
||||
while (data_size > 0) {
|
||||
if (!decoded_frame) {
|
||||
if (!(decoded_frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
|
||||
data, data_size,
|
||||
AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while parsing\n");
|
||||
exit(1);
|
||||
}
|
||||
data += ret;
|
||||
data_size -= ret;
|
||||
|
||||
if (pkt->size)
|
||||
decode(c, pkt, decoded_frame, outfile);
|
||||
|
||||
if (data_size < AUDIO_REFILL_THRESH) {
|
||||
memmove(inbuf, data, data_size);
|
||||
data = inbuf;
|
||||
len = fread(data + data_size, 1,
|
||||
AUDIO_INBUF_SIZE - data_size, f);
|
||||
if (len > 0)
|
||||
data_size += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* flush the decoder */
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
decode(c, pkt, decoded_frame, outfile);
|
||||
|
||||
/* print output pcm infomations, because there have no metadata of pcm */
|
||||
sfmt = c->sample_fmt;
|
||||
|
||||
if (av_sample_fmt_is_planar(sfmt)) {
|
||||
const char *packed = av_get_sample_fmt_name(sfmt);
|
||||
printf("Warning: the sample format the decoder produced is planar "
|
||||
"(%s). This example will output the first channel only.\n",
|
||||
packed ? packed : "?");
|
||||
sfmt = av_get_packed_sample_fmt(sfmt);
|
||||
}
|
||||
|
||||
n_channels = c->channels;
|
||||
if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
|
||||
goto end;
|
||||
|
||||
printf("Play the output audio file with the command:\n"
|
||||
"ffplay -f %s -ac %d -ar %d %s\n",
|
||||
fmt, n_channels, c->sample_rate,
|
||||
outfilename);
|
||||
end:
|
||||
fclose(outfile);
|
||||
fclose(f);
|
||||
|
||||
avcodec_free_context(&c);
|
||||
av_parser_close(parser);
|
||||
av_frame_free(&decoded_frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* video decoding with libavcodec API example
|
||||
*
|
||||
* @example decode_video.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#define INBUF_SIZE 4096
|
||||
|
||||
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
|
||||
char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
|
||||
f = fopen(filename,"wb");
|
||||
fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
|
||||
for (i = 0; i < ysize; i++)
|
||||
fwrite(buf + i * wrap, 1, xsize, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
|
||||
const char *filename)
|
||||
{
|
||||
char buf[1024];
|
||||
int ret;
|
||||
|
||||
ret = avcodec_send_packet(dec_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error sending a packet for decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("saving frame %3d\n", dec_ctx->frame_number);
|
||||
fflush(stdout);
|
||||
|
||||
/* the picture is allocated by the decoder. no need to
|
||||
free it */
|
||||
snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);
|
||||
pgm_save(frame->data[0], frame->linesize[0],
|
||||
frame->width, frame->height, buf);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename, *outfilename;
|
||||
const AVCodec *codec;
|
||||
AVCodecParserContext *parser;
|
||||
AVCodecContext *c= NULL;
|
||||
FILE *f;
|
||||
AVFrame *frame;
|
||||
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
uint8_t *data;
|
||||
size_t data_size;
|
||||
int ret;
|
||||
AVPacket *pkt;
|
||||
|
||||
if (argc <= 2) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n"
|
||||
"And check your input file is encoded by mpeg1video please.\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
filename = argv[1];
|
||||
outfilename = argv[2];
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt)
|
||||
exit(1);
|
||||
|
||||
/* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
|
||||
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
/* find the MPEG-1 video decoder */
|
||||
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
parser = av_parser_init(codec->id);
|
||||
if (!parser) {
|
||||
fprintf(stderr, "parser not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate video codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* For some codecs, such as msmpeg4 and mpeg4, width and height
|
||||
MUST be initialized there because this information is not
|
||||
available in the bitstream. */
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (!feof(f)) {
|
||||
/* read raw data from the input file */
|
||||
data_size = fread(inbuf, 1, INBUF_SIZE, f);
|
||||
if (!data_size)
|
||||
break;
|
||||
|
||||
/* use the parser to split the data into frames */
|
||||
data = inbuf;
|
||||
while (data_size > 0) {
|
||||
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
|
||||
data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while parsing\n");
|
||||
exit(1);
|
||||
}
|
||||
data += ret;
|
||||
data_size -= ret;
|
||||
|
||||
if (pkt->size)
|
||||
decode(c, frame, pkt, outfilename);
|
||||
}
|
||||
}
|
||||
|
||||
/* flush the decoder */
|
||||
decode(c, frame, NULL, outfilename);
|
||||
|
||||
fclose(f);
|
||||
|
||||
av_parser_close(parser);
|
||||
avcodec_free_context(&c);
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
-650
@@ -1,650 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* libavcodec API use example.
|
||||
*
|
||||
* Note that libavcodec only handles codecs (mpeg, mpeg4, etc...),
|
||||
* not file formats (avi, vob, mp4, mov, mkv, mxf, flv, mpegts, mpegps, etc...). See library 'libavformat' for the
|
||||
* format handling
|
||||
* @example doc/examples/decoding_encoding.c
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/common.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libavutil/mathematics.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
|
||||
#define INBUF_SIZE 4096
|
||||
#define AUDIO_INBUF_SIZE 20480
|
||||
#define AUDIO_REFILL_THRESH 4096
|
||||
|
||||
/* check that a given sample format is supported by the encoder */
|
||||
static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
const enum AVSampleFormat *p = codec->sample_fmts;
|
||||
|
||||
while (*p != AV_SAMPLE_FMT_NONE) {
|
||||
if (*p == sample_fmt)
|
||||
return 1;
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* just pick the highest supported samplerate */
|
||||
static int select_sample_rate(AVCodec *codec)
|
||||
{
|
||||
const int *p;
|
||||
int best_samplerate = 0;
|
||||
|
||||
if (!codec->supported_samplerates)
|
||||
return 44100;
|
||||
|
||||
p = codec->supported_samplerates;
|
||||
while (*p) {
|
||||
best_samplerate = FFMAX(*p, best_samplerate);
|
||||
p++;
|
||||
}
|
||||
return best_samplerate;
|
||||
}
|
||||
|
||||
/* select layout with the highest channel count */
|
||||
static int select_channel_layout(AVCodec *codec)
|
||||
{
|
||||
const uint64_t *p;
|
||||
uint64_t best_ch_layout = 0;
|
||||
int best_nb_channels = 0;
|
||||
|
||||
if (!codec->channel_layouts)
|
||||
return AV_CH_LAYOUT_STEREO;
|
||||
|
||||
p = codec->channel_layouts;
|
||||
while (*p) {
|
||||
int nb_channels = av_get_channel_layout_nb_channels(*p);
|
||||
|
||||
if (nb_channels > best_nb_channels) {
|
||||
best_ch_layout = *p;
|
||||
best_nb_channels = nb_channels;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return best_ch_layout;
|
||||
}
|
||||
|
||||
/*
|
||||
* Audio encoding example
|
||||
*/
|
||||
static void audio_encode_example(const char *filename)
|
||||
{
|
||||
AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
AVFrame *frame;
|
||||
AVPacket pkt;
|
||||
int i, j, k, ret, got_output;
|
||||
int buffer_size;
|
||||
FILE *f;
|
||||
uint16_t *samples;
|
||||
float t, tincr;
|
||||
|
||||
printf("Encode audio file %s\n", filename);
|
||||
|
||||
/* find the MP2 encoder */
|
||||
codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate audio codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* put sample parameters */
|
||||
c->bit_rate = 64000;
|
||||
|
||||
/* check that the encoder supports s16 pcm input */
|
||||
c->sample_fmt = AV_SAMPLE_FMT_S16;
|
||||
if (!check_sample_fmt(codec, c->sample_fmt)) {
|
||||
fprintf(stderr, "Encoder does not support sample format %s",
|
||||
av_get_sample_fmt_name(c->sample_fmt));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* select other audio parameters supported by the encoder */
|
||||
c->sample_rate = select_sample_rate(codec);
|
||||
c->channel_layout = select_channel_layout(codec);
|
||||
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* frame containing input raw audio */
|
||||
frame = avcodec_alloc_frame();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame->nb_samples = c->frame_size;
|
||||
frame->format = c->sample_fmt;
|
||||
frame->channel_layout = c->channel_layout;
|
||||
|
||||
/* the codec gives us the frame size, in samples,
|
||||
* we calculate the size of the samples buffer in bytes */
|
||||
buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
|
||||
c->sample_fmt, 0);
|
||||
samples = av_malloc(buffer_size);
|
||||
if (!samples) {
|
||||
fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
|
||||
buffer_size);
|
||||
exit(1);
|
||||
}
|
||||
/* setup the data pointers in the AVFrame */
|
||||
ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
|
||||
(const uint8_t*)samples, buffer_size, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not setup audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* encode a single tone sound */
|
||||
t = 0;
|
||||
tincr = 2 * M_PI * 440.0 / c->sample_rate;
|
||||
for(i=0;i<200;i++) {
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||
pkt.size = 0;
|
||||
|
||||
for (j = 0; j < c->frame_size; j++) {
|
||||
samples[2*j] = (int)(sin(t) * 10000);
|
||||
|
||||
for (k = 1; k < c->channels; k++)
|
||||
samples[2*j + k] = samples[2*j];
|
||||
t += tincr;
|
||||
}
|
||||
/* encode the samples */
|
||||
ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
if (got_output) {
|
||||
fwrite(pkt.data, 1, pkt.size, f);
|
||||
av_free_packet(&pkt);
|
||||
}
|
||||
}
|
||||
|
||||
/* get the delayed frames */
|
||||
for (got_output = 1; got_output; i++) {
|
||||
ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (got_output) {
|
||||
fwrite(pkt.data, 1, pkt.size, f);
|
||||
av_free_packet(&pkt);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
av_freep(&samples);
|
||||
avcodec_free_frame(&frame);
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Audio decoding.
|
||||
*/
|
||||
static void audio_decode_example(const char *outfilename, const char *filename)
|
||||
{
|
||||
AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int len;
|
||||
FILE *f, *outfile;
|
||||
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
|
||||
AVPacket avpkt;
|
||||
AVFrame *decoded_frame = NULL;
|
||||
|
||||
av_init_packet(&avpkt);
|
||||
|
||||
printf("Decode audio file %s to %s\n", filename, outfilename);
|
||||
|
||||
/* find the mpeg audio decoder */
|
||||
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate audio codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
outfile = fopen(outfilename, "wb");
|
||||
if (!outfile) {
|
||||
av_free(c);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* decode until eof */
|
||||
avpkt.data = inbuf;
|
||||
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
||||
|
||||
while (avpkt.size > 0) {
|
||||
int got_frame = 0;
|
||||
|
||||
if (!decoded_frame) {
|
||||
if (!(decoded_frame = avcodec_alloc_frame())) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
} else
|
||||
avcodec_get_frame_defaults(decoded_frame);
|
||||
|
||||
len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "Error while decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
if (got_frame) {
|
||||
/* if a frame has been decoded, output it */
|
||||
int data_size = av_samples_get_buffer_size(NULL, c->channels,
|
||||
decoded_frame->nb_samples,
|
||||
c->sample_fmt, 1);
|
||||
fwrite(decoded_frame->data[0], 1, data_size, outfile);
|
||||
}
|
||||
avpkt.size -= len;
|
||||
avpkt.data += len;
|
||||
avpkt.dts =
|
||||
avpkt.pts = AV_NOPTS_VALUE;
|
||||
if (avpkt.size < AUDIO_REFILL_THRESH) {
|
||||
/* Refill the input buffer, to avoid trying to decode
|
||||
* incomplete frames. Instead of this, one could also use
|
||||
* a parser, or use a proper container format through
|
||||
* libavformat. */
|
||||
memmove(inbuf, avpkt.data, avpkt.size);
|
||||
avpkt.data = inbuf;
|
||||
len = fread(avpkt.data + avpkt.size, 1,
|
||||
AUDIO_INBUF_SIZE - avpkt.size, f);
|
||||
if (len > 0)
|
||||
avpkt.size += len;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
fclose(f);
|
||||
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
avcodec_free_frame(&decoded_frame);
|
||||
}
|
||||
|
||||
/*
|
||||
* Video encoding example
|
||||
*/
|
||||
static void video_encode_example(const char *filename, int codec_id)
|
||||
{
|
||||
AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int i, ret, x, y, got_output;
|
||||
FILE *f;
|
||||
AVFrame *frame;
|
||||
AVPacket pkt;
|
||||
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
|
||||
|
||||
printf("Encode video file %s\n", filename);
|
||||
|
||||
/* find the mpeg1 video encoder */
|
||||
codec = avcodec_find_encoder(codec_id);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate video codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* put sample parameters */
|
||||
c->bit_rate = 400000;
|
||||
/* resolution must be a multiple of two */
|
||||
c->width = 352;
|
||||
c->height = 288;
|
||||
/* frames per second */
|
||||
c->time_base= (AVRational){1,25};
|
||||
c->gop_size = 10; /* emit one intra frame every ten frames */
|
||||
c->max_b_frames=1;
|
||||
c->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||
|
||||
if(codec_id == AV_CODEC_ID_H264)
|
||||
av_opt_set(c->priv_data, "preset", "slow", 0);
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = avcodec_alloc_frame();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
frame->format = c->pix_fmt;
|
||||
frame->width = c->width;
|
||||
frame->height = c->height;
|
||||
|
||||
/* the image can be allocated by any means and av_image_alloc() is
|
||||
* just the most convenient way if av_malloc() is to be used */
|
||||
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
|
||||
c->pix_fmt, 32);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate raw picture buffer\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* encode 1 second of video */
|
||||
for(i=0;i<25;i++) {
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||
pkt.size = 0;
|
||||
|
||||
fflush(stdout);
|
||||
/* prepare a dummy image */
|
||||
/* Y */
|
||||
for(y=0;y<c->height;y++) {
|
||||
for(x=0;x<c->width;x++) {
|
||||
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cb and Cr */
|
||||
for(y=0;y<c->height/2;y++) {
|
||||
for(x=0;x<c->width/2;x++) {
|
||||
frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
|
||||
frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
|
||||
}
|
||||
}
|
||||
|
||||
frame->pts = i;
|
||||
|
||||
/* encode the image */
|
||||
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (got_output) {
|
||||
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
||||
fwrite(pkt.data, 1, pkt.size, f);
|
||||
av_free_packet(&pkt);
|
||||
}
|
||||
}
|
||||
|
||||
/* get the delayed frames */
|
||||
for (got_output = 1; got_output; i++) {
|
||||
fflush(stdout);
|
||||
|
||||
ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (got_output) {
|
||||
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
||||
fwrite(pkt.data, 1, pkt.size, f);
|
||||
av_free_packet(&pkt);
|
||||
}
|
||||
}
|
||||
|
||||
/* add sequence end code to have a real mpeg file */
|
||||
fwrite(endcode, 1, sizeof(endcode), f);
|
||||
fclose(f);
|
||||
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
av_freep(&frame->data[0]);
|
||||
avcodec_free_frame(&frame);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Video decoding example
|
||||
*/
|
||||
|
||||
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
|
||||
char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
|
||||
f=fopen(filename,"w");
|
||||
fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
|
||||
for(i=0;i<ysize;i++)
|
||||
fwrite(buf + i * wrap,1,xsize,f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
|
||||
AVFrame *frame, int *frame_count, AVPacket *pkt, int last)
|
||||
{
|
||||
int len, got_frame;
|
||||
char buf[1024];
|
||||
|
||||
len = avcodec_decode_video2(avctx, frame, &got_frame, pkt);
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "Error while decoding frame %d\n", *frame_count);
|
||||
return len;
|
||||
}
|
||||
if (got_frame) {
|
||||
printf("Saving %sframe %3d\n", last ? "last " : "", *frame_count);
|
||||
fflush(stdout);
|
||||
|
||||
/* the picture is allocated by the decoder, no need to free it */
|
||||
snprintf(buf, sizeof(buf), outfilename, *frame_count);
|
||||
pgm_save(frame->data[0], frame->linesize[0],
|
||||
avctx->width, avctx->height, buf);
|
||||
(*frame_count)++;
|
||||
}
|
||||
if (pkt->data) {
|
||||
pkt->size -= len;
|
||||
pkt->data += len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void video_decode_example(const char *outfilename, const char *filename)
|
||||
{
|
||||
AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int frame_count;
|
||||
FILE *f;
|
||||
AVFrame *frame;
|
||||
uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
|
||||
AVPacket avpkt;
|
||||
|
||||
av_init_packet(&avpkt);
|
||||
|
||||
/* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
|
||||
memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
printf("Decode video file %s to %s\n", filename, outfilename);
|
||||
|
||||
/* find the mpeg1 video decoder */
|
||||
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate video codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(codec->capabilities&CODEC_CAP_TRUNCATED)
|
||||
c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
|
||||
|
||||
/* For some codecs, such as msmpeg4 and mpeg4, width and height
|
||||
MUST be initialized there because this information is not
|
||||
available in the bitstream. */
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = avcodec_alloc_frame();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame_count = 0;
|
||||
for(;;) {
|
||||
avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
|
||||
if (avpkt.size == 0)
|
||||
break;
|
||||
|
||||
/* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
|
||||
and this is the only method to use them because you cannot
|
||||
know the compressed data size before analysing it.
|
||||
|
||||
BUT some other codecs (msmpeg4, mpeg4) are inherently frame
|
||||
based, so you must call them with all the data for one
|
||||
frame exactly. You must also initialize 'width' and
|
||||
'height' before initializing them. */
|
||||
|
||||
/* NOTE2: some codecs allow the raw parameters (frame size,
|
||||
sample rate) to be changed at any frame. We handle this, so
|
||||
you should also take care of it */
|
||||
|
||||
/* here, we use a stream based decoder (mpeg1video), so we
|
||||
feed decoder and see if it could decode a frame */
|
||||
avpkt.data = inbuf;
|
||||
while (avpkt.size > 0)
|
||||
if (decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 0) < 0)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* some codecs, such as MPEG, transmit the I and P frame with a
|
||||
latency of one frame. You must do the following to have a
|
||||
chance to get the last frame of the video */
|
||||
avpkt.data = NULL;
|
||||
avpkt.size = 0;
|
||||
decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1);
|
||||
|
||||
fclose(f);
|
||||
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
avcodec_free_frame(&frame);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *output_type;
|
||||
|
||||
/* register all the codecs */
|
||||
avcodec_register_all();
|
||||
|
||||
if (argc < 2) {
|
||||
printf("usage: %s output_type\n"
|
||||
"API example program to decode/encode a media stream with libavcodec.\n"
|
||||
"This program generates a synthetic stream and encodes it to a file\n"
|
||||
"named test.h264, test.mp2 or test.mpg depending on output_type.\n"
|
||||
"The encoded stream is then decoded and written to a raw data output.\n"
|
||||
"output_type must be choosen between 'h264', 'mp2', 'mpg'.\n",
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
output_type = argv[1];
|
||||
|
||||
if (!strcmp(output_type, "h264")) {
|
||||
video_encode_example("test.h264", AV_CODEC_ID_H264);
|
||||
} else if (!strcmp(output_type, "mp2")) {
|
||||
audio_encode_example("test.mp2");
|
||||
audio_decode_example("test.sw", "test.mp2");
|
||||
} else if (!strcmp(output_type, "mpg")) {
|
||||
video_encode_example("test.mpg", AV_CODEC_ID_MPEG1VIDEO);
|
||||
video_decode_example("test%02d.pgm", "test.mpg");
|
||||
} else {
|
||||
fprintf(stderr, "Invalid output type '%s', choose between 'h264', 'mp2', or 'mpg'\n",
|
||||
output_type);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+152
-111
@@ -22,20 +22,23 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* libavformat demuxing API use example.
|
||||
* Demuxing and decoding example.
|
||||
*
|
||||
* Show how to use the libavformat and libavcodec API to demux and
|
||||
* decode audio and video data.
|
||||
* @example doc/examples/demuxing.c
|
||||
* @example demuxing_decoding.c
|
||||
*/
|
||||
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
#include <libavutil/timestamp.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
static AVFormatContext *fmt_ctx = NULL;
|
||||
static AVCodecContext *video_dec_ctx = NULL, *audio_dec_ctx;
|
||||
static int width, height;
|
||||
static enum AVPixelFormat pix_fmt;
|
||||
static AVStream *video_stream = NULL, *audio_stream = NULL;
|
||||
static const char *src_filename = NULL;
|
||||
static const char *video_dst_filename = NULL;
|
||||
@@ -49,80 +52,105 @@ static int video_dst_bufsize;
|
||||
|
||||
static int video_stream_idx = -1, audio_stream_idx = -1;
|
||||
static AVFrame *frame = NULL;
|
||||
static AVPacket pkt;
|
||||
static AVPacket *pkt = NULL;
|
||||
static int video_frame_count = 0;
|
||||
static int audio_frame_count = 0;
|
||||
|
||||
static int decode_packet(int *got_frame, int cached)
|
||||
static int output_video_frame(AVFrame *frame)
|
||||
{
|
||||
int ret = 0;
|
||||
int decoded = pkt.size;
|
||||
|
||||
if (pkt.stream_index == video_stream_idx) {
|
||||
/* decode video frame */
|
||||
ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error decoding video frame\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (*got_frame) {
|
||||
printf("video_frame%s n:%d coded_n:%d pts:%s\n",
|
||||
cached ? "(cached)" : "",
|
||||
video_frame_count++, frame->coded_picture_number,
|
||||
av_ts2timestr(frame->pts, &video_dec_ctx->time_base));
|
||||
|
||||
/* copy decoded frame to destination buffer:
|
||||
* this is required since rawvideo expects non aligned data */
|
||||
av_image_copy(video_dst_data, video_dst_linesize,
|
||||
(const uint8_t **)(frame->data), frame->linesize,
|
||||
video_dec_ctx->pix_fmt, video_dec_ctx->width, video_dec_ctx->height);
|
||||
|
||||
/* write to rawvideo file */
|
||||
fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);
|
||||
}
|
||||
} else if (pkt.stream_index == audio_stream_idx) {
|
||||
/* decode audio frame */
|
||||
ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error decoding audio frame\n");
|
||||
return ret;
|
||||
}
|
||||
/* Some audio decoders decode only part of the packet, and have to be
|
||||
* called again with the remainder of the packet data.
|
||||
* Sample: fate-suite/lossless-audio/luckynight-partial.shn
|
||||
* Also, some decoders might over-read the packet. */
|
||||
decoded = FFMIN(ret, pkt.size);
|
||||
|
||||
if (*got_frame) {
|
||||
size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format);
|
||||
printf("audio_frame%s n:%d nb_samples:%d pts:%s\n",
|
||||
cached ? "(cached)" : "",
|
||||
audio_frame_count++, frame->nb_samples,
|
||||
av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
|
||||
|
||||
/* Write the raw audio data samples of the first plane. This works
|
||||
* fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
|
||||
* most audio decoders output planar audio, which uses a separate
|
||||
* plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
|
||||
* In other words, this code will write only the first audio channel
|
||||
* in these cases.
|
||||
* You should use libswresample or libavfilter to convert the frame
|
||||
* to packed data. */
|
||||
fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
|
||||
}
|
||||
if (frame->width != width || frame->height != height ||
|
||||
frame->format != pix_fmt) {
|
||||
/* To handle this change, one could call av_image_alloc again and
|
||||
* decode the following frames into another rawvideo file. */
|
||||
fprintf(stderr, "Error: Width, height and pixel format have to be "
|
||||
"constant in a rawvideo file, but the width, height or "
|
||||
"pixel format of the input video changed:\n"
|
||||
"old: width = %d, height = %d, format = %s\n"
|
||||
"new: width = %d, height = %d, format = %s\n",
|
||||
width, height, av_get_pix_fmt_name(pix_fmt),
|
||||
frame->width, frame->height,
|
||||
av_get_pix_fmt_name(frame->format));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return decoded;
|
||||
printf("video_frame n:%d coded_n:%d\n",
|
||||
video_frame_count++, frame->coded_picture_number);
|
||||
|
||||
/* copy decoded frame to destination buffer:
|
||||
* this is required since rawvideo expects non aligned data */
|
||||
av_image_copy(video_dst_data, video_dst_linesize,
|
||||
(const uint8_t **)(frame->data), frame->linesize,
|
||||
pix_fmt, width, height);
|
||||
|
||||
/* write to rawvideo file */
|
||||
fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int output_audio_frame(AVFrame *frame)
|
||||
{
|
||||
size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format);
|
||||
printf("audio_frame n:%d nb_samples:%d pts:%s\n",
|
||||
audio_frame_count++, frame->nb_samples,
|
||||
av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
|
||||
|
||||
/* Write the raw audio data samples of the first plane. This works
|
||||
* fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
|
||||
* most audio decoders output planar audio, which uses a separate
|
||||
* plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
|
||||
* In other words, this code will write only the first audio channel
|
||||
* in these cases.
|
||||
* You should use libswresample or libavfilter to convert the frame
|
||||
* to packed data. */
|
||||
fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_packet(AVCodecContext *dec, const AVPacket *pkt)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// submit the packet to the decoder
|
||||
ret = avcodec_send_packet(dec, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error submitting a packet for decoding (%s)\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// get all the available frames from the decoder
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec, frame);
|
||||
if (ret < 0) {
|
||||
// those two return values are special and mean there is no output
|
||||
// frame available, but there were no errors during decoding
|
||||
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
|
||||
return 0;
|
||||
|
||||
fprintf(stderr, "Error during decoding (%s)\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// write the frame data to output file
|
||||
if (dec->codec->type == AVMEDIA_TYPE_VIDEO)
|
||||
ret = output_video_frame(frame);
|
||||
else
|
||||
ret = output_audio_frame(frame);
|
||||
|
||||
av_frame_unref(frame);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_codec_context(int *stream_idx,
|
||||
AVFormatContext *fmt_ctx, enum AVMediaType type)
|
||||
AVCodecContext **dec_ctx, AVFormatContext *fmt_ctx, enum AVMediaType type)
|
||||
{
|
||||
int ret;
|
||||
int ret, stream_index;
|
||||
AVStream *st;
|
||||
AVCodecContext *dec_ctx = NULL;
|
||||
AVCodec *dec = NULL;
|
||||
const AVCodec *dec = NULL;
|
||||
|
||||
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
|
||||
if (ret < 0) {
|
||||
@@ -130,23 +158,39 @@ static int open_codec_context(int *stream_idx,
|
||||
av_get_media_type_string(type), src_filename);
|
||||
return ret;
|
||||
} else {
|
||||
*stream_idx = ret;
|
||||
st = fmt_ctx->streams[*stream_idx];
|
||||
stream_index = ret;
|
||||
st = fmt_ctx->streams[stream_index];
|
||||
|
||||
/* find decoder for the stream */
|
||||
dec_ctx = st->codec;
|
||||
dec = avcodec_find_decoder(dec_ctx->codec_id);
|
||||
dec = avcodec_find_decoder(st->codecpar->codec_id);
|
||||
if (!dec) {
|
||||
fprintf(stderr, "Failed to find %s codec\n",
|
||||
av_get_media_type_string(type));
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
/* Allocate a codec context for the decoder */
|
||||
*dec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!*dec_ctx) {
|
||||
fprintf(stderr, "Failed to allocate the %s codec context\n",
|
||||
av_get_media_type_string(type));
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Copy codec parameters from input stream to output codec context */
|
||||
if ((ret = avcodec_parameters_to_context(*dec_ctx, st->codecpar)) < 0) {
|
||||
fprintf(stderr, "Failed to copy %s codec parameters to decoder context\n",
|
||||
av_get_media_type_string(type));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||
/* Init the decoders */
|
||||
if ((ret = avcodec_open2(*dec_ctx, dec, NULL)) < 0) {
|
||||
fprintf(stderr, "Failed to open %s codec\n",
|
||||
av_get_media_type_string(type));
|
||||
return ret;
|
||||
}
|
||||
*stream_idx = stream_index;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -183,24 +227,21 @@ static int get_format_from_sample_fmt(const char **fmt,
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int ret = 0, got_frame;
|
||||
int ret = 0;
|
||||
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
|
||||
fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
|
||||
"API example program to show how to read frames from an input file.\n"
|
||||
"This program reads frames from a file, decodes them, and writes decoded\n"
|
||||
"video frames to a rawvideo file named video_output_file, and decoded\n"
|
||||
"audio frames to a rawaudio file named audio_output_file.\n"
|
||||
"\n", argv[0]);
|
||||
"audio frames to a rawaudio file named audio_output_file.\n",
|
||||
argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
src_filename = argv[1];
|
||||
video_dst_filename = argv[2];
|
||||
audio_dst_filename = argv[3];
|
||||
|
||||
/* register all formats and codecs */
|
||||
av_register_all();
|
||||
|
||||
/* open input file, and allocate format context */
|
||||
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open source file %s\n", src_filename);
|
||||
@@ -213,9 +254,8 @@ int main (int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
|
||||
if (open_codec_context(&video_stream_idx, &video_dec_ctx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
|
||||
video_stream = fmt_ctx->streams[video_stream_idx];
|
||||
video_dec_ctx = video_stream->codec;
|
||||
|
||||
video_dst_file = fopen(video_dst_filename, "wb");
|
||||
if (!video_dst_file) {
|
||||
@@ -225,9 +265,11 @@ int main (int argc, char **argv)
|
||||
}
|
||||
|
||||
/* allocate image where the decoded image will be put */
|
||||
width = video_dec_ctx->width;
|
||||
height = video_dec_ctx->height;
|
||||
pix_fmt = video_dec_ctx->pix_fmt;
|
||||
ret = av_image_alloc(video_dst_data, video_dst_linesize,
|
||||
video_dec_ctx->width, video_dec_ctx->height,
|
||||
video_dec_ctx->pix_fmt, 1);
|
||||
width, height, pix_fmt, 1);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate raw video buffer\n");
|
||||
goto end;
|
||||
@@ -235,12 +277,11 @@ int main (int argc, char **argv)
|
||||
video_dst_bufsize = ret;
|
||||
}
|
||||
|
||||
if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
|
||||
if (open_codec_context(&audio_stream_idx, &audio_dec_ctx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
|
||||
audio_stream = fmt_ctx->streams[audio_stream_idx];
|
||||
audio_dec_ctx = audio_stream->codec;
|
||||
audio_dst_file = fopen(audio_dst_filename, "wb");
|
||||
if (!audio_dst_file) {
|
||||
fprintf(stderr, "Could not open destination file %s\n", video_dst_filename);
|
||||
fprintf(stderr, "Could not open destination file %s\n", audio_dst_filename);
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
@@ -255,17 +296,19 @@ int main (int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
frame = avcodec_alloc_frame();
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate frame\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* initialize packet, set data to NULL, let the demuxer fill it */
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL;
|
||||
pkt.size = 0;
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "Could not allocate packet\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (video_stream)
|
||||
printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename);
|
||||
@@ -273,31 +316,30 @@ int main (int argc, char **argv)
|
||||
printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename);
|
||||
|
||||
/* read frames from the file */
|
||||
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
|
||||
AVPacket orig_pkt = pkt;
|
||||
do {
|
||||
ret = decode_packet(&got_frame, 0);
|
||||
if (ret < 0)
|
||||
break;
|
||||
pkt.data += ret;
|
||||
pkt.size -= ret;
|
||||
} while (pkt.size > 0);
|
||||
av_free_packet(&orig_pkt);
|
||||
while (av_read_frame(fmt_ctx, pkt) >= 0) {
|
||||
// check if the packet belongs to a stream we are interested in, otherwise
|
||||
// skip it
|
||||
if (pkt->stream_index == video_stream_idx)
|
||||
ret = decode_packet(video_dec_ctx, pkt);
|
||||
else if (pkt->stream_index == audio_stream_idx)
|
||||
ret = decode_packet(audio_dec_ctx, pkt);
|
||||
av_packet_unref(pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* flush cached frames */
|
||||
pkt.data = NULL;
|
||||
pkt.size = 0;
|
||||
do {
|
||||
decode_packet(&got_frame, 1);
|
||||
} while (got_frame);
|
||||
/* flush the decoders */
|
||||
if (video_dec_ctx)
|
||||
decode_packet(video_dec_ctx, NULL);
|
||||
if (audio_dec_ctx)
|
||||
decode_packet(audio_dec_ctx, NULL);
|
||||
|
||||
printf("Demuxing succeeded.\n");
|
||||
|
||||
if (video_stream) {
|
||||
printf("Play the output video file with the command:\n"
|
||||
"ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
|
||||
av_get_pix_fmt_name(video_dec_ctx->pix_fmt), video_dec_ctx->width, video_dec_ctx->height,
|
||||
av_get_pix_fmt_name(pix_fmt), width, height,
|
||||
video_dst_filename);
|
||||
}
|
||||
|
||||
@@ -325,16 +367,15 @@ int main (int argc, char **argv)
|
||||
}
|
||||
|
||||
end:
|
||||
if (video_dec_ctx)
|
||||
avcodec_close(video_dec_ctx);
|
||||
if (audio_dec_ctx)
|
||||
avcodec_close(audio_dec_ctx);
|
||||
avcodec_free_context(&video_dec_ctx);
|
||||
avcodec_free_context(&audio_dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
if (video_dst_file)
|
||||
fclose(video_dst_file);
|
||||
if (audio_dst_file)
|
||||
fclose(audio_dst_file);
|
||||
av_free(frame);
|
||||
av_packet_free(&pkt);
|
||||
av_frame_free(&frame);
|
||||
av_free(video_dst_data[0]);
|
||||
|
||||
return ret < 0;
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* audio encoding with libavcodec API example.
|
||||
*
|
||||
* @example encode_audio.c
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/common.h>
|
||||
#include <libavutil/frame.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
|
||||
/* check that a given sample format is supported by the encoder */
|
||||
static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
const enum AVSampleFormat *p = codec->sample_fmts;
|
||||
|
||||
while (*p != AV_SAMPLE_FMT_NONE) {
|
||||
if (*p == sample_fmt)
|
||||
return 1;
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* just pick the highest supported samplerate */
|
||||
static int select_sample_rate(const AVCodec *codec)
|
||||
{
|
||||
const int *p;
|
||||
int best_samplerate = 0;
|
||||
|
||||
if (!codec->supported_samplerates)
|
||||
return 44100;
|
||||
|
||||
p = codec->supported_samplerates;
|
||||
while (*p) {
|
||||
if (!best_samplerate || abs(44100 - *p) < abs(44100 - best_samplerate))
|
||||
best_samplerate = *p;
|
||||
p++;
|
||||
}
|
||||
return best_samplerate;
|
||||
}
|
||||
|
||||
/* select layout with the highest channel count */
|
||||
static int select_channel_layout(const AVCodec *codec)
|
||||
{
|
||||
const uint64_t *p;
|
||||
uint64_t best_ch_layout = 0;
|
||||
int best_nb_channels = 0;
|
||||
|
||||
if (!codec->channel_layouts)
|
||||
return AV_CH_LAYOUT_STEREO;
|
||||
|
||||
p = codec->channel_layouts;
|
||||
while (*p) {
|
||||
int nb_channels = av_get_channel_layout_nb_channels(*p);
|
||||
|
||||
if (nb_channels > best_nb_channels) {
|
||||
best_ch_layout = *p;
|
||||
best_nb_channels = nb_channels;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return best_ch_layout;
|
||||
}
|
||||
|
||||
static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt,
|
||||
FILE *output)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* send the frame for encoding */
|
||||
ret = avcodec_send_frame(ctx, frame);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error sending the frame to the encoder\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* read all the available output packets (in general there may be any
|
||||
* number of them */
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(ctx, pkt);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fwrite(pkt->data, 1, pkt->size, output);
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
AVFrame *frame;
|
||||
AVPacket *pkt;
|
||||
int i, j, k, ret;
|
||||
FILE *f;
|
||||
uint16_t *samples;
|
||||
float t, tincr;
|
||||
|
||||
if (argc <= 1) {
|
||||
fprintf(stderr, "Usage: %s <output file>\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
filename = argv[1];
|
||||
|
||||
/* find the MP2 encoder */
|
||||
codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate audio codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* put sample parameters */
|
||||
c->bit_rate = 64000;
|
||||
|
||||
/* check that the encoder supports s16 pcm input */
|
||||
c->sample_fmt = AV_SAMPLE_FMT_S16;
|
||||
if (!check_sample_fmt(codec, c->sample_fmt)) {
|
||||
fprintf(stderr, "Encoder does not support sample format %s",
|
||||
av_get_sample_fmt_name(c->sample_fmt));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* select other audio parameters supported by the encoder */
|
||||
c->sample_rate = select_sample_rate(codec);
|
||||
c->channel_layout = select_channel_layout(codec);
|
||||
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* packet for holding encoded output */
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "could not allocate the packet\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* frame containing input raw audio */
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame->nb_samples = c->frame_size;
|
||||
frame->format = c->sample_fmt;
|
||||
frame->channel_layout = c->channel_layout;
|
||||
|
||||
/* allocate the data buffers */
|
||||
ret = av_frame_get_buffer(frame, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate audio data buffers\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* encode a single tone sound */
|
||||
t = 0;
|
||||
tincr = 2 * M_PI * 440.0 / c->sample_rate;
|
||||
for (i = 0; i < 200; i++) {
|
||||
/* make sure the frame is writable -- makes a copy if the encoder
|
||||
* kept a reference internally */
|
||||
ret = av_frame_make_writable(frame);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
samples = (uint16_t*)frame->data[0];
|
||||
|
||||
for (j = 0; j < c->frame_size; j++) {
|
||||
samples[2*j] = (int)(sin(t) * 10000);
|
||||
|
||||
for (k = 1; k < c->channels; k++)
|
||||
samples[2*j + k] = samples[2*j];
|
||||
t += tincr;
|
||||
}
|
||||
encode(c, frame, pkt, f);
|
||||
}
|
||||
|
||||
/* flush the encoder */
|
||||
encode(c, NULL, pkt, f);
|
||||
|
||||
fclose(f);
|
||||
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
avcodec_free_context(&c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* video encoding with libavcodec API example
|
||||
*
|
||||
* @example encode_video.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
|
||||
static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
|
||||
FILE *outfile)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* send the frame to the encoder */
|
||||
if (frame)
|
||||
printf("Send frame %3"PRId64"\n", frame->pts);
|
||||
|
||||
ret = avcodec_send_frame(enc_ctx, frame);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error sending a frame for encoding\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(enc_ctx, pkt);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error during encoding\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);
|
||||
fwrite(pkt->data, 1, pkt->size, outfile);
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename, *codec_name;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int i, ret, x, y;
|
||||
FILE *f;
|
||||
AVFrame *frame;
|
||||
AVPacket *pkt;
|
||||
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
|
||||
|
||||
if (argc <= 2) {
|
||||
fprintf(stderr, "Usage: %s <output file> <codec name>\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
filename = argv[1];
|
||||
codec_name = argv[2];
|
||||
|
||||
/* find the mpeg1video encoder */
|
||||
codec = avcodec_find_encoder_by_name(codec_name);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec '%s' not found\n", codec_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate video codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt)
|
||||
exit(1);
|
||||
|
||||
/* put sample parameters */
|
||||
c->bit_rate = 400000;
|
||||
/* resolution must be a multiple of two */
|
||||
c->width = 352;
|
||||
c->height = 288;
|
||||
/* frames per second */
|
||||
c->time_base = (AVRational){1, 25};
|
||||
c->framerate = (AVRational){25, 1};
|
||||
|
||||
/* emit one intra frame every ten frames
|
||||
* check frame pict_type before passing frame
|
||||
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
|
||||
* then gop_size is ignored and the output of encoder
|
||||
* will always be I frame irrespective to gop_size
|
||||
*/
|
||||
c->gop_size = 10;
|
||||
c->max_b_frames = 1;
|
||||
c->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||
|
||||
if (codec->id == AV_CODEC_ID_H264)
|
||||
av_opt_set(c->priv_data, "preset", "slow", 0);
|
||||
|
||||
/* open it */
|
||||
ret = avcodec_open2(c, codec, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
frame->format = c->pix_fmt;
|
||||
frame->width = c->width;
|
||||
frame->height = c->height;
|
||||
|
||||
ret = av_frame_get_buffer(frame, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate the video frame data\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* encode 1 second of video */
|
||||
for (i = 0; i < 25; i++) {
|
||||
fflush(stdout);
|
||||
|
||||
/* Make sure the frame data is writable.
|
||||
On the first round, the frame is fresh from av_frame_get_buffer()
|
||||
and therefore we know it is writable.
|
||||
But on the next rounds, encode() will have called
|
||||
avcodec_send_frame(), and the codec may have kept a reference to
|
||||
the frame in its internal structures, that makes the frame
|
||||
unwritable.
|
||||
av_frame_make_writable() checks that and allocates a new buffer
|
||||
for the frame only if necessary.
|
||||
*/
|
||||
ret = av_frame_make_writable(frame);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
/* Prepare a dummy image.
|
||||
In real code, this is where you would have your own logic for
|
||||
filling the frame. FFmpeg does not care what you put in the
|
||||
frame.
|
||||
*/
|
||||
/* Y */
|
||||
for (y = 0; y < c->height; y++) {
|
||||
for (x = 0; x < c->width; x++) {
|
||||
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cb and Cr */
|
||||
for (y = 0; y < c->height/2; y++) {
|
||||
for (x = 0; x < c->width/2; x++) {
|
||||
frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
|
||||
frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
|
||||
}
|
||||
}
|
||||
|
||||
frame->pts = i;
|
||||
|
||||
/* encode the image */
|
||||
encode(c, frame, pkt, f);
|
||||
}
|
||||
|
||||
/* flush the encoder */
|
||||
encode(c, NULL, pkt, f);
|
||||
|
||||
/* Add sequence end code to have a real MPEG file.
|
||||
It makes only sense because this tiny examples writes packets
|
||||
directly. This is called "elementary stream" and only works for some
|
||||
codecs. To create a valid file, you usually need to write packets
|
||||
into a proper file format or protocol; see muxing.c.
|
||||
*/
|
||||
if (codec->id == AV_CODEC_ID_MPEG1VIDEO || codec->id == AV_CODEC_ID_MPEG2VIDEO)
|
||||
fwrite(endcode, 1, sizeof(endcode), f);
|
||||
fclose(f);
|
||||
|
||||
avcodec_free_context(&c);
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Stefano Sabatini
|
||||
* Copyright (c) 2014 Clément Bœsch
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <libavutil/motion_vector.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
static AVFormatContext *fmt_ctx = NULL;
|
||||
static AVCodecContext *video_dec_ctx = NULL;
|
||||
static AVStream *video_stream = NULL;
|
||||
static const char *src_filename = NULL;
|
||||
|
||||
static int video_stream_idx = -1;
|
||||
static AVFrame *frame = NULL;
|
||||
static int video_frame_count = 0;
|
||||
|
||||
static int decode_packet(const AVPacket *pkt)
|
||||
{
|
||||
int ret = avcodec_send_packet(video_dec_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while sending a packet to the decoder: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(video_dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
break;
|
||||
} else if (ret < 0) {
|
||||
fprintf(stderr, "Error while receiving a frame from the decoder: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
int i;
|
||||
AVFrameSideData *sd;
|
||||
|
||||
video_frame_count++;
|
||||
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS);
|
||||
if (sd) {
|
||||
const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
|
||||
for (i = 0; i < sd->size / sizeof(*mvs); i++) {
|
||||
const AVMotionVector *mv = &mvs[i];
|
||||
printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64"\n",
|
||||
video_frame_count, mv->source,
|
||||
mv->w, mv->h, mv->src_x, mv->src_y,
|
||||
mv->dst_x, mv->dst_y, mv->flags);
|
||||
}
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
|
||||
{
|
||||
int ret;
|
||||
AVStream *st;
|
||||
AVCodecContext *dec_ctx = NULL;
|
||||
const AVCodec *dec = NULL;
|
||||
AVDictionary *opts = NULL;
|
||||
|
||||
ret = av_find_best_stream(fmt_ctx, type, -1, -1, &dec, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not find %s stream in input file '%s'\n",
|
||||
av_get_media_type_string(type), src_filename);
|
||||
return ret;
|
||||
} else {
|
||||
int stream_idx = ret;
|
||||
st = fmt_ctx->streams[stream_idx];
|
||||
|
||||
dec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!dec_ctx) {
|
||||
fprintf(stderr, "Failed to allocate codec\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
ret = avcodec_parameters_to_context(dec_ctx, st->codecpar);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to copy codec parameters to codec context\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init the video decoder */
|
||||
av_dict_set(&opts, "flags2", "+export_mvs", 0);
|
||||
ret = avcodec_open2(dec_ctx, dec, &opts);
|
||||
av_dict_free(&opts);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to open %s codec\n",
|
||||
av_get_media_type_string(type));
|
||||
return ret;
|
||||
}
|
||||
|
||||
video_stream_idx = stream_idx;
|
||||
video_stream = fmt_ctx->streams[video_stream_idx];
|
||||
video_dec_ctx = dec_ctx;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
AVPacket *pkt = NULL;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <video>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
src_filename = argv[1];
|
||||
|
||||
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open source file %s\n", src_filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
|
||||
fprintf(stderr, "Could not find stream information\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
open_codec_context(fmt_ctx, AVMEDIA_TYPE_VIDEO);
|
||||
|
||||
av_dump_format(fmt_ctx, 0, src_filename, 0);
|
||||
|
||||
if (!video_stream) {
|
||||
fprintf(stderr, "Could not find video stream in the input, aborting\n");
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate frame\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "Could not allocate AVPacket\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
printf("framenum,source,blockw,blockh,srcx,srcy,dstx,dsty,flags\n");
|
||||
|
||||
/* read frames from the file */
|
||||
while (av_read_frame(fmt_ctx, pkt) >= 0) {
|
||||
if (pkt->stream_index == video_stream_idx)
|
||||
ret = decode_packet(pkt);
|
||||
av_packet_unref(pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* flush cached frames */
|
||||
decode_packet(NULL);
|
||||
|
||||
end:
|
||||
avcodec_free_context(&video_dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
return ret < 0;
|
||||
}
|
||||
+363
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* copyright (c) 2013 Andrew Kelley
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* libavfilter API usage example.
|
||||
*
|
||||
* @example filter_audio.c
|
||||
* This example will generate a sine wave audio,
|
||||
* pass it through a simple filter chain, and then compute the MD5 checksum of
|
||||
* the output data.
|
||||
*
|
||||
* The filter chain it uses is:
|
||||
* (input) -> abuffer -> volume -> aformat -> abuffersink -> (output)
|
||||
*
|
||||
* abuffer: This provides the endpoint where you can feed the decoded samples.
|
||||
* volume: In this example we hardcode it to 0.90.
|
||||
* aformat: This converts the samples to the samplefreq, channel layout,
|
||||
* and sample format required by the audio device.
|
||||
* abuffersink: This provides the endpoint where you can read the samples after
|
||||
* they have passed through the filter chain.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/md5.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/samplefmt.h"
|
||||
|
||||
#include "libavfilter/avfilter.h"
|
||||
#include "libavfilter/buffersink.h"
|
||||
#include "libavfilter/buffersrc.h"
|
||||
|
||||
#define INPUT_SAMPLERATE 48000
|
||||
#define INPUT_FORMAT AV_SAMPLE_FMT_FLTP
|
||||
#define INPUT_CHANNEL_LAYOUT AV_CH_LAYOUT_5POINT0
|
||||
|
||||
#define VOLUME_VAL 0.90
|
||||
|
||||
static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
|
||||
AVFilterContext **sink)
|
||||
{
|
||||
AVFilterGraph *filter_graph;
|
||||
AVFilterContext *abuffer_ctx;
|
||||
const AVFilter *abuffer;
|
||||
AVFilterContext *volume_ctx;
|
||||
const AVFilter *volume;
|
||||
AVFilterContext *aformat_ctx;
|
||||
const AVFilter *aformat;
|
||||
AVFilterContext *abuffersink_ctx;
|
||||
const AVFilter *abuffersink;
|
||||
|
||||
AVDictionary *options_dict = NULL;
|
||||
uint8_t options_str[1024];
|
||||
uint8_t ch_layout[64];
|
||||
|
||||
int err;
|
||||
|
||||
/* Create a new filtergraph, which will contain all the filters. */
|
||||
filter_graph = avfilter_graph_alloc();
|
||||
if (!filter_graph) {
|
||||
fprintf(stderr, "Unable to create filter graph.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Create the abuffer filter;
|
||||
* it will be used for feeding the data into the graph. */
|
||||
abuffer = avfilter_get_by_name("abuffer");
|
||||
if (!abuffer) {
|
||||
fprintf(stderr, "Could not find the abuffer filter.\n");
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
abuffer_ctx = avfilter_graph_alloc_filter(filter_graph, abuffer, "src");
|
||||
if (!abuffer_ctx) {
|
||||
fprintf(stderr, "Could not allocate the abuffer instance.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Set the filter options through the AVOptions API. */
|
||||
av_get_channel_layout_string(ch_layout, sizeof(ch_layout), 0, INPUT_CHANNEL_LAYOUT);
|
||||
av_opt_set (abuffer_ctx, "channel_layout", ch_layout, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set (abuffer_ctx, "sample_fmt", av_get_sample_fmt_name(INPUT_FORMAT), AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_q (abuffer_ctx, "time_base", (AVRational){ 1, INPUT_SAMPLERATE }, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(abuffer_ctx, "sample_rate", INPUT_SAMPLERATE, AV_OPT_SEARCH_CHILDREN);
|
||||
|
||||
/* Now initialize the filter; we pass NULL options, since we have already
|
||||
* set all the options above. */
|
||||
err = avfilter_init_str(abuffer_ctx, NULL);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Could not initialize the abuffer filter.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Create volume filter. */
|
||||
volume = avfilter_get_by_name("volume");
|
||||
if (!volume) {
|
||||
fprintf(stderr, "Could not find the volume filter.\n");
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
volume_ctx = avfilter_graph_alloc_filter(filter_graph, volume, "volume");
|
||||
if (!volume_ctx) {
|
||||
fprintf(stderr, "Could not allocate the volume instance.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* A different way of passing the options is as key/value pairs in a
|
||||
* dictionary. */
|
||||
av_dict_set(&options_dict, "volume", AV_STRINGIFY(VOLUME_VAL), 0);
|
||||
err = avfilter_init_dict(volume_ctx, &options_dict);
|
||||
av_dict_free(&options_dict);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Could not initialize the volume filter.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Create the aformat filter;
|
||||
* it ensures that the output is of the format we want. */
|
||||
aformat = avfilter_get_by_name("aformat");
|
||||
if (!aformat) {
|
||||
fprintf(stderr, "Could not find the aformat filter.\n");
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
aformat_ctx = avfilter_graph_alloc_filter(filter_graph, aformat, "aformat");
|
||||
if (!aformat_ctx) {
|
||||
fprintf(stderr, "Could not allocate the aformat instance.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* A third way of passing the options is in a string of the form
|
||||
* key1=value1:key2=value2.... */
|
||||
snprintf(options_str, sizeof(options_str),
|
||||
"sample_fmts=%s:sample_rates=%d:channel_layouts=0x%"PRIx64,
|
||||
av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), 44100,
|
||||
(uint64_t)AV_CH_LAYOUT_STEREO);
|
||||
err = avfilter_init_str(aformat_ctx, options_str);
|
||||
if (err < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not initialize the aformat filter.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Finally create the abuffersink filter;
|
||||
* it will be used to get the filtered data out of the graph. */
|
||||
abuffersink = avfilter_get_by_name("abuffersink");
|
||||
if (!abuffersink) {
|
||||
fprintf(stderr, "Could not find the abuffersink filter.\n");
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
abuffersink_ctx = avfilter_graph_alloc_filter(filter_graph, abuffersink, "sink");
|
||||
if (!abuffersink_ctx) {
|
||||
fprintf(stderr, "Could not allocate the abuffersink instance.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* This filter takes no options. */
|
||||
err = avfilter_init_str(abuffersink_ctx, NULL);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Could not initialize the abuffersink instance.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Connect the filters;
|
||||
* in this simple case the filters just form a linear chain. */
|
||||
err = avfilter_link(abuffer_ctx, 0, volume_ctx, 0);
|
||||
if (err >= 0)
|
||||
err = avfilter_link(volume_ctx, 0, aformat_ctx, 0);
|
||||
if (err >= 0)
|
||||
err = avfilter_link(aformat_ctx, 0, abuffersink_ctx, 0);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Error connecting filters\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Configure the graph. */
|
||||
err = avfilter_graph_config(filter_graph, NULL);
|
||||
if (err < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error configuring the filter graph\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
*graph = filter_graph;
|
||||
*src = abuffer_ctx;
|
||||
*sink = abuffersink_ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do something useful with the filtered data: this simple
|
||||
* example just prints the MD5 checksum of each plane to stdout. */
|
||||
static int process_output(struct AVMD5 *md5, AVFrame *frame)
|
||||
{
|
||||
int planar = av_sample_fmt_is_planar(frame->format);
|
||||
int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
|
||||
int planes = planar ? channels : 1;
|
||||
int bps = av_get_bytes_per_sample(frame->format);
|
||||
int plane_size = bps * frame->nb_samples * (planar ? 1 : channels);
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < planes; i++) {
|
||||
uint8_t checksum[16];
|
||||
|
||||
av_md5_init(md5);
|
||||
av_md5_sum(checksum, frame->extended_data[i], plane_size);
|
||||
|
||||
fprintf(stdout, "plane %d: 0x", i);
|
||||
for (j = 0; j < sizeof(checksum); j++)
|
||||
fprintf(stdout, "%02X", checksum[j]);
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Construct a frame of audio data to be filtered;
|
||||
* this simple example just synthesizes a sine wave. */
|
||||
static int get_input(AVFrame *frame, int frame_num)
|
||||
{
|
||||
int err, i, j;
|
||||
|
||||
#define FRAME_SIZE 1024
|
||||
|
||||
/* Set up the frame properties and allocate the buffer for the data. */
|
||||
frame->sample_rate = INPUT_SAMPLERATE;
|
||||
frame->format = INPUT_FORMAT;
|
||||
frame->channel_layout = INPUT_CHANNEL_LAYOUT;
|
||||
frame->nb_samples = FRAME_SIZE;
|
||||
frame->pts = frame_num * FRAME_SIZE;
|
||||
|
||||
err = av_frame_get_buffer(frame, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Fill the data for each channel. */
|
||||
for (i = 0; i < 5; i++) {
|
||||
float *data = (float*)frame->extended_data[i];
|
||||
|
||||
for (j = 0; j < frame->nb_samples; j++)
|
||||
data[j] = sin(2 * M_PI * (frame_num + j) * (i + 1) / FRAME_SIZE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct AVMD5 *md5;
|
||||
AVFilterGraph *graph;
|
||||
AVFilterContext *src, *sink;
|
||||
AVFrame *frame;
|
||||
uint8_t errstr[1024];
|
||||
float duration;
|
||||
int err, nb_frames, i;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <duration>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
duration = atof(argv[1]);
|
||||
nb_frames = duration * INPUT_SAMPLERATE / FRAME_SIZE;
|
||||
if (nb_frames <= 0) {
|
||||
fprintf(stderr, "Invalid duration: %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Allocate the frame we will be using to store the data. */
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Error allocating the frame\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
md5 = av_md5_alloc();
|
||||
if (!md5) {
|
||||
fprintf(stderr, "Error allocating the MD5 context\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set up the filtergraph. */
|
||||
err = init_filter_graph(&graph, &src, &sink);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Unable to init filter graph:");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* the main filtering loop */
|
||||
for (i = 0; i < nb_frames; i++) {
|
||||
/* get an input frame to be filtered */
|
||||
err = get_input(frame, i);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Error generating input frame:");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Send the frame to the input of the filtergraph. */
|
||||
err = av_buffersrc_add_frame(src, frame);
|
||||
if (err < 0) {
|
||||
av_frame_unref(frame);
|
||||
fprintf(stderr, "Error submitting the frame to the filtergraph:");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Get all the filtered output that is available. */
|
||||
while ((err = av_buffersink_get_frame(sink, frame)) >= 0) {
|
||||
/* now do something with our filtered frame */
|
||||
err = process_output(md5, frame);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Error processing the filtered frame:");
|
||||
goto fail;
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
|
||||
if (err == AVERROR(EAGAIN)) {
|
||||
/* Need to feed more frames in. */
|
||||
continue;
|
||||
} else if (err == AVERROR_EOF) {
|
||||
/* Nothing more to do, finish. */
|
||||
break;
|
||||
} else if (err < 0) {
|
||||
/* An error occurred. */
|
||||
fprintf(stderr, "Error filtering the data:");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
avfilter_graph_free(&graph);
|
||||
av_frame_free(&frame);
|
||||
av_freep(&md5);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
av_strerror(err, errstr, sizeof(errstr));
|
||||
fprintf(stderr, "%s\n", errstr);
|
||||
return 1;
|
||||
}
|
||||
+83
-54
@@ -25,17 +25,16 @@
|
||||
/**
|
||||
* @file
|
||||
* API example for audio decoding and filtering
|
||||
* @example doc/examples/filtering_audio.c
|
||||
* @example filtering_audio.c
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavfilter/avfiltergraph.h>
|
||||
#include <libavfilter/avcodec.h>
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
static const char *filter_descr = "aresample=8000,aformat=sample_fmts=s16:channel_layouts=mono";
|
||||
@@ -50,8 +49,8 @@ static int audio_stream_index = -1;
|
||||
|
||||
static int open_input_file(const char *filename)
|
||||
{
|
||||
const AVCodec *dec;
|
||||
int ret;
|
||||
AVCodec *dec;
|
||||
|
||||
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
|
||||
@@ -66,12 +65,16 @@ static int open_input_file(const char *filename)
|
||||
/* select the audio stream */
|
||||
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot find a audio stream in the input file\n");
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot find an audio stream in the input file\n");
|
||||
return ret;
|
||||
}
|
||||
audio_stream_index = ret;
|
||||
dec_ctx = fmt_ctx->streams[audio_stream_index]->codec;
|
||||
av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
|
||||
|
||||
/* create decoding context */
|
||||
dec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!dec_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[audio_stream_index]->codecpar);
|
||||
|
||||
/* init the audio decoder */
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||
@@ -85,9 +88,9 @@ static int open_input_file(const char *filename)
|
||||
static int init_filters(const char *filters_descr)
|
||||
{
|
||||
char args[512];
|
||||
int ret;
|
||||
AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
|
||||
AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
|
||||
int ret = 0;
|
||||
const AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
|
||||
const AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
|
||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||
AVFilterInOut *inputs = avfilter_inout_alloc();
|
||||
static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
|
||||
@@ -97,6 +100,10 @@ static int init_filters(const char *filters_descr)
|
||||
AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;
|
||||
|
||||
filter_graph = avfilter_graph_alloc();
|
||||
if (!outputs || !inputs || !filter_graph) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* buffer audio source: the decoded frames from the decoder will be inserted here. */
|
||||
if (!dec_ctx->channel_layout)
|
||||
@@ -109,7 +116,7 @@ static int init_filters(const char *filters_descr)
|
||||
args, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
|
||||
return ret;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* buffer audio sink: to terminate the filter chain. */
|
||||
@@ -117,47 +124,63 @@ static int init_filters(const char *filters_descr)
|
||||
NULL, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
|
||||
return ret;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_opt_set_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1,
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
|
||||
return ret;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_opt_set_int_list(buffersink_ctx, "channel_layouts", out_channel_layouts, -1,
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
|
||||
return ret;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_opt_set_int_list(buffersink_ctx, "sample_rates", out_sample_rates, -1,
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
|
||||
return ret;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Endpoints for the filter graph. */
|
||||
/*
|
||||
* Set the endpoints for the filter graph. The filter_graph will
|
||||
* be linked to the graph described by filters_descr.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The buffer source output must be connected to the input pad of
|
||||
* the first filter described by filters_descr; since the first
|
||||
* filter input label is not specified, it is set to "in" by
|
||||
* default.
|
||||
*/
|
||||
outputs->name = av_strdup("in");
|
||||
outputs->filter_ctx = buffersrc_ctx;
|
||||
outputs->pad_idx = 0;
|
||||
outputs->next = NULL;
|
||||
|
||||
/*
|
||||
* The buffer sink input must be connected to the output pad of
|
||||
* the last filter described by filters_descr; since the last
|
||||
* filter output label is not specified, it is set to "out" by
|
||||
* default.
|
||||
*/
|
||||
inputs->name = av_strdup("out");
|
||||
inputs->filter_ctx = buffersink_ctx;
|
||||
inputs->pad_idx = 0;
|
||||
inputs->next = NULL;
|
||||
|
||||
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
|
||||
&inputs, &outputs, NULL)) < 0)
|
||||
return ret;
|
||||
&inputs, &outputs, NULL)) < 0)
|
||||
goto end;
|
||||
|
||||
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
|
||||
return ret;
|
||||
goto end;
|
||||
|
||||
/* Print summary of the sink buffer
|
||||
* Note: args buffer is reused to store channel layout string */
|
||||
@@ -168,12 +191,16 @@ static int init_filters(const char *filters_descr)
|
||||
(char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"),
|
||||
args);
|
||||
|
||||
return 0;
|
||||
end:
|
||||
avfilter_inout_free(&inputs);
|
||||
avfilter_inout_free(&outputs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void print_frame(const AVFrame *frame)
|
||||
{
|
||||
const int n = frame->nb_samples * av_get_channel_layout_nb_channels(av_frame_get_channel_layout(frame));
|
||||
const int n = frame->nb_samples * av_get_channel_layout_nb_channels(frame->channel_layout);
|
||||
const uint16_t *p = (uint16_t*)frame->data[0];
|
||||
const uint16_t *p_end = p + n;
|
||||
|
||||
@@ -188,13 +215,12 @@ static void print_frame(const AVFrame *frame)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
AVPacket packet;
|
||||
AVPacket *packet = av_packet_alloc();
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
AVFrame *filt_frame = av_frame_alloc();
|
||||
int got_frame;
|
||||
|
||||
if (!frame || !filt_frame) {
|
||||
perror("Could not allocate frame");
|
||||
if (!packet || !frame || !filt_frame) {
|
||||
fprintf(stderr, "Could not allocate frame or packet\n");
|
||||
exit(1);
|
||||
}
|
||||
if (argc != 2) {
|
||||
@@ -202,10 +228,6 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
avcodec_register_all();
|
||||
av_register_all();
|
||||
avfilter_register_all();
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
if ((ret = init_filters(filter_descr)) < 0)
|
||||
@@ -213,51 +235,58 @@ int main(int argc, char **argv)
|
||||
|
||||
/* read all packets */
|
||||
while (1) {
|
||||
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
|
||||
if ((ret = av_read_frame(fmt_ctx, packet)) < 0)
|
||||
break;
|
||||
|
||||
if (packet.stream_index == audio_stream_index) {
|
||||
avcodec_get_frame_defaults(frame);
|
||||
got_frame = 0;
|
||||
ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, &packet);
|
||||
if (packet->stream_index == audio_stream_index) {
|
||||
ret = avcodec_send_packet(dec_ctx, packet);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n");
|
||||
continue;
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (got_frame) {
|
||||
/* push the audio data from decoded frame into the filtergraph */
|
||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, 0) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
break;
|
||||
} else if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* pull filtered audio from the filtergraph */
|
||||
while (1) {
|
||||
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
||||
if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
if (ret >= 0) {
|
||||
/* push the audio data from decoded frame into the filtergraph */
|
||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
|
||||
break;
|
||||
if(ret < 0)
|
||||
goto end;
|
||||
print_frame(filt_frame);
|
||||
av_frame_unref(filt_frame);
|
||||
}
|
||||
|
||||
/* pull filtered audio from the filtergraph */
|
||||
while (1) {
|
||||
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
print_frame(filt_frame);
|
||||
av_frame_unref(filt_frame);
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
av_free_packet(&packet);
|
||||
av_packet_unref(packet);
|
||||
}
|
||||
end:
|
||||
avfilter_graph_free(&filter_graph);
|
||||
if (dec_ctx)
|
||||
avcodec_close(dec_ctx);
|
||||
avcodec_free_context(&dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
av_packet_free(&packet);
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&filt_frame);
|
||||
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
char buf[1024];
|
||||
av_strerror(ret, buf, sizeof(buf));
|
||||
fprintf(stderr, "Error occurred: %s\n", buf);
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
+88
-46
@@ -24,20 +24,24 @@
|
||||
/**
|
||||
* @file
|
||||
* API example for decoding and filtering
|
||||
* @example doc/examples/filtering_video.c
|
||||
* @example filtering_video.c
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 600 /* for usleep */
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavfilter/avfiltergraph.h>
|
||||
#include <libavfilter/avcodec.h>
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
const char *filter_descr = "scale=78:24";
|
||||
const char *filter_descr = "scale=78:24,transpose=cclock";
|
||||
/* other way:
|
||||
scale=78:24 [scl]; [scl] transpose=cclock // assumes "[in]" and "[out]" to be input output pads respectively
|
||||
*/
|
||||
|
||||
static AVFormatContext *fmt_ctx;
|
||||
static AVCodecContext *dec_ctx;
|
||||
@@ -49,8 +53,8 @@ static int64_t last_pts = AV_NOPTS_VALUE;
|
||||
|
||||
static int open_input_file(const char *filename)
|
||||
{
|
||||
const AVCodec *dec;
|
||||
int ret;
|
||||
AVCodec *dec;
|
||||
|
||||
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
|
||||
@@ -69,7 +73,12 @@ static int open_input_file(const char *filename)
|
||||
return ret;
|
||||
}
|
||||
video_stream_index = ret;
|
||||
dec_ctx = fmt_ctx->streams[video_stream_index]->codec;
|
||||
|
||||
/* create decoding context */
|
||||
dec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!dec_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[video_stream_index]->codecpar);
|
||||
|
||||
/* init the video decoder */
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||
@@ -83,47 +92,71 @@ static int open_input_file(const char *filename)
|
||||
static int init_filters(const char *filters_descr)
|
||||
{
|
||||
char args[512];
|
||||
int ret;
|
||||
AVFilter *buffersrc = avfilter_get_by_name("buffer");
|
||||
AVFilter *buffersink = avfilter_get_by_name("buffersink");
|
||||
int ret = 0;
|
||||
const AVFilter *buffersrc = avfilter_get_by_name("buffer");
|
||||
const AVFilter *buffersink = avfilter_get_by_name("buffersink");
|
||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||
AVFilterInOut *inputs = avfilter_inout_alloc();
|
||||
AVRational time_base = fmt_ctx->streams[video_stream_index]->time_base;
|
||||
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
|
||||
AVBufferSinkParams *buffersink_params;
|
||||
|
||||
filter_graph = avfilter_graph_alloc();
|
||||
if (!outputs || !inputs || !filter_graph) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* buffer video source: the decoded frames from the decoder will be inserted here. */
|
||||
snprintf(args, sizeof(args),
|
||||
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
|
||||
dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
|
||||
dec_ctx->time_base.num, dec_ctx->time_base.den,
|
||||
time_base.num, time_base.den,
|
||||
dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
|
||||
|
||||
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
|
||||
args, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
|
||||
return ret;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* buffer video sink: to terminate the filter chain. */
|
||||
buffersink_params = av_buffersink_params_alloc();
|
||||
buffersink_params->pixel_fmts = pix_fmts;
|
||||
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
|
||||
NULL, buffersink_params, filter_graph);
|
||||
av_free(buffersink_params);
|
||||
NULL, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
|
||||
return ret;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Endpoints for the filter graph. */
|
||||
ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,
|
||||
AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the endpoints for the filter graph. The filter_graph will
|
||||
* be linked to the graph described by filters_descr.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The buffer source output must be connected to the input pad of
|
||||
* the first filter described by filters_descr; since the first
|
||||
* filter input label is not specified, it is set to "in" by
|
||||
* default.
|
||||
*/
|
||||
outputs->name = av_strdup("in");
|
||||
outputs->filter_ctx = buffersrc_ctx;
|
||||
outputs->pad_idx = 0;
|
||||
outputs->next = NULL;
|
||||
|
||||
/*
|
||||
* The buffer sink input must be connected to the output pad of
|
||||
* the last filter described by filters_descr; since the last
|
||||
* filter output label is not specified, it is set to "out" by
|
||||
* default.
|
||||
*/
|
||||
inputs->name = av_strdup("out");
|
||||
inputs->filter_ctx = buffersink_ctx;
|
||||
inputs->pad_idx = 0;
|
||||
@@ -131,11 +164,16 @@ static int init_filters(const char *filters_descr)
|
||||
|
||||
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
|
||||
&inputs, &outputs, NULL)) < 0)
|
||||
return ret;
|
||||
goto end;
|
||||
|
||||
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
goto end;
|
||||
|
||||
end:
|
||||
avfilter_inout_free(&inputs);
|
||||
avfilter_inout_free(&outputs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void display_frame(const AVFrame *frame, AVRational time_base)
|
||||
@@ -172,23 +210,22 @@ static void display_frame(const AVFrame *frame, AVRational time_base)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
AVPacket packet;
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
AVFrame *filt_frame = av_frame_alloc();
|
||||
int got_frame;
|
||||
AVPacket *packet;
|
||||
AVFrame *frame;
|
||||
AVFrame *filt_frame;
|
||||
|
||||
if (!frame || !filt_frame) {
|
||||
perror("Could not allocate frame");
|
||||
exit(1);
|
||||
}
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s file\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
avcodec_register_all();
|
||||
av_register_all();
|
||||
avfilter_register_all();
|
||||
frame = av_frame_alloc();
|
||||
filt_frame = av_frame_alloc();
|
||||
packet = av_packet_alloc();
|
||||
if (!frame || !filt_frame || !packet) {
|
||||
fprintf(stderr, "Could not allocate frame or packet\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
@@ -197,20 +234,26 @@ int main(int argc, char **argv)
|
||||
|
||||
/* read all packets */
|
||||
while (1) {
|
||||
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
|
||||
if ((ret = av_read_frame(fmt_ctx, packet)) < 0)
|
||||
break;
|
||||
|
||||
if (packet.stream_index == video_stream_index) {
|
||||
avcodec_get_frame_defaults(frame);
|
||||
got_frame = 0;
|
||||
ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, &packet);
|
||||
if (packet->stream_index == video_stream_index) {
|
||||
ret = avcodec_send_packet(dec_ctx, packet);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error decoding video\n");
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (got_frame) {
|
||||
frame->pts = av_frame_get_best_effort_timestamp(frame);
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
break;
|
||||
} else if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
frame->pts = frame->best_effort_timestamp;
|
||||
|
||||
/* push the decoded frame into the filtergraph */
|
||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
|
||||
@@ -228,22 +271,21 @@ int main(int argc, char **argv)
|
||||
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
|
||||
av_frame_unref(filt_frame);
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
}
|
||||
av_free_packet(&packet);
|
||||
av_packet_unref(packet);
|
||||
}
|
||||
end:
|
||||
avfilter_graph_free(&filter_graph);
|
||||
if (dec_ctx)
|
||||
avcodec_close(dec_ctx);
|
||||
avcodec_free_context(&dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&filt_frame);
|
||||
av_packet_free(&packet);
|
||||
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
char buf[1024];
|
||||
av_strerror(ret, buf, sizeof(buf));
|
||||
fprintf(stderr, "Error occurred: %s\n", buf);
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Stephan Holljes
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* libavformat multi-client network API usage example.
|
||||
*
|
||||
* @example http_multiclient.c
|
||||
* This example will serve a file without decoding or demuxing it over http.
|
||||
* Multiple clients can connect and will receive the same file.
|
||||
*/
|
||||
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void process_client(AVIOContext *client, const char *in_uri)
|
||||
{
|
||||
AVIOContext *input = NULL;
|
||||
uint8_t buf[1024];
|
||||
int ret, n, reply_code;
|
||||
uint8_t *resource = NULL;
|
||||
while ((ret = avio_handshake(client)) > 0) {
|
||||
av_opt_get(client, "resource", AV_OPT_SEARCH_CHILDREN, &resource);
|
||||
// check for strlen(resource) is necessary, because av_opt_get()
|
||||
// may return empty string.
|
||||
if (resource && strlen(resource))
|
||||
break;
|
||||
av_freep(&resource);
|
||||
}
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
av_log(client, AV_LOG_TRACE, "resource=%p\n", resource);
|
||||
if (resource && resource[0] == '/' && !strcmp((resource + 1), in_uri)) {
|
||||
reply_code = 200;
|
||||
} else {
|
||||
reply_code = AVERROR_HTTP_NOT_FOUND;
|
||||
}
|
||||
if ((ret = av_opt_set_int(client, "reply_code", reply_code, AV_OPT_SEARCH_CHILDREN)) < 0) {
|
||||
av_log(client, AV_LOG_ERROR, "Failed to set reply_code: %s.\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
av_log(client, AV_LOG_TRACE, "Set reply code to %d\n", reply_code);
|
||||
|
||||
while ((ret = avio_handshake(client)) > 0);
|
||||
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
fprintf(stderr, "Handshake performed.\n");
|
||||
if (reply_code != 200)
|
||||
goto end;
|
||||
fprintf(stderr, "Opening input file.\n");
|
||||
if ((ret = avio_open2(&input, in_uri, AVIO_FLAG_READ, NULL, NULL)) < 0) {
|
||||
av_log(input, AV_LOG_ERROR, "Failed to open input: %s: %s.\n", in_uri,
|
||||
av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
for(;;) {
|
||||
n = avio_read(input, buf, sizeof(buf));
|
||||
if (n < 0) {
|
||||
if (n == AVERROR_EOF)
|
||||
break;
|
||||
av_log(input, AV_LOG_ERROR, "Error reading from input: %s.\n",
|
||||
av_err2str(n));
|
||||
break;
|
||||
}
|
||||
avio_write(client, buf, n);
|
||||
avio_flush(client);
|
||||
}
|
||||
end:
|
||||
fprintf(stderr, "Flushing client\n");
|
||||
avio_flush(client);
|
||||
fprintf(stderr, "Closing client\n");
|
||||
avio_close(client);
|
||||
fprintf(stderr, "Closing input\n");
|
||||
avio_close(input);
|
||||
av_freep(&resource);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
AVDictionary *options = NULL;
|
||||
AVIOContext *client = NULL, *server = NULL;
|
||||
const char *in_uri, *out_uri;
|
||||
int ret, pid;
|
||||
av_log_set_level(AV_LOG_TRACE);
|
||||
if (argc < 3) {
|
||||
printf("usage: %s input http://hostname[:port]\n"
|
||||
"API example program to serve http to multiple clients.\n"
|
||||
"\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uri = argv[1];
|
||||
out_uri = argv[2];
|
||||
|
||||
avformat_network_init();
|
||||
|
||||
if ((ret = av_dict_set(&options, "listen", "2", 0)) < 0) {
|
||||
fprintf(stderr, "Failed to set listen mode for server: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
if ((ret = avio_open2(&server, out_uri, AVIO_FLAG_WRITE, NULL, &options)) < 0) {
|
||||
fprintf(stderr, "Failed to open server: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
fprintf(stderr, "Entering main loop.\n");
|
||||
for(;;) {
|
||||
if ((ret = avio_accept(server, &client)) < 0)
|
||||
goto end;
|
||||
fprintf(stderr, "Accepted client, forking process.\n");
|
||||
// XXX: Since we don't reap our children and don't ignore signals
|
||||
// this produces zombie processes.
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("Fork failed");
|
||||
ret = AVERROR(errno);
|
||||
goto end;
|
||||
}
|
||||
if (pid == 0) {
|
||||
fprintf(stderr, "In child.\n");
|
||||
process_client(client, in_uri);
|
||||
avio_close(server);
|
||||
exit(0);
|
||||
}
|
||||
if (pid > 0)
|
||||
avio_close(client);
|
||||
}
|
||||
end:
|
||||
avio_close(server);
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
fprintf(stderr, "Some errors occurred: %s\n", av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+256
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Jun Zhao
|
||||
* Copyright (c) 2017 Kaixuan Liu
|
||||
*
|
||||
* HW Acceleration API (video decoding) decode sample
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* HW-Accelerated decoding example.
|
||||
*
|
||||
* @example hw_decode.c
|
||||
* This example shows how to do HW-accelerated decoding with output
|
||||
* frames from the HW video surfaces.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/avassert.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
|
||||
static AVBufferRef *hw_device_ctx = NULL;
|
||||
static enum AVPixelFormat hw_pix_fmt;
|
||||
static FILE *output_file = NULL;
|
||||
|
||||
static int hw_decoder_init(AVCodecContext *ctx, const enum AVHWDeviceType type)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if ((err = av_hwdevice_ctx_create(&hw_device_ctx, type,
|
||||
NULL, NULL, 0)) < 0) {
|
||||
fprintf(stderr, "Failed to create specified HW device.\n");
|
||||
return err;
|
||||
}
|
||||
ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static enum AVPixelFormat get_hw_format(AVCodecContext *ctx,
|
||||
const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
const enum AVPixelFormat *p;
|
||||
|
||||
for (p = pix_fmts; *p != -1; p++) {
|
||||
if (*p == hw_pix_fmt)
|
||||
return *p;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Failed to get HW surface format.\n");
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
static int decode_write(AVCodecContext *avctx, AVPacket *packet)
|
||||
{
|
||||
AVFrame *frame = NULL, *sw_frame = NULL;
|
||||
AVFrame *tmp_frame = NULL;
|
||||
uint8_t *buffer = NULL;
|
||||
int size;
|
||||
int ret = 0;
|
||||
|
||||
ret = avcodec_send_packet(avctx, packet);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (!(frame = av_frame_alloc()) || !(sw_frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "Can not alloc frame\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = avcodec_receive_frame(avctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&sw_frame);
|
||||
return 0;
|
||||
} else if (ret < 0) {
|
||||
fprintf(stderr, "Error while decoding\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (frame->format == hw_pix_fmt) {
|
||||
/* retrieve data from GPU to CPU */
|
||||
if ((ret = av_hwframe_transfer_data(sw_frame, frame, 0)) < 0) {
|
||||
fprintf(stderr, "Error transferring the data to system memory\n");
|
||||
goto fail;
|
||||
}
|
||||
tmp_frame = sw_frame;
|
||||
} else
|
||||
tmp_frame = frame;
|
||||
|
||||
size = av_image_get_buffer_size(tmp_frame->format, tmp_frame->width,
|
||||
tmp_frame->height, 1);
|
||||
buffer = av_malloc(size);
|
||||
if (!buffer) {
|
||||
fprintf(stderr, "Can not alloc buffer\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
ret = av_image_copy_to_buffer(buffer, size,
|
||||
(const uint8_t * const *)tmp_frame->data,
|
||||
(const int *)tmp_frame->linesize, tmp_frame->format,
|
||||
tmp_frame->width, tmp_frame->height, 1);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Can not copy image to buffer\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((ret = fwrite(buffer, 1, size, output_file)) < 0) {
|
||||
fprintf(stderr, "Failed to dump raw data.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&sw_frame);
|
||||
av_freep(&buffer);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
AVFormatContext *input_ctx = NULL;
|
||||
int video_stream, ret;
|
||||
AVStream *video = NULL;
|
||||
AVCodecContext *decoder_ctx = NULL;
|
||||
const AVCodec *decoder = NULL;
|
||||
AVPacket *packet = NULL;
|
||||
enum AVHWDeviceType type;
|
||||
int i;
|
||||
|
||||
if (argc < 4) {
|
||||
fprintf(stderr, "Usage: %s <device type> <input file> <output file>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
type = av_hwdevice_find_type_by_name(argv[1]);
|
||||
if (type == AV_HWDEVICE_TYPE_NONE) {
|
||||
fprintf(stderr, "Device type %s is not supported.\n", argv[1]);
|
||||
fprintf(stderr, "Available device types:");
|
||||
while((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE)
|
||||
fprintf(stderr, " %s", av_hwdevice_get_type_name(type));
|
||||
fprintf(stderr, "\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
packet = av_packet_alloc();
|
||||
if (!packet) {
|
||||
fprintf(stderr, "Failed to allocate AVPacket\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open the input file */
|
||||
if (avformat_open_input(&input_ctx, argv[2], NULL, NULL) != 0) {
|
||||
fprintf(stderr, "Cannot open input file '%s'\n", argv[2]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (avformat_find_stream_info(input_ctx, NULL) < 0) {
|
||||
fprintf(stderr, "Cannot find input stream information.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find the video stream information */
|
||||
ret = av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot find a video stream in the input file\n");
|
||||
return -1;
|
||||
}
|
||||
video_stream = ret;
|
||||
|
||||
for (i = 0;; i++) {
|
||||
const AVCodecHWConfig *config = avcodec_get_hw_config(decoder, i);
|
||||
if (!config) {
|
||||
fprintf(stderr, "Decoder %s does not support device type %s.\n",
|
||||
decoder->name, av_hwdevice_get_type_name(type));
|
||||
return -1;
|
||||
}
|
||||
if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
|
||||
config->device_type == type) {
|
||||
hw_pix_fmt = config->pix_fmt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(decoder_ctx = avcodec_alloc_context3(decoder)))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
video = input_ctx->streams[video_stream];
|
||||
if (avcodec_parameters_to_context(decoder_ctx, video->codecpar) < 0)
|
||||
return -1;
|
||||
|
||||
decoder_ctx->get_format = get_hw_format;
|
||||
|
||||
if (hw_decoder_init(decoder_ctx, type) < 0)
|
||||
return -1;
|
||||
|
||||
if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0) {
|
||||
fprintf(stderr, "Failed to open codec for stream #%u\n", video_stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open the file to dump raw data */
|
||||
output_file = fopen(argv[3], "w+b");
|
||||
|
||||
/* actual decoding and dump the raw data */
|
||||
while (ret >= 0) {
|
||||
if ((ret = av_read_frame(input_ctx, packet)) < 0)
|
||||
break;
|
||||
|
||||
if (video_stream == packet->stream_index)
|
||||
ret = decode_write(decoder_ctx, packet);
|
||||
|
||||
av_packet_unref(packet);
|
||||
}
|
||||
|
||||
/* flush the decoder */
|
||||
ret = decode_write(decoder_ctx, NULL);
|
||||
|
||||
if (output_file)
|
||||
fclose(output_file);
|
||||
av_packet_free(&packet);
|
||||
avcodec_free_context(&decoder_ctx);
|
||||
avformat_close_input(&input_ctx);
|
||||
av_buffer_unref(&hw_device_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+7
-3
@@ -23,7 +23,7 @@
|
||||
/**
|
||||
* @file
|
||||
* Shows how the metadata API can be used in application programs.
|
||||
* @example doc/examples/metadata.c
|
||||
* @example metadata.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -34,7 +34,7 @@
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
AVFormatContext *fmt_ctx = NULL;
|
||||
AVDictionaryEntry *tag = NULL;
|
||||
const AVDictionaryEntry *tag = NULL;
|
||||
int ret;
|
||||
|
||||
if (argc != 2) {
|
||||
@@ -44,10 +44,14 @@ int main (int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
av_register_all();
|
||||
if ((ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL)))
|
||||
return ret;
|
||||
|
||||
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
|
||||
printf("%s=%s\n", tag->key, tag->value);
|
||||
|
||||
|
||||
Vendored
+373
-276
@@ -24,9 +24,9 @@
|
||||
* @file
|
||||
* libavformat API example.
|
||||
*
|
||||
* Output a media file in any supported libavformat format.
|
||||
* The default codecs are used.
|
||||
* @example doc/examples/muxing.c
|
||||
* Output a media file in any supported libavformat format. The default
|
||||
* codecs are used.
|
||||
* @example muxing.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -34,26 +34,101 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <libavutil/avassert.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/mathematics.h>
|
||||
#include <libavutil/timestamp.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libswscale/swscale.h>
|
||||
#include <libswresample/swresample.h>
|
||||
|
||||
/* 5 seconds stream duration */
|
||||
#define STREAM_DURATION 200.0
|
||||
#define STREAM_DURATION 10.0
|
||||
#define STREAM_FRAME_RATE 25 /* 25 images/s */
|
||||
#define STREAM_NB_FRAMES ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
|
||||
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
|
||||
|
||||
static int sws_flags = SWS_BICUBIC;
|
||||
#define SCALE_FLAGS SWS_BICUBIC
|
||||
|
||||
// a wrapper around a single output AVStream
|
||||
typedef struct OutputStream {
|
||||
AVStream *st;
|
||||
AVCodecContext *enc;
|
||||
|
||||
/* pts of the next frame that will be generated */
|
||||
int64_t next_pts;
|
||||
int samples_count;
|
||||
|
||||
AVFrame *frame;
|
||||
AVFrame *tmp_frame;
|
||||
|
||||
AVPacket *tmp_pkt;
|
||||
|
||||
float t, tincr, tincr2;
|
||||
|
||||
struct SwsContext *sws_ctx;
|
||||
struct SwrContext *swr_ctx;
|
||||
} OutputStream;
|
||||
|
||||
static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
|
||||
{
|
||||
AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
|
||||
|
||||
printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
|
||||
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
|
||||
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
|
||||
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
|
||||
pkt->stream_index);
|
||||
}
|
||||
|
||||
static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c,
|
||||
AVStream *st, AVFrame *frame, AVPacket *pkt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
// send the frame to the encoder
|
||||
ret = avcodec_send_frame(c, frame);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error sending a frame to the encoder: %s\n",
|
||||
av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(c, pkt);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding a frame: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* rescale output packet timestamp values from codec to stream timebase */
|
||||
av_packet_rescale_ts(pkt, c->time_base, st->time_base);
|
||||
pkt->stream_index = st->index;
|
||||
|
||||
/* Write the compressed frame to the media file. */
|
||||
log_packet(fmt_ctx, pkt);
|
||||
ret = av_interleaved_write_frame(fmt_ctx, pkt);
|
||||
/* pkt is now blank (av_interleaved_write_frame() takes ownership of
|
||||
* its contents and resets pkt), so that no unreferencing is necessary.
|
||||
* This would be different if one used av_write_frame(). */
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while writing output packet: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return ret == AVERROR_EOF ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Add an output stream. */
|
||||
static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
|
||||
enum AVCodecID codec_id)
|
||||
static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
||||
const AVCodec **codec,
|
||||
enum AVCodecID codec_id)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
AVStream *st;
|
||||
int i;
|
||||
|
||||
/* find the encoder */
|
||||
*codec = avcodec_find_encoder(codec_id);
|
||||
@@ -63,20 +138,49 @@ static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
st = avformat_new_stream(oc, *codec);
|
||||
if (!st) {
|
||||
ost->tmp_pkt = av_packet_alloc();
|
||||
if (!ost->tmp_pkt) {
|
||||
fprintf(stderr, "Could not allocate AVPacket\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ost->st = avformat_new_stream(oc, NULL);
|
||||
if (!ost->st) {
|
||||
fprintf(stderr, "Could not allocate stream\n");
|
||||
exit(1);
|
||||
}
|
||||
st->id = oc->nb_streams-1;
|
||||
c = st->codec;
|
||||
ost->st->id = oc->nb_streams-1;
|
||||
c = avcodec_alloc_context3(*codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not alloc an encoding context\n");
|
||||
exit(1);
|
||||
}
|
||||
ost->enc = c;
|
||||
|
||||
switch ((*codec)->type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
c->sample_fmt = AV_SAMPLE_FMT_FLTP;
|
||||
c->sample_fmt = (*codec)->sample_fmts ?
|
||||
(*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
|
||||
c->bit_rate = 64000;
|
||||
c->sample_rate = 44100;
|
||||
c->channels = 2;
|
||||
if ((*codec)->supported_samplerates) {
|
||||
c->sample_rate = (*codec)->supported_samplerates[0];
|
||||
for (i = 0; (*codec)->supported_samplerates[i]; i++) {
|
||||
if ((*codec)->supported_samplerates[i] == 44100)
|
||||
c->sample_rate = 44100;
|
||||
}
|
||||
}
|
||||
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
|
||||
c->channel_layout = AV_CH_LAYOUT_STEREO;
|
||||
if ((*codec)->channel_layouts) {
|
||||
c->channel_layout = (*codec)->channel_layouts[0];
|
||||
for (i = 0; (*codec)->channel_layouts[i]; i++) {
|
||||
if ((*codec)->channel_layouts[i] == AV_CH_LAYOUT_STEREO)
|
||||
c->channel_layout = AV_CH_LAYOUT_STEREO;
|
||||
}
|
||||
}
|
||||
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
|
||||
ost->st->time_base = (AVRational){ 1, c->sample_rate };
|
||||
break;
|
||||
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
@@ -90,12 +194,13 @@ static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
|
||||
* of which frame timestamps are represented. For fixed-fps content,
|
||||
* timebase should be 1/framerate and timestamp increments should be
|
||||
* identical to 1. */
|
||||
c->time_base.den = STREAM_FRAME_RATE;
|
||||
c->time_base.num = 1;
|
||||
ost->st->time_base = (AVRational){ 1, STREAM_FRAME_RATE };
|
||||
c->time_base = ost->st->time_base;
|
||||
|
||||
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
|
||||
c->pix_fmt = STREAM_PIX_FMT;
|
||||
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
|
||||
/* just for testing, we also add B frames */
|
||||
/* just for testing, we also add B-frames */
|
||||
c->max_b_frames = 2;
|
||||
}
|
||||
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
|
||||
@@ -104,7 +209,7 @@ static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
|
||||
* the motion of the chroma plane does not match the luma plane. */
|
||||
c->mb_decision = 2;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -112,235 +217,250 @@ static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
|
||||
|
||||
/* Some formats want stream headers to be separate. */
|
||||
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
return st;
|
||||
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
/* audio output */
|
||||
|
||||
static float t, tincr, tincr2;
|
||||
|
||||
static uint8_t **src_samples_data;
|
||||
static int src_samples_linesize;
|
||||
static int src_nb_samples;
|
||||
|
||||
static int max_dst_nb_samples;
|
||||
uint8_t **dst_samples_data;
|
||||
int dst_samples_linesize;
|
||||
int dst_samples_size;
|
||||
|
||||
struct SwrContext *swr_ctx = NULL;
|
||||
|
||||
static void open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st)
|
||||
static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
|
||||
uint64_t channel_layout,
|
||||
int sample_rate, int nb_samples)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
int ret;
|
||||
|
||||
c = st->codec;
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Error allocating an audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame->format = sample_fmt;
|
||||
frame->channel_layout = channel_layout;
|
||||
frame->sample_rate = sample_rate;
|
||||
frame->nb_samples = nb_samples;
|
||||
|
||||
if (nb_samples) {
|
||||
ret = av_frame_get_buffer(frame, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error allocating an audio buffer\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void open_audio(AVFormatContext *oc, const AVCodec *codec,
|
||||
OutputStream *ost, AVDictionary *opt_arg)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
int nb_samples;
|
||||
int ret;
|
||||
AVDictionary *opt = NULL;
|
||||
|
||||
c = ost->enc;
|
||||
|
||||
/* open it */
|
||||
ret = avcodec_open2(c, codec, NULL);
|
||||
av_dict_copy(&opt, opt_arg, 0);
|
||||
ret = avcodec_open2(c, codec, &opt);
|
||||
av_dict_free(&opt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open audio codec: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* init signal generator */
|
||||
t = 0;
|
||||
tincr = 2 * M_PI * 110.0 / c->sample_rate;
|
||||
ost->t = 0;
|
||||
ost->tincr = 2 * M_PI * 110.0 / c->sample_rate;
|
||||
/* increment frequency by 110 Hz per second */
|
||||
tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
|
||||
ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
|
||||
|
||||
src_nb_samples = c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE ?
|
||||
10000 : c->frame_size;
|
||||
if (c->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
|
||||
nb_samples = 10000;
|
||||
else
|
||||
nb_samples = c->frame_size;
|
||||
|
||||
ret = av_samples_alloc_array_and_samples(&src_samples_data, &src_samples_linesize, c->channels,
|
||||
src_nb_samples, c->sample_fmt, 0);
|
||||
ost->frame = alloc_audio_frame(c->sample_fmt, c->channel_layout,
|
||||
c->sample_rate, nb_samples);
|
||||
ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout,
|
||||
c->sample_rate, nb_samples);
|
||||
|
||||
/* copy the stream parameters to the muxer */
|
||||
ret = avcodec_parameters_from_context(ost->st->codecpar, c);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate source samples\n");
|
||||
fprintf(stderr, "Could not copy the stream parameters\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* create resampler context */
|
||||
if (c->sample_fmt != AV_SAMPLE_FMT_S16) {
|
||||
swr_ctx = swr_alloc();
|
||||
if (!swr_ctx) {
|
||||
fprintf(stderr, "Could not allocate resampler context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* set options */
|
||||
av_opt_set_int (swr_ctx, "in_channel_count", c->channels, 0);
|
||||
av_opt_set_int (swr_ctx, "in_sample_rate", c->sample_rate, 0);
|
||||
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||
av_opt_set_int (swr_ctx, "out_channel_count", c->channels, 0);
|
||||
av_opt_set_int (swr_ctx, "out_sample_rate", c->sample_rate, 0);
|
||||
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
|
||||
ost->swr_ctx = swr_alloc();
|
||||
if (!ost->swr_ctx) {
|
||||
fprintf(stderr, "Could not allocate resampler context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* initialize the resampling context */
|
||||
if ((ret = swr_init(swr_ctx)) < 0) {
|
||||
fprintf(stderr, "Failed to initialize the resampling context\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/* set options */
|
||||
av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0);
|
||||
av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0);
|
||||
av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||
av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0);
|
||||
av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0);
|
||||
av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
|
||||
|
||||
/* compute the number of converted samples: buffering is avoided
|
||||
* ensuring that the output buffer will contain at least all the
|
||||
* converted input samples */
|
||||
max_dst_nb_samples = src_nb_samples;
|
||||
ret = av_samples_alloc_array_and_samples(&dst_samples_data, &dst_samples_linesize, c->channels,
|
||||
max_dst_nb_samples, c->sample_fmt, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate destination samples\n");
|
||||
/* initialize the resampling context */
|
||||
if ((ret = swr_init(ost->swr_ctx)) < 0) {
|
||||
fprintf(stderr, "Failed to initialize the resampling context\n");
|
||||
exit(1);
|
||||
}
|
||||
dst_samples_size = av_samples_get_buffer_size(NULL, c->channels, max_dst_nb_samples,
|
||||
c->sample_fmt, 0);
|
||||
}
|
||||
|
||||
/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
|
||||
* 'nb_channels' channels. */
|
||||
static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
|
||||
static AVFrame *get_audio_frame(OutputStream *ost)
|
||||
{
|
||||
AVFrame *frame = ost->tmp_frame;
|
||||
int j, i, v;
|
||||
int16_t *q;
|
||||
int16_t *q = (int16_t*)frame->data[0];
|
||||
|
||||
q = samples;
|
||||
for (j = 0; j < frame_size; j++) {
|
||||
v = (int)(sin(t) * 10000);
|
||||
for (i = 0; i < nb_channels; i++)
|
||||
/* check if we want to generate more frames */
|
||||
if (av_compare_ts(ost->next_pts, ost->enc->time_base,
|
||||
STREAM_DURATION, (AVRational){ 1, 1 }) > 0)
|
||||
return NULL;
|
||||
|
||||
for (j = 0; j <frame->nb_samples; j++) {
|
||||
v = (int)(sin(ost->t) * 10000);
|
||||
for (i = 0; i < ost->enc->channels; i++)
|
||||
*q++ = v;
|
||||
t += tincr;
|
||||
tincr += tincr2;
|
||||
ost->t += ost->tincr;
|
||||
ost->tincr += ost->tincr2;
|
||||
}
|
||||
|
||||
frame->pts = ost->next_pts;
|
||||
ost->next_pts += frame->nb_samples;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void write_audio_frame(AVFormatContext *oc, AVStream *st)
|
||||
/*
|
||||
* encode one audio frame and send it to the muxer
|
||||
* return 1 when encoding is finished, 0 otherwise
|
||||
*/
|
||||
static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
AVPacket pkt = { 0 }; // data and size must be 0;
|
||||
AVFrame *frame = avcodec_alloc_frame();
|
||||
int got_packet, ret, dst_nb_samples;
|
||||
AVFrame *frame;
|
||||
int ret;
|
||||
int dst_nb_samples;
|
||||
|
||||
av_init_packet(&pkt);
|
||||
c = st->codec;
|
||||
c = ost->enc;
|
||||
|
||||
get_audio_frame((int16_t *)src_samples_data[0], src_nb_samples, c->channels);
|
||||
frame = get_audio_frame(ost);
|
||||
|
||||
/* convert samples from native format to destination codec format, using the resampler */
|
||||
if (swr_ctx) {
|
||||
if (frame) {
|
||||
/* convert samples from native format to destination codec format, using the resampler */
|
||||
/* compute destination number of samples */
|
||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, c->sample_rate) + src_nb_samples,
|
||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples,
|
||||
c->sample_rate, c->sample_rate, AV_ROUND_UP);
|
||||
if (dst_nb_samples > max_dst_nb_samples) {
|
||||
av_free(dst_samples_data[0]);
|
||||
ret = av_samples_alloc(dst_samples_data, &dst_samples_linesize, c->channels,
|
||||
dst_nb_samples, c->sample_fmt, 0);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
max_dst_nb_samples = dst_nb_samples;
|
||||
dst_samples_size = av_samples_get_buffer_size(NULL, c->channels, dst_nb_samples,
|
||||
c->sample_fmt, 0);
|
||||
}
|
||||
av_assert0(dst_nb_samples == frame->nb_samples);
|
||||
|
||||
/* when we pass a frame to the encoder, it may keep a reference to it
|
||||
* internally;
|
||||
* make sure we do not overwrite it here
|
||||
*/
|
||||
ret = av_frame_make_writable(ost->frame);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
/* convert to destination format */
|
||||
ret = swr_convert(swr_ctx,
|
||||
dst_samples_data, dst_nb_samples,
|
||||
(const uint8_t **)src_samples_data, src_nb_samples);
|
||||
ret = swr_convert(ost->swr_ctx,
|
||||
ost->frame->data, dst_nb_samples,
|
||||
(const uint8_t **)frame->data, frame->nb_samples);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while converting\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
dst_samples_data[0] = src_samples_data[0];
|
||||
dst_nb_samples = src_nb_samples;
|
||||
frame = ost->frame;
|
||||
|
||||
frame->pts = av_rescale_q(ost->samples_count, (AVRational){1, c->sample_rate}, c->time_base);
|
||||
ost->samples_count += dst_nb_samples;
|
||||
}
|
||||
|
||||
frame->nb_samples = dst_nb_samples;
|
||||
avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
|
||||
dst_samples_data[0], dst_samples_size, 0);
|
||||
|
||||
ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!got_packet)
|
||||
return;
|
||||
|
||||
pkt.stream_index = st->index;
|
||||
|
||||
/* Write the compressed frame to the media file. */
|
||||
ret = av_interleaved_write_frame(oc, &pkt);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Error while writing audio frame: %s\n",
|
||||
av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
avcodec_free_frame(&frame);
|
||||
}
|
||||
|
||||
static void close_audio(AVFormatContext *oc, AVStream *st)
|
||||
{
|
||||
avcodec_close(st->codec);
|
||||
av_free(src_samples_data[0]);
|
||||
av_free(dst_samples_data[0]);
|
||||
return write_frame(oc, c, ost->st, frame, ost->tmp_pkt);
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
/* video output */
|
||||
|
||||
static AVFrame *frame;
|
||||
static AVPicture src_picture, dst_picture;
|
||||
static int frame_count;
|
||||
static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
|
||||
{
|
||||
AVFrame *picture;
|
||||
int ret;
|
||||
|
||||
static void open_video(AVFormatContext *oc, AVCodec *codec, AVStream *st)
|
||||
picture = av_frame_alloc();
|
||||
if (!picture)
|
||||
return NULL;
|
||||
|
||||
picture->format = pix_fmt;
|
||||
picture->width = width;
|
||||
picture->height = height;
|
||||
|
||||
/* allocate the buffers for the frame data */
|
||||
ret = av_frame_get_buffer(picture, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate frame data.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return picture;
|
||||
}
|
||||
|
||||
static void open_video(AVFormatContext *oc, const AVCodec *codec,
|
||||
OutputStream *ost, AVDictionary *opt_arg)
|
||||
{
|
||||
int ret;
|
||||
AVCodecContext *c = st->codec;
|
||||
AVCodecContext *c = ost->enc;
|
||||
AVDictionary *opt = NULL;
|
||||
|
||||
av_dict_copy(&opt, opt_arg, 0);
|
||||
|
||||
/* open the codec */
|
||||
ret = avcodec_open2(c, codec, NULL);
|
||||
ret = avcodec_open2(c, codec, &opt);
|
||||
av_dict_free(&opt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open video codec: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* allocate and init a re-usable frame */
|
||||
frame = avcodec_alloc_frame();
|
||||
if (!frame) {
|
||||
ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);
|
||||
if (!ost->frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Allocate the encoded raw picture. */
|
||||
ret = avpicture_alloc(&dst_picture, c->pix_fmt, c->width, c->height);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate picture: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* If the output format is not YUV420P, then a temporary YUV420P
|
||||
* picture is needed too. It is then converted to the required
|
||||
* output format. */
|
||||
ost->tmp_frame = NULL;
|
||||
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
|
||||
ret = avpicture_alloc(&src_picture, AV_PIX_FMT_YUV420P, c->width, c->height);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate temporary picture: %s\n",
|
||||
av_err2str(ret));
|
||||
ost->tmp_frame = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
|
||||
if (!ost->tmp_frame) {
|
||||
fprintf(stderr, "Could not allocate temporary picture\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* copy data and linesize picture pointers to frame */
|
||||
*((AVPicture *)frame) = dst_picture;
|
||||
/* copy the stream parameters to the muxer */
|
||||
ret = avcodec_parameters_from_context(ost->st->codecpar, c);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not copy the stream parameters\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare a dummy image. */
|
||||
static void fill_yuv_image(AVPicture *pict, int frame_index,
|
||||
static void fill_yuv_image(AVFrame *pict, int frame_index,
|
||||
int width, int height)
|
||||
{
|
||||
int x, y, i;
|
||||
@@ -361,85 +481,65 @@ static void fill_yuv_image(AVPicture *pict, int frame_index,
|
||||
}
|
||||
}
|
||||
|
||||
static void write_video_frame(AVFormatContext *oc, AVStream *st)
|
||||
static AVFrame *get_video_frame(OutputStream *ost)
|
||||
{
|
||||
int ret;
|
||||
static struct SwsContext *sws_ctx;
|
||||
AVCodecContext *c = st->codec;
|
||||
AVCodecContext *c = ost->enc;
|
||||
|
||||
if (frame_count >= STREAM_NB_FRAMES) {
|
||||
/* No more frames to compress. The codec has a latency of a few
|
||||
* frames if using B-frames, so we get the last frames by
|
||||
* passing the same picture again. */
|
||||
} else {
|
||||
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
|
||||
/* as we only generate a YUV420P picture, we must convert it
|
||||
* to the codec pixel format if needed */
|
||||
if (!sws_ctx) {
|
||||
sws_ctx = sws_getContext(c->width, c->height, AV_PIX_FMT_YUV420P,
|
||||
c->width, c->height, c->pix_fmt,
|
||||
sws_flags, NULL, NULL, NULL);
|
||||
if (!sws_ctx) {
|
||||
fprintf(stderr,
|
||||
"Could not initialize the conversion context\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
fill_yuv_image(&src_picture, frame_count, c->width, c->height);
|
||||
sws_scale(sws_ctx,
|
||||
(const uint8_t * const *)src_picture.data, src_picture.linesize,
|
||||
0, c->height, dst_picture.data, dst_picture.linesize);
|
||||
} else {
|
||||
fill_yuv_image(&dst_picture, frame_count, c->width, c->height);
|
||||
}
|
||||
}
|
||||
/* check if we want to generate more frames */
|
||||
if (av_compare_ts(ost->next_pts, c->time_base,
|
||||
STREAM_DURATION, (AVRational){ 1, 1 }) > 0)
|
||||
return NULL;
|
||||
|
||||
if (oc->oformat->flags & AVFMT_RAWPICTURE) {
|
||||
/* Raw video case - directly store the picture in the packet */
|
||||
AVPacket pkt;
|
||||
av_init_packet(&pkt);
|
||||
|
||||
pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
pkt.stream_index = st->index;
|
||||
pkt.data = dst_picture.data[0];
|
||||
pkt.size = sizeof(AVPicture);
|
||||
|
||||
ret = av_interleaved_write_frame(oc, &pkt);
|
||||
} else {
|
||||
AVPacket pkt = { 0 };
|
||||
int got_packet;
|
||||
av_init_packet(&pkt);
|
||||
|
||||
/* encode the image */
|
||||
ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
/* If size is zero, it means the image was buffered. */
|
||||
|
||||
if (!ret && got_packet && pkt.size) {
|
||||
pkt.stream_index = st->index;
|
||||
|
||||
/* Write the compressed frame to the media file. */
|
||||
ret = av_interleaved_write_frame(oc, &pkt);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
|
||||
/* when we pass a frame to the encoder, it may keep a reference to it
|
||||
* internally; make sure we do not overwrite it here */
|
||||
if (av_frame_make_writable(ost->frame) < 0)
|
||||
exit(1);
|
||||
|
||||
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
|
||||
/* as we only generate a YUV420P picture, we must convert it
|
||||
* to the codec pixel format if needed */
|
||||
if (!ost->sws_ctx) {
|
||||
ost->sws_ctx = sws_getContext(c->width, c->height,
|
||||
AV_PIX_FMT_YUV420P,
|
||||
c->width, c->height,
|
||||
c->pix_fmt,
|
||||
SCALE_FLAGS, NULL, NULL, NULL);
|
||||
if (!ost->sws_ctx) {
|
||||
fprintf(stderr,
|
||||
"Could not initialize the conversion context\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
fill_yuv_image(ost->tmp_frame, ost->next_pts, c->width, c->height);
|
||||
sws_scale(ost->sws_ctx, (const uint8_t * const *) ost->tmp_frame->data,
|
||||
ost->tmp_frame->linesize, 0, c->height, ost->frame->data,
|
||||
ost->frame->linesize);
|
||||
} else {
|
||||
fill_yuv_image(ost->frame, ost->next_pts, c->width, c->height);
|
||||
}
|
||||
frame_count++;
|
||||
|
||||
ost->frame->pts = ost->next_pts++;
|
||||
|
||||
return ost->frame;
|
||||
}
|
||||
|
||||
static void close_video(AVFormatContext *oc, AVStream *st)
|
||||
/*
|
||||
* encode one video frame and send it to the muxer
|
||||
* return 1 when encoding is finished, 0 otherwise
|
||||
*/
|
||||
static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
|
||||
{
|
||||
avcodec_close(st->codec);
|
||||
av_free(src_picture.data[0]);
|
||||
av_free(dst_picture.data[0]);
|
||||
av_free(frame);
|
||||
return write_frame(oc, ost->enc, ost->st, get_video_frame(ost), ost->tmp_pkt);
|
||||
}
|
||||
|
||||
static void close_stream(AVFormatContext *oc, OutputStream *ost)
|
||||
{
|
||||
avcodec_free_context(&ost->enc);
|
||||
av_frame_free(&ost->frame);
|
||||
av_frame_free(&ost->tmp_frame);
|
||||
av_packet_free(&ost->tmp_pkt);
|
||||
sws_freeContext(ost->sws_ctx);
|
||||
swr_free(&ost->swr_ctx);
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
@@ -447,18 +547,18 @@ static void close_video(AVFormatContext *oc, AVStream *st)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
OutputStream video_st = { 0 }, audio_st = { 0 };
|
||||
const AVOutputFormat *fmt;
|
||||
const char *filename;
|
||||
AVOutputFormat *fmt;
|
||||
AVFormatContext *oc;
|
||||
AVStream *audio_st, *video_st;
|
||||
AVCodec *audio_codec, *video_codec;
|
||||
double audio_time, video_time;
|
||||
const AVCodec *audio_codec, *video_codec;
|
||||
int ret;
|
||||
int have_video = 0, have_audio = 0;
|
||||
int encode_video = 0, encode_audio = 0;
|
||||
AVDictionary *opt = NULL;
|
||||
int i;
|
||||
|
||||
/* Initialize libavcodec, and register all codecs and formats. */
|
||||
av_register_all();
|
||||
|
||||
if (argc != 2) {
|
||||
if (argc < 2) {
|
||||
printf("usage: %s output_file\n"
|
||||
"API example program to output a media file with libavformat.\n"
|
||||
"This program generates a synthetic audio and video stream, encodes and\n"
|
||||
@@ -470,6 +570,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
filename = argv[1];
|
||||
for (i = 2; i+1 < argc; i+=2) {
|
||||
if (!strcmp(argv[i], "-flags") || !strcmp(argv[i], "-fflags"))
|
||||
av_dict_set(&opt, argv[i]+1, argv[i+1], 0);
|
||||
}
|
||||
|
||||
/* allocate the output media context */
|
||||
avformat_alloc_output_context2(&oc, NULL, NULL, filename);
|
||||
@@ -477,29 +581,31 @@ int main(int argc, char **argv)
|
||||
printf("Could not deduce output format from file extension: using MPEG.\n");
|
||||
avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
|
||||
}
|
||||
if (!oc) {
|
||||
if (!oc)
|
||||
return 1;
|
||||
}
|
||||
|
||||
fmt = oc->oformat;
|
||||
|
||||
/* Add the audio and video streams using the default format codecs
|
||||
* and initialize the codecs. */
|
||||
video_st = NULL;
|
||||
audio_st = NULL;
|
||||
|
||||
if (fmt->video_codec != AV_CODEC_ID_NONE) {
|
||||
video_st = add_stream(oc, &video_codec, fmt->video_codec);
|
||||
add_stream(&video_st, oc, &video_codec, fmt->video_codec);
|
||||
have_video = 1;
|
||||
encode_video = 1;
|
||||
}
|
||||
if (fmt->audio_codec != AV_CODEC_ID_NONE) {
|
||||
audio_st = add_stream(oc, &audio_codec, fmt->audio_codec);
|
||||
add_stream(&audio_st, oc, &audio_codec, fmt->audio_codec);
|
||||
have_audio = 1;
|
||||
encode_audio = 1;
|
||||
}
|
||||
|
||||
/* Now that all the parameters are set, we can open the audio and
|
||||
* video codecs and allocate the necessary encode buffers. */
|
||||
if (video_st)
|
||||
open_video(oc, video_codec, video_st);
|
||||
if (audio_st)
|
||||
open_audio(oc, audio_codec, audio_st);
|
||||
if (have_video)
|
||||
open_video(oc, video_codec, &video_st, opt);
|
||||
|
||||
if (have_audio)
|
||||
open_audio(oc, audio_codec, &audio_st, opt);
|
||||
|
||||
av_dump_format(oc, 0, filename, 1);
|
||||
|
||||
@@ -514,30 +620,21 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* Write the stream header, if any. */
|
||||
ret = avformat_write_header(oc, NULL);
|
||||
ret = avformat_write_header(oc, &opt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error occurred when opening output file: %s\n",
|
||||
av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (frame)
|
||||
frame->pts = 0;
|
||||
for (;;) {
|
||||
/* Compute current audio and video time. */
|
||||
audio_time = audio_st ? audio_st->pts.val * av_q2d(audio_st->time_base) : 0.0;
|
||||
video_time = video_st ? video_st->pts.val * av_q2d(video_st->time_base) : 0.0;
|
||||
|
||||
if ((!audio_st || audio_time >= STREAM_DURATION) &&
|
||||
(!video_st || video_time >= STREAM_DURATION))
|
||||
break;
|
||||
|
||||
/* write interleaved audio and video frames */
|
||||
if (!video_st || (video_st && audio_st && audio_time < video_time)) {
|
||||
write_audio_frame(oc, audio_st);
|
||||
while (encode_video || encode_audio) {
|
||||
/* select the stream to encode */
|
||||
if (encode_video &&
|
||||
(!encode_audio || av_compare_ts(video_st.next_pts, video_st.enc->time_base,
|
||||
audio_st.next_pts, audio_st.enc->time_base) <= 0)) {
|
||||
encode_video = !write_video_frame(oc, &video_st);
|
||||
} else {
|
||||
write_video_frame(oc, video_st);
|
||||
frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base);
|
||||
encode_audio = !write_audio_frame(oc, &audio_st);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,14 +645,14 @@ int main(int argc, char **argv)
|
||||
av_write_trailer(oc);
|
||||
|
||||
/* Close each codec. */
|
||||
if (video_st)
|
||||
close_video(oc, video_st);
|
||||
if (audio_st)
|
||||
close_audio(oc, audio_st);
|
||||
if (have_video)
|
||||
close_stream(oc, &video_st);
|
||||
if (have_audio)
|
||||
close_stream(oc, &audio_st);
|
||||
|
||||
if (!(fmt->flags & AVFMT_NOFILE))
|
||||
/* Close the output file. */
|
||||
avio_close(oc->pb);
|
||||
avio_closep(&oc->pb);
|
||||
|
||||
/* free the stream */
|
||||
avformat_free_context(oc);
|
||||
|
||||
Vendored
+244
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Anton Khirnov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Intel QSV-accelerated H.264 decoding example.
|
||||
*
|
||||
* @example qsvdec.c
|
||||
* This example shows how to do QSV-accelerated H.264 decoding with output
|
||||
* frames in the GPU video surfaces.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavformat/avio.h"
|
||||
|
||||
#include "libavcodec/avcodec.h"
|
||||
|
||||
#include "libavutil/buffer.h"
|
||||
#include "libavutil/error.h"
|
||||
#include "libavutil/hwcontext.h"
|
||||
#include "libavutil/hwcontext_qsv.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
while (*pix_fmts != AV_PIX_FMT_NONE) {
|
||||
if (*pix_fmts == AV_PIX_FMT_QSV) {
|
||||
return AV_PIX_FMT_QSV;
|
||||
}
|
||||
|
||||
pix_fmts++;
|
||||
}
|
||||
|
||||
fprintf(stderr, "The QSV pixel format not offered in get_format()\n");
|
||||
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
static int decode_packet(AVCodecContext *decoder_ctx,
|
||||
AVFrame *frame, AVFrame *sw_frame,
|
||||
AVPacket *pkt, AVIOContext *output_ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = avcodec_send_packet(decoder_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
int i, j;
|
||||
|
||||
ret = avcodec_receive_frame(decoder_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* A real program would do something useful with the decoded frame here.
|
||||
* We just retrieve the raw data and write it to a file, which is rather
|
||||
* useless but pedagogic. */
|
||||
ret = av_hwframe_transfer_data(sw_frame, frame, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error transferring the data to system memory\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(sw_frame->data) && sw_frame->data[i]; i++)
|
||||
for (j = 0; j < (sw_frame->height >> (i > 0)); j++)
|
||||
avio_write(output_ctx, sw_frame->data[i] + j * sw_frame->linesize[i], sw_frame->width);
|
||||
|
||||
fail:
|
||||
av_frame_unref(sw_frame);
|
||||
av_frame_unref(frame);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
AVFormatContext *input_ctx = NULL;
|
||||
AVStream *video_st = NULL;
|
||||
AVCodecContext *decoder_ctx = NULL;
|
||||
const AVCodec *decoder;
|
||||
|
||||
AVPacket *pkt = NULL;
|
||||
AVFrame *frame = NULL, *sw_frame = NULL;
|
||||
|
||||
AVIOContext *output_ctx = NULL;
|
||||
|
||||
int ret, i;
|
||||
|
||||
AVBufferRef *device_ref = NULL;
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* open the input file */
|
||||
ret = avformat_open_input(&input_ctx, argv[1], NULL, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot open input file '%s': ", argv[1]);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* find the first H.264 video stream */
|
||||
for (i = 0; i < input_ctx->nb_streams; i++) {
|
||||
AVStream *st = input_ctx->streams[i];
|
||||
|
||||
if (st->codecpar->codec_id == AV_CODEC_ID_H264 && !video_st)
|
||||
video_st = st;
|
||||
else
|
||||
st->discard = AVDISCARD_ALL;
|
||||
}
|
||||
if (!video_st) {
|
||||
fprintf(stderr, "No H.264 video stream in the input file\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* open the hardware device */
|
||||
ret = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_QSV,
|
||||
"auto", NULL, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot open the hardware device\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* initialize the decoder */
|
||||
decoder = avcodec_find_decoder_by_name("h264_qsv");
|
||||
if (!decoder) {
|
||||
fprintf(stderr, "The QSV decoder is not present in libavcodec\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
decoder_ctx = avcodec_alloc_context3(decoder);
|
||||
if (!decoder_ctx) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto finish;
|
||||
}
|
||||
decoder_ctx->codec_id = AV_CODEC_ID_H264;
|
||||
if (video_st->codecpar->extradata_size) {
|
||||
decoder_ctx->extradata = av_mallocz(video_st->codecpar->extradata_size +
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!decoder_ctx->extradata) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto finish;
|
||||
}
|
||||
memcpy(decoder_ctx->extradata, video_st->codecpar->extradata,
|
||||
video_st->codecpar->extradata_size);
|
||||
decoder_ctx->extradata_size = video_st->codecpar->extradata_size;
|
||||
}
|
||||
|
||||
|
||||
decoder_ctx->hw_device_ctx = av_buffer_ref(device_ref);
|
||||
decoder_ctx->get_format = get_format;
|
||||
|
||||
ret = avcodec_open2(decoder_ctx, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error opening the decoder: ");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* open the output stream */
|
||||
ret = avio_open(&output_ctx, argv[2], AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error opening the output context: ");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
sw_frame = av_frame_alloc();
|
||||
pkt = av_packet_alloc();
|
||||
if (!frame || !sw_frame || !pkt) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* actual decoding */
|
||||
while (ret >= 0) {
|
||||
ret = av_read_frame(input_ctx, pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
if (pkt->stream_index == video_st->index)
|
||||
ret = decode_packet(decoder_ctx, frame, sw_frame, pkt, output_ctx);
|
||||
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
|
||||
/* flush the decoder */
|
||||
ret = decode_packet(decoder_ctx, frame, sw_frame, NULL, output_ctx);
|
||||
|
||||
finish:
|
||||
if (ret < 0) {
|
||||
char buf[1024];
|
||||
av_strerror(ret, buf, sizeof(buf));
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
}
|
||||
|
||||
avformat_close_input(&input_ctx);
|
||||
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&sw_frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
avcodec_free_context(&decoder_ctx);
|
||||
|
||||
av_buffer_unref(&device_ref);
|
||||
|
||||
avio_close(output_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Stefano Sabatini
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* libavformat/libavcodec demuxing and muxing API example.
|
||||
*
|
||||
* Remux streams from one container format to another.
|
||||
* @example remuxing.c
|
||||
*/
|
||||
|
||||
#include <libavutil/timestamp.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt, const char *tag)
|
||||
{
|
||||
AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
|
||||
|
||||
printf("%s: pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
|
||||
tag,
|
||||
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
|
||||
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
|
||||
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
|
||||
pkt->stream_index);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const AVOutputFormat *ofmt = NULL;
|
||||
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
||||
AVPacket *pkt = NULL;
|
||||
const char *in_filename, *out_filename;
|
||||
int ret, i;
|
||||
int stream_index = 0;
|
||||
int *stream_mapping = NULL;
|
||||
int stream_mapping_size = 0;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("usage: %s input output\n"
|
||||
"API example program to remux a media file with libavformat and libavcodec.\n"
|
||||
"The output format is guessed according to the file extension.\n"
|
||||
"\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_filename = argv[1];
|
||||
out_filename = argv[2];
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "Could not allocate AVPacket\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
|
||||
fprintf(stderr, "Could not open input file '%s'", in_filename);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
|
||||
fprintf(stderr, "Failed to retrieve input stream information");
|
||||
goto end;
|
||||
}
|
||||
|
||||
av_dump_format(ifmt_ctx, 0, in_filename, 0);
|
||||
|
||||
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
|
||||
if (!ofmt_ctx) {
|
||||
fprintf(stderr, "Could not create output context\n");
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
stream_mapping_size = ifmt_ctx->nb_streams;
|
||||
stream_mapping = av_calloc(stream_mapping_size, sizeof(*stream_mapping));
|
||||
if (!stream_mapping) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ofmt = ofmt_ctx->oformat;
|
||||
|
||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||
AVStream *out_stream;
|
||||
AVStream *in_stream = ifmt_ctx->streams[i];
|
||||
AVCodecParameters *in_codecpar = in_stream->codecpar;
|
||||
|
||||
if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
|
||||
in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
|
||||
in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
|
||||
stream_mapping[i] = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
stream_mapping[i] = stream_index++;
|
||||
|
||||
out_stream = avformat_new_stream(ofmt_ctx, NULL);
|
||||
if (!out_stream) {
|
||||
fprintf(stderr, "Failed allocating output stream\n");
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to copy codec parameters\n");
|
||||
goto end;
|
||||
}
|
||||
out_stream->codecpar->codec_tag = 0;
|
||||
}
|
||||
av_dump_format(ofmt_ctx, 0, out_filename, 1);
|
||||
|
||||
if (!(ofmt->flags & AVFMT_NOFILE)) {
|
||||
ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open output file '%s'", out_filename);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ret = avformat_write_header(ofmt_ctx, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error occurred when opening output file\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
AVStream *in_stream, *out_stream;
|
||||
|
||||
ret = av_read_frame(ifmt_ctx, pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
in_stream = ifmt_ctx->streams[pkt->stream_index];
|
||||
if (pkt->stream_index >= stream_mapping_size ||
|
||||
stream_mapping[pkt->stream_index] < 0) {
|
||||
av_packet_unref(pkt);
|
||||
continue;
|
||||
}
|
||||
|
||||
pkt->stream_index = stream_mapping[pkt->stream_index];
|
||||
out_stream = ofmt_ctx->streams[pkt->stream_index];
|
||||
log_packet(ifmt_ctx, pkt, "in");
|
||||
|
||||
/* copy packet */
|
||||
av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
|
||||
pkt->pos = -1;
|
||||
log_packet(ofmt_ctx, pkt, "out");
|
||||
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
|
||||
/* pkt is now blank (av_interleaved_write_frame() takes ownership of
|
||||
* its contents and resets pkt), so that no unreferencing is necessary.
|
||||
* This would be different if one used av_write_frame(). */
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error muxing packet\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
av_write_trailer(ofmt_ctx);
|
||||
end:
|
||||
av_packet_free(&pkt);
|
||||
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
|
||||
/* close output */
|
||||
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
|
||||
avio_closep(&ofmt_ctx->pb);
|
||||
avformat_free_context(ofmt_ctx);
|
||||
|
||||
av_freep(&stream_mapping);
|
||||
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+8
-5
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example doc/examples/resampling_audio.c
|
||||
* @example resampling_audio.c
|
||||
* libswresample API use example.
|
||||
*/
|
||||
|
||||
@@ -62,7 +62,7 @@ static int get_format_from_sample_fmt(const char **fmt,
|
||||
/**
|
||||
* Fill dst buffer with nb_samples, generated starting from t.
|
||||
*/
|
||||
void fill_samples(double *dst, int nb_samples, int nb_channels, int sample_rate, double *t)
|
||||
static void fill_samples(double *dst, int nb_samples, int nb_channels, int sample_rate, double *t)
|
||||
{
|
||||
int i, j;
|
||||
double tincr = 1.0 / sample_rate, *dstp = dst;
|
||||
@@ -168,7 +168,7 @@ int main(int argc, char **argv)
|
||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) +
|
||||
src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
|
||||
if (dst_nb_samples > max_dst_nb_samples) {
|
||||
av_free(dst_data[0]);
|
||||
av_freep(&dst_data[0]);
|
||||
ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels,
|
||||
dst_nb_samples, dst_sample_fmt, 1);
|
||||
if (ret < 0)
|
||||
@@ -184,6 +184,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
|
||||
ret, dst_sample_fmt, 1);
|
||||
if (dst_bufsize < 0) {
|
||||
fprintf(stderr, "Could not get sample buffer size\n");
|
||||
goto end;
|
||||
}
|
||||
printf("t:%f in:%d out:%d\n", t, src_nb_samples, ret);
|
||||
fwrite(dst_data[0], 1, dst_bufsize, dst_file);
|
||||
} while (t < 10);
|
||||
@@ -195,8 +199,7 @@ int main(int argc, char **argv)
|
||||
fmt, dst_ch_layout, dst_nb_channels, dst_rate, dst_filename);
|
||||
|
||||
end:
|
||||
if (dst_file)
|
||||
fclose(dst_file);
|
||||
fclose(dst_file);
|
||||
|
||||
if (src_data)
|
||||
av_freep(&src_data[0]);
|
||||
|
||||
+2
-3
@@ -23,7 +23,7 @@
|
||||
/**
|
||||
* @file
|
||||
* libswscale API use example.
|
||||
* @example doc/examples/scaling_video.c
|
||||
* @example scaling_video.c
|
||||
*/
|
||||
|
||||
#include <libavutil/imgutils.h>
|
||||
@@ -132,8 +132,7 @@ int main(int argc, char **argv)
|
||||
av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h, dst_filename);
|
||||
|
||||
end:
|
||||
if (dst_file)
|
||||
fclose(dst_file);
|
||||
fclose(dst_file);
|
||||
av_freep(&src_data[0]);
|
||||
av_freep(&dst_data[0]);
|
||||
sws_freeContext(sws_ctx);
|
||||
|
||||
+894
@@ -0,0 +1,894 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Andreas Unterweger
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Simple audio converter
|
||||
*
|
||||
* @example transcode_aac.c
|
||||
* Convert an input audio file to AAC in an MP4 container using FFmpeg.
|
||||
* Formats other than MP4 are supported based on the output file extension.
|
||||
* @author Andreas Unterweger ([email protected])
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavformat/avio.h"
|
||||
|
||||
#include "libavcodec/avcodec.h"
|
||||
|
||||
#include "libavutil/audio_fifo.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
#include "libswresample/swresample.h"
|
||||
|
||||
/* The output bit rate in bit/s */
|
||||
#define OUTPUT_BIT_RATE 96000
|
||||
/* The number of output channels */
|
||||
#define OUTPUT_CHANNELS 2
|
||||
|
||||
/**
|
||||
* Open an input file and the required decoder.
|
||||
* @param filename File to be opened
|
||||
* @param[out] input_format_context Format context of opened file
|
||||
* @param[out] input_codec_context Codec context of opened file
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int open_input_file(const char *filename,
|
||||
AVFormatContext **input_format_context,
|
||||
AVCodecContext **input_codec_context)
|
||||
{
|
||||
AVCodecContext *avctx;
|
||||
const AVCodec *input_codec;
|
||||
int error;
|
||||
|
||||
/* Open the input file to read from it. */
|
||||
if ((error = avformat_open_input(input_format_context, filename, NULL,
|
||||
NULL)) < 0) {
|
||||
fprintf(stderr, "Could not open input file '%s' (error '%s')\n",
|
||||
filename, av_err2str(error));
|
||||
*input_format_context = NULL;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Get information on the input file (number of streams etc.). */
|
||||
if ((error = avformat_find_stream_info(*input_format_context, NULL)) < 0) {
|
||||
fprintf(stderr, "Could not open find stream info (error '%s')\n",
|
||||
av_err2str(error));
|
||||
avformat_close_input(input_format_context);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Make sure that there is only one stream in the input file. */
|
||||
if ((*input_format_context)->nb_streams != 1) {
|
||||
fprintf(stderr, "Expected one audio input stream, but found %d\n",
|
||||
(*input_format_context)->nb_streams);
|
||||
avformat_close_input(input_format_context);
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/* Find a decoder for the audio stream. */
|
||||
if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codecpar->codec_id))) {
|
||||
fprintf(stderr, "Could not find input codec\n");
|
||||
avformat_close_input(input_format_context);
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/* Allocate a new decoding context. */
|
||||
avctx = avcodec_alloc_context3(input_codec);
|
||||
if (!avctx) {
|
||||
fprintf(stderr, "Could not allocate a decoding context\n");
|
||||
avformat_close_input(input_format_context);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Initialize the stream parameters with demuxer information. */
|
||||
error = avcodec_parameters_to_context(avctx, (*input_format_context)->streams[0]->codecpar);
|
||||
if (error < 0) {
|
||||
avformat_close_input(input_format_context);
|
||||
avcodec_free_context(&avctx);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Open the decoder for the audio stream to use it later. */
|
||||
if ((error = avcodec_open2(avctx, input_codec, NULL)) < 0) {
|
||||
fprintf(stderr, "Could not open input codec (error '%s')\n",
|
||||
av_err2str(error));
|
||||
avcodec_free_context(&avctx);
|
||||
avformat_close_input(input_format_context);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Save the decoder context for easier access later. */
|
||||
*input_codec_context = avctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an output file and the required encoder.
|
||||
* Also set some basic encoder parameters.
|
||||
* Some of these parameters are based on the input file's parameters.
|
||||
* @param filename File to be opened
|
||||
* @param input_codec_context Codec context of input file
|
||||
* @param[out] output_format_context Format context of output file
|
||||
* @param[out] output_codec_context Codec context of output file
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int open_output_file(const char *filename,
|
||||
AVCodecContext *input_codec_context,
|
||||
AVFormatContext **output_format_context,
|
||||
AVCodecContext **output_codec_context)
|
||||
{
|
||||
AVCodecContext *avctx = NULL;
|
||||
AVIOContext *output_io_context = NULL;
|
||||
AVStream *stream = NULL;
|
||||
const AVCodec *output_codec = NULL;
|
||||
int error;
|
||||
|
||||
/* Open the output file to write to it. */
|
||||
if ((error = avio_open(&output_io_context, filename,
|
||||
AVIO_FLAG_WRITE)) < 0) {
|
||||
fprintf(stderr, "Could not open output file '%s' (error '%s')\n",
|
||||
filename, av_err2str(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Create a new format context for the output container format. */
|
||||
if (!(*output_format_context = avformat_alloc_context())) {
|
||||
fprintf(stderr, "Could not allocate output format context\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Associate the output file (pointer) with the container format context. */
|
||||
(*output_format_context)->pb = output_io_context;
|
||||
|
||||
/* Guess the desired container format based on the file extension. */
|
||||
if (!((*output_format_context)->oformat = av_guess_format(NULL, filename,
|
||||
NULL))) {
|
||||
fprintf(stderr, "Could not find output file format\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!((*output_format_context)->url = av_strdup(filename))) {
|
||||
fprintf(stderr, "Could not allocate url.\n");
|
||||
error = AVERROR(ENOMEM);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Find the encoder to be used by its name. */
|
||||
if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC))) {
|
||||
fprintf(stderr, "Could not find an AAC encoder.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Create a new audio stream in the output file container. */
|
||||
if (!(stream = avformat_new_stream(*output_format_context, NULL))) {
|
||||
fprintf(stderr, "Could not create new stream\n");
|
||||
error = AVERROR(ENOMEM);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
avctx = avcodec_alloc_context3(output_codec);
|
||||
if (!avctx) {
|
||||
fprintf(stderr, "Could not allocate an encoding context\n");
|
||||
error = AVERROR(ENOMEM);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Set the basic encoder parameters.
|
||||
* The input file's sample rate is used to avoid a sample rate conversion. */
|
||||
avctx->channels = OUTPUT_CHANNELS;
|
||||
avctx->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS);
|
||||
avctx->sample_rate = input_codec_context->sample_rate;
|
||||
avctx->sample_fmt = output_codec->sample_fmts[0];
|
||||
avctx->bit_rate = OUTPUT_BIT_RATE;
|
||||
|
||||
/* Allow the use of the experimental AAC encoder. */
|
||||
avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
||||
|
||||
/* Set the sample rate for the container. */
|
||||
stream->time_base.den = input_codec_context->sample_rate;
|
||||
stream->time_base.num = 1;
|
||||
|
||||
/* Some container formats (like MP4) require global headers to be present.
|
||||
* Mark the encoder so that it behaves accordingly. */
|
||||
if ((*output_format_context)->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
avctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
/* Open the encoder for the audio stream to use it later. */
|
||||
if ((error = avcodec_open2(avctx, output_codec, NULL)) < 0) {
|
||||
fprintf(stderr, "Could not open output codec (error '%s')\n",
|
||||
av_err2str(error));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
error = avcodec_parameters_from_context(stream->codecpar, avctx);
|
||||
if (error < 0) {
|
||||
fprintf(stderr, "Could not initialize stream parameters\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Save the encoder context for easier access later. */
|
||||
*output_codec_context = avctx;
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
avcodec_free_context(&avctx);
|
||||
avio_closep(&(*output_format_context)->pb);
|
||||
avformat_free_context(*output_format_context);
|
||||
*output_format_context = NULL;
|
||||
return error < 0 ? error : AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize one data packet for reading or writing.
|
||||
* @param[out] packet Packet to be initialized
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int init_packet(AVPacket **packet)
|
||||
{
|
||||
if (!(*packet = av_packet_alloc())) {
|
||||
fprintf(stderr, "Could not allocate packet\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize one audio frame for reading from the input file.
|
||||
* @param[out] frame Frame to be initialized
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int init_input_frame(AVFrame **frame)
|
||||
{
|
||||
if (!(*frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "Could not allocate input frame\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the audio resampler based on the input and output codec settings.
|
||||
* If the input and output sample formats differ, a conversion is required
|
||||
* libswresample takes care of this, but requires initialization.
|
||||
* @param input_codec_context Codec context of the input file
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @param[out] resample_context Resample context for the required conversion
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int init_resampler(AVCodecContext *input_codec_context,
|
||||
AVCodecContext *output_codec_context,
|
||||
SwrContext **resample_context)
|
||||
{
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Create a resampler context for the conversion.
|
||||
* Set the conversion parameters.
|
||||
* Default channel layouts based on the number of channels
|
||||
* are assumed for simplicity (they are sometimes not detected
|
||||
* properly by the demuxer and/or decoder).
|
||||
*/
|
||||
*resample_context = swr_alloc_set_opts(NULL,
|
||||
av_get_default_channel_layout(output_codec_context->channels),
|
||||
output_codec_context->sample_fmt,
|
||||
output_codec_context->sample_rate,
|
||||
av_get_default_channel_layout(input_codec_context->channels),
|
||||
input_codec_context->sample_fmt,
|
||||
input_codec_context->sample_rate,
|
||||
0, NULL);
|
||||
if (!*resample_context) {
|
||||
fprintf(stderr, "Could not allocate resample context\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
/*
|
||||
* Perform a sanity check so that the number of converted samples is
|
||||
* not greater than the number of samples to be converted.
|
||||
* If the sample rates differ, this case has to be handled differently
|
||||
*/
|
||||
av_assert0(output_codec_context->sample_rate == input_codec_context->sample_rate);
|
||||
|
||||
/* Open the resampler with the specified parameters. */
|
||||
if ((error = swr_init(*resample_context)) < 0) {
|
||||
fprintf(stderr, "Could not open resample context\n");
|
||||
swr_free(resample_context);
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a FIFO buffer for the audio samples to be encoded.
|
||||
* @param[out] fifo Sample buffer
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context)
|
||||
{
|
||||
/* Create the FIFO buffer based on the specified output sample format. */
|
||||
if (!(*fifo = av_audio_fifo_alloc(output_codec_context->sample_fmt,
|
||||
output_codec_context->channels, 1))) {
|
||||
fprintf(stderr, "Could not allocate FIFO\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the header of the output file container.
|
||||
* @param output_format_context Format context of the output file
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int write_output_file_header(AVFormatContext *output_format_context)
|
||||
{
|
||||
int error;
|
||||
if ((error = avformat_write_header(output_format_context, NULL)) < 0) {
|
||||
fprintf(stderr, "Could not write output file header (error '%s')\n",
|
||||
av_err2str(error));
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode one audio frame from the input file.
|
||||
* @param frame Audio frame to be decoded
|
||||
* @param input_format_context Format context of the input file
|
||||
* @param input_codec_context Codec context of the input file
|
||||
* @param[out] data_present Indicates whether data has been decoded
|
||||
* @param[out] finished Indicates whether the end of file has
|
||||
* been reached and all data has been
|
||||
* decoded. If this flag is false, there
|
||||
* is more data to be decoded, i.e., this
|
||||
* function has to be called again.
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int decode_audio_frame(AVFrame *frame,
|
||||
AVFormatContext *input_format_context,
|
||||
AVCodecContext *input_codec_context,
|
||||
int *data_present, int *finished)
|
||||
{
|
||||
/* Packet used for temporary storage. */
|
||||
AVPacket *input_packet;
|
||||
int error;
|
||||
|
||||
error = init_packet(&input_packet);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
/* Read one audio frame from the input file into a temporary packet. */
|
||||
if ((error = av_read_frame(input_format_context, input_packet)) < 0) {
|
||||
/* If we are at the end of the file, flush the decoder below. */
|
||||
if (error == AVERROR_EOF)
|
||||
*finished = 1;
|
||||
else {
|
||||
fprintf(stderr, "Could not read frame (error '%s')\n",
|
||||
av_err2str(error));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send the audio frame stored in the temporary packet to the decoder.
|
||||
* The input audio stream decoder is used to do this. */
|
||||
if ((error = avcodec_send_packet(input_codec_context, input_packet)) < 0) {
|
||||
fprintf(stderr, "Could not send packet for decoding (error '%s')\n",
|
||||
av_err2str(error));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Receive one frame from the decoder. */
|
||||
error = avcodec_receive_frame(input_codec_context, frame);
|
||||
/* If the decoder asks for more data to be able to decode a frame,
|
||||
* return indicating that no data is present. */
|
||||
if (error == AVERROR(EAGAIN)) {
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
/* If the end of the input file is reached, stop decoding. */
|
||||
} else if (error == AVERROR_EOF) {
|
||||
*finished = 1;
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
} else if (error < 0) {
|
||||
fprintf(stderr, "Could not decode frame (error '%s')\n",
|
||||
av_err2str(error));
|
||||
goto cleanup;
|
||||
/* Default case: Return decoded data. */
|
||||
} else {
|
||||
*data_present = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
av_packet_free(&input_packet);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a temporary storage for the specified number of audio samples.
|
||||
* The conversion requires temporary storage due to the different format.
|
||||
* The number of audio samples to be allocated is specified in frame_size.
|
||||
* @param[out] converted_input_samples Array of converted samples. The
|
||||
* dimensions are reference, channel
|
||||
* (for multi-channel audio), sample.
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @param frame_size Number of samples to be converted in
|
||||
* each round
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int init_converted_samples(uint8_t ***converted_input_samples,
|
||||
AVCodecContext *output_codec_context,
|
||||
int frame_size)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Allocate as many pointers as there are audio channels.
|
||||
* Each pointer will later point to the audio samples of the corresponding
|
||||
* channels (although it may be NULL for interleaved formats).
|
||||
*/
|
||||
if (!(*converted_input_samples = calloc(output_codec_context->channels,
|
||||
sizeof(**converted_input_samples)))) {
|
||||
fprintf(stderr, "Could not allocate converted input sample pointers\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Allocate memory for the samples of all channels in one consecutive
|
||||
* block for convenience. */
|
||||
if ((error = av_samples_alloc(*converted_input_samples, NULL,
|
||||
output_codec_context->channels,
|
||||
frame_size,
|
||||
output_codec_context->sample_fmt, 0)) < 0) {
|
||||
fprintf(stderr,
|
||||
"Could not allocate converted input samples (error '%s')\n",
|
||||
av_err2str(error));
|
||||
av_freep(&(*converted_input_samples)[0]);
|
||||
free(*converted_input_samples);
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the input audio samples into the output sample format.
|
||||
* The conversion happens on a per-frame basis, the size of which is
|
||||
* specified by frame_size.
|
||||
* @param input_data Samples to be decoded. The dimensions are
|
||||
* channel (for multi-channel audio), sample.
|
||||
* @param[out] converted_data Converted samples. The dimensions are channel
|
||||
* (for multi-channel audio), sample.
|
||||
* @param frame_size Number of samples to be converted
|
||||
* @param resample_context Resample context for the conversion
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int convert_samples(const uint8_t **input_data,
|
||||
uint8_t **converted_data, const int frame_size,
|
||||
SwrContext *resample_context)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Convert the samples using the resampler. */
|
||||
if ((error = swr_convert(resample_context,
|
||||
converted_data, frame_size,
|
||||
input_data , frame_size)) < 0) {
|
||||
fprintf(stderr, "Could not convert input samples (error '%s')\n",
|
||||
av_err2str(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add converted input audio samples to the FIFO buffer for later processing.
|
||||
* @param fifo Buffer to add the samples to
|
||||
* @param converted_input_samples Samples to be added. The dimensions are channel
|
||||
* (for multi-channel audio), sample.
|
||||
* @param frame_size Number of samples to be converted
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int add_samples_to_fifo(AVAudioFifo *fifo,
|
||||
uint8_t **converted_input_samples,
|
||||
const int frame_size)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Make the FIFO as large as it needs to be to hold both,
|
||||
* the old and the new samples. */
|
||||
if ((error = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size)) < 0) {
|
||||
fprintf(stderr, "Could not reallocate FIFO\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Store the new samples in the FIFO buffer. */
|
||||
if (av_audio_fifo_write(fifo, (void **)converted_input_samples,
|
||||
frame_size) < frame_size) {
|
||||
fprintf(stderr, "Could not write data to FIFO\n");
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read one audio frame from the input file, decode, convert and store
|
||||
* it in the FIFO buffer.
|
||||
* @param fifo Buffer used for temporary storage
|
||||
* @param input_format_context Format context of the input file
|
||||
* @param input_codec_context Codec context of the input file
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @param resampler_context Resample context for the conversion
|
||||
* @param[out] finished Indicates whether the end of file has
|
||||
* been reached and all data has been
|
||||
* decoded. If this flag is false,
|
||||
* there is more data to be decoded,
|
||||
* i.e., this function has to be called
|
||||
* again.
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int read_decode_convert_and_store(AVAudioFifo *fifo,
|
||||
AVFormatContext *input_format_context,
|
||||
AVCodecContext *input_codec_context,
|
||||
AVCodecContext *output_codec_context,
|
||||
SwrContext *resampler_context,
|
||||
int *finished)
|
||||
{
|
||||
/* Temporary storage of the input samples of the frame read from the file. */
|
||||
AVFrame *input_frame = NULL;
|
||||
/* Temporary storage for the converted input samples. */
|
||||
uint8_t **converted_input_samples = NULL;
|
||||
int data_present = 0;
|
||||
int ret = AVERROR_EXIT;
|
||||
|
||||
/* Initialize temporary storage for one input frame. */
|
||||
if (init_input_frame(&input_frame))
|
||||
goto cleanup;
|
||||
/* Decode one frame worth of audio samples. */
|
||||
if (decode_audio_frame(input_frame, input_format_context,
|
||||
input_codec_context, &data_present, finished))
|
||||
goto cleanup;
|
||||
/* If we are at the end of the file and there are no more samples
|
||||
* in the decoder which are delayed, we are actually finished.
|
||||
* This must not be treated as an error. */
|
||||
if (*finished) {
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
/* If there is decoded data, convert and store it. */
|
||||
if (data_present) {
|
||||
/* Initialize the temporary storage for the converted input samples. */
|
||||
if (init_converted_samples(&converted_input_samples, output_codec_context,
|
||||
input_frame->nb_samples))
|
||||
goto cleanup;
|
||||
|
||||
/* Convert the input samples to the desired output sample format.
|
||||
* This requires a temporary storage provided by converted_input_samples. */
|
||||
if (convert_samples((const uint8_t**)input_frame->extended_data, converted_input_samples,
|
||||
input_frame->nb_samples, resampler_context))
|
||||
goto cleanup;
|
||||
|
||||
/* Add the converted input samples to the FIFO buffer for later processing. */
|
||||
if (add_samples_to_fifo(fifo, converted_input_samples,
|
||||
input_frame->nb_samples))
|
||||
goto cleanup;
|
||||
ret = 0;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
if (converted_input_samples) {
|
||||
av_freep(&converted_input_samples[0]);
|
||||
free(converted_input_samples);
|
||||
}
|
||||
av_frame_free(&input_frame);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize one input frame for writing to the output file.
|
||||
* The frame will be exactly frame_size samples large.
|
||||
* @param[out] frame Frame to be initialized
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @param frame_size Size of the frame
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int init_output_frame(AVFrame **frame,
|
||||
AVCodecContext *output_codec_context,
|
||||
int frame_size)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Create a new frame to store the audio samples. */
|
||||
if (!(*frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "Could not allocate output frame\n");
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/* Set the frame's parameters, especially its size and format.
|
||||
* av_frame_get_buffer needs this to allocate memory for the
|
||||
* audio samples of the frame.
|
||||
* Default channel layouts based on the number of channels
|
||||
* are assumed for simplicity. */
|
||||
(*frame)->nb_samples = frame_size;
|
||||
(*frame)->channel_layout = output_codec_context->channel_layout;
|
||||
(*frame)->format = output_codec_context->sample_fmt;
|
||||
(*frame)->sample_rate = output_codec_context->sample_rate;
|
||||
|
||||
/* Allocate the samples of the created frame. This call will make
|
||||
* sure that the audio frame can hold as many samples as specified. */
|
||||
if ((error = av_frame_get_buffer(*frame, 0)) < 0) {
|
||||
fprintf(stderr, "Could not allocate output frame samples (error '%s')\n",
|
||||
av_err2str(error));
|
||||
av_frame_free(frame);
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Global timestamp for the audio frames. */
|
||||
static int64_t pts = 0;
|
||||
|
||||
/**
|
||||
* Encode one frame worth of audio to the output file.
|
||||
* @param frame Samples to be encoded
|
||||
* @param output_format_context Format context of the output file
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @param[out] data_present Indicates whether data has been
|
||||
* encoded
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int encode_audio_frame(AVFrame *frame,
|
||||
AVFormatContext *output_format_context,
|
||||
AVCodecContext *output_codec_context,
|
||||
int *data_present)
|
||||
{
|
||||
/* Packet used for temporary storage. */
|
||||
AVPacket *output_packet;
|
||||
int error;
|
||||
|
||||
error = init_packet(&output_packet);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
/* Set a timestamp based on the sample rate for the container. */
|
||||
if (frame) {
|
||||
frame->pts = pts;
|
||||
pts += frame->nb_samples;
|
||||
}
|
||||
|
||||
/* Send the audio frame stored in the temporary packet to the encoder.
|
||||
* The output audio stream encoder is used to do this. */
|
||||
error = avcodec_send_frame(output_codec_context, frame);
|
||||
/* The encoder signals that it has nothing more to encode. */
|
||||
if (error == AVERROR_EOF) {
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
} else if (error < 0) {
|
||||
fprintf(stderr, "Could not send packet for encoding (error '%s')\n",
|
||||
av_err2str(error));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Receive one encoded frame from the encoder. */
|
||||
error = avcodec_receive_packet(output_codec_context, output_packet);
|
||||
/* If the encoder asks for more data to be able to provide an
|
||||
* encoded frame, return indicating that no data is present. */
|
||||
if (error == AVERROR(EAGAIN)) {
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
/* If the last frame has been encoded, stop encoding. */
|
||||
} else if (error == AVERROR_EOF) {
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
} else if (error < 0) {
|
||||
fprintf(stderr, "Could not encode frame (error '%s')\n",
|
||||
av_err2str(error));
|
||||
goto cleanup;
|
||||
/* Default case: Return encoded data. */
|
||||
} else {
|
||||
*data_present = 1;
|
||||
}
|
||||
|
||||
/* Write one audio frame from the temporary packet to the output file. */
|
||||
if (*data_present &&
|
||||
(error = av_write_frame(output_format_context, output_packet)) < 0) {
|
||||
fprintf(stderr, "Could not write frame (error '%s')\n",
|
||||
av_err2str(error));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
av_packet_free(&output_packet);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load one audio frame from the FIFO buffer, encode and write it to the
|
||||
* output file.
|
||||
* @param fifo Buffer used for temporary storage
|
||||
* @param output_format_context Format context of the output file
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int load_encode_and_write(AVAudioFifo *fifo,
|
||||
AVFormatContext *output_format_context,
|
||||
AVCodecContext *output_codec_context)
|
||||
{
|
||||
/* Temporary storage of the output samples of the frame written to the file. */
|
||||
AVFrame *output_frame;
|
||||
/* Use the maximum number of possible samples per frame.
|
||||
* If there is less than the maximum possible frame size in the FIFO
|
||||
* buffer use this number. Otherwise, use the maximum possible frame size. */
|
||||
const int frame_size = FFMIN(av_audio_fifo_size(fifo),
|
||||
output_codec_context->frame_size);
|
||||
int data_written;
|
||||
|
||||
/* Initialize temporary storage for one output frame. */
|
||||
if (init_output_frame(&output_frame, output_codec_context, frame_size))
|
||||
return AVERROR_EXIT;
|
||||
|
||||
/* Read as many samples from the FIFO buffer as required to fill the frame.
|
||||
* The samples are stored in the frame temporarily. */
|
||||
if (av_audio_fifo_read(fifo, (void **)output_frame->data, frame_size) < frame_size) {
|
||||
fprintf(stderr, "Could not read data from FIFO\n");
|
||||
av_frame_free(&output_frame);
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/* Encode one frame worth of audio samples. */
|
||||
if (encode_audio_frame(output_frame, output_format_context,
|
||||
output_codec_context, &data_written)) {
|
||||
av_frame_free(&output_frame);
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
av_frame_free(&output_frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the trailer of the output file container.
|
||||
* @param output_format_context Format context of the output file
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int write_output_file_trailer(AVFormatContext *output_format_context)
|
||||
{
|
||||
int error;
|
||||
if ((error = av_write_trailer(output_format_context)) < 0) {
|
||||
fprintf(stderr, "Could not write output file trailer (error '%s')\n",
|
||||
av_err2str(error));
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
AVFormatContext *input_format_context = NULL, *output_format_context = NULL;
|
||||
AVCodecContext *input_codec_context = NULL, *output_codec_context = NULL;
|
||||
SwrContext *resample_context = NULL;
|
||||
AVAudioFifo *fifo = NULL;
|
||||
int ret = AVERROR_EXIT;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Open the input file for reading. */
|
||||
if (open_input_file(argv[1], &input_format_context,
|
||||
&input_codec_context))
|
||||
goto cleanup;
|
||||
/* Open the output file for writing. */
|
||||
if (open_output_file(argv[2], input_codec_context,
|
||||
&output_format_context, &output_codec_context))
|
||||
goto cleanup;
|
||||
/* Initialize the resampler to be able to convert audio sample formats. */
|
||||
if (init_resampler(input_codec_context, output_codec_context,
|
||||
&resample_context))
|
||||
goto cleanup;
|
||||
/* Initialize the FIFO buffer to store audio samples to be encoded. */
|
||||
if (init_fifo(&fifo, output_codec_context))
|
||||
goto cleanup;
|
||||
/* Write the header of the output file container. */
|
||||
if (write_output_file_header(output_format_context))
|
||||
goto cleanup;
|
||||
|
||||
/* Loop as long as we have input samples to read or output samples
|
||||
* to write; abort as soon as we have neither. */
|
||||
while (1) {
|
||||
/* Use the encoder's desired frame size for processing. */
|
||||
const int output_frame_size = output_codec_context->frame_size;
|
||||
int finished = 0;
|
||||
|
||||
/* Make sure that there is one frame worth of samples in the FIFO
|
||||
* buffer so that the encoder can do its work.
|
||||
* Since the decoder's and the encoder's frame size may differ, we
|
||||
* need to FIFO buffer to store as many frames worth of input samples
|
||||
* that they make up at least one frame worth of output samples. */
|
||||
while (av_audio_fifo_size(fifo) < output_frame_size) {
|
||||
/* Decode one frame worth of audio samples, convert it to the
|
||||
* output sample format and put it into the FIFO buffer. */
|
||||
if (read_decode_convert_and_store(fifo, input_format_context,
|
||||
input_codec_context,
|
||||
output_codec_context,
|
||||
resample_context, &finished))
|
||||
goto cleanup;
|
||||
|
||||
/* If we are at the end of the input file, we continue
|
||||
* encoding the remaining audio samples to the output file. */
|
||||
if (finished)
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we have enough samples for the encoder, we encode them.
|
||||
* At the end of the file, we pass the remaining samples to
|
||||
* the encoder. */
|
||||
while (av_audio_fifo_size(fifo) >= output_frame_size ||
|
||||
(finished && av_audio_fifo_size(fifo) > 0))
|
||||
/* Take one frame worth of audio samples from the FIFO buffer,
|
||||
* encode it and write it to the output file. */
|
||||
if (load_encode_and_write(fifo, output_format_context,
|
||||
output_codec_context))
|
||||
goto cleanup;
|
||||
|
||||
/* If we are at the end of the input file and have encoded
|
||||
* all remaining samples, we can exit this loop and finish. */
|
||||
if (finished) {
|
||||
int data_written;
|
||||
/* Flush the encoder as it may have delayed frames. */
|
||||
do {
|
||||
data_written = 0;
|
||||
if (encode_audio_frame(NULL, output_format_context,
|
||||
output_codec_context, &data_written))
|
||||
goto cleanup;
|
||||
} while (data_written);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the trailer of the output file container. */
|
||||
if (write_output_file_trailer(output_format_context))
|
||||
goto cleanup;
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
if (fifo)
|
||||
av_audio_fifo_free(fifo);
|
||||
swr_free(&resample_context);
|
||||
if (output_codec_context)
|
||||
avcodec_free_context(&output_codec_context);
|
||||
if (output_format_context) {
|
||||
avio_closep(&output_format_context->pb);
|
||||
avformat_free_context(output_format_context);
|
||||
}
|
||||
if (input_codec_context)
|
||||
avcodec_free_context(&input_codec_context);
|
||||
if (input_format_context)
|
||||
avformat_close_input(&input_format_context);
|
||||
|
||||
return ret;
|
||||
}
|
||||
+622
@@ -0,0 +1,622 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Nicolas George
|
||||
* Copyright (c) 2011 Stefano Sabatini
|
||||
* Copyright (c) 2014 Andrey Utkin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* API example for demuxing, decoding, filtering, encoding and muxing
|
||||
* @example transcoding.c
|
||||
*/
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
|
||||
static AVFormatContext *ifmt_ctx;
|
||||
static AVFormatContext *ofmt_ctx;
|
||||
typedef struct FilteringContext {
|
||||
AVFilterContext *buffersink_ctx;
|
||||
AVFilterContext *buffersrc_ctx;
|
||||
AVFilterGraph *filter_graph;
|
||||
|
||||
AVPacket *enc_pkt;
|
||||
AVFrame *filtered_frame;
|
||||
} FilteringContext;
|
||||
static FilteringContext *filter_ctx;
|
||||
|
||||
typedef struct StreamContext {
|
||||
AVCodecContext *dec_ctx;
|
||||
AVCodecContext *enc_ctx;
|
||||
|
||||
AVFrame *dec_frame;
|
||||
} StreamContext;
|
||||
static StreamContext *stream_ctx;
|
||||
|
||||
static int open_input_file(const char *filename)
|
||||
{
|
||||
int ret;
|
||||
unsigned int i;
|
||||
|
||||
ifmt_ctx = NULL;
|
||||
if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
stream_ctx = av_calloc(ifmt_ctx->nb_streams, sizeof(*stream_ctx));
|
||||
if (!stream_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||
AVStream *stream = ifmt_ctx->streams[i];
|
||||
const AVCodec *dec = avcodec_find_decoder(stream->codecpar->codec_id);
|
||||
AVCodecContext *codec_ctx;
|
||||
if (!dec) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Failed to find decoder for stream #%u\n", i);
|
||||
return AVERROR_DECODER_NOT_FOUND;
|
||||
}
|
||||
codec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!codec_ctx) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Failed to allocate the decoder context for stream #%u\n", i);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
ret = avcodec_parameters_to_context(codec_ctx, stream->codecpar);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Failed to copy decoder parameters to input decoder context "
|
||||
"for stream #%u\n", i);
|
||||
return ret;
|
||||
}
|
||||
/* Reencode video & audio and remux subtitles etc. */
|
||||
if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
|
||||
|| codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
codec_ctx->framerate = av_guess_frame_rate(ifmt_ctx, stream, NULL);
|
||||
/* Open decoder */
|
||||
ret = avcodec_open2(codec_ctx, dec, NULL);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
stream_ctx[i].dec_ctx = codec_ctx;
|
||||
|
||||
stream_ctx[i].dec_frame = av_frame_alloc();
|
||||
if (!stream_ctx[i].dec_frame)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
av_dump_format(ifmt_ctx, 0, filename, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_output_file(const char *filename)
|
||||
{
|
||||
AVStream *out_stream;
|
||||
AVStream *in_stream;
|
||||
AVCodecContext *dec_ctx, *enc_ctx;
|
||||
const AVCodec *encoder;
|
||||
int ret;
|
||||
unsigned int i;
|
||||
|
||||
ofmt_ctx = NULL;
|
||||
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, filename);
|
||||
if (!ofmt_ctx) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not create output context\n");
|
||||
return AVERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||
out_stream = avformat_new_stream(ofmt_ctx, NULL);
|
||||
if (!out_stream) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n");
|
||||
return AVERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
in_stream = ifmt_ctx->streams[i];
|
||||
dec_ctx = stream_ctx[i].dec_ctx;
|
||||
|
||||
if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
|
||||
|| dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
/* in this example, we choose transcoding to same codec */
|
||||
encoder = avcodec_find_encoder(dec_ctx->codec_id);
|
||||
if (!encoder) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
enc_ctx = avcodec_alloc_context3(encoder);
|
||||
if (!enc_ctx) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Failed to allocate the encoder context\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* In this example, we transcode to same properties (picture size,
|
||||
* sample rate etc.). These properties can be changed for output
|
||||
* streams easily using filters */
|
||||
if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
enc_ctx->height = dec_ctx->height;
|
||||
enc_ctx->width = dec_ctx->width;
|
||||
enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;
|
||||
/* take first format from list of supported formats */
|
||||
if (encoder->pix_fmts)
|
||||
enc_ctx->pix_fmt = encoder->pix_fmts[0];
|
||||
else
|
||||
enc_ctx->pix_fmt = dec_ctx->pix_fmt;
|
||||
/* video time_base can be set to whatever is handy and supported by encoder */
|
||||
enc_ctx->time_base = av_inv_q(dec_ctx->framerate);
|
||||
} else {
|
||||
enc_ctx->sample_rate = dec_ctx->sample_rate;
|
||||
enc_ctx->channel_layout = dec_ctx->channel_layout;
|
||||
enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout);
|
||||
/* take first format from list of supported formats */
|
||||
enc_ctx->sample_fmt = encoder->sample_fmts[0];
|
||||
enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
|
||||
}
|
||||
|
||||
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
/* Third parameter can be used to pass settings to encoder */
|
||||
ret = avcodec_open2(enc_ctx, encoder, NULL);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
|
||||
return ret;
|
||||
}
|
||||
ret = avcodec_parameters_from_context(out_stream->codecpar, enc_ctx);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Failed to copy encoder parameters to output stream #%u\n", i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
out_stream->time_base = enc_ctx->time_base;
|
||||
stream_ctx[i].enc_ctx = enc_ctx;
|
||||
} else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n", i);
|
||||
return AVERROR_INVALIDDATA;
|
||||
} else {
|
||||
/* if this stream must be remuxed */
|
||||
ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Copying parameters for stream #%u failed\n", i);
|
||||
return ret;
|
||||
}
|
||||
out_stream->time_base = in_stream->time_base;
|
||||
}
|
||||
|
||||
}
|
||||
av_dump_format(ofmt_ctx, 0, filename, 1);
|
||||
|
||||
if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {
|
||||
ret = avio_open(&ofmt_ctx->pb, filename, AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not open output file '%s'", filename);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* init muxer, write output file header */
|
||||
ret = avformat_write_header(ofmt_ctx, NULL);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,
|
||||
AVCodecContext *enc_ctx, const char *filter_spec)
|
||||
{
|
||||
char args[512];
|
||||
int ret = 0;
|
||||
const AVFilter *buffersrc = NULL;
|
||||
const AVFilter *buffersink = NULL;
|
||||
AVFilterContext *buffersrc_ctx = NULL;
|
||||
AVFilterContext *buffersink_ctx = NULL;
|
||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||
AVFilterInOut *inputs = avfilter_inout_alloc();
|
||||
AVFilterGraph *filter_graph = avfilter_graph_alloc();
|
||||
|
||||
if (!outputs || !inputs || !filter_graph) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
buffersrc = avfilter_get_by_name("buffer");
|
||||
buffersink = avfilter_get_by_name("buffersink");
|
||||
if (!buffersrc || !buffersink) {
|
||||
av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
snprintf(args, sizeof(args),
|
||||
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
|
||||
dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
|
||||
dec_ctx->time_base.num, dec_ctx->time_base.den,
|
||||
dec_ctx->sample_aspect_ratio.num,
|
||||
dec_ctx->sample_aspect_ratio.den);
|
||||
|
||||
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
|
||||
args, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
|
||||
NULL, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_opt_set_bin(buffersink_ctx, "pix_fmts",
|
||||
(uint8_t*)&enc_ctx->pix_fmt, sizeof(enc_ctx->pix_fmt),
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
|
||||
goto end;
|
||||
}
|
||||
} else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
buffersrc = avfilter_get_by_name("abuffer");
|
||||
buffersink = avfilter_get_by_name("abuffersink");
|
||||
if (!buffersrc || !buffersink) {
|
||||
av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!dec_ctx->channel_layout)
|
||||
dec_ctx->channel_layout =
|
||||
av_get_default_channel_layout(dec_ctx->channels);
|
||||
snprintf(args, sizeof(args),
|
||||
"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
|
||||
dec_ctx->time_base.num, dec_ctx->time_base.den, dec_ctx->sample_rate,
|
||||
av_get_sample_fmt_name(dec_ctx->sample_fmt),
|
||||
dec_ctx->channel_layout);
|
||||
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
|
||||
args, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
|
||||
NULL, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_opt_set_bin(buffersink_ctx, "sample_fmts",
|
||||
(uint8_t*)&enc_ctx->sample_fmt, sizeof(enc_ctx->sample_fmt),
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_opt_set_bin(buffersink_ctx, "channel_layouts",
|
||||
(uint8_t*)&enc_ctx->channel_layout,
|
||||
sizeof(enc_ctx->channel_layout), AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_opt_set_bin(buffersink_ctx, "sample_rates",
|
||||
(uint8_t*)&enc_ctx->sample_rate, sizeof(enc_ctx->sample_rate),
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Endpoints for the filter graph. */
|
||||
outputs->name = av_strdup("in");
|
||||
outputs->filter_ctx = buffersrc_ctx;
|
||||
outputs->pad_idx = 0;
|
||||
outputs->next = NULL;
|
||||
|
||||
inputs->name = av_strdup("out");
|
||||
inputs->filter_ctx = buffersink_ctx;
|
||||
inputs->pad_idx = 0;
|
||||
inputs->next = NULL;
|
||||
|
||||
if (!outputs->name || !inputs->name) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_spec,
|
||||
&inputs, &outputs, NULL)) < 0)
|
||||
goto end;
|
||||
|
||||
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
|
||||
goto end;
|
||||
|
||||
/* Fill FilteringContext */
|
||||
fctx->buffersrc_ctx = buffersrc_ctx;
|
||||
fctx->buffersink_ctx = buffersink_ctx;
|
||||
fctx->filter_graph = filter_graph;
|
||||
|
||||
end:
|
||||
avfilter_inout_free(&inputs);
|
||||
avfilter_inout_free(&outputs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int init_filters(void)
|
||||
{
|
||||
const char *filter_spec;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
filter_ctx = av_malloc_array(ifmt_ctx->nb_streams, sizeof(*filter_ctx));
|
||||
if (!filter_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||
filter_ctx[i].buffersrc_ctx = NULL;
|
||||
filter_ctx[i].buffersink_ctx = NULL;
|
||||
filter_ctx[i].filter_graph = NULL;
|
||||
if (!(ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO
|
||||
|| ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO))
|
||||
continue;
|
||||
|
||||
|
||||
if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
filter_spec = "null"; /* passthrough (dummy) filter for video */
|
||||
else
|
||||
filter_spec = "anull"; /* passthrough (dummy) filter for audio */
|
||||
ret = init_filter(&filter_ctx[i], stream_ctx[i].dec_ctx,
|
||||
stream_ctx[i].enc_ctx, filter_spec);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
filter_ctx[i].enc_pkt = av_packet_alloc();
|
||||
if (!filter_ctx[i].enc_pkt)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
filter_ctx[i].filtered_frame = av_frame_alloc();
|
||||
if (!filter_ctx[i].filtered_frame)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encode_write_frame(unsigned int stream_index, int flush)
|
||||
{
|
||||
StreamContext *stream = &stream_ctx[stream_index];
|
||||
FilteringContext *filter = &filter_ctx[stream_index];
|
||||
AVFrame *filt_frame = flush ? NULL : filter->filtered_frame;
|
||||
AVPacket *enc_pkt = filter->enc_pkt;
|
||||
int ret;
|
||||
|
||||
av_log(NULL, AV_LOG_INFO, "Encoding frame\n");
|
||||
/* encode filtered frame */
|
||||
av_packet_unref(enc_pkt);
|
||||
|
||||
ret = avcodec_send_frame(stream->enc_ctx, filt_frame);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(stream->enc_ctx, enc_pkt);
|
||||
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return 0;
|
||||
|
||||
/* prepare packet for muxing */
|
||||
enc_pkt->stream_index = stream_index;
|
||||
av_packet_rescale_ts(enc_pkt,
|
||||
stream->enc_ctx->time_base,
|
||||
ofmt_ctx->streams[stream_index]->time_base);
|
||||
|
||||
av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
|
||||
/* mux encoded frame */
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
|
||||
{
|
||||
FilteringContext *filter = &filter_ctx[stream_index];
|
||||
int ret;
|
||||
|
||||
av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n");
|
||||
/* push the decoded frame into the filtergraph */
|
||||
ret = av_buffersrc_add_frame_flags(filter->buffersrc_ctx,
|
||||
frame, 0);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* pull filtered frames from the filtergraph */
|
||||
while (1) {
|
||||
av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters\n");
|
||||
ret = av_buffersink_get_frame(filter->buffersink_ctx,
|
||||
filter->filtered_frame);
|
||||
if (ret < 0) {
|
||||
/* if no more frames for output - returns AVERROR(EAGAIN)
|
||||
* if flushed and no more frames for output - returns AVERROR_EOF
|
||||
* rewrite retcode to 0 to show it as normal procedure completion
|
||||
*/
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
filter->filtered_frame->pict_type = AV_PICTURE_TYPE_NONE;
|
||||
ret = encode_write_frame(stream_index, 0);
|
||||
av_frame_unref(filter->filtered_frame);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int flush_encoder(unsigned int stream_index)
|
||||
{
|
||||
if (!(stream_ctx[stream_index].enc_ctx->codec->capabilities &
|
||||
AV_CODEC_CAP_DELAY))
|
||||
return 0;
|
||||
|
||||
av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index);
|
||||
return encode_write_frame(stream_index, 1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
AVPacket *packet = NULL;
|
||||
unsigned int stream_index;
|
||||
unsigned int i;
|
||||
|
||||
if (argc != 3) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
if ((ret = open_output_file(argv[2])) < 0)
|
||||
goto end;
|
||||
if ((ret = init_filters()) < 0)
|
||||
goto end;
|
||||
if (!(packet = av_packet_alloc()))
|
||||
goto end;
|
||||
|
||||
/* read all packets */
|
||||
while (1) {
|
||||
if ((ret = av_read_frame(ifmt_ctx, packet)) < 0)
|
||||
break;
|
||||
stream_index = packet->stream_index;
|
||||
av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n",
|
||||
stream_index);
|
||||
|
||||
if (filter_ctx[stream_index].filter_graph) {
|
||||
StreamContext *stream = &stream_ctx[stream_index];
|
||||
|
||||
av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n");
|
||||
|
||||
av_packet_rescale_ts(packet,
|
||||
ifmt_ctx->streams[stream_index]->time_base,
|
||||
stream->dec_ctx->time_base);
|
||||
ret = avcodec_send_packet(stream->dec_ctx, packet);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Decoding failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(stream->dec_ctx, stream->dec_frame);
|
||||
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
|
||||
break;
|
||||
else if (ret < 0)
|
||||
goto end;
|
||||
|
||||
stream->dec_frame->pts = stream->dec_frame->best_effort_timestamp;
|
||||
ret = filter_encode_write_frame(stream->dec_frame, stream_index);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
/* remux this frame without reencoding */
|
||||
av_packet_rescale_ts(packet,
|
||||
ifmt_ctx->streams[stream_index]->time_base,
|
||||
ofmt_ctx->streams[stream_index]->time_base);
|
||||
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, packet);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
}
|
||||
av_packet_unref(packet);
|
||||
}
|
||||
|
||||
/* flush filters and encoders */
|
||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||
/* flush filter */
|
||||
if (!filter_ctx[i].filter_graph)
|
||||
continue;
|
||||
ret = filter_encode_write_frame(NULL, i);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Flushing filter failed\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* flush encoder */
|
||||
ret = flush_encoder(i);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
av_write_trailer(ofmt_ctx);
|
||||
end:
|
||||
av_packet_free(&packet);
|
||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||
avcodec_free_context(&stream_ctx[i].dec_ctx);
|
||||
if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && stream_ctx[i].enc_ctx)
|
||||
avcodec_free_context(&stream_ctx[i].enc_ctx);
|
||||
if (filter_ctx && filter_ctx[i].filter_graph) {
|
||||
avfilter_graph_free(&filter_ctx[i].filter_graph);
|
||||
av_packet_free(&filter_ctx[i].enc_pkt);
|
||||
av_frame_free(&filter_ctx[i].filtered_frame);
|
||||
}
|
||||
|
||||
av_frame_free(&stream_ctx[i].dec_frame);
|
||||
}
|
||||
av_free(filter_ctx);
|
||||
av_free(stream_ctx);
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
|
||||
avio_closep(&ofmt_ctx->pb);
|
||||
avformat_free_context(ofmt_ctx);
|
||||
|
||||
if (ret < 0)
|
||||
av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret));
|
||||
|
||||
return ret ? 1 : 0;
|
||||
}
|
||||
+224
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Video Acceleration API (video encoding) encode sample
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Intel VAAPI-accelerated encoding example.
|
||||
*
|
||||
* @example vaapi_encode.c
|
||||
* This example shows how to do VAAPI-accelerated encoding. now only support NV12
|
||||
* raw file, usage like: vaapi_encode 1920 1080 input.yuv output.h264
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
#include <libavutil/hwcontext.h>
|
||||
|
||||
static int width, height;
|
||||
static AVBufferRef *hw_device_ctx = NULL;
|
||||
|
||||
static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx)
|
||||
{
|
||||
AVBufferRef *hw_frames_ref;
|
||||
AVHWFramesContext *frames_ctx = NULL;
|
||||
int err = 0;
|
||||
|
||||
if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
|
||||
fprintf(stderr, "Failed to create VAAPI frame context.\n");
|
||||
return -1;
|
||||
}
|
||||
frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
|
||||
frames_ctx->format = AV_PIX_FMT_VAAPI;
|
||||
frames_ctx->sw_format = AV_PIX_FMT_NV12;
|
||||
frames_ctx->width = width;
|
||||
frames_ctx->height = height;
|
||||
frames_ctx->initial_pool_size = 20;
|
||||
if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0) {
|
||||
fprintf(stderr, "Failed to initialize VAAPI frame context."
|
||||
"Error code: %s\n",av_err2str(err));
|
||||
av_buffer_unref(&hw_frames_ref);
|
||||
return err;
|
||||
}
|
||||
ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
|
||||
if (!ctx->hw_frames_ctx)
|
||||
err = AVERROR(ENOMEM);
|
||||
|
||||
av_buffer_unref(&hw_frames_ref);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int encode_write(AVCodecContext *avctx, AVFrame *frame, FILE *fout)
|
||||
{
|
||||
int ret = 0;
|
||||
AVPacket *enc_pkt;
|
||||
|
||||
if (!(enc_pkt = av_packet_alloc()))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if ((ret = avcodec_send_frame(avctx, frame)) < 0) {
|
||||
fprintf(stderr, "Error code: %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
while (1) {
|
||||
ret = avcodec_receive_packet(avctx, enc_pkt);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
enc_pkt->stream_index = 0;
|
||||
ret = fwrite(enc_pkt->data, enc_pkt->size, 1, fout);
|
||||
av_packet_unref(enc_pkt);
|
||||
}
|
||||
|
||||
end:
|
||||
av_packet_free(&enc_pkt);
|
||||
ret = ((ret == AVERROR(EAGAIN)) ? 0 : -1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int size, err;
|
||||
FILE *fin = NULL, *fout = NULL;
|
||||
AVFrame *sw_frame = NULL, *hw_frame = NULL;
|
||||
AVCodecContext *avctx = NULL;
|
||||
const AVCodec *codec = NULL;
|
||||
const char *enc_name = "h264_vaapi";
|
||||
|
||||
if (argc < 5) {
|
||||
fprintf(stderr, "Usage: %s <width> <height> <input file> <output file>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
width = atoi(argv[1]);
|
||||
height = atoi(argv[2]);
|
||||
size = width * height;
|
||||
|
||||
if (!(fin = fopen(argv[3], "r"))) {
|
||||
fprintf(stderr, "Fail to open input file : %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (!(fout = fopen(argv[4], "w+b"))) {
|
||||
fprintf(stderr, "Fail to open output file : %s\n", strerror(errno));
|
||||
err = -1;
|
||||
goto close;
|
||||
}
|
||||
|
||||
err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI,
|
||||
NULL, NULL, 0);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Failed to create a VAAPI device. Error code: %s\n", av_err2str(err));
|
||||
goto close;
|
||||
}
|
||||
|
||||
if (!(codec = avcodec_find_encoder_by_name(enc_name))) {
|
||||
fprintf(stderr, "Could not find encoder.\n");
|
||||
err = -1;
|
||||
goto close;
|
||||
}
|
||||
|
||||
if (!(avctx = avcodec_alloc_context3(codec))) {
|
||||
err = AVERROR(ENOMEM);
|
||||
goto close;
|
||||
}
|
||||
|
||||
avctx->width = width;
|
||||
avctx->height = height;
|
||||
avctx->time_base = (AVRational){1, 25};
|
||||
avctx->framerate = (AVRational){25, 1};
|
||||
avctx->sample_aspect_ratio = (AVRational){1, 1};
|
||||
avctx->pix_fmt = AV_PIX_FMT_VAAPI;
|
||||
|
||||
/* set hw_frames_ctx for encoder's AVCodecContext */
|
||||
if ((err = set_hwframe_ctx(avctx, hw_device_ctx)) < 0) {
|
||||
fprintf(stderr, "Failed to set hwframe context.\n");
|
||||
goto close;
|
||||
}
|
||||
|
||||
if ((err = avcodec_open2(avctx, codec, NULL)) < 0) {
|
||||
fprintf(stderr, "Cannot open video encoder codec. Error code: %s\n", av_err2str(err));
|
||||
goto close;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (!(sw_frame = av_frame_alloc())) {
|
||||
err = AVERROR(ENOMEM);
|
||||
goto close;
|
||||
}
|
||||
/* read data into software frame, and transfer them into hw frame */
|
||||
sw_frame->width = width;
|
||||
sw_frame->height = height;
|
||||
sw_frame->format = AV_PIX_FMT_NV12;
|
||||
if ((err = av_frame_get_buffer(sw_frame, 0)) < 0)
|
||||
goto close;
|
||||
if ((err = fread((uint8_t*)(sw_frame->data[0]), size, 1, fin)) <= 0)
|
||||
break;
|
||||
if ((err = fread((uint8_t*)(sw_frame->data[1]), size/2, 1, fin)) <= 0)
|
||||
break;
|
||||
|
||||
if (!(hw_frame = av_frame_alloc())) {
|
||||
err = AVERROR(ENOMEM);
|
||||
goto close;
|
||||
}
|
||||
if ((err = av_hwframe_get_buffer(avctx->hw_frames_ctx, hw_frame, 0)) < 0) {
|
||||
fprintf(stderr, "Error code: %s.\n", av_err2str(err));
|
||||
goto close;
|
||||
}
|
||||
if (!hw_frame->hw_frames_ctx) {
|
||||
err = AVERROR(ENOMEM);
|
||||
goto close;
|
||||
}
|
||||
if ((err = av_hwframe_transfer_data(hw_frame, sw_frame, 0)) < 0) {
|
||||
fprintf(stderr, "Error while transferring frame data to surface."
|
||||
"Error code: %s.\n", av_err2str(err));
|
||||
goto close;
|
||||
}
|
||||
|
||||
if ((err = (encode_write(avctx, hw_frame, fout))) < 0) {
|
||||
fprintf(stderr, "Failed to encode.\n");
|
||||
goto close;
|
||||
}
|
||||
av_frame_free(&hw_frame);
|
||||
av_frame_free(&sw_frame);
|
||||
}
|
||||
|
||||
/* flush encoder */
|
||||
err = encode_write(avctx, NULL, fout);
|
||||
if (err == AVERROR_EOF)
|
||||
err = 0;
|
||||
|
||||
close:
|
||||
if (fin)
|
||||
fclose(fin);
|
||||
if (fout)
|
||||
fclose(fout);
|
||||
av_frame_free(&sw_frame);
|
||||
av_frame_free(&hw_frame);
|
||||
avcodec_free_context(&avctx);
|
||||
av_buffer_unref(&hw_device_ctx);
|
||||
|
||||
return err;
|
||||
}
|
||||
+308
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Video Acceleration API (video transcoding) transcode sample
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Intel VAAPI-accelerated transcoding example.
|
||||
*
|
||||
* @example vaapi_transcode.c
|
||||
* This example shows how to do VAAPI-accelerated transcoding.
|
||||
* Usage: vaapi_transcode input_stream codec output_stream
|
||||
* e.g: - vaapi_transcode input.mp4 h264_vaapi output_h264.mp4
|
||||
* - vaapi_transcode input.mp4 vp9_vaapi output_vp9.ivf
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
static AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
||||
static AVBufferRef *hw_device_ctx = NULL;
|
||||
static AVCodecContext *decoder_ctx = NULL, *encoder_ctx = NULL;
|
||||
static int video_stream = -1;
|
||||
static AVStream *ost;
|
||||
static int initialized = 0;
|
||||
|
||||
static enum AVPixelFormat get_vaapi_format(AVCodecContext *ctx,
|
||||
const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
const enum AVPixelFormat *p;
|
||||
|
||||
for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
|
||||
if (*p == AV_PIX_FMT_VAAPI)
|
||||
return *p;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unable to decode this file using VA-API.\n");
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
static int open_input_file(const char *filename)
|
||||
{
|
||||
int ret;
|
||||
const AVCodec *decoder = NULL;
|
||||
AVStream *video = NULL;
|
||||
|
||||
if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
|
||||
fprintf(stderr, "Cannot open input file '%s', Error code: %s\n",
|
||||
filename, av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
|
||||
fprintf(stderr, "Cannot find input stream information. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot find a video stream in the input file. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
video_stream = ret;
|
||||
|
||||
if (!(decoder_ctx = avcodec_alloc_context3(decoder)))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
video = ifmt_ctx->streams[video_stream];
|
||||
if ((ret = avcodec_parameters_to_context(decoder_ctx, video->codecpar)) < 0) {
|
||||
fprintf(stderr, "avcodec_parameters_to_context error. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
decoder_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
||||
if (!decoder_ctx->hw_device_ctx) {
|
||||
fprintf(stderr, "A hardware device reference create failed.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
decoder_ctx->get_format = get_vaapi_format;
|
||||
|
||||
if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0)
|
||||
fprintf(stderr, "Failed to open codec for decoding. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int encode_write(AVPacket *enc_pkt, AVFrame *frame)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
av_packet_unref(enc_pkt);
|
||||
|
||||
if ((ret = avcodec_send_frame(encoder_ctx, frame)) < 0) {
|
||||
fprintf(stderr, "Error during encoding. Error code: %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
while (1) {
|
||||
ret = avcodec_receive_packet(encoder_ctx, enc_pkt);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
enc_pkt->stream_index = 0;
|
||||
av_packet_rescale_ts(enc_pkt, ifmt_ctx->streams[video_stream]->time_base,
|
||||
ofmt_ctx->streams[0]->time_base);
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during writing data to output file. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (ret == AVERROR_EOF)
|
||||
return 0;
|
||||
ret = ((ret == AVERROR(EAGAIN)) ? 0:-1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dec_enc(AVPacket *pkt, const AVCodec *enc_codec)
|
||||
{
|
||||
AVFrame *frame;
|
||||
int ret = 0;
|
||||
|
||||
ret = avcodec_send_packet(decoder_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding. Error code: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
if (!(frame = av_frame_alloc()))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ret = avcodec_receive_frame(decoder_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
av_frame_free(&frame);
|
||||
return 0;
|
||||
} else if (ret < 0) {
|
||||
fprintf(stderr, "Error while decoding. Error code: %s\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
/* we need to ref hw_frames_ctx of decoder to initialize encoder's codec.
|
||||
Only after we get a decoded frame, can we obtain its hw_frames_ctx */
|
||||
encoder_ctx->hw_frames_ctx = av_buffer_ref(decoder_ctx->hw_frames_ctx);
|
||||
if (!encoder_ctx->hw_frames_ctx) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
/* set AVCodecContext Parameters for encoder, here we keep them stay
|
||||
* the same as decoder.
|
||||
* xxx: now the sample can't handle resolution change case.
|
||||
*/
|
||||
encoder_ctx->time_base = av_inv_q(decoder_ctx->framerate);
|
||||
encoder_ctx->pix_fmt = AV_PIX_FMT_VAAPI;
|
||||
encoder_ctx->width = decoder_ctx->width;
|
||||
encoder_ctx->height = decoder_ctx->height;
|
||||
|
||||
if ((ret = avcodec_open2(encoder_ctx, enc_codec, NULL)) < 0) {
|
||||
fprintf(stderr, "Failed to open encode codec. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(ost = avformat_new_stream(ofmt_ctx, enc_codec))) {
|
||||
fprintf(stderr, "Failed to allocate stream for output format.\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ost->time_base = encoder_ctx->time_base;
|
||||
ret = avcodec_parameters_from_context(ost->codecpar, encoder_ctx);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to copy the stream parameters. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* write the stream header */
|
||||
if ((ret = avformat_write_header(ofmt_ctx, NULL)) < 0) {
|
||||
fprintf(stderr, "Error while writing stream header. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
if ((ret = encode_write(pkt, frame)) < 0)
|
||||
fprintf(stderr, "Error during encoding and writing.\n");
|
||||
|
||||
fail:
|
||||
av_frame_free(&frame);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const AVCodec *enc_codec;
|
||||
int ret = 0;
|
||||
AVPacket *dec_pkt;
|
||||
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "Usage: %s <input file> <encode codec> <output file>\n"
|
||||
"The output format is guessed according to the file extension.\n"
|
||||
"\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, NULL, NULL, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to create a VAAPI device. Error code: %s\n", av_err2str(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
dec_pkt = av_packet_alloc();
|
||||
if (!dec_pkt) {
|
||||
fprintf(stderr, "Failed to allocate decode packet\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
|
||||
if (!(enc_codec = avcodec_find_encoder_by_name(argv[2]))) {
|
||||
fprintf(stderr, "Could not find encoder '%s'\n", argv[2]);
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = (avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, argv[3]))) < 0) {
|
||||
fprintf(stderr, "Failed to deduce output format from file extension. Error code: "
|
||||
"%s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!(encoder_ctx = avcodec_alloc_context3(enc_codec))) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avio_open(&ofmt_ctx->pb, argv[3], AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot open output file. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* read all packets and only transcoding video */
|
||||
while (ret >= 0) {
|
||||
if ((ret = av_read_frame(ifmt_ctx, dec_pkt)) < 0)
|
||||
break;
|
||||
|
||||
if (video_stream == dec_pkt->stream_index)
|
||||
ret = dec_enc(dec_pkt, enc_codec);
|
||||
|
||||
av_packet_unref(dec_pkt);
|
||||
}
|
||||
|
||||
/* flush decoder */
|
||||
av_packet_unref(dec_pkt);
|
||||
ret = dec_enc(dec_pkt, enc_codec);
|
||||
|
||||
/* flush encoder */
|
||||
ret = encode_write(dec_pkt, NULL);
|
||||
|
||||
/* write the trailer for output stream */
|
||||
av_write_trailer(ofmt_ctx);
|
||||
|
||||
end:
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
avformat_close_input(&ofmt_ctx);
|
||||
avcodec_free_context(&decoder_ctx);
|
||||
avcodec_free_context(&encoder_ctx);
|
||||
av_buffer_unref(&hw_device_ctx);
|
||||
av_packet_free(&dec_pkt);
|
||||
return ret;
|
||||
}
|
||||
Vendored
-680
@@ -1,680 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : FFmpeg FAQ: </title>
|
||||
|
||||
<meta name="description" content="FFmpeg FAQ: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : FFmpeg FAQ: ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">FFmpeg FAQ</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-General-Questions" href="#General-Questions">1. General Questions</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Why-doesn_0027t-FFmpeg-support-feature-_005bxyz_005d_003f" href="#Why-doesn_0027t-FFmpeg-support-feature-_005bxyz_005d_003f">1.1 Why doesn’t FFmpeg support feature [xyz]?</a></li>
|
||||
<li><a name="toc-FFmpeg-does-not-support-codec-XXX_002e-Can-you-include-a-Windows-DLL-loader-to-support-it_003f" href="#FFmpeg-does-not-support-codec-XXX_002e-Can-you-include-a-Windows-DLL-loader-to-support-it_003f">1.2 FFmpeg does not support codec XXX. Can you include a Windows DLL loader to support it?</a></li>
|
||||
<li><a name="toc-I-cannot-read-this-file-although-this-format-seems-to-be-supported-by-ffmpeg_002e" href="#I-cannot-read-this-file-although-this-format-seems-to-be-supported-by-ffmpeg_002e">1.3 I cannot read this file although this format seems to be supported by ffmpeg.</a></li>
|
||||
<li><a name="toc-Which-codecs-are-supported-by-Windows_003f" href="#Which-codecs-are-supported-by-Windows_003f">1.4 Which codecs are supported by Windows?</a></li>
|
||||
</ul></li>
|
||||
<li><a name="toc-Compilation" href="#Compilation">2. Compilation</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-error_003a-can_0027t-find-a-register-in-class-_0027GENERAL_005fREGS_0027-while-reloading-_0027asm_0027" href="#error_003a-can_0027t-find-a-register-in-class-_0027GENERAL_005fREGS_0027-while-reloading-_0027asm_0027">2.1 <code>error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'</code></a></li>
|
||||
<li><a name="toc-I-have-installed-this-library-with-my-distro_0027s-package-manager_002e-Why-does-configure-not-see-it_003f" href="#I-have-installed-this-library-with-my-distro_0027s-package-manager_002e-Why-does-configure-not-see-it_003f">2.2 I have installed this library with my distro’s package manager. Why does <code>configure</code> not see it?</a></li>
|
||||
</ul></li>
|
||||
<li><a name="toc-Usage" href="#Usage">3. Usage</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-ffmpeg-does-not-work_003b-what-is-wrong_003f" href="#ffmpeg-does-not-work_003b-what-is-wrong_003f">3.1 ffmpeg does not work; what is wrong?</a></li>
|
||||
<li><a name="toc-How-do-I-encode-single-pictures-into-movies_003f" href="#How-do-I-encode-single-pictures-into-movies_003f">3.2 How do I encode single pictures into movies?</a></li>
|
||||
<li><a name="toc-How-do-I-encode-movie-to-single-pictures_003f" href="#How-do-I-encode-movie-to-single-pictures_003f">3.3 How do I encode movie to single pictures?</a></li>
|
||||
<li><a name="toc-Why-do-I-see-a-slight-quality-degradation-with-multithreaded-MPEG_002a-encoding_003f" href="#Why-do-I-see-a-slight-quality-degradation-with-multithreaded-MPEG_002a-encoding_003f">3.4 Why do I see a slight quality degradation with multithreaded MPEG* encoding?</a></li>
|
||||
<li><a name="toc-How-can-I-read-from-the-standard-input-or-write-to-the-standard-output_003f" href="#How-can-I-read-from-the-standard-input-or-write-to-the-standard-output_003f">3.5 How can I read from the standard input or write to the standard output?</a></li>
|
||||
<li><a name="toc-_002df-jpeg-doesn_0027t-work_002e" href="#g_t_002df-jpeg-doesn_0027t-work_002e">3.6 -f jpeg doesn’t work.</a></li>
|
||||
<li><a name="toc-Why-can-I-not-change-the-frame-rate_003f" href="#Why-can-I-not-change-the-frame-rate_003f">3.7 Why can I not change the frame rate?</a></li>
|
||||
<li><a name="toc-How-do-I-encode-Xvid-or-DivX-video-with-ffmpeg_003f" href="#How-do-I-encode-Xvid-or-DivX-video-with-ffmpeg_003f">3.8 How do I encode Xvid or DivX video with ffmpeg?</a></li>
|
||||
<li><a name="toc-Which-are-good-parameters-for-encoding-high-quality-MPEG_002d4_003f" href="#Which-are-good-parameters-for-encoding-high-quality-MPEG_002d4_003f">3.9 Which are good parameters for encoding high quality MPEG-4?</a></li>
|
||||
<li><a name="toc-Which-are-good-parameters-for-encoding-high-quality-MPEG_002d1_002fMPEG_002d2_003f" href="#Which-are-good-parameters-for-encoding-high-quality-MPEG_002d1_002fMPEG_002d2_003f">3.10 Which are good parameters for encoding high quality MPEG-1/MPEG-2?</a></li>
|
||||
<li><a name="toc-Interlaced-video-looks-very-bad-when-encoded-with-ffmpeg_002c-what-is-wrong_003f" href="#Interlaced-video-looks-very-bad-when-encoded-with-ffmpeg_002c-what-is-wrong_003f">3.11 Interlaced video looks very bad when encoded with ffmpeg, what is wrong?</a></li>
|
||||
<li><a name="toc-How-can-I-read-DirectShow-files_003f" href="#How-can-I-read-DirectShow-files_003f">3.12 How can I read DirectShow files?</a></li>
|
||||
<li><a name="toc-How-can-I-join-video-files_003f" href="#How-can-I-join-video-files_003f">3.13 How can I join video files?</a></li>
|
||||
<li><a name="toc-How-can-I-concatenate-video-files_003f" href="#How-can-I-concatenate-video-files_003f">3.14 How can I concatenate video files?</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Concatenating-using-the-concat-filter" href="#Concatenating-using-the-concat-filter">3.14.1 Concatenating using the concat <em>filter</em></a></li>
|
||||
<li><a name="toc-Concatenating-using-the-concat-demuxer" href="#Concatenating-using-the-concat-demuxer">3.14.2 Concatenating using the concat <em>demuxer</em></a></li>
|
||||
<li><a name="toc-Concatenating-using-the-concat-protocol-_0028file-level_0029" href="#Concatenating-using-the-concat-protocol-_0028file-level_0029">3.14.3 Concatenating using the concat <em>protocol</em> (file level)</a></li>
|
||||
<li><a name="toc-Concatenating-using-raw-audio-and-video" href="#Concatenating-using-raw-audio-and-video">3.14.4 Concatenating using raw audio and video</a></li>
|
||||
</ul></li>
|
||||
<li><a name="toc-_002dprofile-option-fails-when-encoding-H_002e264-video-with-AAC-audio" href="#g_t_002dprofile-option-fails-when-encoding-H_002e264-video-with-AAC-audio">3.15 -profile option fails when encoding H.264 video with AAC audio</a></li>
|
||||
<li><a name="toc-Using-_002df-lavfi_002c-audio-becomes-mono-for-no-apparent-reason_002e" href="#Using-_002df-lavfi_002c-audio-becomes-mono-for-no-apparent-reason_002e">3.16 Using ‘<samp>-f lavfi</samp>’, audio becomes mono for no apparent reason.</a></li>
|
||||
<li><a name="toc-Why-does-FFmpeg-not-see-the-subtitles-in-my-VOB-file_003f" href="#Why-does-FFmpeg-not-see-the-subtitles-in-my-VOB-file_003f">3.17 Why does FFmpeg not see the subtitles in my VOB file?</a></li>
|
||||
<li><a name="toc-Why-was-the-ffmpeg-_002dsameq-option-removed_003f-What-to-use-instead_003f" href="#Why-was-the-ffmpeg-_002dsameq-option-removed_003f-What-to-use-instead_003f">3.18 Why was the <code>ffmpeg</code> ‘<samp>-sameq</samp>’ option removed? What to use instead?</a></li>
|
||||
</ul></li>
|
||||
<li><a name="toc-Development" href="#Development">4. Development</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Are-there-examples-illustrating-how-to-use-the-FFmpeg-libraries_002c-particularly-libavcodec-and-libavformat_003f" href="#Are-there-examples-illustrating-how-to-use-the-FFmpeg-libraries_002c-particularly-libavcodec-and-libavformat_003f">4.1 Are there examples illustrating how to use the FFmpeg libraries, particularly libavcodec and libavformat?</a></li>
|
||||
<li><a name="toc-Can-you-support-my-C-compiler-XXX_003f" href="#Can-you-support-my-C-compiler-XXX_003f">4.2 Can you support my C compiler XXX?</a></li>
|
||||
<li><a name="toc-Is-Microsoft-Visual-C_002b_002b-supported_003f" href="#Is-Microsoft-Visual-C_002b_002b-supported_003f">4.3 Is Microsoft Visual C++ supported?</a></li>
|
||||
<li><a name="toc-Can-you-add-automake_002c-libtool-or-autoconf-support_003f" href="#Can-you-add-automake_002c-libtool-or-autoconf-support_003f">4.4 Can you add automake, libtool or autoconf support?</a></li>
|
||||
<li><a name="toc-Why-not-rewrite-FFmpeg-in-object_002doriented-C_002b_002b_003f" href="#Why-not-rewrite-FFmpeg-in-object_002doriented-C_002b_002b_003f">4.5 Why not rewrite FFmpeg in object-oriented C++?</a></li>
|
||||
<li><a name="toc-Why-are-the-ffmpeg-programs-devoid-of-debugging-symbols_003f" href="#Why-are-the-ffmpeg-programs-devoid-of-debugging-symbols_003f">4.6 Why are the ffmpeg programs devoid of debugging symbols?</a></li>
|
||||
<li><a name="toc-I-do-not-like-the-LGPL_002c-can-I-contribute-code-under-the-GPL-instead_003f" href="#I-do-not-like-the-LGPL_002c-can-I-contribute-code-under-the-GPL-instead_003f">4.7 I do not like the LGPL, can I contribute code under the GPL instead?</a></li>
|
||||
<li><a name="toc-I_0027m-using-FFmpeg-from-within-my-C-application-but-the-linker-complains-about-missing-symbols-from-the-libraries-themselves_002e" href="#I_0027m-using-FFmpeg-from-within-my-C-application-but-the-linker-complains-about-missing-symbols-from-the-libraries-themselves_002e">4.8 I’m using FFmpeg from within my C application but the linker complains about missing symbols from the libraries themselves.</a></li>
|
||||
<li><a name="toc-I_0027m-using-FFmpeg-from-within-my-C_002b_002b-application-but-the-linker-complains-about-missing-symbols-which-seem-to-be-available_002e" href="#I_0027m-using-FFmpeg-from-within-my-C_002b_002b-application-but-the-linker-complains-about-missing-symbols-which-seem-to-be-available_002e">4.9 I’m using FFmpeg from within my C++ application but the linker complains about missing symbols which seem to be available.</a></li>
|
||||
<li><a name="toc-I_0027m-using-libavutil-from-within-my-C_002b_002b-application-but-the-compiler-complains-about-_0027UINT64_005fC_0027-was-not-declared-in-this-scope" href="#I_0027m-using-libavutil-from-within-my-C_002b_002b-application-but-the-compiler-complains-about-_0027UINT64_005fC_0027-was-not-declared-in-this-scope">4.10 I’m using libavutil from within my C++ application but the compiler complains about ’UINT64_C’ was not declared in this scope</a></li>
|
||||
<li><a name="toc-I-have-a-file-in-memory-_002f-a-API-different-from-_002aopen_002f_002aread_002f-libc-how-do-I-use-it-with-libavformat_003f" href="#I-have-a-file-in-memory-_002f-a-API-different-from-_002aopen_002f_002aread_002f-libc-how-do-I-use-it-with-libavformat_003f">4.11 I have a file in memory / a API different from *open/*read/ libc how do I use it with libavformat?</a></li>
|
||||
<li><a name="toc-Where-is-the-documentation-about-ffv1_002c-msmpeg4_002c-asv1_002c-4xm_003f" href="#Where-is-the-documentation-about-ffv1_002c-msmpeg4_002c-asv1_002c-4xm_003f">4.12 Where is the documentation about ffv1, msmpeg4, asv1, 4xm?</a></li>
|
||||
<li><a name="toc-How-do-I-feed-H_002e263_002dRTP-_0028and-other-codecs-in-RTP_0029-to-libavcodec_003f" href="#How-do-I-feed-H_002e263_002dRTP-_0028and-other-codecs-in-RTP_0029-to-libavcodec_003f">4.13 How do I feed H.263-RTP (and other codecs in RTP) to libavcodec?</a></li>
|
||||
<li><a name="toc-AVStream_002er_005fframe_005frate-is-wrong_002c-it-is-much-larger-than-the-frame-rate_002e" href="#AVStream_002er_005fframe_005frate-is-wrong_002c-it-is-much-larger-than-the-frame-rate_002e">4.14 AVStream.r_frame_rate is wrong, it is much larger than the frame rate.</a></li>
|
||||
<li><a name="toc-Why-is-make-fate-not-running-all-tests_003f" href="#Why-is-make-fate-not-running-all-tests_003f">4.15 Why is <code>make fate</code> not running all tests?</a></li>
|
||||
<li><a name="toc-Why-is-make-fate-not-finding-the-samples_003f" href="#Why-is-make-fate-not-finding-the-samples_003f">4.16 Why is <code>make fate</code> not finding the samples?</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="General-Questions"></a>
|
||||
<h1 class="chapter"><a href="faq.html#toc-General-Questions">1. General Questions</a></h1>
|
||||
|
||||
<a name="Why-doesn_0027t-FFmpeg-support-feature-_005bxyz_005d_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Why-doesn_0027t-FFmpeg-support-feature-_005bxyz_005d_003f">1.1 Why doesn’t FFmpeg support feature [xyz]?</a></h2>
|
||||
|
||||
<p>Because no one has taken on that task yet. FFmpeg development is
|
||||
driven by the tasks that are important to the individual developers.
|
||||
If there is a feature that is important to you, the best way to get
|
||||
it implemented is to undertake the task yourself or sponsor a developer.
|
||||
</p>
|
||||
<a name="FFmpeg-does-not-support-codec-XXX_002e-Can-you-include-a-Windows-DLL-loader-to-support-it_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-FFmpeg-does-not-support-codec-XXX_002e-Can-you-include-a-Windows-DLL-loader-to-support-it_003f">1.2 FFmpeg does not support codec XXX. Can you include a Windows DLL loader to support it?</a></h2>
|
||||
|
||||
<p>No. Windows DLLs are not portable, bloated and often slow.
|
||||
Moreover FFmpeg strives to support all codecs natively.
|
||||
A DLL loader is not conducive to that goal.
|
||||
</p>
|
||||
<a name="I-cannot-read-this-file-although-this-format-seems-to-be-supported-by-ffmpeg_002e"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-I-cannot-read-this-file-although-this-format-seems-to-be-supported-by-ffmpeg_002e">1.3 I cannot read this file although this format seems to be supported by ffmpeg.</a></h2>
|
||||
|
||||
<p>Even if ffmpeg can read the container format, it may not support all its
|
||||
codecs. Please consult the supported codec list in the ffmpeg
|
||||
documentation.
|
||||
</p>
|
||||
<a name="Which-codecs-are-supported-by-Windows_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Which-codecs-are-supported-by-Windows_003f">1.4 Which codecs are supported by Windows?</a></h2>
|
||||
|
||||
<p>Windows does not support standard formats like MPEG very well, unless you
|
||||
install some additional codecs.
|
||||
</p>
|
||||
<p>The following list of video codecs should work on most Windows systems:
|
||||
</p><dl compact="compact">
|
||||
<dt> ‘<samp>msmpeg4v2</samp>’</dt>
|
||||
<dd><p>.avi/.asf
|
||||
</p></dd>
|
||||
<dt> ‘<samp>msmpeg4</samp>’</dt>
|
||||
<dd><p>.asf only
|
||||
</p></dd>
|
||||
<dt> ‘<samp>wmv1</samp>’</dt>
|
||||
<dd><p>.asf only
|
||||
</p></dd>
|
||||
<dt> ‘<samp>wmv2</samp>’</dt>
|
||||
<dd><p>.asf only
|
||||
</p></dd>
|
||||
<dt> ‘<samp>mpeg4</samp>’</dt>
|
||||
<dd><p>Only if you have some MPEG-4 codec like ffdshow or Xvid installed.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>mpeg1video</samp>’</dt>
|
||||
<dd><p>.mpg only
|
||||
</p></dd>
|
||||
</dl>
|
||||
<p>Note, ASF files often have .wmv or .wma extensions in Windows. It should also
|
||||
be mentioned that Microsoft claims a patent on the ASF format, and may sue
|
||||
or threaten users who create ASF files with non-Microsoft software. It is
|
||||
strongly advised to avoid ASF where possible.
|
||||
</p>
|
||||
<p>The following list of audio codecs should work on most Windows systems:
|
||||
</p><dl compact="compact">
|
||||
<dt> ‘<samp>adpcm_ima_wav</samp>’</dt>
|
||||
<dt> ‘<samp>adpcm_ms</samp>’</dt>
|
||||
<dt> ‘<samp>pcm_s16le</samp>’</dt>
|
||||
<dd><p>always
|
||||
</p></dd>
|
||||
<dt> ‘<samp>libmp3lame</samp>’</dt>
|
||||
<dd><p>If some MP3 codec like LAME is installed.
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<a name="Compilation"></a>
|
||||
<h1 class="chapter"><a href="faq.html#toc-Compilation">2. Compilation</a></h1>
|
||||
|
||||
<a name="error_003a-can_0027t-find-a-register-in-class-_0027GENERAL_005fREGS_0027-while-reloading-_0027asm_0027"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-error_003a-can_0027t-find-a-register-in-class-_0027GENERAL_005fREGS_0027-while-reloading-_0027asm_0027">2.1 <code>error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'</code></a></h2>
|
||||
|
||||
<p>This is a bug in gcc. Do not report it to us. Instead, please report it to
|
||||
the gcc developers. Note that we will not add workarounds for gcc bugs.
|
||||
</p>
|
||||
<p>Also note that (some of) the gcc developers believe this is not a bug or
|
||||
not a bug they should fix:
|
||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11203">http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11203</a>.
|
||||
Then again, some of them do not know the difference between an undecidable
|
||||
problem and an NP-hard problem...
|
||||
</p>
|
||||
<a name="I-have-installed-this-library-with-my-distro_0027s-package-manager_002e-Why-does-configure-not-see-it_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-I-have-installed-this-library-with-my-distro_0027s-package-manager_002e-Why-does-configure-not-see-it_003f">2.2 I have installed this library with my distro’s package manager. Why does <code>configure</code> not see it?</a></h2>
|
||||
|
||||
<p>Distributions usually split libraries in several packages. The main package
|
||||
contains the files necessary to run programs using the library. The
|
||||
development package contains the files necessary to build programs using the
|
||||
library. Sometimes, docs and/or data are in a separate package too.
|
||||
</p>
|
||||
<p>To build FFmpeg, you need to install the development package. It is usually
|
||||
called ‘<tt>libfoo-dev</tt>’ or ‘<tt>libfoo-devel</tt>’. You can remove it after the
|
||||
build is finished, but be sure to keep the main package.
|
||||
</p>
|
||||
<a name="Usage"></a>
|
||||
<h1 class="chapter"><a href="faq.html#toc-Usage">3. Usage</a></h1>
|
||||
|
||||
<a name="ffmpeg-does-not-work_003b-what-is-wrong_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-ffmpeg-does-not-work_003b-what-is-wrong_003f">3.1 ffmpeg does not work; what is wrong?</a></h2>
|
||||
|
||||
<p>Try a <code>make distclean</code> in the ffmpeg source directory before the build.
|
||||
If this does not help see
|
||||
(<a href="http://ffmpeg.org/bugreports.html">http://ffmpeg.org/bugreports.html</a>).
|
||||
</p>
|
||||
<a name="How-do-I-encode-single-pictures-into-movies_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-How-do-I-encode-single-pictures-into-movies_003f">3.2 How do I encode single pictures into movies?</a></h2>
|
||||
|
||||
<p>First, rename your pictures to follow a numerical sequence.
|
||||
For example, img1.jpg, img2.jpg, img3.jpg,...
|
||||
Then you may run:
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">ffmpeg -f image2 -i img%d.jpg /tmp/a.mpg
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>Notice that ‘<samp>%d</samp>’ is replaced by the image number.
|
||||
</p>
|
||||
<p>‘<tt>img%03d.jpg</tt>’ means the sequence ‘<tt>img001.jpg</tt>’, ‘<tt>img002.jpg</tt>’, etc.
|
||||
</p>
|
||||
<p>Use the ‘<samp>-start_number</samp>’ option to declare a starting number for
|
||||
the sequence. This is useful if your sequence does not start with
|
||||
‘<tt>img001.jpg</tt>’ but is still in a numerical order. The following
|
||||
example will start with ‘<tt>img100.jpg</tt>’:
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">ffmpeg -f image2 -start_number 100 -i img%d.jpg /tmp/a.mpg
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>If you have large number of pictures to rename, you can use the
|
||||
following command to ease the burden. The command, using the bourne
|
||||
shell syntax, symbolically links all files in the current directory
|
||||
that match <code>*jpg</code> to the ‘<tt>/tmp</tt>’ directory in the sequence of
|
||||
‘<tt>img001.jpg</tt>’, ‘<tt>img002.jpg</tt>’ and so on.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">x=1; for i in *jpg; do counter=$(printf %03d $x); ln -s "$i" /tmp/img"$counter".jpg; x=$(($x+1)); done
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>If you want to sequence them by oldest modified first, substitute
|
||||
<code>$(ls -r -t *jpg)</code> in place of <code>*jpg</code>.
|
||||
</p>
|
||||
<p>Then run:
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>The same logic is used for any image format that ffmpeg reads.
|
||||
</p>
|
||||
<p>You can also use <code>cat</code> to pipe images to ffmpeg:
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">cat *.jpg | ffmpeg -f image2pipe -c:v mjpeg -i - output.mpg
|
||||
</pre></td></tr></table>
|
||||
|
||||
<a name="How-do-I-encode-movie-to-single-pictures_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-How-do-I-encode-movie-to-single-pictures_003f">3.3 How do I encode movie to single pictures?</a></h2>
|
||||
|
||||
<p>Use:
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">ffmpeg -i movie.mpg movie%d.jpg
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>The ‘<tt>movie.mpg</tt>’ used as input will be converted to
|
||||
‘<tt>movie1.jpg</tt>’, ‘<tt>movie2.jpg</tt>’, etc...
|
||||
</p>
|
||||
<p>Instead of relying on file format self-recognition, you may also use
|
||||
</p><dl compact="compact">
|
||||
<dt> ‘<samp>-c:v ppm</samp>’</dt>
|
||||
<dt> ‘<samp>-c:v png</samp>’</dt>
|
||||
<dt> ‘<samp>-c:v mjpeg</samp>’</dt>
|
||||
</dl>
|
||||
<p>to force the encoding.
|
||||
</p>
|
||||
<p>Applying that to the previous example:
|
||||
</p><table><tr><td> </td><td><pre class="example">ffmpeg -i movie.mpg -f image2 -c:v mjpeg menu%d.jpg
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>Beware that there is no "jpeg" codec. Use "mjpeg" instead.
|
||||
</p>
|
||||
<a name="Why-do-I-see-a-slight-quality-degradation-with-multithreaded-MPEG_002a-encoding_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Why-do-I-see-a-slight-quality-degradation-with-multithreaded-MPEG_002a-encoding_003f">3.4 Why do I see a slight quality degradation with multithreaded MPEG* encoding?</a></h2>
|
||||
|
||||
<p>For multithreaded MPEG* encoding, the encoded slices must be independent,
|
||||
otherwise thread n would practically have to wait for n-1 to finish, so it’s
|
||||
quite logical that there is a small reduction of quality. This is not a bug.
|
||||
</p>
|
||||
<a name="How-can-I-read-from-the-standard-input-or-write-to-the-standard-output_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-How-can-I-read-from-the-standard-input-or-write-to-the-standard-output_003f">3.5 How can I read from the standard input or write to the standard output?</a></h2>
|
||||
|
||||
<p>Use ‘<tt>-</tt>’ as file name.
|
||||
</p>
|
||||
<a name="g_t_002df-jpeg-doesn_0027t-work_002e"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-_002df-jpeg-doesn_0027t-work_002e">3.6 -f jpeg doesn’t work.</a></h2>
|
||||
|
||||
<p>Try ’-f image2 test%d.jpg’.
|
||||
</p>
|
||||
<a name="Why-can-I-not-change-the-frame-rate_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Why-can-I-not-change-the-frame-rate_003f">3.7 Why can I not change the frame rate?</a></h2>
|
||||
|
||||
<p>Some codecs, like MPEG-1/2, only allow a small number of fixed frame rates.
|
||||
Choose a different codec with the -c:v command line option.
|
||||
</p>
|
||||
<a name="How-do-I-encode-Xvid-or-DivX-video-with-ffmpeg_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-How-do-I-encode-Xvid-or-DivX-video-with-ffmpeg_003f">3.8 How do I encode Xvid or DivX video with ffmpeg?</a></h2>
|
||||
|
||||
<p>Both Xvid and DivX (version 4+) are implementations of the ISO MPEG-4
|
||||
standard (note that there are many other coding formats that use this
|
||||
same standard). Thus, use ’-c:v mpeg4’ to encode in these formats. The
|
||||
default fourcc stored in an MPEG-4-coded file will be ’FMP4’. If you want
|
||||
a different fourcc, use the ’-vtag’ option. E.g., ’-vtag xvid’ will
|
||||
force the fourcc ’xvid’ to be stored as the video fourcc rather than the
|
||||
default.
|
||||
</p>
|
||||
<a name="Which-are-good-parameters-for-encoding-high-quality-MPEG_002d4_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Which-are-good-parameters-for-encoding-high-quality-MPEG_002d4_003f">3.9 Which are good parameters for encoding high quality MPEG-4?</a></h2>
|
||||
|
||||
<p>’-mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -g 300 -pass 1/2’,
|
||||
things to try: ’-bf 2’, ’-flags qprd’, ’-flags mv0’, ’-flags skiprd’.
|
||||
</p>
|
||||
<a name="Which-are-good-parameters-for-encoding-high-quality-MPEG_002d1_002fMPEG_002d2_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Which-are-good-parameters-for-encoding-high-quality-MPEG_002d1_002fMPEG_002d2_003f">3.10 Which are good parameters for encoding high quality MPEG-1/MPEG-2?</a></h2>
|
||||
|
||||
<p>’-mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -pass 1/2’
|
||||
but beware the ’-g 100’ might cause problems with some decoders.
|
||||
Things to try: ’-bf 2’, ’-flags qprd’, ’-flags mv0’, ’-flags skiprd.
|
||||
</p>
|
||||
<a name="Interlaced-video-looks-very-bad-when-encoded-with-ffmpeg_002c-what-is-wrong_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Interlaced-video-looks-very-bad-when-encoded-with-ffmpeg_002c-what-is-wrong_003f">3.11 Interlaced video looks very bad when encoded with ffmpeg, what is wrong?</a></h2>
|
||||
|
||||
<p>You should use ’-flags +ilme+ildct’ and maybe ’-flags +alt’ for interlaced
|
||||
material, and try ’-top 0/1’ if the result looks really messed-up.
|
||||
</p>
|
||||
<a name="How-can-I-read-DirectShow-files_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-How-can-I-read-DirectShow-files_003f">3.12 How can I read DirectShow files?</a></h2>
|
||||
|
||||
<p>If you have built FFmpeg with <code>./configure --enable-avisynth</code>
|
||||
(only possible on MinGW/Cygwin platforms),
|
||||
then you may use any file that DirectShow can read as input.
|
||||
</p>
|
||||
<p>Just create an "input.avs" text file with this single line ...
|
||||
</p><table><tr><td> </td><td><pre class="example">DirectShowSource("C:\path to your file\yourfile.asf")
|
||||
</pre></td></tr></table>
|
||||
<p>... and then feed that text file to ffmpeg:
|
||||
</p><table><tr><td> </td><td><pre class="example">ffmpeg -i input.avs
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>For ANY other help on AviSynth, please visit the
|
||||
<a href="http://www.avisynth.org/">AviSynth homepage</a>.
|
||||
</p>
|
||||
<a name="How-can-I-join-video-files_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-How-can-I-join-video-files_003f">3.13 How can I join video files?</a></h2>
|
||||
|
||||
<p>To "join" video files is quite ambiguous. The following list explains the
|
||||
different kinds of "joining" and points out how those are addressed in
|
||||
FFmpeg. To join video files may mean:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
To put them one after the other: this is called to <em>concatenate</em> them
|
||||
(in short: concat) and is addressed
|
||||
<a href="#How-can-I-concatenate-video-files">in this very faq</a>.
|
||||
|
||||
</li><li>
|
||||
To put them together in the same file, to let the user choose between the
|
||||
different versions (example: different audio languages): this is called to
|
||||
<em>multiplex</em> them together (in short: mux), and is done by simply
|
||||
invoking ffmpeg with several ‘<samp>-i</samp>’ options.
|
||||
|
||||
</li><li>
|
||||
For audio, to put all channels together in a single stream (example: two
|
||||
mono streams into one stereo stream): this is sometimes called to
|
||||
<em>merge</em> them, and can be done using the
|
||||
<a href="http://ffmpeg.org/ffmpeg-filters.html#amerge"><code>amerge</code></a> filter.
|
||||
|
||||
</li><li>
|
||||
For audio, to play one on top of the other: this is called to <em>mix</em>
|
||||
them, and can be done by first merging them into a single stream and then
|
||||
using the <a href="http://ffmpeg.org/ffmpeg-filters.html#pan"><code>pan</code></a> filter to mix
|
||||
the channels at will.
|
||||
|
||||
</li><li>
|
||||
For video, to display both together, side by side or one on top of a part of
|
||||
the other; it can be done using the
|
||||
<a href="http://ffmpeg.org/ffmpeg-filters.html#overlay"><code>overlay</code></a> video filter.
|
||||
|
||||
</li></ul>
|
||||
|
||||
<p><a name="How-can-I-concatenate-video-files"></a>
|
||||
</p><a name="How-can-I-concatenate-video-files_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-How-can-I-concatenate-video-files_003f">3.14 How can I concatenate video files?</a></h2>
|
||||
|
||||
<p>There are several solutions, depending on the exact circumstances.
|
||||
</p>
|
||||
<a name="Concatenating-using-the-concat-filter"></a>
|
||||
<h3 class="subsection"><a href="faq.html#toc-Concatenating-using-the-concat-filter">3.14.1 Concatenating using the concat <em>filter</em></a></h3>
|
||||
|
||||
<p>FFmpeg has a <a href="http://ffmpeg.org/ffmpeg-filters.html#concat"><code>concat</code></a> filter designed specifically for that, with examples in the
|
||||
documentation. This operation is recommended if you need to re-encode.
|
||||
</p>
|
||||
<a name="Concatenating-using-the-concat-demuxer"></a>
|
||||
<h3 class="subsection"><a href="faq.html#toc-Concatenating-using-the-concat-demuxer">3.14.2 Concatenating using the concat <em>demuxer</em></a></h3>
|
||||
|
||||
<p>FFmpeg has a <a href="http://www.ffmpeg.org/ffmpeg-formats.html#concat"><code>concat</code></a> demuxer which you can use when you want to avoid a re-encode and
|
||||
your format doesn’t support file level concatenation.
|
||||
</p>
|
||||
<a name="Concatenating-using-the-concat-protocol-_0028file-level_0029"></a>
|
||||
<h3 class="subsection"><a href="faq.html#toc-Concatenating-using-the-concat-protocol-_0028file-level_0029">3.14.3 Concatenating using the concat <em>protocol</em> (file level)</a></h3>
|
||||
|
||||
<p>FFmpeg has a <a href="http://ffmpeg.org/ffmpeg-protocols.html#concat"><code>concat</code></a> protocol designed specifically for that, with examples in the
|
||||
documentation.
|
||||
</p>
|
||||
<p>A few multimedia containers (MPEG-1, MPEG-2 PS, DV) allow to concatenate
|
||||
video by merely concatenating the files containing them.
|
||||
</p>
|
||||
<p>Hence you may concatenate your multimedia files by first transcoding them to
|
||||
these privileged formats, then using the humble <code>cat</code> command (or the
|
||||
equally humble <code>copy</code> under Windows), and finally transcoding back to your
|
||||
format of choice.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">ffmpeg -i input1.avi -qscale:v 1 intermediate1.mpg
|
||||
ffmpeg -i input2.avi -qscale:v 1 intermediate2.mpg
|
||||
cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg
|
||||
ffmpeg -i intermediate_all.mpg -qscale:v 2 output.avi
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>Additionally, you can use the <code>concat</code> protocol instead of <code>cat</code> or
|
||||
<code>copy</code> which will avoid creation of a potentially huge intermediate file.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">ffmpeg -i input1.avi -qscale:v 1 intermediate1.mpg
|
||||
ffmpeg -i input2.avi -qscale:v 1 intermediate2.mpg
|
||||
ffmpeg -i concat:"intermediate1.mpg|intermediate2.mpg" -c copy intermediate_all.mpg
|
||||
ffmpeg -i intermediate_all.mpg -qscale:v 2 output.avi
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>Note that you may need to escape the character "|" which is special for many
|
||||
shells.
|
||||
</p>
|
||||
<p>Another option is usage of named pipes, should your platform support it:
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">mkfifo intermediate1.mpg
|
||||
mkfifo intermediate2.mpg
|
||||
ffmpeg -i input1.avi -qscale:v 1 -y intermediate1.mpg < /dev/null &
|
||||
ffmpeg -i input2.avi -qscale:v 1 -y intermediate2.mpg < /dev/null &
|
||||
cat intermediate1.mpg intermediate2.mpg |\
|
||||
ffmpeg -f mpeg -i - -c:v mpeg4 -acodec libmp3lame output.avi
|
||||
</pre></td></tr></table>
|
||||
|
||||
<a name="Concatenating-using-raw-audio-and-video"></a>
|
||||
<h3 class="subsection"><a href="faq.html#toc-Concatenating-using-raw-audio-and-video">3.14.4 Concatenating using raw audio and video</a></h3>
|
||||
|
||||
<p>Similarly, the yuv4mpegpipe format, and the raw video, raw audio codecs also
|
||||
allow concatenation, and the transcoding step is almost lossless.
|
||||
When using multiple yuv4mpegpipe(s), the first line needs to be discarded
|
||||
from all but the first stream. This can be accomplished by piping through
|
||||
<code>tail</code> as seen below. Note that when piping through <code>tail</code> you
|
||||
must use command grouping, <code>{ ;}</code>, to background properly.
|
||||
</p>
|
||||
<p>For example, let’s say we want to concatenate two FLV files into an
|
||||
output.flv file:
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">mkfifo temp1.a
|
||||
mkfifo temp1.v
|
||||
mkfifo temp2.a
|
||||
mkfifo temp2.v
|
||||
mkfifo all.a
|
||||
mkfifo all.v
|
||||
ffmpeg -i input1.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
|
||||
ffmpeg -i input2.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
|
||||
ffmpeg -i input1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null &
|
||||
{ ffmpeg -i input2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; } &
|
||||
cat temp1.a temp2.a > all.a &
|
||||
cat temp1.v temp2.v > all.v &
|
||||
ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
|
||||
-f yuv4mpegpipe -i all.v \
|
||||
-y output.flv
|
||||
rm temp[12].[av] all.[av]
|
||||
</pre></td></tr></table>
|
||||
|
||||
<a name="g_t_002dprofile-option-fails-when-encoding-H_002e264-video-with-AAC-audio"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-_002dprofile-option-fails-when-encoding-H_002e264-video-with-AAC-audio">3.15 -profile option fails when encoding H.264 video with AAC audio</a></h2>
|
||||
|
||||
<p><code>ffmpeg</code> prints an error like
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">Undefined constant or missing '(' in 'baseline'
|
||||
Unable to parse option value "baseline"
|
||||
Error setting option profile to value baseline.
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>Short answer: write ‘<samp>-profile:v</samp>’ instead of ‘<samp>-profile</samp>’.
|
||||
</p>
|
||||
<p>Long answer: this happens because the ‘<samp>-profile</samp>’ option can apply to both
|
||||
video and audio. Specifically the AAC encoder also defines some profiles, none
|
||||
of which are named <var>baseline</var>.
|
||||
</p>
|
||||
<p>The solution is to apply the ‘<samp>-profile</samp>’ option to the video stream only
|
||||
by using <a href="http://ffmpeg.org/ffmpeg.html#Stream-specifiers-1">Stream specifiers</a>.
|
||||
Appending <code>:v</code> to it will do exactly that.
|
||||
</p>
|
||||
<a name="Using-_002df-lavfi_002c-audio-becomes-mono-for-no-apparent-reason_002e"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Using-_002df-lavfi_002c-audio-becomes-mono-for-no-apparent-reason_002e">3.16 Using ‘<samp>-f lavfi</samp>’, audio becomes mono for no apparent reason.</a></h2>
|
||||
|
||||
<p>Use ‘<samp>-dumpgraph -</samp>’ to find out exactly where the channel layout is
|
||||
lost.
|
||||
</p>
|
||||
<p>Most likely, it is through <code>auto-inserted aresample</code>. Try to understand
|
||||
why the converting filter was needed at that place.
|
||||
</p>
|
||||
<p>Just before the output is a likely place, as ‘<samp>-f lavfi</samp>’ currently
|
||||
only support packed S16.
|
||||
</p>
|
||||
<p>Then insert the correct <code>aformat</code> explicitly in the filtergraph,
|
||||
specifying the exact format.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">aformat=sample_fmts=s16:channel_layouts=stereo
|
||||
</pre></td></tr></table>
|
||||
|
||||
<a name="Why-does-FFmpeg-not-see-the-subtitles-in-my-VOB-file_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Why-does-FFmpeg-not-see-the-subtitles-in-my-VOB-file_003f">3.17 Why does FFmpeg not see the subtitles in my VOB file?</a></h2>
|
||||
|
||||
<p>VOB and a few other formats do not have a global header that describes
|
||||
everything present in the file. Instead, applications are supposed to scan
|
||||
the file to see what it contains. Since VOB files are frequently large, only
|
||||
the beginning is scanned. If the subtitles happen only later in the file,
|
||||
they will not be initally detected.
|
||||
</p>
|
||||
<p>Some applications, including the <code>ffmpeg</code> command-line tool, can only
|
||||
work with streams that were detected during the initial scan; streams that
|
||||
are detected later are ignored.
|
||||
</p>
|
||||
<p>The size of the initial scan is controlled by two options: <code>probesize</code>
|
||||
(default ~5 Mo) and <code>analyzeduration</code> (default 5,000,000 µs = 5 s). For
|
||||
the subtitle stream to be detected, both values must be large enough.
|
||||
</p>
|
||||
<a name="Why-was-the-ffmpeg-_002dsameq-option-removed_003f-What-to-use-instead_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Why-was-the-ffmpeg-_002dsameq-option-removed_003f-What-to-use-instead_003f">3.18 Why was the <code>ffmpeg</code> ‘<samp>-sameq</samp>’ option removed? What to use instead?</a></h2>
|
||||
|
||||
<p>The ‘<samp>-sameq</samp>’ option meant "same quantizer", and made sense only in a
|
||||
very limited set of cases. Unfortunately, a lot of people mistook it for
|
||||
"same quality" and used it in places where it did not make sense: it had
|
||||
roughly the expected visible effect, but achieved it in a very inefficient
|
||||
way.
|
||||
</p>
|
||||
<p>Each encoder has its own set of options to set the quality-vs-size balance,
|
||||
use the options for the encoder you are using to set the quality level to a
|
||||
point acceptable for your tastes. The most common options to do that are
|
||||
‘<samp>-qscale</samp>’ and ‘<samp>-qmax</samp>’, but you should peruse the documentation
|
||||
of the encoder you chose.
|
||||
</p>
|
||||
<a name="Development"></a>
|
||||
<h1 class="chapter"><a href="faq.html#toc-Development">4. Development</a></h1>
|
||||
|
||||
<a name="Are-there-examples-illustrating-how-to-use-the-FFmpeg-libraries_002c-particularly-libavcodec-and-libavformat_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Are-there-examples-illustrating-how-to-use-the-FFmpeg-libraries_002c-particularly-libavcodec-and-libavformat_003f">4.1 Are there examples illustrating how to use the FFmpeg libraries, particularly libavcodec and libavformat?</a></h2>
|
||||
|
||||
<p>Yes. Check the ‘<tt>doc/examples</tt>’ directory in the source
|
||||
repository, also available online at:
|
||||
<a href="https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples">https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples</a>.
|
||||
</p>
|
||||
<p>Examples are also installed by default, usually in
|
||||
<code>$PREFIX/share/ffmpeg/examples</code>.
|
||||
</p>
|
||||
<p>Also you may read the Developers Guide of the FFmpeg documentation. Alternatively,
|
||||
examine the source code for one of the many open source projects that
|
||||
already incorporate FFmpeg at (<a href="projects.html">projects.html</a>).
|
||||
</p>
|
||||
<a name="Can-you-support-my-C-compiler-XXX_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Can-you-support-my-C-compiler-XXX_003f">4.2 Can you support my C compiler XXX?</a></h2>
|
||||
|
||||
<p>It depends. If your compiler is C99-compliant, then patches to support
|
||||
it are likely to be welcome if they do not pollute the source code
|
||||
with <code>#ifdef</code>s related to the compiler.
|
||||
</p>
|
||||
<a name="Is-Microsoft-Visual-C_002b_002b-supported_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Is-Microsoft-Visual-C_002b_002b-supported_003f">4.3 Is Microsoft Visual C++ supported?</a></h2>
|
||||
|
||||
<p>Yes. Please see the <a href="platform.html">Microsoft Visual C++</a>
|
||||
section in the FFmpeg documentation.
|
||||
</p>
|
||||
<a name="Can-you-add-automake_002c-libtool-or-autoconf-support_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Can-you-add-automake_002c-libtool-or-autoconf-support_003f">4.4 Can you add automake, libtool or autoconf support?</a></h2>
|
||||
|
||||
<p>No. These tools are too bloated and they complicate the build.
|
||||
</p>
|
||||
<a name="Why-not-rewrite-FFmpeg-in-object_002doriented-C_002b_002b_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Why-not-rewrite-FFmpeg-in-object_002doriented-C_002b_002b_003f">4.5 Why not rewrite FFmpeg in object-oriented C++?</a></h2>
|
||||
|
||||
<p>FFmpeg is already organized in a highly modular manner and does not need to
|
||||
be rewritten in a formal object language. Further, many of the developers
|
||||
favor straight C; it works for them. For more arguments on this matter,
|
||||
read <a href="http://www.tux.org/lkml/#s15">"Programming Religion"</a>.
|
||||
</p>
|
||||
<a name="Why-are-the-ffmpeg-programs-devoid-of-debugging-symbols_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Why-are-the-ffmpeg-programs-devoid-of-debugging-symbols_003f">4.6 Why are the ffmpeg programs devoid of debugging symbols?</a></h2>
|
||||
|
||||
<p>The build process creates <code>ffmpeg_g</code>, <code>ffplay_g</code>, etc. which
|
||||
contain full debug information. Those binaries are stripped to create
|
||||
<code>ffmpeg</code>, <code>ffplay</code>, etc. If you need the debug information, use
|
||||
the *_g versions.
|
||||
</p>
|
||||
<a name="I-do-not-like-the-LGPL_002c-can-I-contribute-code-under-the-GPL-instead_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-I-do-not-like-the-LGPL_002c-can-I-contribute-code-under-the-GPL-instead_003f">4.7 I do not like the LGPL, can I contribute code under the GPL instead?</a></h2>
|
||||
|
||||
<p>Yes, as long as the code is optional and can easily and cleanly be placed
|
||||
under #if CONFIG_GPL without breaking anything. So, for example, a new codec
|
||||
or filter would be OK under GPL while a bug fix to LGPL code would not.
|
||||
</p>
|
||||
<a name="I_0027m-using-FFmpeg-from-within-my-C-application-but-the-linker-complains-about-missing-symbols-from-the-libraries-themselves_002e"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-I_0027m-using-FFmpeg-from-within-my-C-application-but-the-linker-complains-about-missing-symbols-from-the-libraries-themselves_002e">4.8 I’m using FFmpeg from within my C application but the linker complains about missing symbols from the libraries themselves.</a></h2>
|
||||
|
||||
<p>FFmpeg builds static libraries by default. In static libraries, dependencies
|
||||
are not handled. That has two consequences. First, you must specify the
|
||||
libraries in dependency order: <code>-lavdevice</code> must come before
|
||||
<code>-lavformat</code>, <code>-lavutil</code> must come after everything else, etc.
|
||||
Second, external libraries that are used in FFmpeg have to be specified too.
|
||||
</p>
|
||||
<p>An easy way to get the full list of required libraries in dependency order
|
||||
is to use <code>pkg-config</code>.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">c99 -o program program.c $(pkg-config --cflags --libs libavformat libavcodec)
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>See ‘<tt>doc/example/Makefile</tt>’ and ‘<tt>doc/example/pc-uninstalled</tt>’ for
|
||||
more details.
|
||||
</p>
|
||||
<a name="I_0027m-using-FFmpeg-from-within-my-C_002b_002b-application-but-the-linker-complains-about-missing-symbols-which-seem-to-be-available_002e"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-I_0027m-using-FFmpeg-from-within-my-C_002b_002b-application-but-the-linker-complains-about-missing-symbols-which-seem-to-be-available_002e">4.9 I’m using FFmpeg from within my C++ application but the linker complains about missing symbols which seem to be available.</a></h2>
|
||||
|
||||
<p>FFmpeg is a pure C project, so to use the libraries within your C++ application
|
||||
you need to explicitly state that you are using a C library. You can do this by
|
||||
encompassing your FFmpeg includes using <code>extern "C"</code>.
|
||||
</p>
|
||||
<p>See <a href="http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.3">http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.3</a>
|
||||
</p>
|
||||
<a name="I_0027m-using-libavutil-from-within-my-C_002b_002b-application-but-the-compiler-complains-about-_0027UINT64_005fC_0027-was-not-declared-in-this-scope"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-I_0027m-using-libavutil-from-within-my-C_002b_002b-application-but-the-compiler-complains-about-_0027UINT64_005fC_0027-was-not-declared-in-this-scope">4.10 I’m using libavutil from within my C++ application but the compiler complains about ’UINT64_C’ was not declared in this scope</a></h2>
|
||||
|
||||
<p>FFmpeg is a pure C project using C99 math features, in order to enable C++
|
||||
to use them you have to append -D__STDC_CONSTANT_MACROS to your CXXFLAGS
|
||||
</p>
|
||||
<a name="I-have-a-file-in-memory-_002f-a-API-different-from-_002aopen_002f_002aread_002f-libc-how-do-I-use-it-with-libavformat_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-I-have-a-file-in-memory-_002f-a-API-different-from-_002aopen_002f_002aread_002f-libc-how-do-I-use-it-with-libavformat_003f">4.11 I have a file in memory / a API different from *open/*read/ libc how do I use it with libavformat?</a></h2>
|
||||
|
||||
<p>You have to create a custom AVIOContext using <code>avio_alloc_context</code>,
|
||||
see ‘<tt>libavformat/aviobuf.c</tt>’ in FFmpeg and ‘<tt>libmpdemux/demux_lavf.c</tt>’ in MPlayer or MPlayer2 sources.
|
||||
</p>
|
||||
<a name="Where-is-the-documentation-about-ffv1_002c-msmpeg4_002c-asv1_002c-4xm_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Where-is-the-documentation-about-ffv1_002c-msmpeg4_002c-asv1_002c-4xm_003f">4.12 Where is the documentation about ffv1, msmpeg4, asv1, 4xm?</a></h2>
|
||||
|
||||
<p>see <a href="http://www.ffmpeg.org/~michael/">http://www.ffmpeg.org/~michael/</a>
|
||||
</p>
|
||||
<a name="How-do-I-feed-H_002e263_002dRTP-_0028and-other-codecs-in-RTP_0029-to-libavcodec_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-How-do-I-feed-H_002e263_002dRTP-_0028and-other-codecs-in-RTP_0029-to-libavcodec_003f">4.13 How do I feed H.263-RTP (and other codecs in RTP) to libavcodec?</a></h2>
|
||||
|
||||
<p>Even if peculiar since it is network oriented, RTP is a container like any
|
||||
other. You have to <em>demux</em> RTP before feeding the payload to libavcodec.
|
||||
In this specific case please look at RFC 4629 to see how it should be done.
|
||||
</p>
|
||||
<a name="AVStream_002er_005fframe_005frate-is-wrong_002c-it-is-much-larger-than-the-frame-rate_002e"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-AVStream_002er_005fframe_005frate-is-wrong_002c-it-is-much-larger-than-the-frame-rate_002e">4.14 AVStream.r_frame_rate is wrong, it is much larger than the frame rate.</a></h2>
|
||||
|
||||
<p><code>r_frame_rate</code> is NOT the average frame rate, it is the smallest frame rate
|
||||
that can accurately represent all timestamps. So no, it is not
|
||||
wrong if it is larger than the average!
|
||||
For example, if you have mixed 25 and 30 fps content, then <code>r_frame_rate</code>
|
||||
will be 150 (it is the least common multiple).
|
||||
If you are looking for the average frame rate, see <code>AVStream.avg_frame_rate</code>.
|
||||
</p>
|
||||
<a name="Why-is-make-fate-not-running-all-tests_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Why-is-make-fate-not-running-all-tests_003f">4.15 Why is <code>make fate</code> not running all tests?</a></h2>
|
||||
|
||||
<p>Make sure you have the fate-suite samples and the <code>SAMPLES</code> Make variable
|
||||
or <code>FATE_SAMPLES</code> environment variable or the <code>--samples</code>
|
||||
<code>configure</code> option is set to the right path.
|
||||
</p>
|
||||
<a name="Why-is-make-fate-not-finding-the-samples_003f"></a>
|
||||
<h2 class="section"><a href="faq.html#toc-Why-is-make-fate-not-finding-the-samples_003f">4.16 Why is <code>make fate</code> not finding the samples?</a></h2>
|
||||
|
||||
<p>Do you happen to have a <code>~</code> character in the samples path to indicate a
|
||||
home directory? The value is used in ways where the shell cannot expand it,
|
||||
causing FATE to not find files. Just replace <code>~</code> by the full path.
|
||||
</p>
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+686
@@ -0,0 +1,686 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle FFmpeg FAQ
|
||||
@titlepage
|
||||
@center @titlefont{FFmpeg FAQ}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter General Questions
|
||||
|
||||
@section Why doesn't FFmpeg support feature [xyz]?
|
||||
|
||||
Because no one has taken on that task yet. FFmpeg development is
|
||||
driven by the tasks that are important to the individual developers.
|
||||
If there is a feature that is important to you, the best way to get
|
||||
it implemented is to undertake the task yourself or sponsor a developer.
|
||||
|
||||
@section FFmpeg does not support codec XXX. Can you include a Windows DLL loader to support it?
|
||||
|
||||
No. Windows DLLs are not portable, bloated and often slow.
|
||||
Moreover FFmpeg strives to support all codecs natively.
|
||||
A DLL loader is not conducive to that goal.
|
||||
|
||||
@section I cannot read this file although this format seems to be supported by ffmpeg.
|
||||
|
||||
Even if ffmpeg can read the container format, it may not support all its
|
||||
codecs. Please consult the supported codec list in the ffmpeg
|
||||
documentation.
|
||||
|
||||
@section Which codecs are supported by Windows?
|
||||
|
||||
Windows does not support standard formats like MPEG very well, unless you
|
||||
install some additional codecs.
|
||||
|
||||
The following list of video codecs should work on most Windows systems:
|
||||
@table @option
|
||||
@item msmpeg4v2
|
||||
.avi/.asf
|
||||
@item msmpeg4
|
||||
.asf only
|
||||
@item wmv1
|
||||
.asf only
|
||||
@item wmv2
|
||||
.asf only
|
||||
@item mpeg4
|
||||
Only if you have some MPEG-4 codec like ffdshow or Xvid installed.
|
||||
@item mpeg1video
|
||||
.mpg only
|
||||
@end table
|
||||
Note, ASF files often have .wmv or .wma extensions in Windows. It should also
|
||||
be mentioned that Microsoft claims a patent on the ASF format, and may sue
|
||||
or threaten users who create ASF files with non-Microsoft software. It is
|
||||
strongly advised to avoid ASF where possible.
|
||||
|
||||
The following list of audio codecs should work on most Windows systems:
|
||||
@table @option
|
||||
@item adpcm_ima_wav
|
||||
@item adpcm_ms
|
||||
@item pcm_s16le
|
||||
always
|
||||
@item libmp3lame
|
||||
If some MP3 codec like LAME is installed.
|
||||
@end table
|
||||
|
||||
|
||||
@chapter Compilation
|
||||
|
||||
@section @code{error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'}
|
||||
|
||||
This is a bug in gcc. Do not report it to us. Instead, please report it to
|
||||
the gcc developers. Note that we will not add workarounds for gcc bugs.
|
||||
|
||||
Also note that (some of) the gcc developers believe this is not a bug or
|
||||
not a bug they should fix:
|
||||
@url{https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11203}.
|
||||
Then again, some of them do not know the difference between an undecidable
|
||||
problem and an NP-hard problem...
|
||||
|
||||
@section I have installed this library with my distro's package manager. Why does @command{configure} not see it?
|
||||
|
||||
Distributions usually split libraries in several packages. The main package
|
||||
contains the files necessary to run programs using the library. The
|
||||
development package contains the files necessary to build programs using the
|
||||
library. Sometimes, docs and/or data are in a separate package too.
|
||||
|
||||
To build FFmpeg, you need to install the development package. It is usually
|
||||
called @file{libfoo-dev} or @file{libfoo-devel}. You can remove it after the
|
||||
build is finished, but be sure to keep the main package.
|
||||
|
||||
@section How do I make @command{pkg-config} find my libraries?
|
||||
|
||||
Somewhere along with your libraries, there is a @file{.pc} file (or several)
|
||||
in a @file{pkgconfig} directory. You need to set environment variables to
|
||||
point @command{pkg-config} to these files.
|
||||
|
||||
If you need to @emph{add} directories to @command{pkg-config}'s search list
|
||||
(typical use case: library installed separately), add it to
|
||||
@code{$PKG_CONFIG_PATH}:
|
||||
|
||||
@example
|
||||
export PKG_CONFIG_PATH=/opt/x264/lib/pkgconfig:/opt/opus/lib/pkgconfig
|
||||
@end example
|
||||
|
||||
If you need to @emph{replace} @command{pkg-config}'s search list
|
||||
(typical use case: cross-compiling), set it in
|
||||
@code{$PKG_CONFIG_LIBDIR}:
|
||||
|
||||
@example
|
||||
export PKG_CONFIG_LIBDIR=/home/me/cross/usr/lib/pkgconfig:/home/me/cross/usr/local/lib/pkgconfig
|
||||
@end example
|
||||
|
||||
If you need to know the library's internal dependencies (typical use: static
|
||||
linking), add the @code{--static} option to @command{pkg-config}:
|
||||
|
||||
@example
|
||||
./configure --pkg-config-flags=--static
|
||||
@end example
|
||||
|
||||
@section How do I use @command{pkg-config} when cross-compiling?
|
||||
|
||||
The best way is to install @command{pkg-config} in your cross-compilation
|
||||
environment. It will automatically use the cross-compilation libraries.
|
||||
|
||||
You can also use @command{pkg-config} from the host environment by
|
||||
specifying explicitly @code{--pkg-config=pkg-config} to @command{configure}.
|
||||
In that case, you must point @command{pkg-config} to the correct directories
|
||||
using the @code{PKG_CONFIG_LIBDIR}, as explained in the previous entry.
|
||||
|
||||
As an intermediate solution, you can place in your cross-compilation
|
||||
environment a script that calls the host @command{pkg-config} with
|
||||
@code{PKG_CONFIG_LIBDIR} set. That script can look like that:
|
||||
|
||||
@example
|
||||
#!/bin/sh
|
||||
PKG_CONFIG_LIBDIR=/path/to/cross/lib/pkgconfig
|
||||
export PKG_CONFIG_LIBDIR
|
||||
exec /usr/bin/pkg-config "$@@"
|
||||
@end example
|
||||
|
||||
@chapter Usage
|
||||
|
||||
@section ffmpeg does not work; what is wrong?
|
||||
|
||||
Try a @code{make distclean} in the ffmpeg source directory before the build.
|
||||
If this does not help see
|
||||
(@url{https://ffmpeg.org/bugreports.html}).
|
||||
|
||||
@section How do I encode single pictures into movies?
|
||||
|
||||
First, rename your pictures to follow a numerical sequence.
|
||||
For example, img1.jpg, img2.jpg, img3.jpg,...
|
||||
Then you may run:
|
||||
|
||||
@example
|
||||
ffmpeg -f image2 -i img%d.jpg /tmp/a.mpg
|
||||
@end example
|
||||
|
||||
Notice that @samp{%d} is replaced by the image number.
|
||||
|
||||
@file{img%03d.jpg} means the sequence @file{img001.jpg}, @file{img002.jpg}, etc.
|
||||
|
||||
Use the @option{-start_number} option to declare a starting number for
|
||||
the sequence. This is useful if your sequence does not start with
|
||||
@file{img001.jpg} but is still in a numerical order. The following
|
||||
example will start with @file{img100.jpg}:
|
||||
|
||||
@example
|
||||
ffmpeg -f image2 -start_number 100 -i img%d.jpg /tmp/a.mpg
|
||||
@end example
|
||||
|
||||
If you have large number of pictures to rename, you can use the
|
||||
following command to ease the burden. The command, using the bourne
|
||||
shell syntax, symbolically links all files in the current directory
|
||||
that match @code{*jpg} to the @file{/tmp} directory in the sequence of
|
||||
@file{img001.jpg}, @file{img002.jpg} and so on.
|
||||
|
||||
@example
|
||||
x=1; for i in *jpg; do counter=$(printf %03d $x); ln -s "$i" /tmp/img"$counter".jpg; x=$(($x+1)); done
|
||||
@end example
|
||||
|
||||
If you want to sequence them by oldest modified first, substitute
|
||||
@code{$(ls -r -t *jpg)} in place of @code{*jpg}.
|
||||
|
||||
Then run:
|
||||
|
||||
@example
|
||||
ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
|
||||
@end example
|
||||
|
||||
The same logic is used for any image format that ffmpeg reads.
|
||||
|
||||
You can also use @command{cat} to pipe images to ffmpeg:
|
||||
|
||||
@example
|
||||
cat *.jpg | ffmpeg -f image2pipe -c:v mjpeg -i - output.mpg
|
||||
@end example
|
||||
|
||||
@section How do I encode movie to single pictures?
|
||||
|
||||
Use:
|
||||
|
||||
@example
|
||||
ffmpeg -i movie.mpg movie%d.jpg
|
||||
@end example
|
||||
|
||||
The @file{movie.mpg} used as input will be converted to
|
||||
@file{movie1.jpg}, @file{movie2.jpg}, etc...
|
||||
|
||||
Instead of relying on file format self-recognition, you may also use
|
||||
@table @option
|
||||
@item -c:v ppm
|
||||
@item -c:v png
|
||||
@item -c:v mjpeg
|
||||
@end table
|
||||
to force the encoding.
|
||||
|
||||
Applying that to the previous example:
|
||||
@example
|
||||
ffmpeg -i movie.mpg -f image2 -c:v mjpeg menu%d.jpg
|
||||
@end example
|
||||
|
||||
Beware that there is no "jpeg" codec. Use "mjpeg" instead.
|
||||
|
||||
@section Why do I see a slight quality degradation with multithreaded MPEG* encoding?
|
||||
|
||||
For multithreaded MPEG* encoding, the encoded slices must be independent,
|
||||
otherwise thread n would practically have to wait for n-1 to finish, so it's
|
||||
quite logical that there is a small reduction of quality. This is not a bug.
|
||||
|
||||
@section How can I read from the standard input or write to the standard output?
|
||||
|
||||
Use @file{-} as file name.
|
||||
|
||||
@section -f jpeg doesn't work.
|
||||
|
||||
Try '-f image2 test%d.jpg'.
|
||||
|
||||
@section Why can I not change the frame rate?
|
||||
|
||||
Some codecs, like MPEG-1/2, only allow a small number of fixed frame rates.
|
||||
Choose a different codec with the -c:v command line option.
|
||||
|
||||
@section How do I encode Xvid or DivX video with ffmpeg?
|
||||
|
||||
Both Xvid and DivX (version 4+) are implementations of the ISO MPEG-4
|
||||
standard (note that there are many other coding formats that use this
|
||||
same standard). Thus, use '-c:v mpeg4' to encode in these formats. The
|
||||
default fourcc stored in an MPEG-4-coded file will be 'FMP4'. If you want
|
||||
a different fourcc, use the '-vtag' option. E.g., '-vtag xvid' will
|
||||
force the fourcc 'xvid' to be stored as the video fourcc rather than the
|
||||
default.
|
||||
|
||||
@section Which are good parameters for encoding high quality MPEG-4?
|
||||
|
||||
'-mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -g 300 -pass 1/2',
|
||||
things to try: '-bf 2', '-mpv_flags qp_rd', '-mpv_flags mv0', '-mpv_flags skip_rd'.
|
||||
|
||||
@section Which are good parameters for encoding high quality MPEG-1/MPEG-2?
|
||||
|
||||
'-mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -pass 1/2'
|
||||
but beware the '-g 100' might cause problems with some decoders.
|
||||
Things to try: '-bf 2', '-mpv_flags qp_rd', '-mpv_flags mv0', '-mpv_flags skip_rd'.
|
||||
|
||||
@section Interlaced video looks very bad when encoded with ffmpeg, what is wrong?
|
||||
|
||||
You should use '-flags +ilme+ildct' and maybe '-flags +alt' for interlaced
|
||||
material, and try '-top 0/1' if the result looks really messed-up.
|
||||
|
||||
@section How can I read DirectShow files?
|
||||
|
||||
If you have built FFmpeg with @code{./configure --enable-avisynth}
|
||||
(only possible on MinGW/Cygwin platforms),
|
||||
then you may use any file that DirectShow can read as input.
|
||||
|
||||
Just create an "input.avs" text file with this single line ...
|
||||
@example
|
||||
DirectShowSource("C:\path to your file\yourfile.asf")
|
||||
@end example
|
||||
... and then feed that text file to ffmpeg:
|
||||
@example
|
||||
ffmpeg -i input.avs
|
||||
@end example
|
||||
|
||||
For ANY other help on AviSynth, please visit the
|
||||
@uref{http://www.avisynth.org/, AviSynth homepage}.
|
||||
|
||||
@section How can I join video files?
|
||||
|
||||
To "join" video files is quite ambiguous. The following list explains the
|
||||
different kinds of "joining" and points out how those are addressed in
|
||||
FFmpeg. To join video files may mean:
|
||||
|
||||
@itemize
|
||||
|
||||
@item
|
||||
To put them one after the other: this is called to @emph{concatenate} them
|
||||
(in short: concat) and is addressed
|
||||
@ref{How can I concatenate video files, in this very faq}.
|
||||
|
||||
@item
|
||||
To put them together in the same file, to let the user choose between the
|
||||
different versions (example: different audio languages): this is called to
|
||||
@emph{multiplex} them together (in short: mux), and is done by simply
|
||||
invoking ffmpeg with several @option{-i} options.
|
||||
|
||||
@item
|
||||
For audio, to put all channels together in a single stream (example: two
|
||||
mono streams into one stereo stream): this is sometimes called to
|
||||
@emph{merge} them, and can be done using the
|
||||
@url{ffmpeg-filters.html#amerge, @code{amerge}} filter.
|
||||
|
||||
@item
|
||||
For audio, to play one on top of the other: this is called to @emph{mix}
|
||||
them, and can be done by first merging them into a single stream and then
|
||||
using the @url{ffmpeg-filters.html#pan, @code{pan}} filter to mix
|
||||
the channels at will.
|
||||
|
||||
@item
|
||||
For video, to display both together, side by side or one on top of a part of
|
||||
the other; it can be done using the
|
||||
@url{ffmpeg-filters.html#overlay, @code{overlay}} video filter.
|
||||
|
||||
@end itemize
|
||||
|
||||
@anchor{How can I concatenate video files}
|
||||
@section How can I concatenate video files?
|
||||
|
||||
There are several solutions, depending on the exact circumstances.
|
||||
|
||||
@subsection Concatenating using the concat @emph{filter}
|
||||
|
||||
FFmpeg has a @url{ffmpeg-filters.html#concat,
|
||||
@code{concat}} filter designed specifically for that, with examples in the
|
||||
documentation. This operation is recommended if you need to re-encode.
|
||||
|
||||
@subsection Concatenating using the concat @emph{demuxer}
|
||||
|
||||
FFmpeg has a @url{ffmpeg-formats.html#concat,
|
||||
@code{concat}} demuxer which you can use when you want to avoid a re-encode and
|
||||
your format doesn't support file level concatenation.
|
||||
|
||||
@subsection Concatenating using the concat @emph{protocol} (file level)
|
||||
|
||||
FFmpeg has a @url{ffmpeg-protocols.html#concat,
|
||||
@code{concat}} protocol designed specifically for that, with examples in the
|
||||
documentation.
|
||||
|
||||
A few multimedia containers (MPEG-1, MPEG-2 PS, DV) allow one to concatenate
|
||||
video by merely concatenating the files containing them.
|
||||
|
||||
Hence you may concatenate your multimedia files by first transcoding them to
|
||||
these privileged formats, then using the humble @code{cat} command (or the
|
||||
equally humble @code{copy} under Windows), and finally transcoding back to your
|
||||
format of choice.
|
||||
|
||||
@example
|
||||
ffmpeg -i input1.avi -qscale:v 1 intermediate1.mpg
|
||||
ffmpeg -i input2.avi -qscale:v 1 intermediate2.mpg
|
||||
cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg
|
||||
ffmpeg -i intermediate_all.mpg -qscale:v 2 output.avi
|
||||
@end example
|
||||
|
||||
Additionally, you can use the @code{concat} protocol instead of @code{cat} or
|
||||
@code{copy} which will avoid creation of a potentially huge intermediate file.
|
||||
|
||||
@example
|
||||
ffmpeg -i input1.avi -qscale:v 1 intermediate1.mpg
|
||||
ffmpeg -i input2.avi -qscale:v 1 intermediate2.mpg
|
||||
ffmpeg -i concat:"intermediate1.mpg|intermediate2.mpg" -c copy intermediate_all.mpg
|
||||
ffmpeg -i intermediate_all.mpg -qscale:v 2 output.avi
|
||||
@end example
|
||||
|
||||
Note that you may need to escape the character "|" which is special for many
|
||||
shells.
|
||||
|
||||
Another option is usage of named pipes, should your platform support it:
|
||||
|
||||
@example
|
||||
mkfifo intermediate1.mpg
|
||||
mkfifo intermediate2.mpg
|
||||
ffmpeg -i input1.avi -qscale:v 1 -y intermediate1.mpg < /dev/null &
|
||||
ffmpeg -i input2.avi -qscale:v 1 -y intermediate2.mpg < /dev/null &
|
||||
cat intermediate1.mpg intermediate2.mpg |\
|
||||
ffmpeg -f mpeg -i - -c:v mpeg4 -c:a libmp3lame output.avi
|
||||
@end example
|
||||
|
||||
@subsection Concatenating using raw audio and video
|
||||
|
||||
Similarly, the yuv4mpegpipe format, and the raw video, raw audio codecs also
|
||||
allow concatenation, and the transcoding step is almost lossless.
|
||||
When using multiple yuv4mpegpipe(s), the first line needs to be discarded
|
||||
from all but the first stream. This can be accomplished by piping through
|
||||
@code{tail} as seen below. Note that when piping through @code{tail} you
|
||||
must use command grouping, @code{@{ ;@}}, to background properly.
|
||||
|
||||
For example, let's say we want to concatenate two FLV files into an
|
||||
output.flv file:
|
||||
|
||||
@example
|
||||
mkfifo temp1.a
|
||||
mkfifo temp1.v
|
||||
mkfifo temp2.a
|
||||
mkfifo temp2.v
|
||||
mkfifo all.a
|
||||
mkfifo all.v
|
||||
ffmpeg -i input1.flv -vn -f u16le -c:a pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
|
||||
ffmpeg -i input2.flv -vn -f u16le -c:a pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
|
||||
ffmpeg -i input1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null &
|
||||
@{ ffmpeg -i input2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; @} &
|
||||
cat temp1.a temp2.a > all.a &
|
||||
cat temp1.v temp2.v > all.v &
|
||||
ffmpeg -f u16le -c:a pcm_s16le -ac 2 -ar 44100 -i all.a \
|
||||
-f yuv4mpegpipe -i all.v \
|
||||
-y output.flv
|
||||
rm temp[12].[av] all.[av]
|
||||
@end example
|
||||
|
||||
@section Using @option{-f lavfi}, audio becomes mono for no apparent reason.
|
||||
|
||||
Use @option{-dumpgraph -} to find out exactly where the channel layout is
|
||||
lost.
|
||||
|
||||
Most likely, it is through @code{auto-inserted aresample}. Try to understand
|
||||
why the converting filter was needed at that place.
|
||||
|
||||
Just before the output is a likely place, as @option{-f lavfi} currently
|
||||
only support packed S16.
|
||||
|
||||
Then insert the correct @code{aformat} explicitly in the filtergraph,
|
||||
specifying the exact format.
|
||||
|
||||
@example
|
||||
aformat=sample_fmts=s16:channel_layouts=stereo
|
||||
@end example
|
||||
|
||||
@section Why does FFmpeg not see the subtitles in my VOB file?
|
||||
|
||||
VOB and a few other formats do not have a global header that describes
|
||||
everything present in the file. Instead, applications are supposed to scan
|
||||
the file to see what it contains. Since VOB files are frequently large, only
|
||||
the beginning is scanned. If the subtitles happen only later in the file,
|
||||
they will not be initially detected.
|
||||
|
||||
Some applications, including the @code{ffmpeg} command-line tool, can only
|
||||
work with streams that were detected during the initial scan; streams that
|
||||
are detected later are ignored.
|
||||
|
||||
The size of the initial scan is controlled by two options: @code{probesize}
|
||||
(default ~5 Mo) and @code{analyzeduration} (default 5,000,000 µs = 5 s). For
|
||||
the subtitle stream to be detected, both values must be large enough.
|
||||
|
||||
@section Why was the @command{ffmpeg} @option{-sameq} option removed? What to use instead?
|
||||
|
||||
The @option{-sameq} option meant "same quantizer", and made sense only in a
|
||||
very limited set of cases. Unfortunately, a lot of people mistook it for
|
||||
"same quality" and used it in places where it did not make sense: it had
|
||||
roughly the expected visible effect, but achieved it in a very inefficient
|
||||
way.
|
||||
|
||||
Each encoder has its own set of options to set the quality-vs-size balance,
|
||||
use the options for the encoder you are using to set the quality level to a
|
||||
point acceptable for your tastes. The most common options to do that are
|
||||
@option{-qscale} and @option{-qmax}, but you should peruse the documentation
|
||||
of the encoder you chose.
|
||||
|
||||
@section I have a stretched video, why does scaling does not fix it?
|
||||
|
||||
A lot of video codecs and formats can store the @emph{aspect ratio} of the
|
||||
video: this is the ratio between the width and the height of either the full
|
||||
image (DAR, display aspect ratio) or individual pixels (SAR, sample aspect
|
||||
ratio). For example, EGA screens at resolution 640×350 had 4:3 DAR and 35:48
|
||||
SAR.
|
||||
|
||||
Most still image processing work with square pixels, i.e. 1:1 SAR, but a lot
|
||||
of video standards, especially from the analogic-numeric transition era, use
|
||||
non-square pixels.
|
||||
|
||||
Most processing filters in FFmpeg handle the aspect ratio to avoid
|
||||
stretching the image: cropping adjusts the DAR to keep the SAR constant,
|
||||
scaling adjusts the SAR to keep the DAR constant.
|
||||
|
||||
If you want to stretch, or “unstretch”, the image, you need to override the
|
||||
information with the
|
||||
@url{ffmpeg-filters.html#setdar_002c-setsar, @code{setdar or setsar filters}}.
|
||||
|
||||
Do not forget to examine carefully the original video to check whether the
|
||||
stretching comes from the image or from the aspect ratio information.
|
||||
|
||||
For example, to fix a badly encoded EGA capture, use the following commands,
|
||||
either the first one to upscale to square pixels or the second one to set
|
||||
the correct aspect ratio or the third one to avoid transcoding (may not work
|
||||
depending on the format / codec / player / phase of the moon):
|
||||
|
||||
@example
|
||||
ffmpeg -i ega_screen.nut -vf scale=640:480,setsar=1 ega_screen_scaled.nut
|
||||
ffmpeg -i ega_screen.nut -vf setdar=4/3 ega_screen_anamorphic.nut
|
||||
ffmpeg -i ega_screen.nut -aspect 4/3 -c copy ega_screen_overridden.nut
|
||||
@end example
|
||||
|
||||
@anchor{background task}
|
||||
@section How do I run ffmpeg as a background task?
|
||||
|
||||
ffmpeg normally checks the console input, for entries like "q" to stop
|
||||
and "?" to give help, while performing operations. ffmpeg does not have a way of
|
||||
detecting when it is running as a background task.
|
||||
When it checks the console input, that can cause the process running ffmpeg
|
||||
in the background to suspend.
|
||||
|
||||
To prevent those input checks, allowing ffmpeg to run as a background task,
|
||||
use the @url{ffmpeg.html#stdin-option, @code{-nostdin} option}
|
||||
in the ffmpeg invocation. This is effective whether you run ffmpeg in a shell
|
||||
or invoke ffmpeg in its own process via an operating system API.
|
||||
|
||||
As an alternative, when you are running ffmpeg in a shell, you can redirect
|
||||
standard input to @code{/dev/null} (on Linux and macOS)
|
||||
or @code{NUL} (on Windows). You can do this redirect either
|
||||
on the ffmpeg invocation, or from a shell script which calls ffmpeg.
|
||||
|
||||
For example:
|
||||
|
||||
@example
|
||||
ffmpeg -nostdin -i INPUT OUTPUT
|
||||
@end example
|
||||
|
||||
or (on Linux, macOS, and other UNIX-like shells):
|
||||
|
||||
@example
|
||||
ffmpeg -i INPUT OUTPUT </dev/null
|
||||
@end example
|
||||
|
||||
or (on Windows):
|
||||
|
||||
@example
|
||||
ffmpeg -i INPUT OUTPUT <NUL
|
||||
@end example
|
||||
|
||||
@section How do I prevent ffmpeg from suspending with a message like @emph{suspended (tty output)}?
|
||||
|
||||
If you run ffmpeg in the background, you may find that its process suspends.
|
||||
There may be a message like @emph{suspended (tty output)}. The question is how
|
||||
to prevent the process from being suspended.
|
||||
|
||||
For example:
|
||||
|
||||
@example
|
||||
% ffmpeg -i INPUT OUTPUT &> ~/tmp/log.txt &
|
||||
[1] 93352
|
||||
%
|
||||
[1] + suspended (tty output) ffmpeg -i INPUT OUTPUT &>
|
||||
@end example
|
||||
|
||||
The message "tty output" notwithstanding, the problem here is that
|
||||
ffmpeg normally checks the console input when it runs. The operating system
|
||||
detects this, and suspends the process until you can bring it to the
|
||||
foreground and attend to it.
|
||||
|
||||
The solution is to use the right techniques to tell ffmpeg not to consult
|
||||
console input. You can use the
|
||||
@url{ffmpeg.html#stdin-option, @code{-nostdin} option},
|
||||
or redirect standard input with @code{< /dev/null}.
|
||||
See FAQ
|
||||
@ref{background task, @emph{How do I run ffmpeg as a background task?}}
|
||||
for details.
|
||||
|
||||
@chapter Development
|
||||
|
||||
@section Are there examples illustrating how to use the FFmpeg libraries, particularly libavcodec and libavformat?
|
||||
|
||||
Yes. Check the @file{doc/examples} directory in the source
|
||||
repository, also available online at:
|
||||
@url{https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples}.
|
||||
|
||||
Examples are also installed by default, usually in
|
||||
@code{$PREFIX/share/ffmpeg/examples}.
|
||||
|
||||
Also you may read the Developers Guide of the FFmpeg documentation. Alternatively,
|
||||
examine the source code for one of the many open source projects that
|
||||
already incorporate FFmpeg at (@url{projects.html}).
|
||||
|
||||
@section Can you support my C compiler XXX?
|
||||
|
||||
It depends. If your compiler is C99-compliant, then patches to support
|
||||
it are likely to be welcome if they do not pollute the source code
|
||||
with @code{#ifdef}s related to the compiler.
|
||||
|
||||
@section Is Microsoft Visual C++ supported?
|
||||
|
||||
Yes. Please see the @uref{platform.html, Microsoft Visual C++}
|
||||
section in the FFmpeg documentation.
|
||||
|
||||
@section Can you add automake, libtool or autoconf support?
|
||||
|
||||
No. These tools are too bloated and they complicate the build.
|
||||
|
||||
@section Why not rewrite FFmpeg in object-oriented C++?
|
||||
|
||||
FFmpeg is already organized in a highly modular manner and does not need to
|
||||
be rewritten in a formal object language. Further, many of the developers
|
||||
favor straight C; it works for them. For more arguments on this matter,
|
||||
read @uref{https://web.archive.org/web/20111004021423/http://kernel.org/pub/linux/docs/lkml/#s15, "Programming Religion"}.
|
||||
|
||||
@section Why are the ffmpeg programs devoid of debugging symbols?
|
||||
|
||||
The build process creates @command{ffmpeg_g}, @command{ffplay_g}, etc. which
|
||||
contain full debug information. Those binaries are stripped to create
|
||||
@command{ffmpeg}, @command{ffplay}, etc. If you need the debug information, use
|
||||
the *_g versions.
|
||||
|
||||
@section I do not like the LGPL, can I contribute code under the GPL instead?
|
||||
|
||||
Yes, as long as the code is optional and can easily and cleanly be placed
|
||||
under #if CONFIG_GPL without breaking anything. So, for example, a new codec
|
||||
or filter would be OK under GPL while a bug fix to LGPL code would not.
|
||||
|
||||
@section I'm using FFmpeg from within my C application but the linker complains about missing symbols from the libraries themselves.
|
||||
|
||||
FFmpeg builds static libraries by default. In static libraries, dependencies
|
||||
are not handled. That has two consequences. First, you must specify the
|
||||
libraries in dependency order: @code{-lavdevice} must come before
|
||||
@code{-lavformat}, @code{-lavutil} must come after everything else, etc.
|
||||
Second, external libraries that are used in FFmpeg have to be specified too.
|
||||
|
||||
An easy way to get the full list of required libraries in dependency order
|
||||
is to use @code{pkg-config}.
|
||||
|
||||
@example
|
||||
c99 -o program program.c $(pkg-config --cflags --libs libavformat libavcodec)
|
||||
@end example
|
||||
|
||||
See @file{doc/example/Makefile} and @file{doc/example/pc-uninstalled} for
|
||||
more details.
|
||||
|
||||
@section I'm using FFmpeg from within my C++ application but the linker complains about missing symbols which seem to be available.
|
||||
|
||||
FFmpeg is a pure C project, so to use the libraries within your C++ application
|
||||
you need to explicitly state that you are using a C library. You can do this by
|
||||
encompassing your FFmpeg includes using @code{extern "C"}.
|
||||
|
||||
See @url{http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.3}
|
||||
|
||||
@section I'm using libavutil from within my C++ application but the compiler complains about 'UINT64_C' was not declared in this scope
|
||||
|
||||
FFmpeg is a pure C project using C99 math features, in order to enable C++
|
||||
to use them you have to append -D__STDC_CONSTANT_MACROS to your CXXFLAGS
|
||||
|
||||
@section I have a file in memory / a API different from *open/*read/ libc how do I use it with libavformat?
|
||||
|
||||
You have to create a custom AVIOContext using @code{avio_alloc_context},
|
||||
see @file{libavformat/aviobuf.c} in FFmpeg and @file{libmpdemux/demux_lavf.c} in MPlayer or MPlayer2 sources.
|
||||
|
||||
@section Where is the documentation about ffv1, msmpeg4, asv1, 4xm?
|
||||
|
||||
see @url{https://www.ffmpeg.org/~michael/}
|
||||
|
||||
@section How do I feed H.263-RTP (and other codecs in RTP) to libavcodec?
|
||||
|
||||
Even if peculiar since it is network oriented, RTP is a container like any
|
||||
other. You have to @emph{demux} RTP before feeding the payload to libavcodec.
|
||||
In this specific case please look at RFC 4629 to see how it should be done.
|
||||
|
||||
@section AVStream.r_frame_rate is wrong, it is much larger than the frame rate.
|
||||
|
||||
@code{r_frame_rate} is NOT the average frame rate, it is the smallest frame rate
|
||||
that can accurately represent all timestamps. So no, it is not
|
||||
wrong if it is larger than the average!
|
||||
For example, if you have mixed 25 and 30 fps content, then @code{r_frame_rate}
|
||||
will be 150 (it is the least common multiple).
|
||||
If you are looking for the average frame rate, see @code{AVStream.avg_frame_rate}.
|
||||
|
||||
@section Why is @code{make fate} not running all tests?
|
||||
|
||||
Make sure you have the fate-suite samples and the @code{SAMPLES} Make variable
|
||||
or @code{FATE_SAMPLES} environment variable or the @code{--samples}
|
||||
@command{configure} option is set to the right path.
|
||||
|
||||
@section Why is @code{make fate} not finding the samples?
|
||||
|
||||
Do you happen to have a @code{~} character in the samples path to indicate a
|
||||
home directory? The value is used in ways where the shell cannot expand it,
|
||||
causing FATE to not find files. Just replace @code{~} by the full path.
|
||||
|
||||
@bye
|
||||
Vendored
-284
@@ -1,284 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : FFmpeg Automated Testing Environment: </title>
|
||||
|
||||
<meta name="description" content="FFmpeg Automated Testing Environment: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : FFmpeg Automated Testing Environment: ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="Top"></a>
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">FFmpeg Automated Testing Environment</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Introduction" href="#Introduction">1. Introduction</a></li>
|
||||
<li><a name="toc-Using-FATE-from-your-FFmpeg-source-directory" href="#Using-FATE-from-your-FFmpeg-source-directory">2. Using FATE from your FFmpeg source directory</a></li>
|
||||
<li><a name="toc-Submitting-the-results-to-the-FFmpeg-result-aggregation-server" href="#Submitting-the-results-to-the-FFmpeg-result-aggregation-server">3. Submitting the results to the FFmpeg result aggregation server</a></li>
|
||||
<li><a name="toc-FATE-makefile-targets-and-variables" href="#FATE-makefile-targets-and-variables">4. FATE makefile targets and variables</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Makefile-targets" href="#Makefile-targets">4.1 Makefile targets</a></li>
|
||||
<li><a name="toc-Makefile-variables" href="#Makefile-variables">4.2 Makefile variables</a></li>
|
||||
<li><a name="toc-Examples" href="#Examples">4.3 Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="Introduction"></a>
|
||||
<h1 class="chapter"><a href="fate.html#toc-Introduction">1. Introduction</a></h1>
|
||||
|
||||
<p> FATE is an extended regression suite on the client-side and a means
|
||||
for results aggregation and presentation on the server-side.
|
||||
</p>
|
||||
<p> The first part of this document explains how you can use FATE from
|
||||
your FFmpeg source directory to test your ffmpeg binary. The second
|
||||
part describes how you can run FATE to submit the results to FFmpeg’s
|
||||
FATE server.
|
||||
</p>
|
||||
<p> In any way you can have a look at the publicly viewable FATE results
|
||||
by visiting this website:
|
||||
</p>
|
||||
<p> <a href="http://fate.ffmpeg.org/">http://fate.ffmpeg.org/</a>
|
||||
</p>
|
||||
<p> This is especially recommended for all people contributing source
|
||||
code to FFmpeg, as it can be seen if some test on some platform broke
|
||||
with their recent contribution. This usually happens on the platforms
|
||||
the developers could not test on.
|
||||
</p>
|
||||
<p> The second part of this document describes how you can run FATE to
|
||||
submit your results to FFmpeg’s FATE server. If you want to submit your
|
||||
results be sure to check that your combination of CPU, OS and compiler
|
||||
is not already listed on the above mentioned website.
|
||||
</p>
|
||||
<p> In the third part you can find a comprehensive listing of FATE makefile
|
||||
targets and variables.
|
||||
</p>
|
||||
|
||||
<a name="Using-FATE-from-your-FFmpeg-source-directory"></a>
|
||||
<h1 class="chapter"><a href="fate.html#toc-Using-FATE-from-your-FFmpeg-source-directory">2. Using FATE from your FFmpeg source directory</a></h1>
|
||||
|
||||
<p> If you want to run FATE on your machine you need to have the samples
|
||||
in place. You can get the samples via the build target fate-rsync.
|
||||
Use this command from the top-level source directory:
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">make fate-rsync SAMPLES=fate-suite/
|
||||
make fate SAMPLES=fate-suite/
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p> The above commands set the samples location by passing a makefile
|
||||
variable via command line. It is also possible to set the samples
|
||||
location at source configuration time by invoking configure with
|
||||
‘–samples=<path to the samples directory>’. Afterwards you can
|
||||
invoke the makefile targets without setting the SAMPLES makefile
|
||||
variable. This is illustrated by the following commands:
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">./configure --samples=fate-suite/
|
||||
make fate-rsync
|
||||
make fate
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p> Yet another way to tell FATE about the location of the sample
|
||||
directory is by making sure the environment variable FATE_SAMPLES
|
||||
contains the path to your samples directory. This can be achieved
|
||||
by e.g. putting that variable in your shell profile or by setting
|
||||
it in your interactive session.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">FATE_SAMPLES=fate-suite/ make fate
|
||||
</pre></td></tr></table>
|
||||
|
||||
<div class="float alert alert-info">
|
||||
<p>Do not put a ’~’ character in the samples path to indicate a home
|
||||
directory. Because of shell nuances, this will cause FATE to fail.
|
||||
</p></div>
|
||||
<p>To use a custom wrapper to run the test, pass ‘<samp>--target-exec</samp>’ to
|
||||
<code>configure</code> or set the <var>TARGET_EXEC</var> Make variable.
|
||||
</p>
|
||||
|
||||
<a name="Submitting-the-results-to-the-FFmpeg-result-aggregation-server"></a>
|
||||
<h1 class="chapter"><a href="fate.html#toc-Submitting-the-results-to-the-FFmpeg-result-aggregation-server">3. Submitting the results to the FFmpeg result aggregation server</a></h1>
|
||||
|
||||
<p> To submit your results to the server you should run fate through the
|
||||
shell script ‘<tt>tests/fate.sh</tt>’ from the FFmpeg sources. This script needs
|
||||
to be invoked with a configuration file as its first argument.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">tests/fate.sh /path/to/fate_config
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p> A configuration file template with comments describing the individual
|
||||
configuration variables can be found at ‘<tt>doc/fate_config.sh.template</tt>’.
|
||||
</p>
|
||||
<p> The mentioned configuration template is also available here:
|
||||
<pre class="verbatim">slot= # some unique identifier
|
||||
repo=git://source.ffmpeg.org/ffmpeg.git # the source repository
|
||||
samples= # path to samples directory
|
||||
workdir= # directory in which to do all the work
|
||||
#fate_recv="ssh -T [email protected]" # command to submit report
|
||||
comment= # optional description
|
||||
build_only= # set to "yes" for a compile-only instance that skips tests
|
||||
|
||||
# the following are optional and map to configure options
|
||||
arch=
|
||||
cpu=
|
||||
cross_prefix=
|
||||
as=
|
||||
cc=
|
||||
ld=
|
||||
target_os=
|
||||
sysroot=
|
||||
target_exec=
|
||||
target_path=
|
||||
target_samples=
|
||||
extra_cflags=
|
||||
extra_ldflags=
|
||||
extra_libs=
|
||||
extra_conf= # extra configure options not covered above
|
||||
|
||||
#make= # name of GNU make if not 'make'
|
||||
makeopts= # extra options passed to 'make'
|
||||
#tar= # command to create a tar archive from its arguments on stdout,
|
||||
# defaults to 'tar c'
|
||||
</pre></p>
|
||||
<p> Create a configuration that suits your needs, based on the configuration
|
||||
template. The ‘slot’ configuration variable can be any string that is not
|
||||
yet used, but it is suggested that you name it adhering to the following
|
||||
pattern <arch>-<os>-<compiler>-<compiler version>. The configuration file
|
||||
itself will be sourced in a shell script, therefore all shell features may
|
||||
be used. This enables you to setup the environment as you need it for your
|
||||
build.
|
||||
</p>
|
||||
<p> For your first test runs the ‘fate_recv’ variable should be empty or
|
||||
commented out. This will run everything as normal except that it will omit
|
||||
the submission of the results to the server. The following files should be
|
||||
present in $workdir as specified in the configuration file:
|
||||
</p>
|
||||
<ul>
|
||||
<li> configure.log
|
||||
</li><li> compile.log
|
||||
</li><li> test.log
|
||||
</li><li> report
|
||||
</li><li> version
|
||||
</li></ul>
|
||||
|
||||
<p> When you have everything working properly you can create an SSH key pair
|
||||
and send the public key to the FATE server administrator who can be contacted
|
||||
at the email address <a href="mailto:[email protected]">[email protected]</a>.
|
||||
</p>
|
||||
<p> Configure your SSH client to use public key authentication with that key
|
||||
when connecting to the FATE server. Also do not forget to check the identity
|
||||
of the server and to accept its host key. This can usually be achieved by
|
||||
running your SSH client manually and killing it after you accepted the key.
|
||||
The FATE server’s fingerprint is:
|
||||
</p>
|
||||
<dl compact="compact">
|
||||
<dt> ‘<samp>RSA</samp>’</dt>
|
||||
<dd><p> d3:f1:83:97:a4:75:2b:a6:fb:d6:e8:aa:81:93:97:51
|
||||
</p></dd>
|
||||
<dt> ‘<samp>ECDSA</samp>’</dt>
|
||||
<dd><p> 76:9f:68:32:04:1e:d5:d4:ec:47:3f:dc:fc:18:17:86
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
<p> If you have problems connecting to the FATE server, it may help to try out
|
||||
the <code>ssh</code> command with one or more ‘<samp>-v</samp>’ options. You should
|
||||
get detailed output concerning your SSH configuration and the authentication
|
||||
process.
|
||||
</p>
|
||||
<p> The only thing left is to automate the execution of the fate.sh script and
|
||||
the synchronisation of the samples directory.
|
||||
</p>
|
||||
|
||||
<a name="FATE-makefile-targets-and-variables"></a>
|
||||
<h1 class="chapter"><a href="fate.html#toc-FATE-makefile-targets-and-variables">4. FATE makefile targets and variables</a></h1>
|
||||
|
||||
<a name="Makefile-targets"></a>
|
||||
<h2 class="section"><a href="fate.html#toc-Makefile-targets">4.1 Makefile targets</a></h2>
|
||||
|
||||
<dl compact="compact">
|
||||
<dt> ‘<samp>fate-rsync</samp>’</dt>
|
||||
<dd><p>Download/synchronize sample files to the configured samples directory.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>fate-list</samp>’</dt>
|
||||
<dd><p>Will list all fate/regression test targets.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>fate</samp>’</dt>
|
||||
<dd><p>Run the FATE test suite (requires the fate-suite dataset).
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
<a name="Makefile-variables"></a>
|
||||
<h2 class="section"><a href="fate.html#toc-Makefile-variables">4.2 Makefile variables</a></h2>
|
||||
|
||||
<dl compact="compact">
|
||||
<dt> ‘<samp>V</samp>’</dt>
|
||||
<dd><p>Verbosity level, can be set to 0, 1 or 2.
|
||||
</p><ul>
|
||||
<li> 0: show just the test arguments
|
||||
</li><li> 1: show just the command used in the test
|
||||
</li><li> 2: show everything
|
||||
</li></ul>
|
||||
|
||||
</dd>
|
||||
<dt> ‘<samp>SAMPLES</samp>’</dt>
|
||||
<dd><p>Specify or override the path to the FATE samples at make time, it has a
|
||||
meaning only while running the regression tests.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>THREADS</samp>’</dt>
|
||||
<dd><p>Specify how many threads to use while running regression tests, it is
|
||||
quite useful to detect thread-related regressions.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>THREAD_TYPE</samp>’</dt>
|
||||
<dd><p>Specify which threading strategy test, either <var>slice</var> or <var>frame</var>,
|
||||
by default <var>slice+frame</var>
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>CPUFLAGS</samp>’</dt>
|
||||
<dd><p>Specify CPU flags.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>TARGET_EXEC</samp>’</dt>
|
||||
<dd><p>Specify or override the wrapper used to run the tests.
|
||||
The <var>TARGET_EXEC</var> option provides a way to run FATE wrapped in
|
||||
<code>valgrind</code>, <code>qemu-user</code> or <code>wine</code> or on remote targets
|
||||
through <code>ssh</code>.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>GEN</samp>’</dt>
|
||||
<dd><p>Set to <var>1</var> to generate the missing or mismatched references.
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
<a name="Examples"></a>
|
||||
<h2 class="section"><a href="fate.html#toc-Examples">4.3 Examples</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">make V=1 SAMPLES=/var/fate/samples THREADS=2 CPUFLAGS=mmx fate
|
||||
</pre></td></tr></table>
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+242
@@ -0,0 +1,242 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle FFmpeg Automated Testing Environment
|
||||
@titlepage
|
||||
@center @titlefont{FFmpeg Automated Testing Environment}
|
||||
@end titlepage
|
||||
|
||||
@node Top
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Introduction
|
||||
|
||||
FATE is an extended regression suite on the client-side and a means
|
||||
for results aggregation and presentation on the server-side.
|
||||
|
||||
The first part of this document explains how you can use FATE from
|
||||
your FFmpeg source directory to test your ffmpeg binary. The second
|
||||
part describes how you can run FATE to submit the results to FFmpeg's
|
||||
FATE server.
|
||||
|
||||
In any way you can have a look at the publicly viewable FATE results
|
||||
by visiting this website:
|
||||
|
||||
@url{http://fate.ffmpeg.org/}
|
||||
|
||||
This is especially recommended for all people contributing source
|
||||
code to FFmpeg, as it can be seen if some test on some platform broke
|
||||
with their recent contribution. This usually happens on the platforms
|
||||
the developers could not test on.
|
||||
|
||||
The second part of this document describes how you can run FATE to
|
||||
submit your results to FFmpeg's FATE server. If you want to submit your
|
||||
results be sure to check that your combination of CPU, OS and compiler
|
||||
is not already listed on the above mentioned website.
|
||||
|
||||
In the third part you can find a comprehensive listing of FATE makefile
|
||||
targets and variables.
|
||||
|
||||
|
||||
@chapter Using FATE from your FFmpeg source directory
|
||||
|
||||
If you want to run FATE on your machine you need to have the samples
|
||||
in place. You can get the samples via the build target fate-rsync.
|
||||
Use this command from the top-level source directory:
|
||||
|
||||
@example
|
||||
make fate-rsync SAMPLES=fate-suite/
|
||||
make fate SAMPLES=fate-suite/
|
||||
@end example
|
||||
|
||||
The above commands set the samples location by passing a makefile
|
||||
variable via command line. It is also possible to set the samples
|
||||
location at source configuration time by invoking configure with
|
||||
@option{--samples=<path to the samples directory>}. Afterwards you can
|
||||
invoke the makefile targets without setting the @var{SAMPLES} makefile
|
||||
variable. This is illustrated by the following commands:
|
||||
|
||||
@example
|
||||
./configure --samples=fate-suite/
|
||||
make fate-rsync
|
||||
make fate
|
||||
@end example
|
||||
|
||||
Yet another way to tell FATE about the location of the sample
|
||||
directory is by making sure the environment variable FATE_SAMPLES
|
||||
contains the path to your samples directory. This can be achieved
|
||||
by e.g. putting that variable in your shell profile or by setting
|
||||
it in your interactive session.
|
||||
|
||||
@example
|
||||
FATE_SAMPLES=fate-suite/ make fate
|
||||
@end example
|
||||
|
||||
@float NOTE
|
||||
Do not put a '~' character in the samples path to indicate a home
|
||||
directory. Because of shell nuances, this will cause FATE to fail.
|
||||
@end float
|
||||
|
||||
To use a custom wrapper to run the test, pass @option{--target-exec} to
|
||||
@command{configure} or set the @var{TARGET_EXEC} Make variable.
|
||||
|
||||
|
||||
@chapter Submitting the results to the FFmpeg result aggregation server
|
||||
|
||||
To submit your results to the server you should run fate through the
|
||||
shell script @file{tests/fate.sh} from the FFmpeg sources. This script needs
|
||||
to be invoked with a configuration file as its first argument.
|
||||
|
||||
@example
|
||||
tests/fate.sh /path/to/fate_config
|
||||
@end example
|
||||
|
||||
A configuration file template with comments describing the individual
|
||||
configuration variables can be found at @file{doc/fate_config.sh.template}.
|
||||
|
||||
@ifhtml
|
||||
The mentioned configuration template is also available here:
|
||||
@verbatiminclude fate_config.sh.template
|
||||
@end ifhtml
|
||||
|
||||
Create a configuration that suits your needs, based on the configuration
|
||||
template. The @env{slot} configuration variable can be any string that is not
|
||||
yet used, but it is suggested that you name it adhering to the following
|
||||
pattern @samp{@var{arch}-@var{os}-@var{compiler}-@var{compiler version}}. The
|
||||
configuration file itself will be sourced in a shell script, therefore all
|
||||
shell features may be used. This enables you to setup the environment as you
|
||||
need it for your build.
|
||||
|
||||
For your first test runs the @env{fate_recv} variable should be empty or
|
||||
commented out. This will run everything as normal except that it will omit
|
||||
the submission of the results to the server. The following files should be
|
||||
present in $workdir as specified in the configuration file:
|
||||
|
||||
@itemize
|
||||
@item configure.log
|
||||
@item compile.log
|
||||
@item test.log
|
||||
@item report
|
||||
@item version
|
||||
@end itemize
|
||||
|
||||
When you have everything working properly you can create an SSH key pair
|
||||
and send the public key to the FATE server administrator who can be contacted
|
||||
at the email address @email{fate-admin@@ffmpeg.org}.
|
||||
|
||||
Configure your SSH client to use public key authentication with that key
|
||||
when connecting to the FATE server. Also do not forget to check the identity
|
||||
of the server and to accept its host key. This can usually be achieved by
|
||||
running your SSH client manually and killing it after you accepted the key.
|
||||
The FATE server's fingerprint is:
|
||||
|
||||
@table @samp
|
||||
@item RSA
|
||||
d3:f1:83:97:a4:75:2b:a6:fb:d6:e8:aa:81:93:97:51
|
||||
@item ECDSA
|
||||
76:9f:68:32:04:1e:d5:d4:ec:47:3f:dc:fc:18:17:86
|
||||
@end table
|
||||
|
||||
If you have problems connecting to the FATE server, it may help to try out
|
||||
the @command{ssh} command with one or more @option{-v} options. You should
|
||||
get detailed output concerning your SSH configuration and the authentication
|
||||
process.
|
||||
|
||||
The only thing left is to automate the execution of the fate.sh script and
|
||||
the synchronisation of the samples directory.
|
||||
|
||||
@chapter Uploading new samples to the fate suite
|
||||
|
||||
If you need a sample uploaded send a mail to samples-request.
|
||||
|
||||
This is for developers who have an account on the fate suite server.
|
||||
If you upload new samples, please make sure they are as small as possible,
|
||||
space on each client, network bandwidth and so on benefit from smaller test cases.
|
||||
Also keep in mind older checkouts use existing sample files, that means in
|
||||
practice generally do not replace, remove or overwrite files as it likely would
|
||||
break older checkouts or releases.
|
||||
Also all needed samples for a commit should be uploaded, ideally 24
|
||||
hours, before the push.
|
||||
If you need an account for frequently uploading samples or you wish to help
|
||||
others by doing that send a mail to ffmpeg-devel.
|
||||
|
||||
@example
|
||||
#First update your local samples copy:
|
||||
rsync -vauL --chmod=Dg+s,Duo+x,ug+rw,o+r,o-w,+X fate-suite.ffmpeg.org:/home/samples/fate-suite/ ~/fate-suite
|
||||
|
||||
#Then do a dry run checking what would be uploaded:
|
||||
rsync -vanL --no-g --chmod=Dg+s,Duo+x,ug+rw,o+r,o-w,+X ~/fate-suite/ fate-suite.ffmpeg.org:/home/samples/fate-suite
|
||||
|
||||
#Upload the files:
|
||||
rsync -vaL --no-g --chmod=Dg+s,Duo+x,ug+rw,o+r,o-w,+X ~/fate-suite/ fate-suite.ffmpeg.org:/home/samples/fate-suite
|
||||
@end example
|
||||
|
||||
|
||||
@chapter FATE makefile targets and variables
|
||||
|
||||
@section Makefile targets
|
||||
|
||||
@table @option
|
||||
@item fate-rsync
|
||||
Download/synchronize sample files to the configured samples directory.
|
||||
|
||||
@item fate-list
|
||||
Will list all fate/regression test targets.
|
||||
|
||||
@item fate
|
||||
Run the FATE test suite (requires the fate-suite dataset).
|
||||
@end table
|
||||
|
||||
@section Makefile variables
|
||||
|
||||
@table @env
|
||||
@item V
|
||||
Verbosity level, can be set to 0, 1 or 2.
|
||||
@itemize
|
||||
@item 0: show just the test arguments
|
||||
@item 1: show just the command used in the test
|
||||
@item 2: show everything
|
||||
@end itemize
|
||||
|
||||
@item SAMPLES
|
||||
Specify or override the path to the FATE samples at make time, it has a
|
||||
meaning only while running the regression tests.
|
||||
|
||||
@item THREADS
|
||||
Specify how many threads to use while running regression tests, it is
|
||||
quite useful to detect thread-related regressions.
|
||||
|
||||
@item THREAD_TYPE
|
||||
Specify which threading strategy test, either @samp{slice} or @samp{frame},
|
||||
by default @samp{slice+frame}
|
||||
|
||||
@item CPUFLAGS
|
||||
Specify CPU flags.
|
||||
|
||||
@item TARGET_EXEC
|
||||
Specify or override the wrapper used to run the tests.
|
||||
The @env{TARGET_EXEC} option provides a way to run FATE wrapped in
|
||||
@command{valgrind}, @command{qemu-user} or @command{wine} or on remote targets
|
||||
through @command{ssh}.
|
||||
|
||||
@item GEN
|
||||
Set to @samp{1} to generate the missing or mismatched references.
|
||||
|
||||
@item HWACCEL
|
||||
Specify which hardware acceleration to use while running regression tests,
|
||||
by default @samp{none} is used.
|
||||
|
||||
@item KEEP
|
||||
Set to @samp{1} to keep temp files generated by fate test(s) when test is successful.
|
||||
Default is @samp{0}, which removes these files. Files are always kept when a test
|
||||
fails.
|
||||
|
||||
@end table
|
||||
|
||||
@section Examples
|
||||
|
||||
@example
|
||||
make V=1 SAMPLES=/var/fate/samples THREADS=2 CPUFLAGS=mmx fate
|
||||
@end example
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
slot= # some unique identifier
|
||||
repo=git://source.ffmpeg.org/ffmpeg.git # the source repository
|
||||
#branch=release/2.6 # the branch to test
|
||||
samples= # path to samples directory
|
||||
workdir= # directory in which to do all the work
|
||||
#fate_recv="ssh -T [email protected]" # command to submit report
|
||||
comment= # optional description
|
||||
build_only= # set to "yes" for a compile-only instance that skips tests
|
||||
ignore_tests=
|
||||
|
||||
# the following are optional and map to configure options
|
||||
arch=
|
||||
cpu=
|
||||
cross_prefix=
|
||||
as=
|
||||
cc=
|
||||
ld=
|
||||
target_os=
|
||||
sysroot=
|
||||
target_exec=
|
||||
target_path=
|
||||
target_samples=
|
||||
extra_cflags=
|
||||
extra_ldflags=
|
||||
extra_libs=
|
||||
extra_conf= # extra configure options not covered above
|
||||
|
||||
#make= # name of GNU make if not 'make'
|
||||
makeopts= # extra options passed to 'make'
|
||||
#makeopts_fate= # extra options passed to 'make' when running tests,
|
||||
# defaulting to makeopts above if this is not set
|
||||
#tar= # command to create a tar archive from its arguments on stdout,
|
||||
# defaults to 'tar c'
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle FFmpeg Bitstream Filters Documentation
|
||||
@titlepage
|
||||
@center @titlefont{FFmpeg Bitstream Filters Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
This document describes the bitstream filters provided by the
|
||||
libavcodec library.
|
||||
|
||||
A bitstream filter operates on the encoded stream data, and performs
|
||||
bitstream level modifications without performing decoding.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@include bitstream_filters.texi
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{libavcodec.html,libavcodec}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavcodec(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffmpeg-bitstream-filters
|
||||
@settitle FFmpeg bitstream filters
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle FFmpeg Codecs Documentation
|
||||
@titlepage
|
||||
@center @titlefont{FFmpeg Codecs Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
This document describes the codecs (decoders and encoders) provided by
|
||||
the libavcodec library.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@include codecs.texi
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{libavcodec.html,libavcodec}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavcodec(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffmpeg-codecs
|
||||
@settitle FFmpeg codecs
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle FFmpeg Devices Documentation
|
||||
@titlepage
|
||||
@center @titlefont{FFmpeg Devices Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
This document describes the input and output devices provided by the
|
||||
libavdevice library.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@include devices.texi
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{libavdevice.html,libavdevice}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavdevice(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffmpeg-devices
|
||||
@settitle FFmpeg devices
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle FFmpeg Filters Documentation
|
||||
@titlepage
|
||||
@center @titlefont{FFmpeg Filters Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
This document describes filters, sources, and sinks provided by the
|
||||
libavfilter library.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@include filters.texi
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{libavfilter.html,libavfilter}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavfilter(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffmpeg-filters
|
||||
@settitle FFmpeg filters
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle FFmpeg Formats Documentation
|
||||
@titlepage
|
||||
@center @titlefont{FFmpeg Formats Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
This document describes the supported formats (muxers and demuxers)
|
||||
provided by the libavformat library.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@include formats.texi
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{libavformat.html,libavformat}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavformat(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffmpeg-formats
|
||||
@settitle FFmpeg formats
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle FFmpeg Protocols Documentation
|
||||
@titlepage
|
||||
@center @titlefont{FFmpeg Protocols Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
This document describes the input and output protocols provided by the
|
||||
libavformat library.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@include protocols.texi
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{libavformat.html,libavformat}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavformat(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffmpeg-protocols
|
||||
@settitle FFmpeg protocols
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle FFmpeg Resampler Documentation
|
||||
@titlepage
|
||||
@center @titlefont{FFmpeg Resampler Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
The FFmpeg resampler provides a high-level interface to the
|
||||
libswresample library audio resampling utilities. In particular it
|
||||
allows one to perform audio resampling, audio channel layout rematrixing,
|
||||
and convert audio format and packing layout.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@include resampler.texi
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{libswresample.html,libswresample}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libswresample(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffmpeg-resampler
|
||||
@settitle FFmpeg Resampler
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
Vendored
+44
@@ -0,0 +1,44 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle FFmpeg Scaler Documentation
|
||||
@titlepage
|
||||
@center @titlefont{FFmpeg Scaler Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
The FFmpeg rescaler provides a high-level interface to the libswscale
|
||||
library image conversion utilities. In particular it allows one to perform
|
||||
image rescaling and pixel format conversion.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@include scaler.texi
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{libswscale.html,libswscale}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libswscale(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffmpeg-scaler
|
||||
@settitle FFmpeg video scaling and pixel format converter
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle FFmpeg Utilities Documentation
|
||||
@titlepage
|
||||
@center @titlefont{FFmpeg Utilities Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
This document describes some generic features and utilities provided
|
||||
by the libavutil library.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@include utils.texi
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{libavutil.html,libavutil}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavutil(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffmpeg-utils
|
||||
@settitle FFmpeg utilities
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
Vendored
-1877
File diff suppressed because it is too large
Load Diff
Vendored
+2296
File diff suppressed because it is too large
Load Diff
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
:
|
||||
ffmpeg.c : libav*
|
||||
======== : ======
|
||||
:
|
||||
:
|
||||
--------------------------------:---> AVStream...
|
||||
InputStream input_streams[] / :
|
||||
/ :
|
||||
InputFile input_files[] +==========================+ / ^ :
|
||||
------> 0 | : st ---:-----------:--/ : :
|
||||
^ +------+-----------+-----+ / +--------------------------+ : :
|
||||
: | :ist_index--:-----:---------/ 1 | : st : | : :
|
||||
: +------+-----------+-----+ +==========================+ : :
|
||||
nb_input_files : | :ist_index--:-----:------------------> 2 | : st : | : :
|
||||
: +------+-----------+-----+ +--------------------------+ : nb_input_streams :
|
||||
: | :ist_index : | 3 | ... | : :
|
||||
v +------+-----------+-----+ +--------------------------+ : :
|
||||
--> 4 | | : :
|
||||
| +--------------------------+ : :
|
||||
| 5 | | : :
|
||||
| +==========================+ v :
|
||||
| :
|
||||
| :
|
||||
| :
|
||||
| :
|
||||
--------- --------------------------------:---> AVStream...
|
||||
\ / :
|
||||
OutputStream output_streams[] / :
|
||||
\ / :
|
||||
+======\======================/======+ ^ :
|
||||
------> 0 | : source_index : st-:--- | : :
|
||||
OutputFile output_files[] / +------------------------------------+ : :
|
||||
/ 1 | : : : | : :
|
||||
^ +------+------------+-----+ / +------------------------------------+ : :
|
||||
: | : ost_index -:-----:------/ 2 | : : : | : :
|
||||
nb_output_files : +------+------------+-----+ +====================================+ : :
|
||||
: | : ost_index -:-----|-----------------> 3 | : : : | : :
|
||||
: +------+------------+-----+ +------------------------------------+ : nb_output_streams :
|
||||
: | : : | 4 | | : :
|
||||
: +------+------------+-----+ +------------------------------------+ : :
|
||||
: | : : | 5 | | : :
|
||||
v +------+------------+-----+ +------------------------------------+ : :
|
||||
6 | | : :
|
||||
+------------------------------------+ : :
|
||||
7 | | : :
|
||||
+====================================+ v :
|
||||
:
|
||||
Vendored
-21641
File diff suppressed because it is too large
Load Diff
Vendored
-666
@@ -1,666 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : ffplay </title>
|
||||
|
||||
<meta name="description" content="ffplay Documentation: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : ffplay ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">ffplay Documentation</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Synopsis" href="#Synopsis">1. Synopsis</a></li>
|
||||
<li><a name="toc-Description" href="#Description">2. Description</a></li>
|
||||
<li><a name="toc-Options" href="#Options">3. Options</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Stream-specifiers-1" href="#Stream-specifiers-1">3.1 Stream specifiers</a></li>
|
||||
<li><a name="toc-Generic-options" href="#Generic-options">3.2 Generic options</a></li>
|
||||
<li><a name="toc-AVOptions" href="#AVOptions">3.3 AVOptions</a></li>
|
||||
<li><a name="toc-Main-options" href="#Main-options">3.4 Main options</a></li>
|
||||
<li><a name="toc-Advanced-options" href="#Advanced-options">3.5 Advanced options</a></li>
|
||||
<li><a name="toc-While-playing" href="#While-playing">3.6 While playing</a></li>
|
||||
</ul></li>
|
||||
<li><a name="toc-See-Also" href="#See-Also">4. See Also</a></li>
|
||||
<li><a name="toc-Authors" href="#Authors">5. Authors</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="Synopsis"></a>
|
||||
<h1 class="chapter"><a href="ffplay.html#toc-Synopsis">1. Synopsis</a></h1>
|
||||
|
||||
<p>ffplay [<var>options</var>] [‘<tt>input_file</tt>’]
|
||||
</p>
|
||||
<a name="Description"></a>
|
||||
<h1 class="chapter"><a href="ffplay.html#toc-Description">2. Description</a></h1>
|
||||
|
||||
<p>FFplay is a very simple and portable media player using the FFmpeg
|
||||
libraries and the SDL library. It is mostly used as a testbed for the
|
||||
various FFmpeg APIs.
|
||||
</p>
|
||||
<a name="Options"></a>
|
||||
<h1 class="chapter"><a href="ffplay.html#toc-Options">3. Options</a></h1>
|
||||
|
||||
<p>All the numerical options, if not specified otherwise, accept a string
|
||||
representing a number as input, which may be followed by one of the SI
|
||||
unit prefixes, for example: ’K’, ’M’, or ’G’.
|
||||
</p>
|
||||
<p>If ’i’ is appended to the SI unit prefix, the complete prefix will be
|
||||
interpreted as a unit prefix for binary multiplies, which are based on
|
||||
powers of 1024 instead of powers of 1000. Appending ’B’ to the SI unit
|
||||
prefix multiplies the value by 8. This allows using, for example:
|
||||
’KB’, ’MiB’, ’G’ and ’B’ as number suffixes.
|
||||
</p>
|
||||
<p>Options which do not take arguments are boolean options, and set the
|
||||
corresponding value to true. They can be set to false by prefixing
|
||||
the option name with "no". For example using "-nofoo"
|
||||
will set the boolean option with name "foo" to false.
|
||||
</p>
|
||||
<p><a name="Stream-specifiers"></a>
|
||||
</p><a name="Stream-specifiers-1"></a>
|
||||
<h2 class="section"><a href="ffplay.html#toc-Stream-specifiers-1">3.1 Stream specifiers</a></h2>
|
||||
<p>Some options are applied per-stream, e.g. bitrate or codec. Stream specifiers
|
||||
are used to precisely specify which stream(s) a given option belongs to.
|
||||
</p>
|
||||
<p>A stream specifier is a string generally appended to the option name and
|
||||
separated from it by a colon. E.g. <code>-codec:a:1 ac3</code> contains the
|
||||
<code>a:1</code> stream specifier, which matches the second audio stream. Therefore, it
|
||||
would select the ac3 codec for the second audio stream.
|
||||
</p>
|
||||
<p>A stream specifier can match several streams, so that the option is applied to all
|
||||
of them. E.g. the stream specifier in <code>-b:a 128k</code> matches all audio
|
||||
streams.
|
||||
</p>
|
||||
<p>An empty stream specifier matches all streams. For example, <code>-codec copy</code>
|
||||
or <code>-codec: copy</code> would copy all the streams without reencoding.
|
||||
</p>
|
||||
<p>Possible forms of stream specifiers are:
|
||||
</p><dl compact="compact">
|
||||
<dt> ‘<samp><var>stream_index</var></samp>’</dt>
|
||||
<dd><p>Matches the stream with this index. E.g. <code>-threads:1 4</code> would set the
|
||||
thread count for the second stream to 4.
|
||||
</p></dd>
|
||||
<dt> ‘<samp><var>stream_type</var>[:<var>stream_index</var>]</samp>’</dt>
|
||||
<dd><p><var>stream_type</var> is one of following: ’v’ for video, ’a’ for audio, ’s’ for subtitle,
|
||||
’d’ for data, and ’t’ for attachments. If <var>stream_index</var> is given, then it matches
|
||||
stream number <var>stream_index</var> of this type. Otherwise, it matches all
|
||||
streams of this type.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>p:<var>program_id</var>[:<var>stream_index</var>]</samp>’</dt>
|
||||
<dd><p>If <var>stream_index</var> is given, then it matches the stream with number <var>stream_index</var>
|
||||
in the program with the id <var>program_id</var>. Otherwise, it matches all streams in the
|
||||
program.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>#<var>stream_id</var></samp>’</dt>
|
||||
<dd><p>Matches the stream by a format-specific ID.
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
<a name="Generic-options"></a>
|
||||
<h2 class="section"><a href="ffplay.html#toc-Generic-options">3.2 Generic options</a></h2>
|
||||
|
||||
<p>These options are shared amongst the ff* tools.
|
||||
</p>
|
||||
<dl compact="compact">
|
||||
<dt> ‘<samp>-L</samp>’</dt>
|
||||
<dd><p>Show license.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-h, -?, -help, --help [<var>arg</var>]</samp>’</dt>
|
||||
<dd><p>Show help. An optional parameter may be specified to print help about a specific
|
||||
item. If no argument is specified, only basic (non advanced) tool
|
||||
options are shown.
|
||||
</p>
|
||||
<p>Possible values of <var>arg</var> are:
|
||||
</p><dl compact="compact">
|
||||
<dt> ‘<samp>long</samp>’</dt>
|
||||
<dd><p>Print advanced tool options in addition to the basic tool options.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>full</samp>’</dt>
|
||||
<dd><p>Print complete list of options, including shared and private options
|
||||
for encoders, decoders, demuxers, muxers, filters, etc.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>decoder=<var>decoder_name</var></samp>’</dt>
|
||||
<dd><p>Print detailed information about the decoder named <var>decoder_name</var>. Use the
|
||||
‘<samp>-decoders</samp>’ option to get a list of all decoders.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>encoder=<var>encoder_name</var></samp>’</dt>
|
||||
<dd><p>Print detailed information about the encoder named <var>encoder_name</var>. Use the
|
||||
‘<samp>-encoders</samp>’ option to get a list of all encoders.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>demuxer=<var>demuxer_name</var></samp>’</dt>
|
||||
<dd><p>Print detailed information about the demuxer named <var>demuxer_name</var>. Use the
|
||||
‘<samp>-formats</samp>’ option to get a list of all demuxers and muxers.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>muxer=<var>muxer_name</var></samp>’</dt>
|
||||
<dd><p>Print detailed information about the muxer named <var>muxer_name</var>. Use the
|
||||
‘<samp>-formats</samp>’ option to get a list of all muxers and demuxers.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>filter=<var>filter_name</var></samp>’</dt>
|
||||
<dd><p>Print detailed information about the filter name <var>filter_name</var>. Use the
|
||||
‘<samp>-filters</samp>’ option to get a list of all filters.
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
</dd>
|
||||
<dt> ‘<samp>-version</samp>’</dt>
|
||||
<dd><p>Show version.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-formats</samp>’</dt>
|
||||
<dd><p>Show available formats.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-codecs</samp>’</dt>
|
||||
<dd><p>Show all codecs known to libavcodec.
|
||||
</p>
|
||||
<p>Note that the term ’codec’ is used throughout this documentation as a shortcut
|
||||
for what is more correctly called a media bitstream format.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-decoders</samp>’</dt>
|
||||
<dd><p>Show available decoders.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-encoders</samp>’</dt>
|
||||
<dd><p>Show all available encoders.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-bsfs</samp>’</dt>
|
||||
<dd><p>Show available bitstream filters.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-protocols</samp>’</dt>
|
||||
<dd><p>Show available protocols.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-filters</samp>’</dt>
|
||||
<dd><p>Show available libavfilter filters.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-pix_fmts</samp>’</dt>
|
||||
<dd><p>Show available pixel formats.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-sample_fmts</samp>’</dt>
|
||||
<dd><p>Show available sample formats.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-layouts</samp>’</dt>
|
||||
<dd><p>Show channel names and standard channel layouts.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-colors</samp>’</dt>
|
||||
<dd><p>Show recognized color names.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-loglevel [repeat+]<var>loglevel</var> | -v [repeat+]<var>loglevel</var></samp>’</dt>
|
||||
<dd><p>Set the logging level used by the library.
|
||||
Adding "repeat+" indicates that repeated log output should not be compressed
|
||||
to the first line and the "Last message repeated n times" line will be
|
||||
omitted. "repeat" can also be used alone.
|
||||
If "repeat" is used alone, and with no prior loglevel set, the default
|
||||
loglevel will be used. If multiple loglevel parameters are given, using
|
||||
’repeat’ will not change the loglevel.
|
||||
<var>loglevel</var> is a number or a string containing one of the following values:
|
||||
</p><dl compact="compact">
|
||||
<dt> ‘<samp>quiet</samp>’</dt>
|
||||
<dd><p>Show nothing at all; be silent.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>panic</samp>’</dt>
|
||||
<dd><p>Only show fatal errors which could lead the process to crash, such as
|
||||
and assert failure. This is not currently used for anything.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>fatal</samp>’</dt>
|
||||
<dd><p>Only show fatal errors. These are errors after which the process absolutely
|
||||
cannot continue after.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>error</samp>’</dt>
|
||||
<dd><p>Show all errors, including ones which can be recovered from.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>warning</samp>’</dt>
|
||||
<dd><p>Show all warnings and errors. Any message related to possibly
|
||||
incorrect or unexpected events will be shown.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>info</samp>’</dt>
|
||||
<dd><p>Show informative messages during processing. This is in addition to
|
||||
warnings and errors. This is the default value.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>verbose</samp>’</dt>
|
||||
<dd><p>Same as <code>info</code>, except more verbose.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>debug</samp>’</dt>
|
||||
<dd><p>Show everything, including debugging information.
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
<p>By default the program logs to stderr, if coloring is supported by the
|
||||
terminal, colors are used to mark errors and warnings. Log coloring
|
||||
can be disabled setting the environment variable
|
||||
<code>AV_LOG_FORCE_NOCOLOR</code> or <code>NO_COLOR</code>, or can be forced setting
|
||||
the environment variable <code>AV_LOG_FORCE_COLOR</code>.
|
||||
The use of the environment variable <code>NO_COLOR</code> is deprecated and
|
||||
will be dropped in a following FFmpeg version.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-report</samp>’</dt>
|
||||
<dd><p>Dump full command line and console output to a file named
|
||||
<code><var>program</var>-<var>YYYYMMDD</var>-<var>HHMMSS</var>.log</code> in the current
|
||||
directory.
|
||||
This file can be useful for bug reports.
|
||||
It also implies <code>-loglevel verbose</code>.
|
||||
</p>
|
||||
<p>Setting the environment variable <code>FFREPORT</code> to any value has the
|
||||
same effect. If the value is a ’:’-separated key=value sequence, these
|
||||
options will affect the report; options values must be escaped if they
|
||||
contain special characters or the options delimiter ’:’ (see the
|
||||
“Quoting and escaping” section in the ffmpeg-utils manual). The
|
||||
following option is recognized:
|
||||
</p><dl compact="compact">
|
||||
<dt> ‘<samp>file</samp>’</dt>
|
||||
<dd><p>set the file name to use for the report; <code>%p</code> is expanded to the name
|
||||
of the program, <code>%t</code> is expanded to a timestamp, <code>%%</code> is expanded
|
||||
to a plain <code>%</code>
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
<p>Errors in parsing the environment variable are not fatal, and will not
|
||||
appear in the report.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-cpuflags flags (<em>global</em>)</samp>’</dt>
|
||||
<dd><p>Allows setting and clearing cpu flags. This option is intended
|
||||
for testing. Do not use it unless you know what you’re doing.
|
||||
</p><table><tr><td> </td><td><pre class="example">ffmpeg -cpuflags -sse+mmx ...
|
||||
ffmpeg -cpuflags mmx ...
|
||||
ffmpeg -cpuflags 0 ...
|
||||
</pre></td></tr></table>
|
||||
<p>Possible flags for this option are:
|
||||
</p><dl compact="compact">
|
||||
<dt> ‘<samp>x86</samp>’</dt>
|
||||
<dd><dl compact="compact">
|
||||
<dt> ‘<samp>mmx</samp>’</dt>
|
||||
<dt> ‘<samp>mmxext</samp>’</dt>
|
||||
<dt> ‘<samp>sse</samp>’</dt>
|
||||
<dt> ‘<samp>sse2</samp>’</dt>
|
||||
<dt> ‘<samp>sse2slow</samp>’</dt>
|
||||
<dt> ‘<samp>sse3</samp>’</dt>
|
||||
<dt> ‘<samp>sse3slow</samp>’</dt>
|
||||
<dt> ‘<samp>ssse3</samp>’</dt>
|
||||
<dt> ‘<samp>atom</samp>’</dt>
|
||||
<dt> ‘<samp>sse4.1</samp>’</dt>
|
||||
<dt> ‘<samp>sse4.2</samp>’</dt>
|
||||
<dt> ‘<samp>avx</samp>’</dt>
|
||||
<dt> ‘<samp>xop</samp>’</dt>
|
||||
<dt> ‘<samp>fma4</samp>’</dt>
|
||||
<dt> ‘<samp>3dnow</samp>’</dt>
|
||||
<dt> ‘<samp>3dnowext</samp>’</dt>
|
||||
<dt> ‘<samp>cmov</samp>’</dt>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt> ‘<samp>ARM</samp>’</dt>
|
||||
<dd><dl compact="compact">
|
||||
<dt> ‘<samp>armv5te</samp>’</dt>
|
||||
<dt> ‘<samp>armv6</samp>’</dt>
|
||||
<dt> ‘<samp>armv6t2</samp>’</dt>
|
||||
<dt> ‘<samp>vfp</samp>’</dt>
|
||||
<dt> ‘<samp>vfpv3</samp>’</dt>
|
||||
<dt> ‘<samp>neon</samp>’</dt>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt> ‘<samp>PowerPC</samp>’</dt>
|
||||
<dd><dl compact="compact">
|
||||
<dt> ‘<samp>altivec</samp>’</dt>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt> ‘<samp>Specific Processors</samp>’</dt>
|
||||
<dd><dl compact="compact">
|
||||
<dt> ‘<samp>pentium2</samp>’</dt>
|
||||
<dt> ‘<samp>pentium3</samp>’</dt>
|
||||
<dt> ‘<samp>pentium4</samp>’</dt>
|
||||
<dt> ‘<samp>k6</samp>’</dt>
|
||||
<dt> ‘<samp>k62</samp>’</dt>
|
||||
<dt> ‘<samp>athlon</samp>’</dt>
|
||||
<dt> ‘<samp>athlonxp</samp>’</dt>
|
||||
<dt> ‘<samp>k8</samp>’</dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</dd>
|
||||
<dt> ‘<samp>-opencl_options options (<em>global</em>)</samp>’</dt>
|
||||
<dd><p>Set OpenCL environment options. This option is only available when
|
||||
FFmpeg has been compiled with <code>--enable-opencl</code>.
|
||||
</p>
|
||||
<p><var>options</var> must be a list of <var>key</var>=<var>value</var> option pairs
|
||||
separated by ’:’. See the “OpenCL Options” section in the
|
||||
ffmpeg-utils manual for the list of supported options.
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
<a name="AVOptions"></a>
|
||||
<h2 class="section"><a href="ffplay.html#toc-AVOptions">3.3 AVOptions</a></h2>
|
||||
|
||||
<p>These options are provided directly by the libavformat, libavdevice and
|
||||
libavcodec libraries. To see the list of available AVOptions, use the
|
||||
‘<samp>-help</samp>’ option. They are separated into two categories:
|
||||
</p><dl compact="compact">
|
||||
<dt> ‘<samp>generic</samp>’</dt>
|
||||
<dd><p>These options can be set for any container, codec or device. Generic options
|
||||
are listed under AVFormatContext options for containers/devices and under
|
||||
AVCodecContext options for codecs.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>private</samp>’</dt>
|
||||
<dd><p>These options are specific to the given container, device or codec. Private
|
||||
options are listed under their corresponding containers/devices/codecs.
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
<p>For example to write an ID3v2.3 header instead of a default ID3v2.4 to
|
||||
an MP3 file, use the ‘<samp>id3v2_version</samp>’ private option of the MP3
|
||||
muxer:
|
||||
</p><table><tr><td> </td><td><pre class="example">ffmpeg -i input.flac -id3v2_version 3 out.mp3
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>All codec AVOptions are per-stream, and thus a stream specifier
|
||||
should be attached to them.
|
||||
</p>
|
||||
<p>Note: the ‘<samp>-nooption</samp>’ syntax cannot be used for boolean
|
||||
AVOptions, use ‘<samp>-option 0</samp>’/‘<samp>-option 1</samp>’.
|
||||
</p>
|
||||
<p>Note: the old undocumented way of specifying per-stream AVOptions by
|
||||
prepending v/a/s to the options name is now obsolete and will be
|
||||
removed soon.
|
||||
</p>
|
||||
<a name="Main-options"></a>
|
||||
<h2 class="section"><a href="ffplay.html#toc-Main-options">3.4 Main options</a></h2>
|
||||
|
||||
<dl compact="compact">
|
||||
<dt> ‘<samp>-x <var>width</var></samp>’</dt>
|
||||
<dd><p>Force displayed width.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-y <var>height</var></samp>’</dt>
|
||||
<dd><p>Force displayed height.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-s <var>size</var></samp>’</dt>
|
||||
<dd><p>Set frame size (WxH or abbreviation), needed for videos which do
|
||||
not contain a header with the frame size like raw YUV. This option
|
||||
has been deprecated in favor of private options, try -video_size.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-an</samp>’</dt>
|
||||
<dd><p>Disable audio.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-vn</samp>’</dt>
|
||||
<dd><p>Disable video.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-ss <var>pos</var></samp>’</dt>
|
||||
<dd><p>Seek to a given position in seconds.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-t <var>duration</var></samp>’</dt>
|
||||
<dd><p>play <duration> seconds of audio/video
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-bytes</samp>’</dt>
|
||||
<dd><p>Seek by bytes.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-nodisp</samp>’</dt>
|
||||
<dd><p>Disable graphical display.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-f <var>fmt</var></samp>’</dt>
|
||||
<dd><p>Force format.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-window_title <var>title</var></samp>’</dt>
|
||||
<dd><p>Set window title (default is the input filename).
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-loop <var>number</var></samp>’</dt>
|
||||
<dd><p>Loops movie playback <number> times. 0 means forever.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-showmode <var>mode</var></samp>’</dt>
|
||||
<dd><p>Set the show mode to use.
|
||||
Available values for <var>mode</var> are:
|
||||
</p><dl compact="compact">
|
||||
<dt> ‘<samp>0, video</samp>’</dt>
|
||||
<dd><p>show video
|
||||
</p></dd>
|
||||
<dt> ‘<samp>1, waves</samp>’</dt>
|
||||
<dd><p>show audio waves
|
||||
</p></dd>
|
||||
<dt> ‘<samp>2, rdft</samp>’</dt>
|
||||
<dd><p>show audio frequency band using RDFT ((Inverse) Real Discrete Fourier Transform)
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
<p>Default value is "video", if video is not present or cannot be played
|
||||
"rdft" is automatically selected.
|
||||
</p>
|
||||
<p>You can interactively cycle through the available show modes by
|
||||
pressing the key <w>.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-vf <var>filtergraph</var></samp>’</dt>
|
||||
<dd><p>Create the filtergraph specified by <var>filtergraph</var> and use it to
|
||||
filter the video stream.
|
||||
</p>
|
||||
<p><var>filtergraph</var> is a description of the filtergraph to apply to
|
||||
the stream, and must have a single video input and a single video
|
||||
output. In the filtergraph, the input is associated to the label
|
||||
<code>in</code>, and the output to the label <code>out</code>. See the
|
||||
ffmpeg-filters manual for more information about the filtergraph
|
||||
syntax.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-af <var>filtergraph</var></samp>’</dt>
|
||||
<dd><p><var>filtergraph</var> is a description of the filtergraph to apply to
|
||||
the input audio.
|
||||
Use the option "-filters" to show all the available filters (including
|
||||
sources and sinks).
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-i <var>input_file</var></samp>’</dt>
|
||||
<dd><p>Read <var>input_file</var>.
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
<a name="Advanced-options"></a>
|
||||
<h2 class="section"><a href="ffplay.html#toc-Advanced-options">3.5 Advanced options</a></h2>
|
||||
<dl compact="compact">
|
||||
<dt> ‘<samp>-pix_fmt <var>format</var></samp>’</dt>
|
||||
<dd><p>Set pixel format.
|
||||
This option has been deprecated in favor of private options, try -pixel_format.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-stats</samp>’</dt>
|
||||
<dd><p>Print several playback statistics, in particular show the stream
|
||||
duration, the codec parameters, the current position in the stream and
|
||||
the audio/video synchronisation drift. It is on by default, to
|
||||
explicitly disable it you need to specify <code>-nostats</code>.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-bug</samp>’</dt>
|
||||
<dd><p>Work around bugs.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-fast</samp>’</dt>
|
||||
<dd><p>Non-spec-compliant optimizations.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-genpts</samp>’</dt>
|
||||
<dd><p>Generate pts.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-rtp_tcp</samp>’</dt>
|
||||
<dd><p>Force RTP/TCP protocol usage instead of RTP/UDP. It is only meaningful
|
||||
if you are streaming with the RTSP protocol.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-sync <var>type</var></samp>’</dt>
|
||||
<dd><p>Set the master clock to audio (<code>type=audio</code>), video
|
||||
(<code>type=video</code>) or external (<code>type=ext</code>). Default is audio. The
|
||||
master clock is used to control audio-video synchronization. Most media
|
||||
players use audio as master clock, but in some cases (streaming or high
|
||||
quality broadcast) it is necessary to change that. This option is mainly
|
||||
used for debugging purposes.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-threads <var>count</var></samp>’</dt>
|
||||
<dd><p>Set the thread count.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-ast <var>audio_stream_number</var></samp>’</dt>
|
||||
<dd><p>Select the desired audio stream number, counting from 0. The number
|
||||
refers to the list of all the input audio streams. If it is greater
|
||||
than the number of audio streams minus one, then the last one is
|
||||
selected, if it is negative the audio playback is disabled.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-vst <var>video_stream_number</var></samp>’</dt>
|
||||
<dd><p>Select the desired video stream number, counting from 0. The number
|
||||
refers to the list of all the input video streams. If it is greater
|
||||
than the number of video streams minus one, then the last one is
|
||||
selected, if it is negative the video playback is disabled.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-sst <var>subtitle_stream_number</var></samp>’</dt>
|
||||
<dd><p>Select the desired subtitle stream number, counting from 0. The number
|
||||
refers to the list of all the input subtitle streams. If it is greater
|
||||
than the number of subtitle streams minus one, then the last one is
|
||||
selected, if it is negative the subtitle rendering is disabled.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-autoexit</samp>’</dt>
|
||||
<dd><p>Exit when video is done playing.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-exitonkeydown</samp>’</dt>
|
||||
<dd><p>Exit if any key is pressed.
|
||||
</p></dd>
|
||||
<dt> ‘<samp>-exitonmousedown</samp>’</dt>
|
||||
<dd><p>Exit if any mouse button is pressed.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-codec:<var>media_specifier</var> <var>codec_name</var></samp>’</dt>
|
||||
<dd><p>Force a specific decoder implementation for the stream identified by
|
||||
<var>media_specifier</var>, which can assume the values <code>a</code> (audio),
|
||||
<code>v</code> (video), and <code>s</code> subtitle.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-acodec <var>codec_name</var></samp>’</dt>
|
||||
<dd><p>Force a specific audio decoder.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-vcodec <var>codec_name</var></samp>’</dt>
|
||||
<dd><p>Force a specific video decoder.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> ‘<samp>-scodec <var>codec_name</var></samp>’</dt>
|
||||
<dd><p>Force a specific subtitle decoder.
|
||||
</p></dd>
|
||||
</dl>
|
||||
|
||||
<a name="While-playing"></a>
|
||||
<h2 class="section"><a href="ffplay.html#toc-While-playing">3.6 While playing</a></h2>
|
||||
|
||||
<dl compact="compact">
|
||||
<dt> <q, ESC></dt>
|
||||
<dd><p>Quit.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> <f></dt>
|
||||
<dd><p>Toggle full screen.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> <p, SPC></dt>
|
||||
<dd><p>Pause.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> <a></dt>
|
||||
<dd><p>Cycle audio channel in the curret program.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> <v></dt>
|
||||
<dd><p>Cycle video channel.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> <t></dt>
|
||||
<dd><p>Cycle subtitle channel in the current program.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> <c></dt>
|
||||
<dd><p>Cycle program.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> <w></dt>
|
||||
<dd><p>Show audio waves.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> <left/right></dt>
|
||||
<dd><p>Seek backward/forward 10 seconds.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> <down/up></dt>
|
||||
<dd><p>Seek backward/forward 1 minute.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> <page down/page up></dt>
|
||||
<dd><p>Seek backward/forward 10 minutes.
|
||||
</p>
|
||||
</dd>
|
||||
<dt> <mouse click></dt>
|
||||
<dd><p>Seek to percentage in file corresponding to fraction of width.
|
||||
</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
<a name="See-Also"></a>
|
||||
<h1 class="chapter"><a href="ffplay.html#toc-See-Also">4. See Also</a></h1>
|
||||
|
||||
<p><a href="ffplay-all.html">ffmpeg-all</a>,
|
||||
<a href="ffmpeg.html">ffmpeg</a>, <a href="ffprobe.html">ffprobe</a>, <a href="ffserver.html">ffserver</a>,
|
||||
<a href="ffmpeg-utils.html">ffmpeg-utils</a>,
|
||||
<a href="ffmpeg-scaler.html">ffmpeg-scaler</a>,
|
||||
<a href="ffmpeg-resampler.html">ffmpeg-resampler</a>,
|
||||
<a href="ffmpeg-codecs.html">ffmpeg-codecs</a>,
|
||||
<a href="ffmpeg-bitstream-filters.html">ffmpeg-bitstream-filters</a>,
|
||||
<a href="ffmpeg-formats.html">ffmpeg-formats</a>,
|
||||
<a href="ffmpeg-devices.html">ffmpeg-devices</a>,
|
||||
<a href="ffmpeg-protocols.html">ffmpeg-protocols</a>,
|
||||
<a href="ffmpeg-filters.html">ffmpeg-filters</a>
|
||||
</p>
|
||||
|
||||
<a name="Authors"></a>
|
||||
<h1 class="chapter"><a href="ffplay.html#toc-Authors">5. Authors</a></h1>
|
||||
|
||||
<p>The FFmpeg developers.
|
||||
</p>
|
||||
<p>For details about the authorship, see the Git history of the project
|
||||
(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
<code>git log</code> in the FFmpeg source directory, or browsing the
|
||||
online repository at <a href="http://source.ffmpeg.org">http://source.ffmpeg.org</a>.
|
||||
</p>
|
||||
<p>Maintainers for the specific components are listed in the file
|
||||
‘<tt>MAINTAINERS</tt>’ in the source code tree.
|
||||
</p>
|
||||
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+344
@@ -0,0 +1,344 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle ffplay Documentation
|
||||
@titlepage
|
||||
@center @titlefont{ffplay Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Synopsis
|
||||
|
||||
ffplay [@var{options}] [@file{input_url}]
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
FFplay is a very simple and portable media player using the FFmpeg
|
||||
libraries and the SDL library. It is mostly used as a testbed for the
|
||||
various FFmpeg APIs.
|
||||
@c man end
|
||||
|
||||
@chapter Options
|
||||
@c man begin OPTIONS
|
||||
|
||||
@include fftools-common-opts.texi
|
||||
|
||||
@section Main options
|
||||
|
||||
@table @option
|
||||
@item -x @var{width}
|
||||
Force displayed width.
|
||||
@item -y @var{height}
|
||||
Force displayed height.
|
||||
@item -s @var{size}
|
||||
Set frame size (WxH or abbreviation), needed for videos which do
|
||||
not contain a header with the frame size like raw YUV. This option
|
||||
has been deprecated in favor of private options, try -video_size.
|
||||
@item -fs
|
||||
Start in fullscreen mode.
|
||||
@item -an
|
||||
Disable audio.
|
||||
@item -vn
|
||||
Disable video.
|
||||
@item -sn
|
||||
Disable subtitles.
|
||||
@item -ss @var{pos}
|
||||
Seek to @var{pos}. Note that in most formats it is not possible to seek
|
||||
exactly, so @command{ffplay} will seek to the nearest seek point to
|
||||
@var{pos}.
|
||||
|
||||
@var{pos} must be a time duration specification,
|
||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
@item -t @var{duration}
|
||||
Play @var{duration} seconds of audio/video.
|
||||
|
||||
@var{duration} must be a time duration specification,
|
||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
@item -bytes
|
||||
Seek by bytes.
|
||||
@item -seek_interval
|
||||
Set custom interval, in seconds, for seeking using left/right keys. Default is 10 seconds.
|
||||
@item -nodisp
|
||||
Disable graphical display.
|
||||
@item -noborder
|
||||
Borderless window.
|
||||
@item -alwaysontop
|
||||
Window always on top. Available on: X11 with SDL >= 2.0.5, Windows SDL >= 2.0.6.
|
||||
@item -volume
|
||||
Set the startup volume. 0 means silence, 100 means no volume reduction or
|
||||
amplification. Negative values are treated as 0, values above 100 are treated
|
||||
as 100.
|
||||
@item -f @var{fmt}
|
||||
Force format.
|
||||
@item -window_title @var{title}
|
||||
Set window title (default is the input filename).
|
||||
@item -left @var{title}
|
||||
Set the x position for the left of the window (default is a centered window).
|
||||
@item -top @var{title}
|
||||
Set the y position for the top of the window (default is a centered window).
|
||||
@item -loop @var{number}
|
||||
Loops movie playback <number> times. 0 means forever.
|
||||
@item -showmode @var{mode}
|
||||
Set the show mode to use.
|
||||
Available values for @var{mode} are:
|
||||
@table @samp
|
||||
@item 0, video
|
||||
show video
|
||||
@item 1, waves
|
||||
show audio waves
|
||||
@item 2, rdft
|
||||
show audio frequency band using RDFT ((Inverse) Real Discrete Fourier Transform)
|
||||
@end table
|
||||
|
||||
Default value is "video", if video is not present or cannot be played
|
||||
"rdft" is automatically selected.
|
||||
|
||||
You can interactively cycle through the available show modes by
|
||||
pressing the key @key{w}.
|
||||
|
||||
@item -vf @var{filtergraph}
|
||||
Create the filtergraph specified by @var{filtergraph} and use it to
|
||||
filter the video stream.
|
||||
|
||||
@var{filtergraph} is a description of the filtergraph to apply to
|
||||
the stream, and must have a single video input and a single video
|
||||
output. In the filtergraph, the input is associated to the label
|
||||
@code{in}, and the output to the label @code{out}. See the
|
||||
ffmpeg-filters manual for more information about the filtergraph
|
||||
syntax.
|
||||
|
||||
You can specify this parameter multiple times and cycle through the specified
|
||||
filtergraphs along with the show modes by pressing the key @key{w}.
|
||||
|
||||
@item -af @var{filtergraph}
|
||||
@var{filtergraph} is a description of the filtergraph to apply to
|
||||
the input audio.
|
||||
Use the option "-filters" to show all the available filters (including
|
||||
sources and sinks).
|
||||
|
||||
@item -i @var{input_url}
|
||||
Read @var{input_url}.
|
||||
@end table
|
||||
|
||||
@section Advanced options
|
||||
@table @option
|
||||
@item -pix_fmt @var{format}
|
||||
Set pixel format.
|
||||
This option has been deprecated in favor of private options, try -pixel_format.
|
||||
|
||||
@item -stats
|
||||
Print several playback statistics, in particular show the stream
|
||||
duration, the codec parameters, the current position in the stream and
|
||||
the audio/video synchronisation drift. It is shown by default, unless the
|
||||
log level is lower than @code{info}. Its display can be forced by manually
|
||||
specifying this option. To disable it, you need to specify @code{-nostats}.
|
||||
|
||||
@item -fast
|
||||
Non-spec-compliant optimizations.
|
||||
@item -genpts
|
||||
Generate pts.
|
||||
@item -sync @var{type}
|
||||
Set the master clock to audio (@code{type=audio}), video
|
||||
(@code{type=video}) or external (@code{type=ext}). Default is audio. The
|
||||
master clock is used to control audio-video synchronization. Most media
|
||||
players use audio as master clock, but in some cases (streaming or high
|
||||
quality broadcast) it is necessary to change that. This option is mainly
|
||||
used for debugging purposes.
|
||||
@item -ast @var{audio_stream_specifier}
|
||||
Select the desired audio stream using the given stream specifier. The stream
|
||||
specifiers are described in the @ref{Stream specifiers} chapter. If this option
|
||||
is not specified, the "best" audio stream is selected in the program of the
|
||||
already selected video stream.
|
||||
@item -vst @var{video_stream_specifier}
|
||||
Select the desired video stream using the given stream specifier. The stream
|
||||
specifiers are described in the @ref{Stream specifiers} chapter. If this option
|
||||
is not specified, the "best" video stream is selected.
|
||||
@item -sst @var{subtitle_stream_specifier}
|
||||
Select the desired subtitle stream using the given stream specifier. The stream
|
||||
specifiers are described in the @ref{Stream specifiers} chapter. If this option
|
||||
is not specified, the "best" subtitle stream is selected in the program of the
|
||||
already selected video or audio stream.
|
||||
@item -autoexit
|
||||
Exit when video is done playing.
|
||||
@item -exitonkeydown
|
||||
Exit if any key is pressed.
|
||||
@item -exitonmousedown
|
||||
Exit if any mouse button is pressed.
|
||||
|
||||
@item -codec:@var{media_specifier} @var{codec_name}
|
||||
Force a specific decoder implementation for the stream identified by
|
||||
@var{media_specifier}, which can assume the values @code{a} (audio),
|
||||
@code{v} (video), and @code{s} subtitle.
|
||||
|
||||
@item -acodec @var{codec_name}
|
||||
Force a specific audio decoder.
|
||||
|
||||
@item -vcodec @var{codec_name}
|
||||
Force a specific video decoder.
|
||||
|
||||
@item -scodec @var{codec_name}
|
||||
Force a specific subtitle decoder.
|
||||
|
||||
@item -autorotate
|
||||
Automatically rotate the video according to file metadata. Enabled by
|
||||
default, use @option{-noautorotate} to disable it.
|
||||
|
||||
@item -framedrop
|
||||
Drop video frames if video is out of sync. Enabled by default if the master
|
||||
clock is not set to video. Use this option to enable frame dropping for all
|
||||
master clock sources, use @option{-noframedrop} to disable it.
|
||||
|
||||
@item -infbuf
|
||||
Do not limit the input buffer size, read as much data as possible from the
|
||||
input as soon as possible. Enabled by default for realtime streams, where data
|
||||
may be dropped if not read in time. Use this option to enable infinite buffers
|
||||
for all inputs, use @option{-noinfbuf} to disable it.
|
||||
|
||||
@item -filter_threads @var{nb_threads}
|
||||
Defines how many threads are used to process a filter pipeline. Each pipeline
|
||||
will produce a thread pool with this many threads available for parallel
|
||||
processing. The default is 0 which means that the thread count will be
|
||||
determined by the number of available CPUs.
|
||||
|
||||
@end table
|
||||
|
||||
@section While playing
|
||||
|
||||
@table @key
|
||||
@item q, ESC
|
||||
Quit.
|
||||
|
||||
@item f
|
||||
Toggle full screen.
|
||||
|
||||
@item p, SPC
|
||||
Pause.
|
||||
|
||||
@item m
|
||||
Toggle mute.
|
||||
|
||||
@item 9, 0
|
||||
Decrease and increase volume respectively.
|
||||
|
||||
@item /, *
|
||||
Decrease and increase volume respectively.
|
||||
|
||||
@item a
|
||||
Cycle audio channel in the current program.
|
||||
|
||||
@item v
|
||||
Cycle video channel.
|
||||
|
||||
@item t
|
||||
Cycle subtitle channel in the current program.
|
||||
|
||||
@item c
|
||||
Cycle program.
|
||||
|
||||
@item w
|
||||
Cycle video filters or show modes.
|
||||
|
||||
@item s
|
||||
Step to the next frame.
|
||||
|
||||
Pause if the stream is not already paused, step to the next video
|
||||
frame, and pause.
|
||||
|
||||
@item left/right
|
||||
Seek backward/forward 10 seconds.
|
||||
|
||||
@item down/up
|
||||
Seek backward/forward 1 minute.
|
||||
|
||||
@item page down/page up
|
||||
Seek to the previous/next chapter.
|
||||
or if there are no chapters
|
||||
Seek backward/forward 10 minutes.
|
||||
|
||||
@item right mouse click
|
||||
Seek to percentage in file corresponding to fraction of width.
|
||||
|
||||
@item left mouse double-click
|
||||
Toggle full screen.
|
||||
|
||||
@end table
|
||||
|
||||
@c man end
|
||||
|
||||
@include config.texi
|
||||
@ifset config-all
|
||||
@set config-readonly
|
||||
@ifset config-avutil
|
||||
@include utils.texi
|
||||
@end ifset
|
||||
@ifset config-avcodec
|
||||
@include codecs.texi
|
||||
@include bitstream_filters.texi
|
||||
@end ifset
|
||||
@ifset config-avformat
|
||||
@include formats.texi
|
||||
@include protocols.texi
|
||||
@end ifset
|
||||
@ifset config-avdevice
|
||||
@include devices.texi
|
||||
@end ifset
|
||||
@ifset config-swresample
|
||||
@include resampler.texi
|
||||
@end ifset
|
||||
@ifset config-swscale
|
||||
@include scaler.texi
|
||||
@end ifset
|
||||
@ifset config-avfilter
|
||||
@include filters.texi
|
||||
@end ifset
|
||||
@include general_contents.texi
|
||||
@end ifset
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@ifset config-all
|
||||
@url{ffplay.html,ffplay},
|
||||
@end ifset
|
||||
@ifset config-not-all
|
||||
@url{ffplay-all.html,ffmpeg-all},
|
||||
@end ifset
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg-utils.html,ffmpeg-utils},
|
||||
@url{ffmpeg-scaler.html,ffmpeg-scaler},
|
||||
@url{ffmpeg-resampler.html,ffmpeg-resampler},
|
||||
@url{ffmpeg-codecs.html,ffmpeg-codecs},
|
||||
@url{ffmpeg-bitstream-filters.html,ffmpeg-bitstream-filters},
|
||||
@url{ffmpeg-formats.html,ffmpeg-formats},
|
||||
@url{ffmpeg-devices.html,ffmpeg-devices},
|
||||
@url{ffmpeg-protocols.html,ffmpeg-protocols},
|
||||
@url{ffmpeg-filters.html,ffmpeg-filters}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
@ifset config-all
|
||||
ffplay(1),
|
||||
@end ifset
|
||||
@ifset config-not-all
|
||||
ffplay-all(1),
|
||||
@end ifset
|
||||
ffmpeg(1), ffprobe(1),
|
||||
ffmpeg-utils(1), ffmpeg-scaler(1), ffmpeg-resampler(1),
|
||||
ffmpeg-codecs(1), ffmpeg-bitstream-filters(1), ffmpeg-formats(1),
|
||||
ffmpeg-devices(1), ffmpeg-protocols(1), ffmpeg-filters(1)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffplay
|
||||
@settitle FFplay media player
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
Vendored
-21984
File diff suppressed because it is too large
Load Diff
Vendored
-1009
File diff suppressed because it is too large
Load Diff
Vendored
+697
@@ -0,0 +1,697 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle ffprobe Documentation
|
||||
@titlepage
|
||||
@center @titlefont{ffprobe Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Synopsis
|
||||
|
||||
ffprobe [@var{options}] [@file{input_url}]
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
ffprobe gathers information from multimedia streams and prints it in
|
||||
human- and machine-readable fashion.
|
||||
|
||||
For example it can be used to check the format of the container used
|
||||
by a multimedia stream and the format and type of each media stream
|
||||
contained in it.
|
||||
|
||||
If a url is specified in input, ffprobe will try to open and
|
||||
probe the url content. If the url cannot be opened or recognized as
|
||||
a multimedia file, a positive exit code is returned.
|
||||
|
||||
ffprobe may be employed both as a standalone application or in
|
||||
combination with a textual filter, which may perform more
|
||||
sophisticated processing, e.g. statistical processing or plotting.
|
||||
|
||||
Options are used to list some of the formats supported by ffprobe or
|
||||
for specifying which information to display, and for setting how
|
||||
ffprobe will show it.
|
||||
|
||||
ffprobe output is designed to be easily parsable by a textual filter,
|
||||
and consists of one or more sections of a form defined by the selected
|
||||
writer, which is specified by the @option{print_format} option.
|
||||
|
||||
Sections may contain other nested sections, and are identified by a
|
||||
name (which may be shared by other sections), and an unique
|
||||
name. See the output of @option{sections}.
|
||||
|
||||
Metadata tags stored in the container or in the streams are recognized
|
||||
and printed in the corresponding "FORMAT", "STREAM" or "PROGRAM_STREAM"
|
||||
section.
|
||||
|
||||
@c man end
|
||||
|
||||
@chapter Options
|
||||
@c man begin OPTIONS
|
||||
|
||||
@include fftools-common-opts.texi
|
||||
|
||||
@section Main options
|
||||
|
||||
@table @option
|
||||
|
||||
@item -f @var{format}
|
||||
Force format to use.
|
||||
|
||||
@item -unit
|
||||
Show the unit of the displayed values.
|
||||
|
||||
@item -prefix
|
||||
Use SI prefixes for the displayed values.
|
||||
Unless the "-byte_binary_prefix" option is used all the prefixes
|
||||
are decimal.
|
||||
|
||||
@item -byte_binary_prefix
|
||||
Force the use of binary prefixes for byte values.
|
||||
|
||||
@item -sexagesimal
|
||||
Use sexagesimal format HH:MM:SS.MICROSECONDS for time values.
|
||||
|
||||
@item -pretty
|
||||
Prettify the format of the displayed values, it corresponds to the
|
||||
options "-unit -prefix -byte_binary_prefix -sexagesimal".
|
||||
|
||||
@item -of, -print_format @var{writer_name}[=@var{writer_options}]
|
||||
Set the output printing format.
|
||||
|
||||
@var{writer_name} specifies the name of the writer, and
|
||||
@var{writer_options} specifies the options to be passed to the writer.
|
||||
|
||||
For example for printing the output in JSON format, specify:
|
||||
@example
|
||||
-print_format json
|
||||
@end example
|
||||
|
||||
For more details on the available output printing formats, see the
|
||||
Writers section below.
|
||||
|
||||
@item -sections
|
||||
Print sections structure and section information, and exit. The output
|
||||
is not meant to be parsed by a machine.
|
||||
|
||||
@item -select_streams @var{stream_specifier}
|
||||
Select only the streams specified by @var{stream_specifier}. This
|
||||
option affects only the options related to streams
|
||||
(e.g. @code{show_streams}, @code{show_packets}, etc.).
|
||||
|
||||
For example to show only audio streams, you can use the command:
|
||||
@example
|
||||
ffprobe -show_streams -select_streams a INPUT
|
||||
@end example
|
||||
|
||||
To show only video packets belonging to the video stream with index 1:
|
||||
@example
|
||||
ffprobe -show_packets -select_streams v:1 INPUT
|
||||
@end example
|
||||
|
||||
@item -show_data
|
||||
Show payload data, as a hexadecimal and ASCII dump. Coupled with
|
||||
@option{-show_packets}, it will dump the packets' data. Coupled with
|
||||
@option{-show_streams}, it will dump the codec extradata.
|
||||
|
||||
The dump is printed as the "data" field. It may contain newlines.
|
||||
|
||||
@item -show_data_hash @var{algorithm}
|
||||
Show a hash of payload data, for packets with @option{-show_packets} and for
|
||||
codec extradata with @option{-show_streams}.
|
||||
|
||||
@item -show_error
|
||||
Show information about the error found when trying to probe the input.
|
||||
|
||||
The error information is printed within a section with name "ERROR".
|
||||
|
||||
@item -show_format
|
||||
Show information about the container format of the input multimedia
|
||||
stream.
|
||||
|
||||
All the container format information is printed within a section with
|
||||
name "FORMAT".
|
||||
|
||||
@item -show_format_entry @var{name}
|
||||
Like @option{-show_format}, but only prints the specified entry of the
|
||||
container format information, rather than all. This option may be given more
|
||||
than once, then all specified entries will be shown.
|
||||
|
||||
This option is deprecated, use @code{show_entries} instead.
|
||||
|
||||
@item -show_entries @var{section_entries}
|
||||
Set list of entries to show.
|
||||
|
||||
Entries are specified according to the following
|
||||
syntax. @var{section_entries} contains a list of section entries
|
||||
separated by @code{:}. Each section entry is composed by a section
|
||||
name (or unique name), optionally followed by a list of entries local
|
||||
to that section, separated by @code{,}.
|
||||
|
||||
If section name is specified but is followed by no @code{=}, all
|
||||
entries are printed to output, together with all the contained
|
||||
sections. Otherwise only the entries specified in the local section
|
||||
entries list are printed. In particular, if @code{=} is specified but
|
||||
the list of local entries is empty, then no entries will be shown for
|
||||
that section.
|
||||
|
||||
Note that the order of specification of the local section entries is
|
||||
not honored in the output, and the usual display order will be
|
||||
retained.
|
||||
|
||||
The formal syntax is given by:
|
||||
@example
|
||||
@var{LOCAL_SECTION_ENTRIES} ::= @var{SECTION_ENTRY_NAME}[,@var{LOCAL_SECTION_ENTRIES}]
|
||||
@var{SECTION_ENTRY} ::= @var{SECTION_NAME}[=[@var{LOCAL_SECTION_ENTRIES}]]
|
||||
@var{SECTION_ENTRIES} ::= @var{SECTION_ENTRY}[:@var{SECTION_ENTRIES}]
|
||||
@end example
|
||||
|
||||
For example, to show only the index and type of each stream, and the PTS
|
||||
time, duration time, and stream index of the packets, you can specify
|
||||
the argument:
|
||||
@example
|
||||
packet=pts_time,duration_time,stream_index : stream=index,codec_type
|
||||
@end example
|
||||
|
||||
To show all the entries in the section "format", but only the codec
|
||||
type in the section "stream", specify the argument:
|
||||
@example
|
||||
format : stream=codec_type
|
||||
@end example
|
||||
|
||||
To show all the tags in the stream and format sections:
|
||||
@example
|
||||
stream_tags : format_tags
|
||||
@end example
|
||||
|
||||
To show only the @code{title} tag (if available) in the stream
|
||||
sections:
|
||||
@example
|
||||
stream_tags=title
|
||||
@end example
|
||||
|
||||
@item -show_packets
|
||||
Show information about each packet contained in the input multimedia
|
||||
stream.
|
||||
|
||||
The information for each single packet is printed within a dedicated
|
||||
section with name "PACKET".
|
||||
|
||||
@item -show_frames
|
||||
Show information about each frame and subtitle contained in the input
|
||||
multimedia stream.
|
||||
|
||||
The information for each single frame is printed within a dedicated
|
||||
section with name "FRAME" or "SUBTITLE".
|
||||
|
||||
@item -show_log @var{loglevel}
|
||||
Show logging information from the decoder about each frame according to
|
||||
the value set in @var{loglevel}, (see @code{-loglevel}). This option requires @code{-show_frames}.
|
||||
|
||||
The information for each log message is printed within a dedicated
|
||||
section with name "LOG".
|
||||
|
||||
@item -show_streams
|
||||
Show information about each media stream contained in the input
|
||||
multimedia stream.
|
||||
|
||||
Each media stream information is printed within a dedicated section
|
||||
with name "STREAM".
|
||||
|
||||
@item -show_programs
|
||||
Show information about programs and their streams contained in the input
|
||||
multimedia stream.
|
||||
|
||||
Each media stream information is printed within a dedicated section
|
||||
with name "PROGRAM_STREAM".
|
||||
|
||||
@item -show_chapters
|
||||
Show information about chapters stored in the format.
|
||||
|
||||
Each chapter is printed within a dedicated section with name "CHAPTER".
|
||||
|
||||
@item -count_frames
|
||||
Count the number of frames per stream and report it in the
|
||||
corresponding stream section.
|
||||
|
||||
@item -count_packets
|
||||
Count the number of packets per stream and report it in the
|
||||
corresponding stream section.
|
||||
|
||||
@item -read_intervals @var{read_intervals}
|
||||
|
||||
Read only the specified intervals. @var{read_intervals} must be a
|
||||
sequence of interval specifications separated by ",".
|
||||
@command{ffprobe} will seek to the interval starting point, and will
|
||||
continue reading from that.
|
||||
|
||||
Each interval is specified by two optional parts, separated by "%".
|
||||
|
||||
The first part specifies the interval start position. It is
|
||||
interpreted as an absolute position, or as a relative offset from the
|
||||
current position if it is preceded by the "+" character. If this first
|
||||
part is not specified, no seeking will be performed when reading this
|
||||
interval.
|
||||
|
||||
The second part specifies the interval end position. It is interpreted
|
||||
as an absolute position, or as a relative offset from the current
|
||||
position if it is preceded by the "+" character. If the offset
|
||||
specification starts with "#", it is interpreted as the number of
|
||||
packets to read (not including the flushing packets) from the interval
|
||||
start. If no second part is specified, the program will read until the
|
||||
end of the input.
|
||||
|
||||
Note that seeking is not accurate, thus the actual interval start
|
||||
point may be different from the specified position. Also, when an
|
||||
interval duration is specified, the absolute end time will be computed
|
||||
by adding the duration to the interval start point found by seeking
|
||||
the file, rather than to the specified start value.
|
||||
|
||||
The formal syntax is given by:
|
||||
@example
|
||||
@var{INTERVAL} ::= [@var{START}|+@var{START_OFFSET}][%[@var{END}|+@var{END_OFFSET}]]
|
||||
@var{INTERVALS} ::= @var{INTERVAL}[,@var{INTERVALS}]
|
||||
@end example
|
||||
|
||||
A few examples follow.
|
||||
@itemize
|
||||
@item
|
||||
Seek to time 10, read packets until 20 seconds after the found seek
|
||||
point, then seek to position @code{01:30} (1 minute and thirty
|
||||
seconds) and read packets until position @code{01:45}.
|
||||
@example
|
||||
10%+20,01:30%01:45
|
||||
@end example
|
||||
|
||||
@item
|
||||
Read only 42 packets after seeking to position @code{01:23}:
|
||||
@example
|
||||
01:23%+#42
|
||||
@end example
|
||||
|
||||
@item
|
||||
Read only the first 20 seconds from the start:
|
||||
@example
|
||||
%+20
|
||||
@end example
|
||||
|
||||
@item
|
||||
Read from the start until position @code{02:30}:
|
||||
@example
|
||||
%02:30
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@item -show_private_data, -private
|
||||
Show private data, that is data depending on the format of the
|
||||
particular shown element.
|
||||
This option is enabled by default, but you may need to disable it
|
||||
for specific uses, for example when creating XSD-compliant XML output.
|
||||
|
||||
@item -show_program_version
|
||||
Show information related to program version.
|
||||
|
||||
Version information is printed within a section with name
|
||||
"PROGRAM_VERSION".
|
||||
|
||||
@item -show_library_versions
|
||||
Show information related to library versions.
|
||||
|
||||
Version information for each library is printed within a section with
|
||||
name "LIBRARY_VERSION".
|
||||
|
||||
@item -show_versions
|
||||
Show information related to program and library versions. This is the
|
||||
equivalent of setting both @option{-show_program_version} and
|
||||
@option{-show_library_versions} options.
|
||||
|
||||
@item -show_pixel_formats
|
||||
Show information about all pixel formats supported by FFmpeg.
|
||||
|
||||
Pixel format information for each format is printed within a section
|
||||
with name "PIXEL_FORMAT".
|
||||
|
||||
@item -show_optional_fields @var{value}
|
||||
Some writers viz. JSON and XML, omit the printing of fields with invalid or non-applicable values,
|
||||
while other writers always print them. This option enables one to control this behaviour.
|
||||
Valid values are @code{always}/@code{1}, @code{never}/@code{0} and @code{auto}/@code{-1}.
|
||||
Default is @var{auto}.
|
||||
|
||||
@item -bitexact
|
||||
Force bitexact output, useful to produce output which is not dependent
|
||||
on the specific build.
|
||||
|
||||
@item -i @var{input_url}
|
||||
Read @var{input_url}.
|
||||
|
||||
@end table
|
||||
@c man end
|
||||
|
||||
@chapter Writers
|
||||
@c man begin WRITERS
|
||||
|
||||
A writer defines the output format adopted by @command{ffprobe}, and will be
|
||||
used for printing all the parts of the output.
|
||||
|
||||
A writer may accept one or more arguments, which specify the options
|
||||
to adopt. The options are specified as a list of @var{key}=@var{value}
|
||||
pairs, separated by ":".
|
||||
|
||||
All writers support the following options:
|
||||
|
||||
@table @option
|
||||
@item string_validation, sv
|
||||
Set string validation mode.
|
||||
|
||||
The following values are accepted.
|
||||
@table @samp
|
||||
@item fail
|
||||
The writer will fail immediately in case an invalid string (UTF-8)
|
||||
sequence or code point is found in the input. This is especially
|
||||
useful to validate input metadata.
|
||||
|
||||
@item ignore
|
||||
Any validation error will be ignored. This will result in possibly
|
||||
broken output, especially with the json or xml writer.
|
||||
|
||||
@item replace
|
||||
The writer will substitute invalid UTF-8 sequences or code points with
|
||||
the string specified with the @option{string_validation_replacement}.
|
||||
@end table
|
||||
|
||||
Default value is @samp{replace}.
|
||||
|
||||
@item string_validation_replacement, svr
|
||||
Set replacement string to use in case @option{string_validation} is
|
||||
set to @samp{replace}.
|
||||
|
||||
In case the option is not specified, the writer will assume the empty
|
||||
string, that is it will remove the invalid sequences from the input
|
||||
strings.
|
||||
@end table
|
||||
|
||||
A description of the currently available writers follows.
|
||||
|
||||
@section default
|
||||
Default format.
|
||||
|
||||
Print each section in the form:
|
||||
@example
|
||||
[SECTION]
|
||||
key1=val1
|
||||
...
|
||||
keyN=valN
|
||||
[/SECTION]
|
||||
@end example
|
||||
|
||||
Metadata tags are printed as a line in the corresponding FORMAT, STREAM or
|
||||
PROGRAM_STREAM section, and are prefixed by the string "TAG:".
|
||||
|
||||
A description of the accepted options follows.
|
||||
|
||||
@table @option
|
||||
|
||||
@item nokey, nk
|
||||
If set to 1 specify not to print the key of each field. Default value
|
||||
is 0.
|
||||
|
||||
@item noprint_wrappers, nw
|
||||
If set to 1 specify not to print the section header and footer.
|
||||
Default value is 0.
|
||||
@end table
|
||||
|
||||
@section compact, csv
|
||||
Compact and CSV format.
|
||||
|
||||
The @code{csv} writer is equivalent to @code{compact}, but supports
|
||||
different defaults.
|
||||
|
||||
Each section is printed on a single line.
|
||||
If no option is specified, the output has the form:
|
||||
@example
|
||||
section|key1=val1| ... |keyN=valN
|
||||
@end example
|
||||
|
||||
Metadata tags are printed in the corresponding "format" or "stream"
|
||||
section. A metadata tag key, if printed, is prefixed by the string
|
||||
"tag:".
|
||||
|
||||
The description of the accepted options follows.
|
||||
|
||||
@table @option
|
||||
|
||||
@item item_sep, s
|
||||
Specify the character to use for separating fields in the output line.
|
||||
It must be a single printable character, it is "|" by default ("," for
|
||||
the @code{csv} writer).
|
||||
|
||||
@item nokey, nk
|
||||
If set to 1 specify not to print the key of each field. Its default
|
||||
value is 0 (1 for the @code{csv} writer).
|
||||
|
||||
@item escape, e
|
||||
Set the escape mode to use, default to "c" ("csv" for the @code{csv}
|
||||
writer).
|
||||
|
||||
It can assume one of the following values:
|
||||
@table @option
|
||||
@item c
|
||||
Perform C-like escaping. Strings containing a newline (@samp{\n}), carriage
|
||||
return (@samp{\r}), a tab (@samp{\t}), a form feed (@samp{\f}), the escaping
|
||||
character (@samp{\}) or the item separator character @var{SEP} are escaped
|
||||
using C-like fashioned escaping, so that a newline is converted to the
|
||||
sequence @samp{\n}, a carriage return to @samp{\r}, @samp{\} to @samp{\\} and
|
||||
the separator @var{SEP} is converted to @samp{\@var{SEP}}.
|
||||
|
||||
@item csv
|
||||
Perform CSV-like escaping, as described in RFC4180. Strings
|
||||
containing a newline (@samp{\n}), a carriage return (@samp{\r}), a double quote
|
||||
(@samp{"}), or @var{SEP} are enclosed in double-quotes.
|
||||
|
||||
@item none
|
||||
Perform no escaping.
|
||||
@end table
|
||||
|
||||
@item print_section, p
|
||||
Print the section name at the beginning of each line if the value is
|
||||
@code{1}, disable it with value set to @code{0}. Default value is
|
||||
@code{1}.
|
||||
|
||||
@end table
|
||||
|
||||
@section flat
|
||||
Flat format.
|
||||
|
||||
A free-form output where each line contains an explicit key=value, such as
|
||||
"streams.stream.3.tags.foo=bar". The output is shell escaped, so it can be
|
||||
directly embedded in sh scripts as long as the separator character is an
|
||||
alphanumeric character or an underscore (see @var{sep_char} option).
|
||||
|
||||
The description of the accepted options follows.
|
||||
|
||||
@table @option
|
||||
@item sep_char, s
|
||||
Separator character used to separate the chapter, the section name, IDs and
|
||||
potential tags in the printed field key.
|
||||
|
||||
Default value is @samp{.}.
|
||||
|
||||
@item hierarchical, h
|
||||
Specify if the section name specification should be hierarchical. If
|
||||
set to 1, and if there is more than one section in the current
|
||||
chapter, the section name will be prefixed by the name of the
|
||||
chapter. A value of 0 will disable this behavior.
|
||||
|
||||
Default value is 1.
|
||||
@end table
|
||||
|
||||
@section ini
|
||||
INI format output.
|
||||
|
||||
Print output in an INI based format.
|
||||
|
||||
The following conventions are adopted:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
all key and values are UTF-8
|
||||
@item
|
||||
@samp{.} is the subgroup separator
|
||||
@item
|
||||
newline, @samp{\t}, @samp{\f}, @samp{\b} and the following characters are
|
||||
escaped
|
||||
@item
|
||||
@samp{\} is the escape character
|
||||
@item
|
||||
@samp{#} is the comment indicator
|
||||
@item
|
||||
@samp{=} is the key/value separator
|
||||
@item
|
||||
@samp{:} is not used but usually parsed as key/value separator
|
||||
@end itemize
|
||||
|
||||
This writer accepts options as a list of @var{key}=@var{value} pairs,
|
||||
separated by @samp{:}.
|
||||
|
||||
The description of the accepted options follows.
|
||||
|
||||
@table @option
|
||||
@item hierarchical, h
|
||||
Specify if the section name specification should be hierarchical. If
|
||||
set to 1, and if there is more than one section in the current
|
||||
chapter, the section name will be prefixed by the name of the
|
||||
chapter. A value of 0 will disable this behavior.
|
||||
|
||||
Default value is 1.
|
||||
@end table
|
||||
|
||||
@section json
|
||||
JSON based format.
|
||||
|
||||
Each section is printed using JSON notation.
|
||||
|
||||
The description of the accepted options follows.
|
||||
|
||||
@table @option
|
||||
|
||||
@item compact, c
|
||||
If set to 1 enable compact output, that is each section will be
|
||||
printed on a single line. Default value is 0.
|
||||
@end table
|
||||
|
||||
For more information about JSON, see @url{http://www.json.org/}.
|
||||
|
||||
@section xml
|
||||
XML based format.
|
||||
|
||||
The XML output is described in the XML schema description file
|
||||
@file{ffprobe.xsd} installed in the FFmpeg datadir.
|
||||
|
||||
An updated version of the schema can be retrieved at the url
|
||||
@url{http://www.ffmpeg.org/schema/ffprobe.xsd}, which redirects to the
|
||||
latest schema committed into the FFmpeg development source code tree.
|
||||
|
||||
Note that the output issued will be compliant to the
|
||||
@file{ffprobe.xsd} schema only when no special global output options
|
||||
(@option{unit}, @option{prefix}, @option{byte_binary_prefix},
|
||||
@option{sexagesimal} etc.) are specified.
|
||||
|
||||
The description of the accepted options follows.
|
||||
|
||||
@table @option
|
||||
|
||||
@item fully_qualified, q
|
||||
If set to 1 specify if the output should be fully qualified. Default
|
||||
value is 0.
|
||||
This is required for generating an XML file which can be validated
|
||||
through an XSD file.
|
||||
|
||||
@item xsd_strict, x
|
||||
If set to 1 perform more checks for ensuring that the output is XSD
|
||||
compliant. Default value is 0.
|
||||
This option automatically sets @option{fully_qualified} to 1.
|
||||
@end table
|
||||
|
||||
For more information about the XML format, see
|
||||
@url{https://www.w3.org/XML/}.
|
||||
@c man end WRITERS
|
||||
|
||||
@chapter Timecode
|
||||
@c man begin TIMECODE
|
||||
|
||||
@command{ffprobe} supports Timecode extraction:
|
||||
|
||||
@itemize
|
||||
|
||||
@item
|
||||
MPEG1/2 timecode is extracted from the GOP, and is available in the video
|
||||
stream details (@option{-show_streams}, see @var{timecode}).
|
||||
|
||||
@item
|
||||
MOV timecode is extracted from tmcd track, so is available in the tmcd
|
||||
stream metadata (@option{-show_streams}, see @var{TAG:timecode}).
|
||||
|
||||
@item
|
||||
DV, GXF and AVI timecodes are available in format metadata
|
||||
(@option{-show_format}, see @var{TAG:timecode}).
|
||||
|
||||
@end itemize
|
||||
@c man end TIMECODE
|
||||
|
||||
@include config.texi
|
||||
@ifset config-all
|
||||
@set config-readonly
|
||||
@ifset config-avutil
|
||||
@include utils.texi
|
||||
@end ifset
|
||||
@ifset config-avcodec
|
||||
@include codecs.texi
|
||||
@include bitstream_filters.texi
|
||||
@end ifset
|
||||
@ifset config-avformat
|
||||
@include formats.texi
|
||||
@include protocols.texi
|
||||
@end ifset
|
||||
@ifset config-avdevice
|
||||
@include devices.texi
|
||||
@end ifset
|
||||
@ifset config-swresample
|
||||
@include resampler.texi
|
||||
@end ifset
|
||||
@ifset config-swscale
|
||||
@include scaler.texi
|
||||
@end ifset
|
||||
@ifset config-avfilter
|
||||
@include filters.texi
|
||||
@end ifset
|
||||
@include general_contents.texi
|
||||
@end ifset
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@ifset config-all
|
||||
@url{ffprobe.html,ffprobe},
|
||||
@end ifset
|
||||
@ifset config-not-all
|
||||
@url{ffprobe-all.html,ffprobe-all},
|
||||
@end ifset
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay},
|
||||
@url{ffmpeg-utils.html,ffmpeg-utils},
|
||||
@url{ffmpeg-scaler.html,ffmpeg-scaler},
|
||||
@url{ffmpeg-resampler.html,ffmpeg-resampler},
|
||||
@url{ffmpeg-codecs.html,ffmpeg-codecs},
|
||||
@url{ffmpeg-bitstream-filters.html,ffmpeg-bitstream-filters},
|
||||
@url{ffmpeg-formats.html,ffmpeg-formats},
|
||||
@url{ffmpeg-devices.html,ffmpeg-devices},
|
||||
@url{ffmpeg-protocols.html,ffmpeg-protocols},
|
||||
@url{ffmpeg-filters.html,ffmpeg-filters}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
@ifset config-all
|
||||
ffprobe(1),
|
||||
@end ifset
|
||||
@ifset config-not-all
|
||||
ffprobe-all(1),
|
||||
@end ifset
|
||||
ffmpeg(1), ffplay(1),
|
||||
ffmpeg-utils(1), ffmpeg-scaler(1), ffmpeg-resampler(1),
|
||||
ffmpeg-codecs(1), ffmpeg-bitstream-filters(1), ffmpeg-formats(1),
|
||||
ffmpeg-devices(1), ffmpeg-protocols(1), ffmpeg-filters(1)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffprobe
|
||||
@settitle ffprobe media prober
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
Vendored
+386
@@ -0,0 +1,386 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://www.ffmpeg.org/schema/ffprobe"
|
||||
xmlns:ffprobe="http://www.ffmpeg.org/schema/ffprobe">
|
||||
|
||||
<xsd:element name="ffprobe" type="ffprobe:ffprobeType"/>
|
||||
|
||||
<xsd:complexType name="ffprobeType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="program_version" type="ffprobe:programVersionType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="library_versions" type="ffprobe:libraryVersionsType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="pixel_formats" type="ffprobe:pixelFormatsType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="packets" type="ffprobe:packetsType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="frames" type="ffprobe:framesType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="packets_and_frames" type="ffprobe:packetsAndFramesType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="programs" type="ffprobe:programsType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="streams" type="ffprobe:streamsType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="chapters" type="ffprobe:chaptersType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="format" type="ffprobe:formatType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="error" type="ffprobe:errorType" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="packetsType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="packet" type="ffprobe:packetType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="framesType">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="frame" type="ffprobe:frameType"/>
|
||||
<xsd:element name="subtitle" type="ffprobe:subtitleType"/>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="packetsAndFramesType">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="packet" type="ffprobe:packetType"/>
|
||||
<xsd:element name="frame" type="ffprobe:frameType"/>
|
||||
<xsd:element name="subtitle" type="ffprobe:subtitleType"/>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="packetType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="side_data_list" type="ffprobe:packetSideDataListType" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="codec_type" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="stream_index" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="pts" type="xsd:long" />
|
||||
<xsd:attribute name="pts_time" type="xsd:float" />
|
||||
<xsd:attribute name="dts" type="xsd:long" />
|
||||
<xsd:attribute name="dts_time" type="xsd:float" />
|
||||
<xsd:attribute name="duration" type="xsd:long" />
|
||||
<xsd:attribute name="duration_time" type="xsd:float" />
|
||||
<xsd:attribute name="size" type="xsd:long" use="required" />
|
||||
<xsd:attribute name="pos" type="xsd:long" />
|
||||
<xsd:attribute name="flags" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="data" type="xsd:string" />
|
||||
<xsd:attribute name="data_hash" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="packetSideDataListType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="side_data" type="ffprobe:packetSideDataType" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="packetSideDataType">
|
||||
<xsd:attribute name="side_data_type" type="xsd:string"/>
|
||||
<xsd:attribute name="side_data_size" type="xsd:int" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="frameType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="logs" type="ffprobe:logsType" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="side_data_list" type="ffprobe:frameSideDataListType" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="media_type" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="stream_index" type="xsd:int" />
|
||||
<xsd:attribute name="key_frame" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="pts" type="xsd:long" />
|
||||
<xsd:attribute name="pts_time" type="xsd:float"/>
|
||||
<xsd:attribute name="pkt_dts" type="xsd:long" />
|
||||
<xsd:attribute name="pkt_dts_time" type="xsd:float"/>
|
||||
<xsd:attribute name="best_effort_timestamp" type="xsd:long" />
|
||||
<xsd:attribute name="best_effort_timestamp_time" type="xsd:float" />
|
||||
<xsd:attribute name="pkt_duration" type="xsd:long" />
|
||||
<xsd:attribute name="pkt_duration_time" type="xsd:float"/>
|
||||
<xsd:attribute name="pkt_pos" type="xsd:long" />
|
||||
<xsd:attribute name="pkt_size" type="xsd:int" />
|
||||
|
||||
<!-- audio attributes -->
|
||||
<xsd:attribute name="sample_fmt" type="xsd:string"/>
|
||||
<xsd:attribute name="nb_samples" type="xsd:long" />
|
||||
<xsd:attribute name="channels" type="xsd:int" />
|
||||
<xsd:attribute name="channel_layout" type="xsd:string"/>
|
||||
|
||||
<!-- video attributes -->
|
||||
<xsd:attribute name="width" type="xsd:long" />
|
||||
<xsd:attribute name="height" type="xsd:long" />
|
||||
<xsd:attribute name="pix_fmt" type="xsd:string"/>
|
||||
<xsd:attribute name="sample_aspect_ratio" type="xsd:string"/>
|
||||
<xsd:attribute name="pict_type" type="xsd:string"/>
|
||||
<xsd:attribute name="coded_picture_number" type="xsd:long" />
|
||||
<xsd:attribute name="display_picture_number" type="xsd:long" />
|
||||
<xsd:attribute name="interlaced_frame" type="xsd:int" />
|
||||
<xsd:attribute name="top_field_first" type="xsd:int" />
|
||||
<xsd:attribute name="repeat_pict" type="xsd:int" />
|
||||
<xsd:attribute name="color_range" type="xsd:string"/>
|
||||
<xsd:attribute name="color_space" type="xsd:string"/>
|
||||
<xsd:attribute name="color_primaries" type="xsd:string"/>
|
||||
<xsd:attribute name="color_transfer" type="xsd:string"/>
|
||||
<xsd:attribute name="chroma_location" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="logsType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="log" type="ffprobe:logType" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="logType">
|
||||
<xsd:attribute name="context" type="xsd:string"/>
|
||||
<xsd:attribute name="level" type="xsd:int" />
|
||||
<xsd:attribute name="category" type="xsd:int" />
|
||||
<xsd:attribute name="parent_context" type="xsd:string"/>
|
||||
<xsd:attribute name="parent_category" type="xsd:int" />
|
||||
<xsd:attribute name="message" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="frameSideDataListType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="side_data" type="ffprobe:frameSideDataType" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="frameSideDataType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="timecodes" type="ffprobe:frameSideDataTimecodeList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="side_data_type" type="xsd:string"/>
|
||||
<xsd:attribute name="side_data_size" type="xsd:int" />
|
||||
<xsd:attribute name="timecode" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="frameSideDataTimecodeList">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="timecode" type="ffprobe:frameSideDataTimecodeType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="frameSideDataTimecodeType">
|
||||
<xsd:attribute name="value" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="subtitleType">
|
||||
<xsd:attribute name="media_type" type="xsd:string" fixed="subtitle" use="required"/>
|
||||
<xsd:attribute name="pts" type="xsd:long" />
|
||||
<xsd:attribute name="pts_time" type="xsd:float"/>
|
||||
<xsd:attribute name="format" type="xsd:int" />
|
||||
<xsd:attribute name="start_display_time" type="xsd:int" />
|
||||
<xsd:attribute name="end_display_time" type="xsd:int" />
|
||||
<xsd:attribute name="num_rects" type="xsd:int" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="streamsType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="stream" type="ffprobe:streamType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="programsType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="program" type="ffprobe:programType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="streamDispositionType">
|
||||
<xsd:attribute name="default" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="dub" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="original" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="comment" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="lyrics" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="karaoke" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="forced" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="hearing_impaired" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="visual_impaired" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="clean_effects" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="attached_pic" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="timed_thumbnails" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="captions" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="descriptions" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="metadata" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="dependent" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="still_image" type="xsd:int" use="required" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="streamType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="disposition" type="ffprobe:streamDispositionType" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="side_data_list" type="ffprobe:packetSideDataListType" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="index" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="codec_name" type="xsd:string" />
|
||||
<xsd:attribute name="codec_long_name" type="xsd:string" />
|
||||
<xsd:attribute name="profile" type="xsd:string" />
|
||||
<xsd:attribute name="codec_type" type="xsd:string" />
|
||||
<xsd:attribute name="codec_tag" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="codec_tag_string" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="extradata" type="xsd:string" />
|
||||
<xsd:attribute name="extradata_size" type="xsd:int" />
|
||||
<xsd:attribute name="extradata_hash" type="xsd:string" />
|
||||
|
||||
<!-- video attributes -->
|
||||
<xsd:attribute name="width" type="xsd:int"/>
|
||||
<xsd:attribute name="height" type="xsd:int"/>
|
||||
<xsd:attribute name="coded_width" type="xsd:int"/>
|
||||
<xsd:attribute name="coded_height" type="xsd:int"/>
|
||||
<xsd:attribute name="closed_captions" type="xsd:boolean"/>
|
||||
<xsd:attribute name="film_grain" type="xsd:boolean"/>
|
||||
<xsd:attribute name="has_b_frames" type="xsd:int"/>
|
||||
<xsd:attribute name="sample_aspect_ratio" type="xsd:string"/>
|
||||
<xsd:attribute name="display_aspect_ratio" type="xsd:string"/>
|
||||
<xsd:attribute name="pix_fmt" type="xsd:string"/>
|
||||
<xsd:attribute name="level" type="xsd:int"/>
|
||||
<xsd:attribute name="color_range" type="xsd:string"/>
|
||||
<xsd:attribute name="color_space" type="xsd:string"/>
|
||||
<xsd:attribute name="color_transfer" type="xsd:string"/>
|
||||
<xsd:attribute name="color_primaries" type="xsd:string"/>
|
||||
<xsd:attribute name="chroma_location" type="xsd:string"/>
|
||||
<xsd:attribute name="field_order" type="xsd:string"/>
|
||||
<xsd:attribute name="refs" type="xsd:int"/>
|
||||
|
||||
<!-- audio attributes -->
|
||||
<xsd:attribute name="sample_fmt" type="xsd:string"/>
|
||||
<xsd:attribute name="sample_rate" type="xsd:int"/>
|
||||
<xsd:attribute name="channels" type="xsd:int"/>
|
||||
<xsd:attribute name="channel_layout" type="xsd:string"/>
|
||||
<xsd:attribute name="bits_per_sample" type="xsd:int"/>
|
||||
|
||||
<xsd:attribute name="id" type="xsd:string"/>
|
||||
<xsd:attribute name="r_frame_rate" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="avg_frame_rate" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="time_base" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="start_pts" type="xsd:long"/>
|
||||
<xsd:attribute name="start_time" type="xsd:float"/>
|
||||
<xsd:attribute name="duration_ts" type="xsd:long"/>
|
||||
<xsd:attribute name="duration" type="xsd:float"/>
|
||||
<xsd:attribute name="bit_rate" type="xsd:int"/>
|
||||
<xsd:attribute name="max_bit_rate" type="xsd:int"/>
|
||||
<xsd:attribute name="bits_per_raw_sample" type="xsd:int"/>
|
||||
<xsd:attribute name="nb_frames" type="xsd:int"/>
|
||||
<xsd:attribute name="nb_read_frames" type="xsd:int"/>
|
||||
<xsd:attribute name="nb_read_packets" type="xsd:int"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="programType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="streams" type="ffprobe:streamsType" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="program_id" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="program_num" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="nb_streams" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="pmt_pid" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="pcr_pid" type="xsd:int" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="formatType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="filename" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="nb_streams" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="nb_programs" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="format_name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="format_long_name" type="xsd:string"/>
|
||||
<xsd:attribute name="start_time" type="xsd:float"/>
|
||||
<xsd:attribute name="duration" type="xsd:float"/>
|
||||
<xsd:attribute name="size" type="xsd:long"/>
|
||||
<xsd:attribute name="bit_rate" type="xsd:long"/>
|
||||
<xsd:attribute name="probe_score" type="xsd:int"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="tagType">
|
||||
<xsd:attribute name="key" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="value" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="errorType">
|
||||
<xsd:attribute name="code" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="string" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="programVersionType">
|
||||
<xsd:attribute name="version" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="copyright" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="build_date" type="xsd:string"/>
|
||||
<xsd:attribute name="build_time" type="xsd:string"/>
|
||||
<xsd:attribute name="compiler_ident" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="configuration" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="chaptersType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="chapter" type="ffprobe:chapterType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="chapterType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="id" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="time_base" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="start" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="start_time" type="xsd:float"/>
|
||||
<xsd:attribute name="end" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="end_time" type="xsd:float" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="libraryVersionType">
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="major" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="minor" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="micro" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="version" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="ident" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="libraryVersionsType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="library_version" type="ffprobe:libraryVersionType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="pixelFormatFlagsType">
|
||||
<xsd:attribute name="big_endian" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="palette" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="bitstream" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="hwaccel" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="planar" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="rgb" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="alpha" type="xsd:int" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="pixelFormatComponentType">
|
||||
<xsd:attribute name="index" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="bit_depth" type="xsd:int" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="pixelFormatComponentsType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="component" type="ffprobe:pixelFormatComponentType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="pixelFormatType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="flags" type="ffprobe:pixelFormatFlagsType" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="components" type="ffprobe:pixelFormatComponentsType" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="nb_components" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="log2_chroma_w" type="xsd:int"/>
|
||||
<xsd:attribute name="log2_chroma_h" type="xsd:int"/>
|
||||
<xsd:attribute name="bits_per_pixel" type="xsd:int"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="pixelFormatsType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="pixel_format" type="ffprobe:pixelFormatType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
+411
@@ -0,0 +1,411 @@
|
||||
All the numerical options, if not specified otherwise, accept a string
|
||||
representing a number as input, which may be followed by one of the SI
|
||||
unit prefixes, for example: 'K', 'M', or 'G'.
|
||||
|
||||
If 'i' is appended to the SI unit prefix, the complete prefix will be
|
||||
interpreted as a unit prefix for binary multiples, which are based on
|
||||
powers of 1024 instead of powers of 1000. Appending 'B' to the SI unit
|
||||
prefix multiplies the value by 8. This allows using, for example:
|
||||
'KB', 'MiB', 'G' and 'B' as number suffixes.
|
||||
|
||||
Options which do not take arguments are boolean options, and set the
|
||||
corresponding value to true. They can be set to false by prefixing
|
||||
the option name with "no". For example using "-nofoo"
|
||||
will set the boolean option with name "foo" to false.
|
||||
|
||||
@anchor{Stream specifiers}
|
||||
@section Stream specifiers
|
||||
Some options are applied per-stream, e.g. bitrate or codec. Stream specifiers
|
||||
are used to precisely specify which stream(s) a given option belongs to.
|
||||
|
||||
A stream specifier is a string generally appended to the option name and
|
||||
separated from it by a colon. E.g. @code{-codec:a:1 ac3} contains the
|
||||
@code{a:1} stream specifier, which matches the second audio stream. Therefore, it
|
||||
would select the ac3 codec for the second audio stream.
|
||||
|
||||
A stream specifier can match several streams, so that the option is applied to all
|
||||
of them. E.g. the stream specifier in @code{-b:a 128k} matches all audio
|
||||
streams.
|
||||
|
||||
An empty stream specifier matches all streams. For example, @code{-codec copy}
|
||||
or @code{-codec: copy} would copy all the streams without reencoding.
|
||||
|
||||
Possible forms of stream specifiers are:
|
||||
@table @option
|
||||
@item @var{stream_index}
|
||||
Matches the stream with this index. E.g. @code{-threads:1 4} would set the
|
||||
thread count for the second stream to 4. If @var{stream_index} is used as an
|
||||
additional stream specifier (see below), then it selects stream number
|
||||
@var{stream_index} from the matching streams. Stream numbering is based on the
|
||||
order of the streams as detected by libavformat except when a program ID is
|
||||
also specified. In this case it is based on the ordering of the streams in the
|
||||
program.
|
||||
@item @var{stream_type}[:@var{additional_stream_specifier}]
|
||||
@var{stream_type} is one of following: 'v' or 'V' for video, 'a' for audio, 's'
|
||||
for subtitle, 'd' for data, and 't' for attachments. 'v' matches all video
|
||||
streams, 'V' only matches video streams which are not attached pictures, video
|
||||
thumbnails or cover arts. If @var{additional_stream_specifier} is used, then
|
||||
it matches streams which both have this type and match the
|
||||
@var{additional_stream_specifier}. Otherwise, it matches all streams of the
|
||||
specified type.
|
||||
@item p:@var{program_id}[:@var{additional_stream_specifier}]
|
||||
Matches streams which are in the program with the id @var{program_id}. If
|
||||
@var{additional_stream_specifier} is used, then it matches streams which both
|
||||
are part of the program and match the @var{additional_stream_specifier}.
|
||||
|
||||
@item #@var{stream_id} or i:@var{stream_id}
|
||||
Match the stream by stream id (e.g. PID in MPEG-TS container).
|
||||
@item m:@var{key}[:@var{value}]
|
||||
Matches streams with the metadata tag @var{key} having the specified value. If
|
||||
@var{value} is not given, matches streams that contain the given tag with any
|
||||
value.
|
||||
@item u
|
||||
Matches streams with usable configuration, the codec must be defined and the
|
||||
essential information such as video dimension or audio sample rate must be present.
|
||||
|
||||
Note that in @command{ffmpeg}, matching by metadata will only work properly for
|
||||
input files.
|
||||
@end table
|
||||
|
||||
@section Generic options
|
||||
|
||||
These options are shared amongst the ff* tools.
|
||||
|
||||
@table @option
|
||||
|
||||
@item -L
|
||||
Show license.
|
||||
|
||||
@item -h, -?, -help, --help [@var{arg}]
|
||||
Show help. An optional parameter may be specified to print help about a specific
|
||||
item. If no argument is specified, only basic (non advanced) tool
|
||||
options are shown.
|
||||
|
||||
Possible values of @var{arg} are:
|
||||
@table @option
|
||||
@item long
|
||||
Print advanced tool options in addition to the basic tool options.
|
||||
|
||||
@item full
|
||||
Print complete list of options, including shared and private options
|
||||
for encoders, decoders, demuxers, muxers, filters, etc.
|
||||
|
||||
@item decoder=@var{decoder_name}
|
||||
Print detailed information about the decoder named @var{decoder_name}. Use the
|
||||
@option{-decoders} option to get a list of all decoders.
|
||||
|
||||
@item encoder=@var{encoder_name}
|
||||
Print detailed information about the encoder named @var{encoder_name}. Use the
|
||||
@option{-encoders} option to get a list of all encoders.
|
||||
|
||||
@item demuxer=@var{demuxer_name}
|
||||
Print detailed information about the demuxer named @var{demuxer_name}. Use the
|
||||
@option{-formats} option to get a list of all demuxers and muxers.
|
||||
|
||||
@item muxer=@var{muxer_name}
|
||||
Print detailed information about the muxer named @var{muxer_name}. Use the
|
||||
@option{-formats} option to get a list of all muxers and demuxers.
|
||||
|
||||
@item filter=@var{filter_name}
|
||||
Print detailed information about the filter named @var{filter_name}. Use the
|
||||
@option{-filters} option to get a list of all filters.
|
||||
|
||||
@item bsf=@var{bitstream_filter_name}
|
||||
Print detailed information about the bitstream filter named @var{bitstream_filter_name}.
|
||||
Use the @option{-bsfs} option to get a list of all bitstream filters.
|
||||
|
||||
@item protocol=@var{protocol_name}
|
||||
Print detailed information about the protocol named @var{protocol_name}.
|
||||
Use the @option{-protocols} option to get a list of all protocols.
|
||||
@end table
|
||||
|
||||
@item -version
|
||||
Show version.
|
||||
|
||||
@item -buildconf
|
||||
Show the build configuration, one option per line.
|
||||
|
||||
@item -formats
|
||||
Show available formats (including devices).
|
||||
|
||||
@item -demuxers
|
||||
Show available demuxers.
|
||||
|
||||
@item -muxers
|
||||
Show available muxers.
|
||||
|
||||
@item -devices
|
||||
Show available devices.
|
||||
|
||||
@item -codecs
|
||||
Show all codecs known to libavcodec.
|
||||
|
||||
Note that the term 'codec' is used throughout this documentation as a shortcut
|
||||
for what is more correctly called a media bitstream format.
|
||||
|
||||
@item -decoders
|
||||
Show available decoders.
|
||||
|
||||
@item -encoders
|
||||
Show all available encoders.
|
||||
|
||||
@item -bsfs
|
||||
Show available bitstream filters.
|
||||
|
||||
@item -protocols
|
||||
Show available protocols.
|
||||
|
||||
@item -filters
|
||||
Show available libavfilter filters.
|
||||
|
||||
@item -pix_fmts
|
||||
Show available pixel formats.
|
||||
|
||||
@item -sample_fmts
|
||||
Show available sample formats.
|
||||
|
||||
@item -layouts
|
||||
Show channel names and standard channel layouts.
|
||||
|
||||
@item -dispositions
|
||||
Show stream dispositions.
|
||||
|
||||
@item -colors
|
||||
Show recognized color names.
|
||||
|
||||
@item -sources @var{device}[,@var{opt1}=@var{val1}[,@var{opt2}=@var{val2}]...]
|
||||
Show autodetected sources of the input device.
|
||||
Some devices may provide system-dependent source names that cannot be autodetected.
|
||||
The returned list cannot be assumed to be always complete.
|
||||
@example
|
||||
ffmpeg -sources pulse,server=192.168.0.4
|
||||
@end example
|
||||
|
||||
@item -sinks @var{device}[,@var{opt1}=@var{val1}[,@var{opt2}=@var{val2}]...]
|
||||
Show autodetected sinks of the output device.
|
||||
Some devices may provide system-dependent sink names that cannot be autodetected.
|
||||
The returned list cannot be assumed to be always complete.
|
||||
@example
|
||||
ffmpeg -sinks pulse,server=192.168.0.4
|
||||
@end example
|
||||
|
||||
@item -loglevel [@var{flags}+]@var{loglevel} | -v [@var{flags}+]@var{loglevel}
|
||||
Set logging level and flags used by the library.
|
||||
|
||||
The optional @var{flags} prefix can consist of the following values:
|
||||
@table @samp
|
||||
@item repeat
|
||||
Indicates that repeated log output should not be compressed to the first line
|
||||
and the "Last message repeated n times" line will be omitted.
|
||||
@item level
|
||||
Indicates that log output should add a @code{[level]} prefix to each message
|
||||
line. This can be used as an alternative to log coloring, e.g. when dumping the
|
||||
log to file.
|
||||
@end table
|
||||
Flags can also be used alone by adding a '+'/'-' prefix to set/reset a single
|
||||
flag without affecting other @var{flags} or changing @var{loglevel}. When
|
||||
setting both @var{flags} and @var{loglevel}, a '+' separator is expected
|
||||
between the last @var{flags} value and before @var{loglevel}.
|
||||
|
||||
@var{loglevel} is a string or a number containing one of the following values:
|
||||
@table @samp
|
||||
@item quiet, -8
|
||||
Show nothing at all; be silent.
|
||||
@item panic, 0
|
||||
Only show fatal errors which could lead the process to crash, such as
|
||||
an assertion failure. This is not currently used for anything.
|
||||
@item fatal, 8
|
||||
Only show fatal errors. These are errors after which the process absolutely
|
||||
cannot continue.
|
||||
@item error, 16
|
||||
Show all errors, including ones which can be recovered from.
|
||||
@item warning, 24
|
||||
Show all warnings and errors. Any message related to possibly
|
||||
incorrect or unexpected events will be shown.
|
||||
@item info, 32
|
||||
Show informative messages during processing. This is in addition to
|
||||
warnings and errors. This is the default value.
|
||||
@item verbose, 40
|
||||
Same as @code{info}, except more verbose.
|
||||
@item debug, 48
|
||||
Show everything, including debugging information.
|
||||
@item trace, 56
|
||||
@end table
|
||||
|
||||
For example to enable repeated log output, add the @code{level} prefix, and set
|
||||
@var{loglevel} to @code{verbose}:
|
||||
@example
|
||||
ffmpeg -loglevel repeat+level+verbose -i input output
|
||||
@end example
|
||||
Another example that enables repeated log output without affecting current
|
||||
state of @code{level} prefix flag or @var{loglevel}:
|
||||
@example
|
||||
ffmpeg [...] -loglevel +repeat
|
||||
@end example
|
||||
|
||||
By default the program logs to stderr. If coloring is supported by the
|
||||
terminal, colors are used to mark errors and warnings. Log coloring
|
||||
can be disabled setting the environment variable
|
||||
@env{AV_LOG_FORCE_NOCOLOR}, or can be forced setting
|
||||
the environment variable @env{AV_LOG_FORCE_COLOR}.
|
||||
|
||||
@item -report
|
||||
Dump full command line and log output to a file named
|
||||
@code{@var{program}-@var{YYYYMMDD}-@var{HHMMSS}.log} in the current
|
||||
directory.
|
||||
This file can be useful for bug reports.
|
||||
It also implies @code{-loglevel debug}.
|
||||
|
||||
Setting the environment variable @env{FFREPORT} to any value has the
|
||||
same effect. If the value is a ':'-separated key=value sequence, these
|
||||
options will affect the report; option values must be escaped if they
|
||||
contain special characters or the options delimiter ':' (see the
|
||||
``Quoting and escaping'' section in the ffmpeg-utils manual).
|
||||
|
||||
The following options are recognized:
|
||||
@table @option
|
||||
@item file
|
||||
set the file name to use for the report; @code{%p} is expanded to the name
|
||||
of the program, @code{%t} is expanded to a timestamp, @code{%%} is expanded
|
||||
to a plain @code{%}
|
||||
@item level
|
||||
set the log verbosity level using a numerical value (see @code{-loglevel}).
|
||||
@end table
|
||||
|
||||
For example, to output a report to a file named @file{ffreport.log}
|
||||
using a log level of @code{32} (alias for log level @code{info}):
|
||||
|
||||
@example
|
||||
FFREPORT=file=ffreport.log:level=32 ffmpeg -i input output
|
||||
@end example
|
||||
|
||||
Errors in parsing the environment variable are not fatal, and will not
|
||||
appear in the report.
|
||||
|
||||
@item -hide_banner
|
||||
Suppress printing banner.
|
||||
|
||||
All FFmpeg tools will normally show a copyright notice, build options
|
||||
and library versions. This option can be used to suppress printing
|
||||
this information.
|
||||
|
||||
@item -cpuflags flags (@emph{global})
|
||||
Allows setting and clearing cpu flags. This option is intended
|
||||
for testing. Do not use it unless you know what you're doing.
|
||||
@example
|
||||
ffmpeg -cpuflags -sse+mmx ...
|
||||
ffmpeg -cpuflags mmx ...
|
||||
ffmpeg -cpuflags 0 ...
|
||||
@end example
|
||||
Possible flags for this option are:
|
||||
@table @samp
|
||||
@item x86
|
||||
@table @samp
|
||||
@item mmx
|
||||
@item mmxext
|
||||
@item sse
|
||||
@item sse2
|
||||
@item sse2slow
|
||||
@item sse3
|
||||
@item sse3slow
|
||||
@item ssse3
|
||||
@item atom
|
||||
@item sse4.1
|
||||
@item sse4.2
|
||||
@item avx
|
||||
@item avx2
|
||||
@item xop
|
||||
@item fma3
|
||||
@item fma4
|
||||
@item 3dnow
|
||||
@item 3dnowext
|
||||
@item bmi1
|
||||
@item bmi2
|
||||
@item cmov
|
||||
@end table
|
||||
@item ARM
|
||||
@table @samp
|
||||
@item armv5te
|
||||
@item armv6
|
||||
@item armv6t2
|
||||
@item vfp
|
||||
@item vfpv3
|
||||
@item neon
|
||||
@item setend
|
||||
@end table
|
||||
@item AArch64
|
||||
@table @samp
|
||||
@item armv8
|
||||
@item vfp
|
||||
@item neon
|
||||
@end table
|
||||
@item PowerPC
|
||||
@table @samp
|
||||
@item altivec
|
||||
@end table
|
||||
@item Specific Processors
|
||||
@table @samp
|
||||
@item pentium2
|
||||
@item pentium3
|
||||
@item pentium4
|
||||
@item k6
|
||||
@item k62
|
||||
@item athlon
|
||||
@item athlonxp
|
||||
@item k8
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@item -cpucount @var{count} (@emph{global})
|
||||
Override detection of CPU count. This option is intended
|
||||
for testing. Do not use it unless you know what you're doing.
|
||||
@example
|
||||
ffmpeg -cpucount 2
|
||||
@end example
|
||||
|
||||
@item -max_alloc @var{bytes}
|
||||
Set the maximum size limit for allocating a block on the heap by ffmpeg's
|
||||
family of malloc functions. Exercise @strong{extreme caution} when using
|
||||
this option. Don't use if you do not understand the full consequence of doing so.
|
||||
Default is INT_MAX.
|
||||
@end table
|
||||
|
||||
@section AVOptions
|
||||
|
||||
These options are provided directly by the libavformat, libavdevice and
|
||||
libavcodec libraries. To see the list of available AVOptions, use the
|
||||
@option{-help} option. They are separated into two categories:
|
||||
@table @option
|
||||
@item generic
|
||||
These options can be set for any container, codec or device. Generic options
|
||||
are listed under AVFormatContext options for containers/devices and under
|
||||
AVCodecContext options for codecs.
|
||||
@item private
|
||||
These options are specific to the given container, device or codec. Private
|
||||
options are listed under their corresponding containers/devices/codecs.
|
||||
@end table
|
||||
|
||||
For example to write an ID3v2.3 header instead of a default ID3v2.4 to
|
||||
an MP3 file, use the @option{id3v2_version} private option of the MP3
|
||||
muxer:
|
||||
@example
|
||||
ffmpeg -i input.flac -id3v2_version 3 out.mp3
|
||||
@end example
|
||||
|
||||
All codec AVOptions are per-stream, and thus a stream specifier
|
||||
should be attached to them:
|
||||
@example
|
||||
ffmpeg -i multichannel.mxf -map 0:v:0 -map 0:a:0 -map 0:a:0 -c:a:0 ac3 -b:a:0 640k -ac:a:1 2 -c:a:1 aac -b:2 128k out.mp4
|
||||
@end example
|
||||
|
||||
In the above example, a multichannel audio stream is mapped twice for output.
|
||||
The first instance is encoded with codec ac3 and bitrate 640k.
|
||||
The second instance is downmixed to 2 channels and encoded with codec aac. A bitrate of 128k is specified for it using
|
||||
absolute index of the output stream.
|
||||
|
||||
Note: the @option{-nooption} syntax cannot be used for boolean
|
||||
AVOptions, use @option{-option 0}/@option{-option 1}.
|
||||
|
||||
Note: the old undocumented way of specifying per-stream AVOptions by
|
||||
prepending v/a/s to the options name is now obsolete and will be
|
||||
removed soon.
|
||||
Vendored
+288
@@ -0,0 +1,288 @@
|
||||
Filter design
|
||||
=============
|
||||
|
||||
This document explains guidelines that should be observed (or ignored with
|
||||
good reason) when writing filters for libavfilter.
|
||||
|
||||
In this document, the word “frame” indicates either a video frame or a group
|
||||
of audio samples, as stored in an AVFrame structure.
|
||||
|
||||
|
||||
Format negotiation
|
||||
==================
|
||||
|
||||
The query_formats method should set, for each input and each output links,
|
||||
the list of supported formats.
|
||||
|
||||
For video links, that means pixel format. For audio links, that means
|
||||
channel layout, sample format (the sample packing is implied by the sample
|
||||
format) and sample rate.
|
||||
|
||||
The lists are not just lists, they are references to shared objects. When
|
||||
the negotiation mechanism computes the intersection of the formats
|
||||
supported at each end of a link, all references to both lists are replaced
|
||||
with a reference to the intersection. And when a single format is
|
||||
eventually chosen for a link amongst the remaining list, again, all
|
||||
references to the list are updated.
|
||||
|
||||
That means that if a filter requires that its input and output have the
|
||||
same format amongst a supported list, all it has to do is use a reference
|
||||
to the same list of formats.
|
||||
|
||||
query_formats can leave some formats unset and return AVERROR(EAGAIN) to
|
||||
cause the negotiation mechanism to try again later. That can be used by
|
||||
filters with complex requirements to use the format negotiated on one link
|
||||
to set the formats supported on another.
|
||||
|
||||
|
||||
Frame references ownership and permissions
|
||||
==========================================
|
||||
|
||||
Principle
|
||||
---------
|
||||
|
||||
Audio and video data are voluminous; the frame and frame reference
|
||||
mechanism is intended to avoid, as much as possible, expensive copies of
|
||||
that data while still allowing the filters to produce correct results.
|
||||
|
||||
The data is stored in buffers represented by AVFrame structures.
|
||||
Several references can point to the same frame buffer; the buffer is
|
||||
automatically deallocated once all corresponding references have been
|
||||
destroyed.
|
||||
|
||||
The characteristics of the data (resolution, sample rate, etc.) are
|
||||
stored in the reference; different references for the same buffer can
|
||||
show different characteristics. In particular, a video reference can
|
||||
point to only a part of a video buffer.
|
||||
|
||||
A reference is usually obtained as input to the filter_frame method or
|
||||
requested using the ff_get_video_buffer or ff_get_audio_buffer
|
||||
functions. A new reference on an existing buffer can be created with
|
||||
av_frame_ref(). A reference is destroyed using
|
||||
the av_frame_free() function.
|
||||
|
||||
Reference ownership
|
||||
-------------------
|
||||
|
||||
At any time, a reference “belongs” to a particular piece of code,
|
||||
usually a filter. With a few caveats that will be explained below, only
|
||||
that piece of code is allowed to access it. It is also responsible for
|
||||
destroying it, although this is sometimes done automatically (see the
|
||||
section on link reference fields).
|
||||
|
||||
Here are the (fairly obvious) rules for reference ownership:
|
||||
|
||||
* A reference received by the filter_frame method belongs to the
|
||||
corresponding filter.
|
||||
|
||||
* A reference passed to ff_filter_frame is given away and must no longer
|
||||
be used.
|
||||
|
||||
* A reference created with av_frame_ref() belongs to the code that
|
||||
created it.
|
||||
|
||||
* A reference obtained with ff_get_video_buffer or ff_get_audio_buffer
|
||||
belongs to the code that requested it.
|
||||
|
||||
* A reference given as return value by the get_video_buffer or
|
||||
get_audio_buffer method is given away and must no longer be used.
|
||||
|
||||
Link reference fields
|
||||
---------------------
|
||||
|
||||
The AVFilterLink structure has a few AVFrame fields.
|
||||
|
||||
partial_buf is used by libavfilter internally and must not be accessed
|
||||
by filters.
|
||||
|
||||
fifo contains frames queued in the filter's input. They belong to the
|
||||
framework until they are taken by the filter.
|
||||
|
||||
Reference permissions
|
||||
---------------------
|
||||
|
||||
Since the same frame data can be shared by several frames, modifying may
|
||||
have unintended consequences. A frame is considered writable if only one
|
||||
reference to it exists. The code owning that reference it then allowed
|
||||
to modify the data.
|
||||
|
||||
A filter can check if a frame is writable by using the
|
||||
av_frame_is_writable() function.
|
||||
|
||||
A filter can ensure that a frame is writable at some point of the code
|
||||
by using the ff_inlink_make_frame_writable() function. It will duplicate
|
||||
the frame if needed.
|
||||
|
||||
A filter can ensure that the frame passed to the filter_frame() callback
|
||||
is writable by setting the needs_writable flag on the corresponding
|
||||
input pad. It does not apply to the activate() callback.
|
||||
|
||||
|
||||
Frame scheduling
|
||||
================
|
||||
|
||||
The purpose of these rules is to ensure that frames flow in the filter
|
||||
graph without getting stuck and accumulating somewhere.
|
||||
|
||||
Simple filters that output one frame for each input frame should not have
|
||||
to worry about it.
|
||||
|
||||
There are two design for filters: one using the filter_frame() and
|
||||
request_frame() callbacks and the other using the activate() callback.
|
||||
|
||||
The design using filter_frame() and request_frame() is legacy, but it is
|
||||
suitable for filters that have a single input and process one frame at a
|
||||
time. New filters with several inputs, that treat several frames at a time
|
||||
or that require a special treatment at EOF should probably use the design
|
||||
using activate().
|
||||
|
||||
activate
|
||||
--------
|
||||
|
||||
This method is called when something must be done in a filter; the
|
||||
definition of that "something" depends on the semantic of the filter.
|
||||
|
||||
The callback must examine the status of the filter's links and proceed
|
||||
accordingly.
|
||||
|
||||
The status of output links is stored in the frame_wanted_out, status_in
|
||||
and status_out fields and tested by the ff_outlink_frame_wanted()
|
||||
function. If this function returns true, then the processing requires a
|
||||
frame on this link and the filter is expected to make efforts in that
|
||||
direction.
|
||||
|
||||
The status of input links is stored by the status_in, fifo and
|
||||
status_out fields; they must not be accessed directly. The fifo field
|
||||
contains the frames that are queued in the input for processing by the
|
||||
filter. The status_in and status_out fields contains the queued status
|
||||
(EOF or error) of the link; status_in is a status change that must be
|
||||
taken into account after all frames in fifo have been processed;
|
||||
status_out is the status that have been taken into account, it is final
|
||||
when it is not 0.
|
||||
|
||||
The typical task of an activate callback is to first check the backward
|
||||
status of output links, and if relevant forward it to the corresponding
|
||||
input. Then, if relevant, for each input link: test the availability of
|
||||
frames in fifo and process them; if no frame is available, test and
|
||||
acknowledge a change of status using ff_inlink_acknowledge_status(); and
|
||||
forward the result (frame or status change) to the corresponding input.
|
||||
If nothing is possible, test the status of outputs and forward it to the
|
||||
corresponding input(s). If still not possible, return FFERROR_NOT_READY.
|
||||
|
||||
If the filters stores internally one or a few frame for some input, it
|
||||
can consider them to be part of the FIFO and delay acknowledging a
|
||||
status change accordingly.
|
||||
|
||||
Example code:
|
||||
|
||||
ret = ff_outlink_get_status(outlink);
|
||||
if (ret) {
|
||||
ff_inlink_set_status(inlink, ret);
|
||||
return 0;
|
||||
}
|
||||
if (priv->next_frame) {
|
||||
/* use it */
|
||||
return 0;
|
||||
}
|
||||
ret = ff_inlink_consume_frame(inlink, &frame);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret) {
|
||||
/* use it */
|
||||
return 0;
|
||||
}
|
||||
ret = ff_inlink_acknowledge_status(inlink, &status, &pts);
|
||||
if (ret) {
|
||||
/* flush */
|
||||
ff_outlink_set_status(outlink, status, pts);
|
||||
return 0;
|
||||
}
|
||||
if (ff_outlink_frame_wanted(outlink)) {
|
||||
ff_inlink_request_frame(inlink);
|
||||
return 0;
|
||||
}
|
||||
return FFERROR_NOT_READY;
|
||||
|
||||
The exact code depends on how similar the /* use it */ blocks are and
|
||||
how related they are to the /* flush */ block, and needs to apply these
|
||||
operations to the correct inlink or outlink if there are several.
|
||||
|
||||
Macros are available to factor that when no extra processing is needed:
|
||||
|
||||
FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
|
||||
FF_FILTER_FORWARD_STATUS_ALL(outlink, filter);
|
||||
FF_FILTER_FORWARD_STATUS(inlink, outlink);
|
||||
FF_FILTER_FORWARD_STATUS_ALL(inlink, filter);
|
||||
FF_FILTER_FORWARD_WANTED(outlink, inlink);
|
||||
|
||||
filter_frame
|
||||
------------
|
||||
|
||||
For filters that do not use the activate() callback, this method is
|
||||
called when a frame is pushed to the filter's input. It can be called at
|
||||
any time except in a reentrant way.
|
||||
|
||||
If the input frame is enough to produce output, then the filter should
|
||||
push the output frames on the output link immediately.
|
||||
|
||||
As an exception to the previous rule, if the input frame is enough to
|
||||
produce several output frames, then the filter needs output only at
|
||||
least one per link. The additional frames can be left buffered in the
|
||||
filter; these buffered frames must be flushed immediately if a new input
|
||||
produces new output.
|
||||
|
||||
(Example: frame rate-doubling filter: filter_frame must (1) flush the
|
||||
second copy of the previous frame, if it is still there, (2) push the
|
||||
first copy of the incoming frame, (3) keep the second copy for later.)
|
||||
|
||||
If the input frame is not enough to produce output, the filter must not
|
||||
call request_frame to get more. It must just process the frame or queue
|
||||
it. The task of requesting more frames is left to the filter's
|
||||
request_frame method or the application.
|
||||
|
||||
If a filter has several inputs, the filter must be ready for frames
|
||||
arriving randomly on any input. Therefore, any filter with several inputs
|
||||
will most likely require some kind of queuing mechanism. It is perfectly
|
||||
acceptable to have a limited queue and to drop frames when the inputs
|
||||
are too unbalanced.
|
||||
|
||||
request_frame
|
||||
-------------
|
||||
|
||||
For filters that do not use the activate() callback, this method is
|
||||
called when a frame is wanted on an output.
|
||||
|
||||
For a source, it should directly call filter_frame on the corresponding
|
||||
output.
|
||||
|
||||
For a filter, if there are queued frames already ready, one of these
|
||||
frames should be pushed. If not, the filter should request a frame on
|
||||
one of its inputs, repeatedly until at least one frame has been pushed.
|
||||
|
||||
Return values:
|
||||
if request_frame could produce a frame, or at least make progress
|
||||
towards producing a frame, it should return 0;
|
||||
if it could not for temporary reasons, it should return AVERROR(EAGAIN);
|
||||
if it could not because there are no more frames, it should return
|
||||
AVERROR_EOF.
|
||||
|
||||
The typical implementation of request_frame for a filter with several
|
||||
inputs will look like that:
|
||||
|
||||
if (frames_queued) {
|
||||
push_one_frame();
|
||||
return 0;
|
||||
}
|
||||
input = input_where_a_frame_is_most_needed();
|
||||
ret = ff_request_frame(input);
|
||||
if (ret == AVERROR_EOF) {
|
||||
process_eof_on_input();
|
||||
} else if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
||||
Note that, except for filters that can have queued frames and sources,
|
||||
request_frame does not push frames: it requests them to its input, and
|
||||
as a reaction, the filter_frame method possibly will be called and do
|
||||
the work.
|
||||
Vendored
+28632
File diff suppressed because it is too large
Load Diff
Vendored
+272
@@ -0,0 +1,272 @@
|
||||
@chapter Format Options
|
||||
@c man begin FORMAT OPTIONS
|
||||
|
||||
The libavformat library provides some generic global options, which
|
||||
can be set on all the muxers and demuxers. In addition each muxer or
|
||||
demuxer may support so-called private options, which are specific for
|
||||
that component.
|
||||
|
||||
Options may be set by specifying -@var{option} @var{value} in the
|
||||
FFmpeg tools, or by setting the value explicitly in the
|
||||
@code{AVFormatContext} options or using the @file{libavutil/opt.h} API
|
||||
for programmatic use.
|
||||
|
||||
The list of supported options follows:
|
||||
|
||||
@table @option
|
||||
@item avioflags @var{flags} (@emph{input/output})
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item direct
|
||||
Reduce buffering.
|
||||
@end table
|
||||
|
||||
@item probesize @var{integer} (@emph{input})
|
||||
Set probing size in bytes, i.e. the size of the data to analyze to get
|
||||
stream information. A higher value will enable detecting more
|
||||
information in case it is dispersed into the stream, but will increase
|
||||
latency. Must be an integer not lesser than 32. It is 5000000 by default.
|
||||
|
||||
@item max_probe_packets @var{integer} (@emph{input})
|
||||
Set the maximum number of buffered packets when probing a codec.
|
||||
Default is 2500 packets.
|
||||
|
||||
@item packetsize @var{integer} (@emph{output})
|
||||
Set packet size.
|
||||
|
||||
@item fflags @var{flags}
|
||||
Set format flags. Some are implemented for a limited number of formats.
|
||||
|
||||
Possible values for input files:
|
||||
@table @samp
|
||||
@item discardcorrupt
|
||||
Discard corrupted packets.
|
||||
@item fastseek
|
||||
Enable fast, but inaccurate seeks for some formats.
|
||||
@item genpts
|
||||
Generate missing PTS if DTS is present.
|
||||
@item igndts
|
||||
Ignore DTS if PTS is set. Inert when nofillin is set.
|
||||
@item ignidx
|
||||
Ignore index.
|
||||
@item nobuffer
|
||||
Reduce the latency introduced by buffering during initial input streams analysis.
|
||||
@item nofillin
|
||||
Do not fill in missing values in packet fields that can be exactly calculated.
|
||||
@item noparse
|
||||
Disable AVParsers, this needs @code{+nofillin} too.
|
||||
@item sortdts
|
||||
Try to interleave output packets by DTS. At present, available only for AVIs with an index.
|
||||
@end table
|
||||
|
||||
Possible values for output files:
|
||||
@table @samp
|
||||
@item autobsf
|
||||
Automatically apply bitstream filters as required by the output format. Enabled by default.
|
||||
@item bitexact
|
||||
Only write platform-, build- and time-independent data.
|
||||
This ensures that file and data checksums are reproducible and match between
|
||||
platforms. Its primary use is for regression testing.
|
||||
@item flush_packets
|
||||
Write out packets immediately.
|
||||
@item shortest
|
||||
Stop muxing at the end of the shortest stream.
|
||||
It may be needed to increase max_interleave_delta to avoid flushing the longer
|
||||
streams before EOF.
|
||||
@end table
|
||||
|
||||
@item seek2any @var{integer} (@emph{input})
|
||||
Allow seeking to non-keyframes on demuxer level when supported if set to 1.
|
||||
Default is 0.
|
||||
|
||||
@item analyzeduration @var{integer} (@emph{input})
|
||||
Specify how many microseconds are analyzed to probe the input. A
|
||||
higher value will enable detecting more accurate information, but will
|
||||
increase latency. It defaults to 5,000,000 microseconds = 5 seconds.
|
||||
|
||||
@item cryptokey @var{hexadecimal string} (@emph{input})
|
||||
Set decryption key.
|
||||
|
||||
@item indexmem @var{integer} (@emph{input})
|
||||
Set max memory used for timestamp index (per stream).
|
||||
|
||||
@item rtbufsize @var{integer} (@emph{input})
|
||||
Set max memory used for buffering real-time frames.
|
||||
|
||||
@item fdebug @var{flags} (@emph{input/output})
|
||||
Print specific debug info.
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item ts
|
||||
@end table
|
||||
|
||||
@item max_delay @var{integer} (@emph{input/output})
|
||||
Set maximum muxing or demuxing delay in microseconds.
|
||||
|
||||
@item fpsprobesize @var{integer} (@emph{input})
|
||||
Set number of frames used to probe fps.
|
||||
|
||||
@item audio_preload @var{integer} (@emph{output})
|
||||
Set microseconds by which audio packets should be interleaved earlier.
|
||||
|
||||
@item chunk_duration @var{integer} (@emph{output})
|
||||
Set microseconds for each chunk.
|
||||
|
||||
@item chunk_size @var{integer} (@emph{output})
|
||||
Set size in bytes for each chunk.
|
||||
|
||||
@item err_detect, f_err_detect @var{flags} (@emph{input})
|
||||
Set error detection flags. @code{f_err_detect} is deprecated and
|
||||
should be used only via the @command{ffmpeg} tool.
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item crccheck
|
||||
Verify embedded CRCs.
|
||||
@item bitstream
|
||||
Detect bitstream specification deviations.
|
||||
@item buffer
|
||||
Detect improper bitstream length.
|
||||
@item explode
|
||||
Abort decoding on minor error detection.
|
||||
@item careful
|
||||
Consider things that violate the spec and have not been seen in the
|
||||
wild as errors.
|
||||
@item compliant
|
||||
Consider all spec non compliancies as errors.
|
||||
@item aggressive
|
||||
Consider things that a sane encoder should not do as an error.
|
||||
@end table
|
||||
|
||||
@item max_interleave_delta @var{integer} (@emph{output})
|
||||
Set maximum buffering duration for interleaving. The duration is
|
||||
expressed in microseconds, and defaults to 10000000 (10 seconds).
|
||||
|
||||
To ensure all the streams are interleaved correctly, libavformat will
|
||||
wait until it has at least one packet for each stream before actually
|
||||
writing any packets to the output file. When some streams are
|
||||
"sparse" (i.e. there are large gaps between successive packets), this
|
||||
can result in excessive buffering.
|
||||
|
||||
This field specifies the maximum difference between the timestamps of the
|
||||
first and the last packet in the muxing queue, above which libavformat
|
||||
will output a packet regardless of whether it has queued a packet for all
|
||||
the streams.
|
||||
|
||||
If set to 0, libavformat will continue buffering packets until it has
|
||||
a packet for each stream, regardless of the maximum timestamp
|
||||
difference between the buffered packets.
|
||||
|
||||
@item use_wallclock_as_timestamps @var{integer} (@emph{input})
|
||||
Use wallclock as timestamps if set to 1. Default is 0.
|
||||
|
||||
@item avoid_negative_ts @var{integer} (@emph{output})
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item make_non_negative
|
||||
Shift timestamps to make them non-negative.
|
||||
Also note that this affects only leading negative timestamps, and not
|
||||
non-monotonic negative timestamps.
|
||||
@item make_zero
|
||||
Shift timestamps so that the first timestamp is 0.
|
||||
@item auto (default)
|
||||
Enables shifting when required by the target format.
|
||||
@item disabled
|
||||
Disables shifting of timestamp.
|
||||
@end table
|
||||
|
||||
When shifting is enabled, all output timestamps are shifted by the
|
||||
same amount. Audio, video, and subtitles desynching and relative
|
||||
timestamp differences are preserved compared to how they would have
|
||||
been without shifting.
|
||||
|
||||
@item skip_initial_bytes @var{integer} (@emph{input})
|
||||
Set number of bytes to skip before reading header and frames if set to 1.
|
||||
Default is 0.
|
||||
|
||||
@item correct_ts_overflow @var{integer} (@emph{input})
|
||||
Correct single timestamp overflows if set to 1. Default is 1.
|
||||
|
||||
@item flush_packets @var{integer} (@emph{output})
|
||||
Flush the underlying I/O stream after each packet. Default is -1 (auto), which
|
||||
means that the underlying protocol will decide, 1 enables it, and has the
|
||||
effect of reducing the latency, 0 disables it and may increase IO throughput in
|
||||
some cases.
|
||||
|
||||
@item output_ts_offset @var{offset} (@emph{output})
|
||||
Set the output time offset.
|
||||
|
||||
@var{offset} must be a time duration specification,
|
||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
|
||||
The offset is added by the muxer to the output timestamps.
|
||||
|
||||
Specifying a positive offset means that the corresponding streams are
|
||||
delayed bt the time duration specified in @var{offset}. Default value
|
||||
is @code{0} (meaning that no offset is applied).
|
||||
|
||||
@item format_whitelist @var{list} (@emph{input})
|
||||
"," separated list of allowed demuxers. By default all are allowed.
|
||||
|
||||
@item dump_separator @var{string} (@emph{input})
|
||||
Separator used to separate the fields printed on the command line about the
|
||||
Stream parameters.
|
||||
For example, to separate the fields with newlines and indentation:
|
||||
@example
|
||||
ffprobe -dump_separator "
|
||||
" -i ~/videos/matrixbench_mpeg2.mpg
|
||||
@end example
|
||||
|
||||
@item max_streams @var{integer} (@emph{input})
|
||||
Specifies the maximum number of streams. This can be used to reject files that
|
||||
would require too many resources due to a large number of streams.
|
||||
|
||||
@item skip_estimate_duration_from_pts @var{bool} (@emph{input})
|
||||
Skip estimation of input duration when calculated using PTS.
|
||||
At present, applicable for MPEG-PS and MPEG-TS.
|
||||
|
||||
@item strict, f_strict @var{integer} (@emph{input/output})
|
||||
Specify how strictly to follow the standards. @code{f_strict} is deprecated and
|
||||
should be used only via the @command{ffmpeg} tool.
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item very
|
||||
strictly conform to an older more strict version of the spec or reference software
|
||||
@item strict
|
||||
strictly conform to all the things in the spec no matter what consequences
|
||||
@item normal
|
||||
|
||||
@item unofficial
|
||||
allow unofficial extensions
|
||||
@item experimental
|
||||
allow non standardized experimental things, experimental
|
||||
(unfinished/work in progress/not well tested) decoders and encoders.
|
||||
Note: experimental decoders can pose a security risk, do not use this for
|
||||
decoding untrusted input.
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@c man end FORMAT OPTIONS
|
||||
|
||||
@anchor{Format stream specifiers}
|
||||
@section Format stream specifiers
|
||||
|
||||
Format stream specifiers allow selection of one or more streams that
|
||||
match specific properties.
|
||||
|
||||
The exact semantics of stream specifiers is defined by the
|
||||
@code{avformat_match_stream_specifier()} function declared in the
|
||||
@file{libavformat/avformat.h} header and documented in the
|
||||
@ref{Stream specifiers,,Stream specifiers section in the ffmpeg(1) manual,ffmpeg}.
|
||||
|
||||
@ifclear config-writeonly
|
||||
@include demuxers.texi
|
||||
@end ifclear
|
||||
@ifclear config-readonly
|
||||
@include muxers.texi
|
||||
@end ifclear
|
||||
@include metadata.texi
|
||||
Vendored
-917
@@ -1,917 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : General </title>
|
||||
|
||||
<meta name="description" content="General Documentation: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : General ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">General Documentation</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-External-libraries" href="#External-libraries">1. External libraries</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-OpenJPEG" href="#OpenJPEG">1.1 OpenJPEG</a></li>
|
||||
<li><a name="toc-OpenCORE_002c-VisualOn_002c-and-Fraunhofer-libraries" href="#OpenCORE_002c-VisualOn_002c-and-Fraunhofer-libraries">1.2 OpenCORE, VisualOn, and Fraunhofer libraries</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-OpenCORE-AMR" href="#OpenCORE-AMR">1.2.1 OpenCORE AMR</a></li>
|
||||
<li><a name="toc-VisualOn-AAC-encoder-library" href="#VisualOn-AAC-encoder-library">1.2.2 VisualOn AAC encoder library</a></li>
|
||||
<li><a name="toc-VisualOn-AMR_002dWB-encoder-library" href="#VisualOn-AMR_002dWB-encoder-library">1.2.3 VisualOn AMR-WB encoder library</a></li>
|
||||
<li><a name="toc-Fraunhofer-AAC-library" href="#Fraunhofer-AAC-library">1.2.4 Fraunhofer AAC library</a></li>
|
||||
</ul></li>
|
||||
<li><a name="toc-LAME" href="#LAME">1.3 LAME</a></li>
|
||||
<li><a name="toc-TwoLAME" href="#TwoLAME">1.4 TwoLAME</a></li>
|
||||
<li><a name="toc-libvpx" href="#libvpx">1.5 libvpx</a></li>
|
||||
<li><a name="toc-libwavpack" href="#libwavpack">1.6 libwavpack</a></li>
|
||||
<li><a name="toc-x264" href="#x264">1.7 x264</a></li>
|
||||
<li><a name="toc-libilbc" href="#libilbc">1.8 libilbc</a></li>
|
||||
<li><a name="toc-libzvbi" href="#libzvbi">1.9 libzvbi</a></li>
|
||||
</ul></li>
|
||||
<li><a name="toc-Supported-File-Formats_002c-Codecs-or-Features" href="#Supported-File-Formats_002c-Codecs-or-Features">2. Supported File Formats, Codecs or Features</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-File-Formats" href="#File-Formats">2.1 File Formats</a></li>
|
||||
<li><a name="toc-Image-Formats" href="#Image-Formats">2.2 Image Formats</a></li>
|
||||
<li><a name="toc-Video-Codecs" href="#Video-Codecs">2.3 Video Codecs</a></li>
|
||||
<li><a name="toc-Audio-Codecs" href="#Audio-Codecs">2.4 Audio Codecs</a></li>
|
||||
<li><a name="toc-Subtitle-Formats" href="#Subtitle-Formats">2.5 Subtitle Formats</a></li>
|
||||
<li><a name="toc-Network-Protocols" href="#Network-Protocols">2.6 Network Protocols</a></li>
|
||||
<li><a name="toc-Input_002fOutput-Devices" href="#Input_002fOutput-Devices">2.7 Input/Output Devices</a></li>
|
||||
<li><a name="toc-Timecode" href="#Timecode">2.8 Timecode</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="External-libraries"></a>
|
||||
<h1 class="chapter"><a href="general.html#toc-External-libraries">1. External libraries</a></h1>
|
||||
|
||||
<p>FFmpeg can be hooked up with a number of external libraries to add support
|
||||
for more formats. None of them are used by default, their use has to be
|
||||
explicitly requested by passing the appropriate flags to
|
||||
<code>./configure</code>.
|
||||
</p>
|
||||
<a name="OpenJPEG"></a>
|
||||
<h2 class="section"><a href="general.html#toc-OpenJPEG">1.1 OpenJPEG</a></h2>
|
||||
|
||||
<p>FFmpeg can use the OpenJPEG libraries for encoding/decoding J2K videos. Go to
|
||||
<a href="http://www.openjpeg.org/">http://www.openjpeg.org/</a> to get the libraries and follow the installation
|
||||
instructions. To enable using OpenJPEG in FFmpeg, pass <code>--enable-libopenjpeg</code> to
|
||||
‘<tt>./configure</tt>’.
|
||||
</p>
|
||||
|
||||
<a name="OpenCORE_002c-VisualOn_002c-and-Fraunhofer-libraries"></a>
|
||||
<h2 class="section"><a href="general.html#toc-OpenCORE_002c-VisualOn_002c-and-Fraunhofer-libraries">1.2 OpenCORE, VisualOn, and Fraunhofer libraries</a></h2>
|
||||
|
||||
<p>Spun off Google Android sources, OpenCore, VisualOn and Fraunhofer
|
||||
libraries provide encoders for a number of audio codecs.
|
||||
</p>
|
||||
<div class="float alert alert-info">
|
||||
<p>OpenCORE and VisualOn libraries are under the Apache License 2.0
|
||||
(see <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a> for details), which is
|
||||
incompatible to the LGPL version 2.1 and GPL version 2. You have to
|
||||
upgrade FFmpeg’s license to LGPL version 3 (or if you have enabled
|
||||
GPL components, GPL version 3) by passing <code>--enable-version3</code> to configure in
|
||||
order to use it.
|
||||
</p>
|
||||
<p>The Fraunhofer AAC library is licensed under a license incompatible to the GPL
|
||||
and is not known to be compatible to the LGPL. Therefore, you have to pass
|
||||
<code>--enable-nonfree</code> to configure to use it.
|
||||
</p></div>
|
||||
<a name="OpenCORE-AMR"></a>
|
||||
<h3 class="subsection"><a href="general.html#toc-OpenCORE-AMR">1.2.1 OpenCORE AMR</a></h3>
|
||||
|
||||
<p>FFmpeg can make use of the OpenCORE libraries for AMR-NB
|
||||
decoding/encoding and AMR-WB decoding.
|
||||
</p>
|
||||
<p>Go to <a href="http://sourceforge.net/projects/opencore-amr/">http://sourceforge.net/projects/opencore-amr/</a> and follow the
|
||||
instructions for installing the libraries.
|
||||
Then pass <code>--enable-libopencore-amrnb</code> and/or
|
||||
<code>--enable-libopencore-amrwb</code> to configure to enable them.
|
||||
</p>
|
||||
<a name="VisualOn-AAC-encoder-library"></a>
|
||||
<h3 class="subsection"><a href="general.html#toc-VisualOn-AAC-encoder-library">1.2.2 VisualOn AAC encoder library</a></h3>
|
||||
|
||||
<p>FFmpeg can make use of the VisualOn AACenc library for AAC encoding.
|
||||
</p>
|
||||
<p>Go to <a href="http://sourceforge.net/projects/opencore-amr/">http://sourceforge.net/projects/opencore-amr/</a> and follow the
|
||||
instructions for installing the library.
|
||||
Then pass <code>--enable-libvo-aacenc</code> to configure to enable it.
|
||||
</p>
|
||||
<a name="VisualOn-AMR_002dWB-encoder-library"></a>
|
||||
<h3 class="subsection"><a href="general.html#toc-VisualOn-AMR_002dWB-encoder-library">1.2.3 VisualOn AMR-WB encoder library</a></h3>
|
||||
|
||||
<p>FFmpeg can make use of the VisualOn AMR-WBenc library for AMR-WB encoding.
|
||||
</p>
|
||||
<p>Go to <a href="http://sourceforge.net/projects/opencore-amr/">http://sourceforge.net/projects/opencore-amr/</a> and follow the
|
||||
instructions for installing the library.
|
||||
Then pass <code>--enable-libvo-amrwbenc</code> to configure to enable it.
|
||||
</p>
|
||||
<a name="Fraunhofer-AAC-library"></a>
|
||||
<h3 class="subsection"><a href="general.html#toc-Fraunhofer-AAC-library">1.2.4 Fraunhofer AAC library</a></h3>
|
||||
|
||||
<p>FFmpeg can make use of the Fraunhofer AAC library for AAC encoding.
|
||||
</p>
|
||||
<p>Go to <a href="http://sourceforge.net/projects/opencore-amr/">http://sourceforge.net/projects/opencore-amr/</a> and follow the
|
||||
instructions for installing the library.
|
||||
Then pass <code>--enable-libfdk-aac</code> to configure to enable it.
|
||||
</p>
|
||||
<a name="LAME"></a>
|
||||
<h2 class="section"><a href="general.html#toc-LAME">1.3 LAME</a></h2>
|
||||
|
||||
<p>FFmpeg can make use of the LAME library for MP3 encoding.
|
||||
</p>
|
||||
<p>Go to <a href="http://lame.sourceforge.net/">http://lame.sourceforge.net/</a> and follow the
|
||||
instructions for installing the library.
|
||||
Then pass <code>--enable-libmp3lame</code> to configure to enable it.
|
||||
</p>
|
||||
<a name="TwoLAME"></a>
|
||||
<h2 class="section"><a href="general.html#toc-TwoLAME">1.4 TwoLAME</a></h2>
|
||||
|
||||
<p>FFmpeg can make use of the TwoLAME library for MP2 encoding.
|
||||
</p>
|
||||
<p>Go to <a href="http://www.twolame.org/">http://www.twolame.org/</a> and follow the
|
||||
instructions for installing the library.
|
||||
Then pass <code>--enable-libtwolame</code> to configure to enable it.
|
||||
</p>
|
||||
<a name="libvpx"></a>
|
||||
<h2 class="section"><a href="general.html#toc-libvpx">1.5 libvpx</a></h2>
|
||||
|
||||
<p>FFmpeg can make use of the libvpx library for VP8/VP9 encoding.
|
||||
</p>
|
||||
<p>Go to <a href="http://www.webmproject.org/">http://www.webmproject.org/</a> and follow the instructions for
|
||||
installing the library. Then pass <code>--enable-libvpx</code> to configure to
|
||||
enable it.
|
||||
</p>
|
||||
<a name="libwavpack"></a>
|
||||
<h2 class="section"><a href="general.html#toc-libwavpack">1.6 libwavpack</a></h2>
|
||||
|
||||
<p>FFmpeg can make use of the libwavpack library for WavPack encoding.
|
||||
</p>
|
||||
<p>Go to <a href="http://www.wavpack.com/">http://www.wavpack.com/</a> and follow the instructions for
|
||||
installing the library. Then pass <code>--enable-libwavpack</code> to configure to
|
||||
enable it.
|
||||
</p>
|
||||
<a name="x264"></a>
|
||||
<h2 class="section"><a href="general.html#toc-x264">1.7 x264</a></h2>
|
||||
|
||||
<p>FFmpeg can make use of the x264 library for H.264 encoding.
|
||||
</p>
|
||||
<p>Go to <a href="http://www.videolan.org/developers/x264.html">http://www.videolan.org/developers/x264.html</a> and follow the
|
||||
instructions for installing the library. Then pass <code>--enable-libx264</code> to
|
||||
configure to enable it.
|
||||
</p>
|
||||
<div class="float alert alert-info">
|
||||
<p>x264 is under the GNU Public License Version 2 or later
|
||||
(see <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html">http://www.gnu.org/licenses/old-licenses/gpl-2.0.html</a> for
|
||||
details), you must upgrade FFmpeg’s license to GPL in order to use it.
|
||||
</p></div>
|
||||
<a name="libilbc"></a>
|
||||
<h2 class="section"><a href="general.html#toc-libilbc">1.8 libilbc</a></h2>
|
||||
|
||||
<p>iLBC is a narrowband speech codec that has been made freely available
|
||||
by Google as part of the WebRTC project. libilbc is a packaging friendly
|
||||
copy of the iLBC codec. FFmpeg can make use of the libilbc library for
|
||||
iLBC encoding and decoding.
|
||||
</p>
|
||||
<p>Go to <a href="https://github.com/dekkers/libilbc">https://github.com/dekkers/libilbc</a> and follow the instructions for
|
||||
installing the library. Then pass <code>--enable-libilbc</code> to configure to
|
||||
enable it.
|
||||
</p>
|
||||
<a name="libzvbi"></a>
|
||||
<h2 class="section"><a href="general.html#toc-libzvbi">1.9 libzvbi</a></h2>
|
||||
|
||||
<p>libzvbi is a VBI decoding library which can be used by FFmpeg to decode DVB
|
||||
teletext pages and DVB teletext subtitles.
|
||||
</p>
|
||||
<p>Go to <a href="http://sourceforge.net/projects/zapping/">http://sourceforge.net/projects/zapping/</a> and follow the instructions for
|
||||
installing the library. Then pass <code>--enable-libzvbi</code> to configure to
|
||||
enable it.
|
||||
</p>
|
||||
<div class="float alert alert-info">
|
||||
<p>libzvbi is licensed under the GNU General Public License Version 2 or later
|
||||
(see <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html">http://www.gnu.org/licenses/old-licenses/gpl-2.0.html</a> for details),
|
||||
you must upgrade FFmpeg’s license to GPL in order to use it.
|
||||
</p></div>
|
||||
|
||||
<a name="Supported-File-Formats_002c-Codecs-or-Features"></a>
|
||||
<h1 class="chapter"><a href="general.html#toc-Supported-File-Formats_002c-Codecs-or-Features">2. Supported File Formats, Codecs or Features</a></h1>
|
||||
|
||||
<p>You can use the <code>-formats</code> and <code>-codecs</code> options to have an exhaustive list.
|
||||
</p>
|
||||
<a name="File-Formats"></a>
|
||||
<h2 class="section"><a href="general.html#toc-File-Formats">2.1 File Formats</a></h2>
|
||||
|
||||
<p>FFmpeg supports the following file formats through the <code>libavformat</code>
|
||||
library:
|
||||
</p>
|
||||
<table>
|
||||
<tr><td width="40%">Name</td><td width="10%">Encoding</td><td width="10%">Decoding</td><td width="40%">Comments</td></tr>
|
||||
<tr><td width="40%">4xm</td><td width="10%"></td><td width="10%">X</td><td width="40%">4X Technologies format, used in some games.</td></tr>
|
||||
<tr><td width="40%">8088flex TMV</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ACT Voice</td><td width="10%"></td><td width="10%">X</td><td width="40%">contains G.729 audio</td></tr>
|
||||
<tr><td width="40%">Adobe Filmstrip</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Audio IFF (AIFF)</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">American Laser Games MM</td><td width="10%"></td><td width="10%">X</td><td width="40%">Multimedia format used in games like Mad Dog McCree.</td></tr>
|
||||
<tr><td width="40%">3GPP AMR</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Amazing Studio Packed Animation File</td><td width="10%"></td><td width="10%">X</td><td width="40%">Multimedia format used in game Heart Of Darkness.</td></tr>
|
||||
<tr><td width="40%">Apple HTTP Live Streaming</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Artworx Data Format</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADP</td><td width="10%"></td><td width="10%">X</td><td width="40%">Audio format used on the Nintendo Gamecube.</td></tr>
|
||||
<tr><td width="40%">AFC</td><td width="10%"></td><td width="10%">X</td><td width="40%">Audio format used on the Nintendo Gamecube.</td></tr>
|
||||
<tr><td width="40%">ASF</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">AST</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Audio format used on the Nintendo Wii.</td></tr>
|
||||
<tr><td width="40%">AVI</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">AviSynth</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">AVR</td><td width="10%"></td><td width="10%">X</td><td width="40%">Audio format used on Mac.</td></tr>
|
||||
<tr><td width="40%">AVS</td><td width="10%"></td><td width="10%">X</td><td width="40%">Multimedia format used by the Creature Shock game.</td></tr>
|
||||
<tr><td width="40%">Beam Software SIFF</td><td width="10%"></td><td width="10%">X</td><td width="40%">Audio and video format used in some games by Beam Software.</td></tr>
|
||||
<tr><td width="40%">Bethesda Softworks VID</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in some games from Bethesda Softworks.</td></tr>
|
||||
<tr><td width="40%">Binary text</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Bink</td><td width="10%"></td><td width="10%">X</td><td width="40%">Multimedia format used by many games.</td></tr>
|
||||
<tr><td width="40%">Bitmap Brothers JV</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Z and Z95 games.</td></tr>
|
||||
<tr><td width="40%">Brute Force & Ignorance</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in the game Flash Traffic: City of Angels.</td></tr>
|
||||
<tr><td width="40%">BRSTM</td><td width="10%"></td><td width="10%">X</td><td width="40%">Audio format used on the Nintendo Wii.</td></tr>
|
||||
<tr><td width="40%">BWF</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">CRI ADX</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Audio-only format used in console video games.</td></tr>
|
||||
<tr><td width="40%">Discworld II BMV</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Interplay C93</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in the game Cyberia from Interplay.</td></tr>
|
||||
<tr><td width="40%">Delphine Software International CIN</td><td width="10%"></td><td width="10%">X</td><td width="40%">Multimedia format used by Delphine Software games.</td></tr>
|
||||
<tr><td width="40%">CD+G</td><td width="10%"></td><td width="10%">X</td><td width="40%">Video format used by CD+G karaoke disks</td></tr>
|
||||
<tr><td width="40%">Commodore CDXL</td><td width="10%"></td><td width="10%">X</td><td width="40%">Amiga CD video format</td></tr>
|
||||
<tr><td width="40%">Core Audio Format</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Apple Core Audio Format</td></tr>
|
||||
<tr><td width="40%">CRC testing format</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">Creative Voice</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Created for the Sound Blaster Pro.</td></tr>
|
||||
<tr><td width="40%">CRYO APC</td><td width="10%"></td><td width="10%">X</td><td width="40%">Audio format used in some games by CRYO Interactive Entertainment.</td></tr>
|
||||
<tr><td width="40%">D-Cinema audio</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Deluxe Paint Animation</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">DFA</td><td width="10%"></td><td width="10%">X</td><td width="40%">This format is used in Chronomaster game</td></tr>
|
||||
<tr><td width="40%">DV video</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">DXA</td><td width="10%"></td><td width="10%">X</td><td width="40%">This format is used in the non-Windows version of the Feeble Files
|
||||
game and different game cutscenes repacked for use with ScummVM.</td></tr>
|
||||
<tr><td width="40%">Electronic Arts cdata</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Electronic Arts Multimedia</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in various EA games; files have extensions like WVE and UV2.</td></tr>
|
||||
<tr><td width="40%">Ensoniq Paris Audio File</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">FFM (FFserver live feed)</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Flash (SWF)</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Flash 9 (AVM2)</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Only embedded audio is decoded.</td></tr>
|
||||
<tr><td width="40%">FLI/FLC/FLX animation</td><td width="10%"></td><td width="10%">X</td><td width="40%">.fli/.flc files</td></tr>
|
||||
<tr><td width="40%">Flash Video (FLV)</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Macromedia Flash video files</td></tr>
|
||||
<tr><td width="40%">framecrc testing format</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">FunCom ISS</td><td width="10%"></td><td width="10%">X</td><td width="40%">Audio format used in various games from FunCom like The Longest Journey.</td></tr>
|
||||
<tr><td width="40%">G.723.1</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">G.729 BIT</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">G.729 raw</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">GIF Animation</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">GXF</td><td width="10%">X</td><td width="10%">X</td><td width="40%">General eXchange Format SMPTE 360M, used by Thomson Grass Valley
|
||||
playout servers.</td></tr>
|
||||
<tr><td width="40%">iCEDraw File</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ICO</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Microsoft Windows ICO</td></tr>
|
||||
<tr><td width="40%">id Quake II CIN video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">id RoQ</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Used in Quake III, Jedi Knight 2 and other computer games.</td></tr>
|
||||
<tr><td width="40%">IEC61937 encapsulation</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">IFF</td><td width="10%"></td><td width="10%">X</td><td width="40%">Interchange File Format</td></tr>
|
||||
<tr><td width="40%">iLBC</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Interplay MVE</td><td width="10%"></td><td width="10%">X</td><td width="40%">Format used in various Interplay computer games.</td></tr>
|
||||
<tr><td width="40%">IV8</td><td width="10%"></td><td width="10%">X</td><td width="40%">A format generated by IndigoVision 8000 video server.</td></tr>
|
||||
<tr><td width="40%">IVF (On2)</td><td width="10%">X</td><td width="10%">X</td><td width="40%">A format used by libvpx</td></tr>
|
||||
<tr><td width="40%">IRCAM</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">LATM</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">LMLM4</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used by Linux Media Labs MPEG-4 PCI boards</td></tr>
|
||||
<tr><td width="40%">LOAS</td><td width="10%"></td><td width="10%">X</td><td width="40%">contains LATM multiplexed AAC audio</td></tr>
|
||||
<tr><td width="40%">LVF</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">LXF</td><td width="10%"></td><td width="10%">X</td><td width="40%">VR native stream format, used by Leitch/Harris’ video servers.</td></tr>
|
||||
<tr><td width="40%">Matroska</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Matroska audio</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">FFmpeg metadata</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Metadata in text format.</td></tr>
|
||||
<tr><td width="40%">MAXIS XA</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Sim City 3000; file extension .xa.</td></tr>
|
||||
<tr><td width="40%">MD Studio</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Metal Gear Solid: The Twin Snakes</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Megalux Frame</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used by Megalux Ultimate Paint</td></tr>
|
||||
<tr><td width="40%">Mobotix .mxg</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Monkey’s Audio</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Motion Pixels MVI</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MOV/QuickTime/MP4</td><td width="10%">X</td><td width="10%">X</td><td width="40%">3GP, 3GP2, PSP, iPod variants supported</td></tr>
|
||||
<tr><td width="40%">MP2</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MP3</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MPEG-1 System</td><td width="10%">X</td><td width="10%">X</td><td width="40%">muxed audio and video, VCD format supported</td></tr>
|
||||
<tr><td width="40%">MPEG-PS (program stream)</td><td width="10%">X</td><td width="10%">X</td><td width="40%">also known as <code>VOB</code> file, SVCD and DVD format supported</td></tr>
|
||||
<tr><td width="40%">MPEG-TS (transport stream)</td><td width="10%">X</td><td width="10%">X</td><td width="40%">also known as DVB Transport Stream</td></tr>
|
||||
<tr><td width="40%">MPEG-4</td><td width="10%">X</td><td width="10%">X</td><td width="40%">MPEG-4 is a variant of QuickTime.</td></tr>
|
||||
<tr><td width="40%">MIME multipart JPEG</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">MSN TCP webcam</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used by MSN Messenger webcam streams.</td></tr>
|
||||
<tr><td width="40%">MTV</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Musepack</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Musepack SV8</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Material eXchange Format (MXF)</td><td width="10%">X</td><td width="10%">X</td><td width="40%">SMPTE 377M, used by D-Cinema, broadcast industry.</td></tr>
|
||||
<tr><td width="40%">Material eXchange Format (MXF), D-10 Mapping</td><td width="10%">X</td><td width="10%">X</td><td width="40%">SMPTE 386M, D-10/IMX Mapping.</td></tr>
|
||||
<tr><td width="40%">NC camera feed</td><td width="10%"></td><td width="10%">X</td><td width="40%">NC (AVIP NC4600) camera streams</td></tr>
|
||||
<tr><td width="40%">NIST SPeech HEader REsources</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">NTT TwinVQ (VQF)</td><td width="10%"></td><td width="10%">X</td><td width="40%">Nippon Telegraph and Telephone Corporation TwinVQ.</td></tr>
|
||||
<tr><td width="40%">Nullsoft Streaming Video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">NuppelVideo</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">NUT</td><td width="10%">X</td><td width="10%">X</td><td width="40%">NUT Open Container Format</td></tr>
|
||||
<tr><td width="40%">Ogg</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Playstation Portable PMP</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Portable Voice Format</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">TechnoTrend PVA</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used by TechnoTrend DVB PCI boards.</td></tr>
|
||||
<tr><td width="40%">QCP</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw ADTS (AAC)</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw AC-3</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw Chinese AVS video</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw CRI ADX</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw Dirac</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw DNxHD</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw DTS</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw DTS-HD</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw E-AC-3</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw FLAC</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw GSM</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw H.261</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw H.263</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw H.264</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw Ingenient MJPEG</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw MJPEG</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw MLP</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw MPEG</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw MPEG-1</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw MPEG-2</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw MPEG-4</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw NULL</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">raw video</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw id RoQ</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">raw Shorten</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw TAK</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw TrueHD</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw VC-1</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM A-law</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM mu-law</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM signed 8 bit</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM signed 16 bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM signed 16 bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM signed 24 bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM signed 24 bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM signed 32 bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM signed 32 bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM unsigned 8 bit</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM unsigned 16 bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM unsigned 16 bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM unsigned 24 bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM unsigned 24 bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM unsigned 32 bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM unsigned 32 bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM floating-point 32 bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM floating-point 32 bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM floating-point 64 bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">raw PCM floating-point 64 bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RDT</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">REDCODE R3D</td><td width="10%"></td><td width="10%">X</td><td width="40%">File format used by RED Digital cameras, contains JPEG 2000 frames and PCM audio.</td></tr>
|
||||
<tr><td width="40%">RealMedia</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Redirector</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RedSpark</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Renderware TeXture Dictionary</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RL2</td><td width="10%"></td><td width="10%">X</td><td width="40%">Audio and video format used in some games by Entertainment Software Partners.</td></tr>
|
||||
<tr><td width="40%">RPL/ARMovie</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Lego Mindstorms RSO</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RSD</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RTMP</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Output is performed by publishing stream to RTMP server</td></tr>
|
||||
<tr><td width="40%">RTP</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RTSP</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">SAP</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">SBG</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">SDP</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Sega FILM/CPK</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in many Sega Saturn console games.</td></tr>
|
||||
<tr><td width="40%">Silicon Graphics Movie</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Sierra SOL</td><td width="10%"></td><td width="10%">X</td><td width="40%">.sol files used in Sierra Online games.</td></tr>
|
||||
<tr><td width="40%">Sierra VMD</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Sierra CD-ROM games.</td></tr>
|
||||
<tr><td width="40%">Smacker</td><td width="10%"></td><td width="10%">X</td><td width="40%">Multimedia format used by many games.</td></tr>
|
||||
<tr><td width="40%">SMJPEG</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Used in certain Loki game ports.</td></tr>
|
||||
<tr><td width="40%">Smush</td><td width="10%"></td><td width="10%">X</td><td width="40%">Multimedia format used in some LucasArts games.</td></tr>
|
||||
<tr><td width="40%">Sony OpenMG (OMA)</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Audio format used in Sony Sonic Stage and Sony Vegas.</td></tr>
|
||||
<tr><td width="40%">Sony PlayStation STR</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Sony Wave64 (W64)</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">SoX native format</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">SUN AU format</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Text files</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">THP</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used on the Nintendo GameCube.</td></tr>
|
||||
<tr><td width="40%">Tiertex Limited SEQ</td><td width="10%"></td><td width="10%">X</td><td width="40%">Tiertex .seq files used in the DOS CD-ROM version of the game Flashback.</td></tr>
|
||||
<tr><td width="40%">True Audio</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">VC-1 test bitstream</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Vivo</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">WAV</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">WavPack</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">WebM</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Windows Televison (WTV)</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Wing Commander III movie</td><td width="10%"></td><td width="10%">X</td><td width="40%">Multimedia format used in Origin’s Wing Commander III computer game.</td></tr>
|
||||
<tr><td width="40%">Westwood Studios audio</td><td width="10%"></td><td width="10%">X</td><td width="40%">Multimedia format used in Westwood Studios games.</td></tr>
|
||||
<tr><td width="40%">Westwood Studios VQA</td><td width="10%"></td><td width="10%">X</td><td width="40%">Multimedia format used in Westwood Studios games.</td></tr>
|
||||
<tr><td width="40%">XMV</td><td width="10%"></td><td width="10%">X</td><td width="40%">Microsoft video container used in Xbox games.</td></tr>
|
||||
<tr><td width="40%">xWMA</td><td width="10%"></td><td width="10%">X</td><td width="40%">Microsoft audio container used by XAudio 2.</td></tr>
|
||||
<tr><td width="40%">eXtended BINary text (XBIN)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">YUV4MPEG pipe</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Psygnosis YOP</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
</table>
|
||||
|
||||
<p><code>X</code> means that encoding (resp. decoding) is supported.
|
||||
</p>
|
||||
<a name="Image-Formats"></a>
|
||||
<h2 class="section"><a href="general.html#toc-Image-Formats">2.2 Image Formats</a></h2>
|
||||
|
||||
<p>FFmpeg can read and write images for each frame of a video sequence. The
|
||||
following image formats are supported:
|
||||
</p>
|
||||
<table>
|
||||
<tr><td width="40%">Name</td><td width="10%">Encoding</td><td width="10%">Decoding</td><td width="40%">Comments</td></tr>
|
||||
<tr><td width="40%">.Y.U.V</td><td width="10%">X</td><td width="10%">X</td><td width="40%">one raw file per component</td></tr>
|
||||
<tr><td width="40%">animated GIF</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">BMP</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Microsoft BMP image</td></tr>
|
||||
<tr><td width="40%">PIX</td><td width="10%"></td><td width="10%">X</td><td width="40%">PIX is an image format used in the Argonaut BRender engine.</td></tr>
|
||||
<tr><td width="40%">DPX</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Digital Picture Exchange</td></tr>
|
||||
<tr><td width="40%">EXR</td><td width="10%"></td><td width="10%">X</td><td width="40%">OpenEXR</td></tr>
|
||||
<tr><td width="40%">JPEG</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Progressive JPEG is not supported.</td></tr>
|
||||
<tr><td width="40%">JPEG 2000</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">JPEG-LS</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">LJPEG</td><td width="10%">X</td><td width="10%"></td><td width="40%">Lossless JPEG</td></tr>
|
||||
<tr><td width="40%">PAM</td><td width="10%">X</td><td width="10%">X</td><td width="40%">PAM is a PNM extension with alpha support.</td></tr>
|
||||
<tr><td width="40%">PBM</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Portable BitMap image</td></tr>
|
||||
<tr><td width="40%">PCX</td><td width="10%">X</td><td width="10%">X</td><td width="40%">PC Paintbrush</td></tr>
|
||||
<tr><td width="40%">PGM</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Portable GrayMap image</td></tr>
|
||||
<tr><td width="40%">PGMYUV</td><td width="10%">X</td><td width="10%">X</td><td width="40%">PGM with U and V components in YUV 4:2:0</td></tr>
|
||||
<tr><td width="40%">PIC</td><td width="10%"></td><td width="10%">X</td><td width="40%">Pictor/PC Paint</td></tr>
|
||||
<tr><td width="40%">PNG</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PPM</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Portable PixelMap image</td></tr>
|
||||
<tr><td width="40%">PTX</td><td width="10%"></td><td width="10%">X</td><td width="40%">V.Flash PTX format</td></tr>
|
||||
<tr><td width="40%">SGI</td><td width="10%">X</td><td width="10%">X</td><td width="40%">SGI RGB image format</td></tr>
|
||||
<tr><td width="40%">Sun Rasterfile</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Sun RAS image format</td></tr>
|
||||
<tr><td width="40%">TIFF</td><td width="10%">X</td><td width="10%">X</td><td width="40%">YUV, JPEG and some extension is not supported yet.</td></tr>
|
||||
<tr><td width="40%">Truevision Targa</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Targa (.TGA) image format</td></tr>
|
||||
<tr><td width="40%">WebP</td><td width="10%"></td><td width="10%">X</td><td width="40%">WebP image format</td></tr>
|
||||
<tr><td width="40%">XBM</td><td width="10%">X</td><td width="10%">X</td><td width="40%">X BitMap image format</td></tr>
|
||||
<tr><td width="40%">XFace</td><td width="10%">X</td><td width="10%">X</td><td width="40%">X-Face image format</td></tr>
|
||||
<tr><td width="40%">XWD</td><td width="10%">X</td><td width="10%">X</td><td width="40%">X Window Dump image format</td></tr>
|
||||
</table>
|
||||
|
||||
<p><code>X</code> means that encoding (resp. decoding) is supported.
|
||||
</p>
|
||||
<p><code>E</code> means that support is provided through an external library.
|
||||
</p>
|
||||
<a name="Video-Codecs"></a>
|
||||
<h2 class="section"><a href="general.html#toc-Video-Codecs">2.3 Video Codecs</a></h2>
|
||||
|
||||
<table>
|
||||
<tr><td width="40%">Name</td><td width="10%">Encoding</td><td width="10%">Decoding</td><td width="40%">Comments</td></tr>
|
||||
<tr><td width="40%">4X Movie</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in certain computer games.</td></tr>
|
||||
<tr><td width="40%">8088flex TMV</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">A64 multicolor</td><td width="10%">X</td><td width="10%"></td><td width="40%">Creates video suitable to be played on a commodore 64 (multicolor mode).</td></tr>
|
||||
<tr><td width="40%">Amazing Studio PAF Video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">American Laser Games MM</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in games like Mad Dog McCree.</td></tr>
|
||||
<tr><td width="40%">AMV Video</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Used in Chinese MP3 players.</td></tr>
|
||||
<tr><td width="40%">ANSI/ASCII art</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Apple Intermediate Codec</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Apple MJPEG-B</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Apple ProRes</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Apple QuickDraw</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: qdrw</td></tr>
|
||||
<tr><td width="40%">Asus v1</td><td width="10%">X</td><td width="10%">X</td><td width="40%">fourcc: ASV1</td></tr>
|
||||
<tr><td width="40%">Asus v2</td><td width="10%">X</td><td width="10%">X</td><td width="40%">fourcc: ASV2</td></tr>
|
||||
<tr><td width="40%">ATI VCR1</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: VCR1</td></tr>
|
||||
<tr><td width="40%">ATI VCR2</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: VCR2</td></tr>
|
||||
<tr><td width="40%">Auravision Aura</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Auravision Aura 2</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Autodesk Animator Flic video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Autodesk RLE</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: AASC</td></tr>
|
||||
<tr><td width="40%">Avid 1:1 10-bit RGB Packer</td><td width="10%">X</td><td width="10%">X</td><td width="40%">fourcc: AVrp</td></tr>
|
||||
<tr><td width="40%">AVS (Audio Video Standard) video</td><td width="10%"></td><td width="10%">X</td><td width="40%">Video encoding used by the Creature Shock game.</td></tr>
|
||||
<tr><td width="40%">AYUV</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Microsoft uncompressed packed 4:4:4:4</td></tr>
|
||||
<tr><td width="40%">Beam Software VB</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Bethesda VID video</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in some games from Bethesda Softworks.</td></tr>
|
||||
<tr><td width="40%">Bink Video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Bitmap Brothers JV video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">y41p Brooktree uncompressed 4:1:1 12-bit</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Brute Force & Ignorance</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in the game Flash Traffic: City of Angels.</td></tr>
|
||||
<tr><td width="40%">C93 video</td><td width="10%"></td><td width="10%">X</td><td width="40%">Codec used in Cyberia game.</td></tr>
|
||||
<tr><td width="40%">CamStudio</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: CSCD</td></tr>
|
||||
<tr><td width="40%">CD+G</td><td width="10%"></td><td width="10%">X</td><td width="40%">Video codec for CD+G karaoke disks</td></tr>
|
||||
<tr><td width="40%">CDXL</td><td width="10%"></td><td width="10%">X</td><td width="40%">Amiga CD video codec</td></tr>
|
||||
<tr><td width="40%">Chinese AVS video</td><td width="10%">E</td><td width="10%">X</td><td width="40%">AVS1-P2, JiZhun profile, encoding through external library libxavs</td></tr>
|
||||
<tr><td width="40%">Delphine Software International CIN video</td><td width="10%"></td><td width="10%">X</td><td width="40%">Codec used in Delphine Software International games.</td></tr>
|
||||
<tr><td width="40%">Discworld II BMV Video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Canopus Lossless Codec</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Cinepak</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Cirrus Logic AccuPak</td><td width="10%">X</td><td width="10%">X</td><td width="40%">fourcc: CLJR</td></tr>
|
||||
<tr><td width="40%">CPiA Video Format</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Creative YUV (CYUV)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">DFA</td><td width="10%"></td><td width="10%">X</td><td width="40%">Codec used in Chronomaster game.</td></tr>
|
||||
<tr><td width="40%">Dirac</td><td width="10%">E</td><td width="10%">X</td><td width="40%">supported through external library libschroedinger</td></tr>
|
||||
<tr><td width="40%">Deluxe Paint Animation</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">DNxHD</td><td width="10%">X</td><td width="10%">X</td><td width="40%">aka SMPTE VC3</td></tr>
|
||||
<tr><td width="40%">Duck TrueMotion 1.0</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: DUCK</td></tr>
|
||||
<tr><td width="40%">Duck TrueMotion 2.0</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: TM20</td></tr>
|
||||
<tr><td width="40%">DV (Digital Video)</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Dxtory capture format</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Feeble Files/ScummVM DXA</td><td width="10%"></td><td width="10%">X</td><td width="40%">Codec originally used in Feeble Files game.</td></tr>
|
||||
<tr><td width="40%">Electronic Arts CMV video</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in NHL 95 game.</td></tr>
|
||||
<tr><td width="40%">Electronic Arts Madcow video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Electronic Arts TGV video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Electronic Arts TGQ video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Electronic Arts TQI video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Escape 124</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Escape 130</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">FFmpeg video codec #1</td><td width="10%">X</td><td width="10%">X</td><td width="40%">lossless codec (fourcc: FFV1)</td></tr>
|
||||
<tr><td width="40%">Flash Screen Video v1</td><td width="10%">X</td><td width="10%">X</td><td width="40%">fourcc: FSV1</td></tr>
|
||||
<tr><td width="40%">Flash Screen Video v2</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Flash Video (FLV)</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Sorenson H.263 used in Flash</td></tr>
|
||||
<tr><td width="40%">Forward Uncompressed</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Fraps</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Go2Webinar</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: G2M4</td></tr>
|
||||
<tr><td width="40%">H.261</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">H.263 / H.263-1996</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">H.263+ / H.263-1998 / H.263 version 2</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10</td><td width="10%">E</td><td width="10%">X</td><td width="40%">encoding supported through external library libx264</td></tr>
|
||||
<tr><td width="40%">HuffYUV</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">HuffYUV FFmpeg variant</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">IBM Ultimotion</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: ULTI</td></tr>
|
||||
<tr><td width="40%">id Cinematic video</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Quake II.</td></tr>
|
||||
<tr><td width="40%">id RoQ video</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Used in Quake III, Jedi Knight 2, other computer games.</td></tr>
|
||||
<tr><td width="40%">IFF ILBM</td><td width="10%"></td><td width="10%">X</td><td width="40%">IFF interleaved bitmap</td></tr>
|
||||
<tr><td width="40%">IFF ByteRun1</td><td width="10%"></td><td width="10%">X</td><td width="40%">IFF run length encoded bitmap</td></tr>
|
||||
<tr><td width="40%">Intel H.263</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Intel Indeo 2</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Intel Indeo 3</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Intel Indeo 4</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Intel Indeo 5</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Interplay C93</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in the game Cyberia from Interplay.</td></tr>
|
||||
<tr><td width="40%">Interplay MVE video</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Interplay .MVE files.</td></tr>
|
||||
<tr><td width="40%">J2K</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Karl Morton’s video codec</td><td width="10%"></td><td width="10%">X</td><td width="40%">Codec used in Worms games.</td></tr>
|
||||
<tr><td width="40%">Kega Game Video (KGV1)</td><td width="10%"></td><td width="10%">X</td><td width="40%">Kega emulator screen capture codec.</td></tr>
|
||||
<tr><td width="40%">Lagarith</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">LCL (LossLess Codec Library) MSZH</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">LCL (LossLess Codec Library) ZLIB</td><td width="10%">E</td><td width="10%">E</td></tr>
|
||||
<tr><td width="40%">LOCO</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">LucasArts Smush</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in LucasArts games.</td></tr>
|
||||
<tr><td width="40%">lossless MJPEG</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Microsoft ATC Screen</td><td width="10%"></td><td width="10%">X</td><td width="40%">Also known as Microsoft Screen 3.</td></tr>
|
||||
<tr><td width="40%">Microsoft Expression Encoder Screen</td><td width="10%"></td><td width="10%">X</td><td width="40%">Also known as Microsoft Titanium Screen 2.</td></tr>
|
||||
<tr><td width="40%">Microsoft RLE</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Microsoft Screen 1</td><td width="10%"></td><td width="10%">X</td><td width="40%">Also known as Windows Media Video V7 Screen.</td></tr>
|
||||
<tr><td width="40%">Microsoft Screen 2</td><td width="10%"></td><td width="10%">X</td><td width="40%">Also known as Windows Media Video V9 Screen.</td></tr>
|
||||
<tr><td width="40%">Microsoft Video 1</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Mimic</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in MSN Messenger Webcam streams.</td></tr>
|
||||
<tr><td width="40%">Miro VideoXL</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: VIXL</td></tr>
|
||||
<tr><td width="40%">MJPEG (Motion JPEG)</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Mobotix MxPEG video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Motion Pixels video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MPEG-1 video</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MPEG-1/2 video XvMC (X-Video Motion Compensation)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MPEG-2 video</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MPEG-4 part 2</td><td width="10%">X</td><td width="10%">X</td><td width="40%">libxvidcore can be used alternatively for encoding.</td></tr>
|
||||
<tr><td width="40%">MPEG-4 part 2 Microsoft variant version 1</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MPEG-4 part 2 Microsoft variant version 2</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MPEG-4 part 2 Microsoft variant version 3</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Nintendo Gamecube THP video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">NuppelVideo/RTjpeg</td><td width="10%"></td><td width="10%">X</td><td width="40%">Video encoding used in NuppelVideo files.</td></tr>
|
||||
<tr><td width="40%">On2 VP3</td><td width="10%"></td><td width="10%">X</td><td width="40%">still experimental</td></tr>
|
||||
<tr><td width="40%">On2 VP5</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: VP50</td></tr>
|
||||
<tr><td width="40%">On2 VP6</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: VP60,VP61,VP62</td></tr>
|
||||
<tr><td width="40%">VP8</td><td width="10%">E</td><td width="10%">X</td><td width="40%">fourcc: VP80, encoding supported through external library libvpx</td></tr>
|
||||
<tr><td width="40%">VP9</td><td width="10%">E</td><td width="10%">X</td><td width="40%">encoding supported through external library libvpx</td></tr>
|
||||
<tr><td width="40%">Pinnacle TARGA CineWave YUV16</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: Y216</td></tr>
|
||||
<tr><td width="40%">Prores</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: apch,apcn,apcs,apco</td></tr>
|
||||
<tr><td width="40%">Q-team QPEG</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourccs: QPEG, Q1.0, Q1.1</td></tr>
|
||||
<tr><td width="40%">QuickTime 8BPS video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">QuickTime Animation (RLE) video</td><td width="10%">X</td><td width="10%">X</td><td width="40%">fourcc: ’rle ’</td></tr>
|
||||
<tr><td width="40%">QuickTime Graphics (SMC)</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: ’smc ’</td></tr>
|
||||
<tr><td width="40%">QuickTime video (RPZA)</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: rpza</td></tr>
|
||||
<tr><td width="40%">R10K AJA Kona 10-bit RGB Codec</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">R210 Quicktime Uncompressed RGB 10-bit</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Raw Video</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RealVideo 1.0</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RealVideo 2.0</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RealVideo 3.0</td><td width="10%"></td><td width="10%">X</td><td width="40%">still far from ideal</td></tr>
|
||||
<tr><td width="40%">RealVideo 4.0</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Renderware TXD (TeXture Dictionary)</td><td width="10%"></td><td width="10%">X</td><td width="40%">Texture dictionaries used by the Renderware Engine.</td></tr>
|
||||
<tr><td width="40%">RL2 video</td><td width="10%"></td><td width="10%">X</td><td width="40%">used in some games by Entertainment Software Partners</td></tr>
|
||||
<tr><td width="40%">SGI RLE 8-bit</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Sierra VMD video</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Sierra VMD files.</td></tr>
|
||||
<tr><td width="40%">Silicon Graphics Motion Video Compressor 1 (MVC1)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Silicon Graphics Motion Video Compressor 2 (MVC2)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Smacker video</td><td width="10%"></td><td width="10%">X</td><td width="40%">Video encoding used in Smacker.</td></tr>
|
||||
<tr><td width="40%">SMPTE VC-1</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Snow</td><td width="10%">X</td><td width="10%">X</td><td width="40%">experimental wavelet codec (fourcc: SNOW)</td></tr>
|
||||
<tr><td width="40%">Sony PlayStation MDEC (Motion DECoder)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Sorenson Vector Quantizer 1</td><td width="10%">X</td><td width="10%">X</td><td width="40%">fourcc: SVQ1</td></tr>
|
||||
<tr><td width="40%">Sorenson Vector Quantizer 3</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: SVQ3</td></tr>
|
||||
<tr><td width="40%">Sunplus JPEG (SP5X)</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: SP5X</td></tr>
|
||||
<tr><td width="40%">TechSmith Screen Capture Codec</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: TSCC</td></tr>
|
||||
<tr><td width="40%">TechSmith Screen Capture Codec 2</td><td width="10%"></td><td width="10%">X</td><td width="40%">fourcc: TSC2</td></tr>
|
||||
<tr><td width="40%">Theora</td><td width="10%">E</td><td width="10%">X</td><td width="40%">encoding supported through external library libtheora</td></tr>
|
||||
<tr><td width="40%">Tiertex Limited SEQ video</td><td width="10%"></td><td width="10%">X</td><td width="40%">Codec used in DOS CD-ROM FlashBack game.</td></tr>
|
||||
<tr><td width="40%">Ut Video</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">v210 QuickTime uncompressed 4:2:2 10-bit</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">v308 QuickTime uncompressed 4:4:4</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">v408 QuickTime uncompressed 4:4:4:4</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">v410 QuickTime uncompressed 4:4:4 10-bit</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">VBLE Lossless Codec</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">VMware Screen Codec / VMware Video</td><td width="10%"></td><td width="10%">X</td><td width="40%">Codec used in videos captured by VMware.</td></tr>
|
||||
<tr><td width="40%">Westwood Studios VQA (Vector Quantized Animation) video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Windows Media Image</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Windows Media Video 7</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Windows Media Video 8</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Windows Media Video 9</td><td width="10%"></td><td width="10%">X</td><td width="40%">not completely working</td></tr>
|
||||
<tr><td width="40%">Wing Commander III / Xan</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Wing Commander III .MVE files.</td></tr>
|
||||
<tr><td width="40%">Wing Commander IV / Xan</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Wing Commander IV.</td></tr>
|
||||
<tr><td width="40%">Winnov WNV1</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">WMV7</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">YAMAHA SMAF</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Psygnosis YOP Video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">yuv4</td><td width="10%">X</td><td width="10%">X</td><td width="40%">libquicktime uncompressed packed 4:2:0</td></tr>
|
||||
<tr><td width="40%">ZeroCodec Lossless Video</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ZLIB</td><td width="10%">X</td><td width="10%">X</td><td width="40%">part of LCL, encoder experimental</td></tr>
|
||||
<tr><td width="40%">Zip Motion Blocks Video</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Encoder works only in PAL8.</td></tr>
|
||||
</table>
|
||||
|
||||
<p><code>X</code> means that encoding (resp. decoding) is supported.
|
||||
</p>
|
||||
<p><code>E</code> means that support is provided through an external library.
|
||||
</p>
|
||||
<a name="Audio-Codecs"></a>
|
||||
<h2 class="section"><a href="general.html#toc-Audio-Codecs">2.4 Audio Codecs</a></h2>
|
||||
|
||||
<table>
|
||||
<tr><td width="40%">Name</td><td width="10%">Encoding</td><td width="10%">Decoding</td><td width="40%">Comments</td></tr>
|
||||
<tr><td width="40%">8SVX exponential</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">8SVX fibonacci</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">AAC+</td><td width="10%">E</td><td width="10%">X</td><td width="40%">encoding supported through external library libaacplus</td></tr>
|
||||
<tr><td width="40%">AAC</td><td width="10%">E</td><td width="10%">X</td><td width="40%">encoding supported through external library libfaac and libvo-aacenc</td></tr>
|
||||
<tr><td width="40%">AC-3</td><td width="10%">IX</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM 4X Movie</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM CDROM XA</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM Creative Technology</td><td width="10%"></td><td width="10%">X</td><td width="40%">16 -> 4, 8 -> 4, 8 -> 3, 8 -> 2</td></tr>
|
||||
<tr><td width="40%">ADPCM Electronic Arts</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in various EA titles.</td></tr>
|
||||
<tr><td width="40%">ADPCM Electronic Arts Maxis CDROM XS</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Sim City 3000.</td></tr>
|
||||
<tr><td width="40%">ADPCM Electronic Arts R1</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM Electronic Arts R2</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM Electronic Arts R3</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM Electronic Arts XAS</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM G.722</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM G.726</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM IMA AMV</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in AMV files</td></tr>
|
||||
<tr><td width="40%">ADPCM IMA Electronic Arts EACS</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM IMA Electronic Arts SEAD</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM IMA Funcom</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM IMA QuickTime</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM IMA Loki SDL MJPEG</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM IMA WAV</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM IMA Westwood</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM ISS IMA</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in FunCom games.</td></tr>
|
||||
<tr><td width="40%">ADPCM IMA Dialogic</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM IMA Duck DK3</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in some Sega Saturn console games.</td></tr>
|
||||
<tr><td width="40%">ADPCM IMA Duck DK4</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in some Sega Saturn console games.</td></tr>
|
||||
<tr><td width="40%">ADPCM IMA Radical</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM Microsoft</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM MS IMA</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM Nintendo Gamecube AFC</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM Nintendo Gamecube DTK</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM Nintendo Gamecube THP</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM QT IMA</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM SEGA CRI ADX</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Used in Sega Dreamcast games.</td></tr>
|
||||
<tr><td width="40%">ADPCM Shockwave Flash</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM Sound Blaster Pro 2-bit</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM Sound Blaster Pro 2.6-bit</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM Sound Blaster Pro 4-bit</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ADPCM Westwood Studios IMA</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Westwood Studios games like Command and Conquer.</td></tr>
|
||||
<tr><td width="40%">ADPCM Yamaha</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">AMR-NB</td><td width="10%">E</td><td width="10%">X</td><td width="40%">encoding supported through external library libopencore-amrnb</td></tr>
|
||||
<tr><td width="40%">AMR-WB</td><td width="10%">E</td><td width="10%">X</td><td width="40%">encoding supported through external library libvo-amrwbenc</td></tr>
|
||||
<tr><td width="40%">Amazing Studio PAF Audio</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Apple lossless audio</td><td width="10%">X</td><td width="10%">X</td><td width="40%">QuickTime fourcc ’alac’</td></tr>
|
||||
<tr><td width="40%">ATRAC1</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">ATRAC3</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Bink Audio</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Bink and Smacker files in many games.</td></tr>
|
||||
<tr><td width="40%">CELT</td><td width="10%"></td><td width="10%">E</td><td width="40%">decoding supported through external library libcelt</td></tr>
|
||||
<tr><td width="40%">Delphine Software International CIN audio</td><td width="10%"></td><td width="10%">X</td><td width="40%">Codec used in Delphine Software International games.</td></tr>
|
||||
<tr><td width="40%">Discworld II BMV Audio</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">COOK</td><td width="10%"></td><td width="10%">X</td><td width="40%">All versions except 5.1 are supported.</td></tr>
|
||||
<tr><td width="40%">DCA (DTS Coherent Acoustics)</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">DPCM id RoQ</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Used in Quake III, Jedi Knight 2 and other computer games.</td></tr>
|
||||
<tr><td width="40%">DPCM Interplay</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in various Interplay computer games.</td></tr>
|
||||
<tr><td width="40%">DPCM Sierra Online</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Sierra Online game audio files.</td></tr>
|
||||
<tr><td width="40%">DPCM Sol</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">DPCM Xan</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Origin’s Wing Commander IV AVI files.</td></tr>
|
||||
<tr><td width="40%">DSP Group TrueSpeech</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">DV audio</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Enhanced AC-3</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">EVRC (Enhanced Variable Rate Codec)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">FLAC (Free Lossless Audio Codec)</td><td width="10%">X</td><td width="10%">IX</td></tr>
|
||||
<tr><td width="40%">G.723.1</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">G.729</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">GSM</td><td width="10%">E</td><td width="10%">X</td><td width="40%">encoding supported through external library libgsm</td></tr>
|
||||
<tr><td width="40%">GSM Microsoft variant</td><td width="10%">E</td><td width="10%">X</td><td width="40%">encoding supported through external library libgsm</td></tr>
|
||||
<tr><td width="40%">IAC (Indeo Audio Coder)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">iLBC (Internet Low Bitrate Codec)</td><td width="10%">E</td><td width="10%">E</td><td width="40%">encoding and decoding supported through external library libilbc</td></tr>
|
||||
<tr><td width="40%">IMC (Intel Music Coder)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MACE (Macintosh Audio Compression/Expansion) 3:1</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MACE (Macintosh Audio Compression/Expansion) 6:1</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MLP (Meridian Lossless Packing)</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in DVD-Audio discs.</td></tr>
|
||||
<tr><td width="40%">Monkey’s Audio</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MP1 (MPEG audio layer 1)</td><td width="10%"></td><td width="10%">IX</td></tr>
|
||||
<tr><td width="40%">MP2 (MPEG audio layer 2)</td><td width="10%">IX</td><td width="10%">IX</td><td width="40%">libtwolame can be used alternatively for encoding.</td></tr>
|
||||
<tr><td width="40%">MP3 (MPEG audio layer 3)</td><td width="10%">E</td><td width="10%">IX</td><td width="40%">encoding supported through external library LAME, ADU MP3 and MP3onMP4 also supported</td></tr>
|
||||
<tr><td width="40%">MPEG-4 Audio Lossless Coding (ALS)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Musepack SV7</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Musepack SV8</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Nellymoser Asao</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Opus</td><td width="10%">E</td><td width="10%">E</td><td width="40%">supported through external library libopus</td></tr>
|
||||
<tr><td width="40%">PCM A-law</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM mu-law</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 8-bit planar</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 16-bit big-endian planar</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 16-bit little-endian planar</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 24-bit little-endian planar</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 32-bit little-endian planar</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM 32-bit floating point big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM 32-bit floating point little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM 64-bit floating point big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM 64-bit floating point little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM D-Cinema audio signed 24-bit</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 8-bit</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 16-bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 16-bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 24-bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 24-bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 32-bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 32-bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM signed 16/20/24-bit big-endian in MPEG-TS</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM unsigned 8-bit</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM unsigned 16-bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM unsigned 16-bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM unsigned 24-bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM unsigned 24-bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM unsigned 32-bit big-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM unsigned 32-bit little-endian</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PCM Zork</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">QCELP / PureVoice</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">QDesign Music Codec 2</td><td width="10%"></td><td width="10%">X</td><td width="40%">There are still some distortions.</td></tr>
|
||||
<tr><td width="40%">RealAudio 1.0 (14.4K)</td><td width="10%">X</td><td width="10%">X</td><td width="40%">Real 14400 bit/s codec</td></tr>
|
||||
<tr><td width="40%">RealAudio 2.0 (28.8K)</td><td width="10%"></td><td width="10%">X</td><td width="40%">Real 28800 bit/s codec</td></tr>
|
||||
<tr><td width="40%">RealAudio 3.0 (dnet)</td><td width="10%">IX</td><td width="10%">X</td><td width="40%">Real low bitrate AC-3 codec</td></tr>
|
||||
<tr><td width="40%">RealAudio Lossless</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RealAudio SIPR / ACELP.NET</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Shorten</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Sierra VMD audio</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in Sierra VMD files.</td></tr>
|
||||
<tr><td width="40%">Smacker audio</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">SMPTE 302M AES3 audio</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Sonic</td><td width="10%">X</td><td width="10%">X</td><td width="40%">experimental codec</td></tr>
|
||||
<tr><td width="40%">Sonic lossless</td><td width="10%">X</td><td width="10%">X</td><td width="40%">experimental codec</td></tr>
|
||||
<tr><td width="40%">Speex</td><td width="10%">E</td><td width="10%">E</td><td width="40%">supported through external library libspeex</td></tr>
|
||||
<tr><td width="40%">TAK (Tom’s lossless Audio Kompressor)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">True Audio (TTA)</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">TrueHD</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in HD-DVD and Blu-Ray discs.</td></tr>
|
||||
<tr><td width="40%">TwinVQ (VQF flavor)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">VIMA</td><td width="10%"></td><td width="10%">X</td><td width="40%">Used in LucasArts SMUSH animations.</td></tr>
|
||||
<tr><td width="40%">Vorbis</td><td width="10%">E</td><td width="10%">X</td><td width="40%">A native but very primitive encoder exists.</td></tr>
|
||||
<tr><td width="40%">Voxware MetaSound</td><td width="10%"></td><td width="10%">X</td><td width="40%">imperfect and incomplete support</td></tr>
|
||||
<tr><td width="40%">WavPack</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Westwood Audio (SND1)</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Windows Media Audio 1</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Windows Media Audio 2</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Windows Media Audio Lossless</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Windows Media Audio Pro</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Windows Media Audio Voice</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
</table>
|
||||
|
||||
<p><code>X</code> means that encoding (resp. decoding) is supported.
|
||||
</p>
|
||||
<p><code>E</code> means that support is provided through an external library.
|
||||
</p>
|
||||
<p><code>I</code> means that an integer-only version is available, too (ensures high
|
||||
performance on systems without hardware floating point support).
|
||||
</p>
|
||||
<a name="Subtitle-Formats"></a>
|
||||
<h2 class="section"><a href="general.html#toc-Subtitle-Formats">2.5 Subtitle Formats</a></h2>
|
||||
|
||||
<table>
|
||||
<tr><td width="40%">Name</td><td width="10%">Muxing</td><td width="10%">Demuxing</td><td width="10%">Encoding</td><td width="10%">Decoding</td></tr>
|
||||
<tr><td width="40%">3GPP Timed Text</td><td width="10%"></td><td width="10%"></td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">AQTitle</td><td width="10%"></td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">DVB</td><td width="10%">X</td><td width="10%">X</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">DVB teletext</td><td width="10%"></td><td width="10%">X</td><td width="10%"></td><td width="10%">E</td></tr>
|
||||
<tr><td width="40%">DVD</td><td width="10%">X</td><td width="10%">X</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">JACOsub</td><td width="10%">X</td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MicroDVD</td><td width="10%">X</td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MPL2</td><td width="10%"></td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MPsub (MPlayer)</td><td width="10%"></td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PGS</td><td width="10%"></td><td width="10%"></td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">PJS (Phoenix)</td><td width="10%"></td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RealText</td><td width="10%"></td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">SAMI</td><td width="10%"></td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">SSA/ASS</td><td width="10%">X</td><td width="10%">X</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">SubRip (SRT)</td><td width="10%">X</td><td width="10%">X</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">SubViewer v1</td><td width="10%"></td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">SubViewer</td><td width="10%"></td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">TED Talks captions</td><td width="10%"></td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">VobSub (IDX+SUB)</td><td width="10%"></td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">VPlayer</td><td width="10%"></td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">WebVTT</td><td width="10%">X</td><td width="10%">X</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">XSUB</td><td width="10%"></td><td width="10%"></td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
</table>
|
||||
|
||||
<p><code>X</code> means that the feature is supported.
|
||||
</p>
|
||||
<p><code>E</code> means that support is provided through an external library.
|
||||
</p>
|
||||
<a name="Network-Protocols"></a>
|
||||
<h2 class="section"><a href="general.html#toc-Network-Protocols">2.6 Network Protocols</a></h2>
|
||||
|
||||
<table>
|
||||
<tr><td width="40%">Name</td><td width="10%">Support</td></tr>
|
||||
<tr><td width="40%">file</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Gopher</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">HLS</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">HTTP</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">HTTPS</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MMSH</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MMST</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">pipe</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RTMP</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RTMPE</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RTMPS</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RTMPT</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RTMPTE</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RTMPTS</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">RTP</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">SCTP</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">TCP</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">TLS</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">UDP</td><td width="10%">X</td></tr>
|
||||
</table>
|
||||
|
||||
<p><code>X</code> means that the protocol is supported.
|
||||
</p>
|
||||
<p><code>E</code> means that support is provided through an external library.
|
||||
</p>
|
||||
|
||||
<a name="Input_002fOutput-Devices"></a>
|
||||
<h2 class="section"><a href="general.html#toc-Input_002fOutput-Devices">2.7 Input/Output Devices</a></h2>
|
||||
|
||||
<table>
|
||||
<tr><td width="40%">Name</td><td width="10%">Input</td><td width="10%">Output</td></tr>
|
||||
<tr><td width="40%">ALSA</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">BKTR</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">caca</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">DV1394</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">Lavfi virtual device</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">Linux framebuffer</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">JACK</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">LIBCDIO</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">LIBDC1394</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">OpenAL</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">OSS</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Pulseaudio</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">SDL</td><td width="10%"></td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">Video4Linux2</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">VfW capture</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
<tr><td width="40%">X11 grabbing</td><td width="10%">X</td><td width="10%"></td></tr>
|
||||
</table>
|
||||
|
||||
<p><code>X</code> means that input/output is supported.
|
||||
</p>
|
||||
<a name="Timecode"></a>
|
||||
<h2 class="section"><a href="general.html#toc-Timecode">2.8 Timecode</a></h2>
|
||||
|
||||
<table>
|
||||
<tr><td width="40%">Codec/format</td><td width="10%">Read</td><td width="10%">Write</td></tr>
|
||||
<tr><td width="40%">AVI</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">DV</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">GXF</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MOV</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MPEG1/2</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
<tr><td width="40%">MXF</td><td width="10%">X</td><td width="10%">X</td></tr>
|
||||
</table>
|
||||
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle General Documentation
|
||||
@titlepage
|
||||
@center @titlefont{General Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@include general_contents.texi
|
||||
|
||||
@bye
|
||||
+1444
File diff suppressed because it is too large
Load Diff
Vendored
-459
@@ -1,459 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : Using git to develop FFmpeg: </title>
|
||||
|
||||
<meta name="description" content="Using git to develop FFmpeg: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : Using git to develop FFmpeg: ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">Using git to develop FFmpeg</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Introduction" href="#Introduction">1. Introduction</a></li>
|
||||
<li><a name="toc-Basics-Usage" href="#Basics-Usage">2. Basics Usage</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Get-GIT" href="#Get-GIT">2.1 Get GIT</a></li>
|
||||
<li><a name="toc-Cloning-the-source-tree" href="#Cloning-the-source-tree">2.2 Cloning the source tree</a></li>
|
||||
<li><a name="toc-Updating-the-source-tree-to-the-latest-revision" href="#Updating-the-source-tree-to-the-latest-revision">2.3 Updating the source tree to the latest revision</a></li>
|
||||
<li><a name="toc-Rebasing-your-local-branches" href="#Rebasing-your-local-branches">2.4 Rebasing your local branches</a></li>
|
||||
<li><a name="toc-Adding_002fremoving-files_002fdirectories" href="#Adding_002fremoving-files_002fdirectories">2.5 Adding/removing files/directories</a></li>
|
||||
<li><a name="toc-Showing-modifications" href="#Showing-modifications">2.6 Showing modifications</a></li>
|
||||
<li><a name="toc-Inspecting-the-changelog" href="#Inspecting-the-changelog">2.7 Inspecting the changelog</a></li>
|
||||
<li><a name="toc-Checking-source-tree-status" href="#Checking-source-tree-status">2.8 Checking source tree status</a></li>
|
||||
<li><a name="toc-Committing" href="#Committing">2.9 Committing</a></li>
|
||||
<li><a name="toc-Preparing-a-patchset" href="#Preparing-a-patchset">2.10 Preparing a patchset</a></li>
|
||||
<li><a name="toc-Sending-patches-for-review" href="#Sending-patches-for-review">2.11 Sending patches for review</a></li>
|
||||
<li><a name="toc-Renaming_002fmoving_002fcopying-files-or-contents-of-files" href="#Renaming_002fmoving_002fcopying-files-or-contents-of-files">2.12 Renaming/moving/copying files or contents of files</a></li>
|
||||
</ul></li>
|
||||
<li><a name="toc-Git-configuration" href="#Git-configuration">3. Git configuration</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Personal-Git-installation" href="#Personal-Git-installation">3.1 Personal Git installation</a></li>
|
||||
<li><a name="toc-Repository-configuration" href="#Repository-configuration">3.2 Repository configuration</a></li>
|
||||
</ul></li>
|
||||
<li><a name="toc-FFmpeg-specific" href="#FFmpeg-specific">4. FFmpeg specific</a>
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Reverting-broken-commits" href="#Reverting-broken-commits">4.1 Reverting broken commits</a></li>
|
||||
<li><a name="toc-Pushing-changes-to-remote-trees" href="#Pushing-changes-to-remote-trees">4.2 Pushing changes to remote trees</a></li>
|
||||
<li><a name="toc-Finding-a-specific-svn-revision" href="#Finding-a-specific-svn-revision">4.3 Finding a specific svn revision</a></li>
|
||||
</ul></li>
|
||||
<li><a name="toc-pre_002dpush-checklist" href="#pre_002dpush-checklist">5. pre-push checklist</a></li>
|
||||
<li><a name="toc-Server-Issues" href="#Server-Issues">6. Server Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="Introduction"></a>
|
||||
<h1 class="chapter"><a href="git-howto.html#toc-Introduction">1. Introduction</a></h1>
|
||||
|
||||
<p>This document aims in giving some quick references on a set of useful git
|
||||
commands. You should always use the extensive and detailed documentation
|
||||
provided directly by git:
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git --help
|
||||
man git
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>shows you the available subcommands,
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git <command> --help
|
||||
man git-<command>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>shows information about the subcommand <command>.
|
||||
</p>
|
||||
<p>Additional information could be found on the
|
||||
<a href="http://gitref.org">Git Reference</a> website
|
||||
</p>
|
||||
<p>For more information about the Git project, visit the
|
||||
</p>
|
||||
<p><a href="http://git-scm.com/">Git website</a>
|
||||
</p>
|
||||
<p>Consult these resources whenever you have problems, they are quite exhaustive.
|
||||
</p>
|
||||
<p>What follows now is a basic introduction to Git and some FFmpeg-specific
|
||||
guidelines to ease the contribution to the project
|
||||
</p>
|
||||
<a name="Basics-Usage"></a>
|
||||
<h1 class="chapter"><a href="git-howto.html#toc-Basics-Usage">2. Basics Usage</a></h1>
|
||||
|
||||
<a name="Get-GIT"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Get-GIT">2.1 Get GIT</a></h2>
|
||||
|
||||
<p>You can get git from <a href="http://git-scm.com/">http://git-scm.com/</a>
|
||||
Most distribution and operating system provide a package for it.
|
||||
</p>
|
||||
|
||||
<a name="Cloning-the-source-tree"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Cloning-the-source-tree">2.2 Cloning the source tree</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git clone git://source.ffmpeg.org/ffmpeg <target>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>This will put the FFmpeg sources into the directory <var><target></var>.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git clone [email protected]:ffmpeg <target>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>This will put the FFmpeg sources into the directory <var><target></var> and let
|
||||
you push back your changes to the remote repository.
|
||||
</p>
|
||||
<p>Make sure that you do not have Windows line endings in your checkouts,
|
||||
otherwise you may experience spurious compilation failures. One way to
|
||||
achieve this is to run
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git config --global core.autocrlf false
|
||||
</pre></td></tr></table>
|
||||
|
||||
|
||||
<a name="Updating-the-source-tree-to-the-latest-revision"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Updating-the-source-tree-to-the-latest-revision">2.3 Updating the source tree to the latest revision</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git pull (--rebase)
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>pulls in the latest changes from the tracked branch. The tracked branch
|
||||
can be remote. By default the master branch tracks the branch master in
|
||||
the remote origin.
|
||||
</p>
|
||||
<div class="float alert alert-warning">
|
||||
<p><code>--rebase</code> (see below) is recommended.
|
||||
</p></div>
|
||||
<a name="Rebasing-your-local-branches"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Rebasing-your-local-branches">2.4 Rebasing your local branches</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git pull --rebase
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>fetches the changes from the main repository and replays your local commits
|
||||
over it. This is required to keep all your local changes at the top of
|
||||
FFmpeg’s master tree. The master tree will reject pushes with merge commits.
|
||||
</p>
|
||||
|
||||
<a name="Adding_002fremoving-files_002fdirectories"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Adding_002fremoving-files_002fdirectories">2.5 Adding/removing files/directories</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git add [-A] <filename/dirname>
|
||||
git rm [-r] <filename/dirname>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>GIT needs to get notified of all changes you make to your working
|
||||
directory that makes files appear or disappear.
|
||||
Line moves across files are automatically tracked.
|
||||
</p>
|
||||
|
||||
<a name="Showing-modifications"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Showing-modifications">2.6 Showing modifications</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git diff <filename(s)>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>will show all local modifications in your working directory as unified diff.
|
||||
</p>
|
||||
|
||||
<a name="Inspecting-the-changelog"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Inspecting-the-changelog">2.7 Inspecting the changelog</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git log <filename(s)>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>You may also use the graphical tools like gitview or gitk or the web
|
||||
interface available at http://source.ffmpeg.org/
|
||||
</p>
|
||||
<a name="Checking-source-tree-status"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Checking-source-tree-status">2.8 Checking source tree status</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git status
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>detects all the changes you made and lists what actions will be taken in case
|
||||
of a commit (additions, modifications, deletions, etc.).
|
||||
</p>
|
||||
|
||||
<a name="Committing"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Committing">2.9 Committing</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git diff --check
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>to double check your changes before committing them to avoid trouble later
|
||||
on. All experienced developers do this on each and every commit, no matter
|
||||
how small.
|
||||
Every one of them has been saved from looking like a fool by this many times.
|
||||
It’s very easy for stray debug output or cosmetic modifications to slip in,
|
||||
please avoid problems through this extra level of scrutiny.
|
||||
</p>
|
||||
<p>For cosmetics-only commits you should get (almost) empty output from
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git diff -w -b <filename(s)>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>Also check the output of
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git status
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>to make sure you don’t have untracked files or deletions.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git add [-i|-p|-A] <filenames/dirnames>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>Make sure you have told git your name and email address
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git config --global user.name "My Name"
|
||||
git config --global user.email [email protected]
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>Use <var>–global</var> to set the global configuration for all your git checkouts.
|
||||
</p>
|
||||
<p>Git will select the changes to the files for commit. Optionally you can use
|
||||
the interactive or the patch mode to select hunk by hunk what should be
|
||||
added to the commit.
|
||||
</p>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git commit
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>Git will commit the selected changes to your current local branch.
|
||||
</p>
|
||||
<p>You will be prompted for a log message in an editor, which is either
|
||||
set in your personal configuration file through
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git config --global core.editor
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>or set by one of the following environment variables:
|
||||
<var>GIT_EDITOR</var>, <var>VISUAL</var> or <var>EDITOR</var>.
|
||||
</p>
|
||||
<p>Log messages should be concise but descriptive. Explain why you made a change,
|
||||
what you did will be obvious from the changes themselves most of the time.
|
||||
Saying just "bug fix" or "10l" is bad. Remember that people of varying skill
|
||||
levels look at and educate themselves while reading through your code. Don’t
|
||||
include filenames in log messages, Git provides that information.
|
||||
</p>
|
||||
<p>Possibly make the commit message have a terse, descriptive first line, an
|
||||
empty line and then a full description. The first line will be used to name
|
||||
the patch by git format-patch.
|
||||
</p>
|
||||
<a name="Preparing-a-patchset"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Preparing-a-patchset">2.10 Preparing a patchset</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git format-patch <commit> [-o directory]
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>will generate a set of patches for each commit between <var><commit></var> and
|
||||
current <var>HEAD</var>. E.g.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git format-patch origin/master
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>will generate patches for all commits on current branch which are not
|
||||
present in upstream.
|
||||
A useful shortcut is also
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git format-patch -n
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>which will generate patches from last <var>n</var> commits.
|
||||
By default the patches are created in the current directory.
|
||||
</p>
|
||||
<a name="Sending-patches-for-review"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Sending-patches-for-review">2.11 Sending patches for review</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git send-email <commit list|directory>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>will send the patches created by <code>git format-patch</code> or directly
|
||||
generates them. All the email fields can be configured in the global/local
|
||||
configuration or overridden by command line.
|
||||
Note that this tool must often be installed separately (e.g. <var>git-email</var>
|
||||
package on Debian-based distros).
|
||||
</p>
|
||||
|
||||
<a name="Renaming_002fmoving_002fcopying-files-or-contents-of-files"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Renaming_002fmoving_002fcopying-files-or-contents-of-files">2.12 Renaming/moving/copying files or contents of files</a></h2>
|
||||
|
||||
<p>Git automatically tracks such changes, making those normal commits.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">mv/cp path/file otherpath/otherfile
|
||||
git add [-A] .
|
||||
git commit
|
||||
</pre></td></tr></table>
|
||||
|
||||
|
||||
<a name="Git-configuration"></a>
|
||||
<h1 class="chapter"><a href="git-howto.html#toc-Git-configuration">3. Git configuration</a></h1>
|
||||
|
||||
<p>In order to simplify a few workflows, it is advisable to configure both
|
||||
your personal Git installation and your local FFmpeg repository.
|
||||
</p>
|
||||
<a name="Personal-Git-installation"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Personal-Git-installation">3.1 Personal Git installation</a></h2>
|
||||
|
||||
<p>Add the following to your ‘<tt>~/.gitconfig</tt>’ to help <code>git send-email</code>
|
||||
and <code>git format-patch</code> detect renames:
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">[diff]
|
||||
renames = copy
|
||||
</pre></td></tr></table>
|
||||
|
||||
<a name="Repository-configuration"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Repository-configuration">3.2 Repository configuration</a></h2>
|
||||
|
||||
<p>In order to have <code>git send-email</code> automatically send patches
|
||||
to the ffmpeg-devel mailing list, add the following stanza
|
||||
to ‘<tt>/path/to/ffmpeg/repository/.git/config</tt>’:
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">[sendemail]
|
||||
to = [email protected]
|
||||
</pre></td></tr></table>
|
||||
|
||||
<a name="FFmpeg-specific"></a>
|
||||
<h1 class="chapter"><a href="git-howto.html#toc-FFmpeg-specific">4. FFmpeg specific</a></h1>
|
||||
|
||||
<a name="Reverting-broken-commits"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Reverting-broken-commits">4.1 Reverting broken commits</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git reset <commit>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p><code>git reset</code> will uncommit the changes till <var><commit></var> rewriting
|
||||
the current branch history.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git commit --amend
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>allows to amend the last commit details quickly.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git rebase -i origin/master
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>will replay local commits over the main repository allowing to edit, merge
|
||||
or remove some of them in the process.
|
||||
</p>
|
||||
<div class="float alert alert-info">
|
||||
<p><code>git reset</code>, <code>git commit --amend</code> and <code>git rebase</code>
|
||||
rewrite history, so you should use them ONLY on your local or topic branches.
|
||||
The main repository will reject those changes.
|
||||
</p></div>
|
||||
<table><tr><td> </td><td><pre class="example">git revert <commit>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p><code>git revert</code> will generate a revert commit. This will not make the
|
||||
faulty commit disappear from the history.
|
||||
</p>
|
||||
<a name="Pushing-changes-to-remote-trees"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Pushing-changes-to-remote-trees">4.2 Pushing changes to remote trees</a></h2>
|
||||
|
||||
<table><tr><td> </td><td><pre class="example">git push
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>Will push the changes to the default remote (<var>origin</var>).
|
||||
Git will prevent you from pushing changes if the local and remote trees are
|
||||
out of sync. Refer to and to sync the local tree.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git remote add <name> <url>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>Will add additional remote with a name reference, it is useful if you want
|
||||
to push your local branch for review on a remote host.
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git push <remote> <refspec>
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>Will push the changes to the <var><remote></var> repository.
|
||||
Omitting <var><refspec></var> makes <code>git push</code> update all the remote
|
||||
branches matching the local ones.
|
||||
</p>
|
||||
<a name="Finding-a-specific-svn-revision"></a>
|
||||
<h2 class="section"><a href="git-howto.html#toc-Finding-a-specific-svn-revision">4.3 Finding a specific svn revision</a></h2>
|
||||
|
||||
<p>Since version 1.7.1 git supports <var>:/foo</var> syntax for specifying commits
|
||||
based on a regular expression. see man gitrevisions
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git show :/'as revision 23456'
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>will show the svn changeset <var>r23456</var>. With older git versions searching in
|
||||
the <code>git log</code> output is the easiest option (especially if a pager with
|
||||
search capabilities is used).
|
||||
This commit can be checked out with
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git checkout -b svn_23456 :/'as revision 23456'
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>or for git < 1.7.1 with
|
||||
</p>
|
||||
<table><tr><td> </td><td><pre class="example">git checkout -b svn_23456 $SHA1
|
||||
</pre></td></tr></table>
|
||||
|
||||
<p>where <var>$SHA1</var> is the commit hash from the <code>git log</code> output.
|
||||
</p>
|
||||
|
||||
<a name="pre_002dpush-checklist"></a>
|
||||
<h1 class="chapter"><a href="git-howto.html#toc-pre_002dpush-checklist">5. pre-push checklist</a></h1>
|
||||
|
||||
<p>Once you have a set of commits that you feel are ready for pushing,
|
||||
work through the following checklist to doublecheck everything is in
|
||||
proper order. This list tries to be exhaustive. In case you are just
|
||||
pushing a typo in a comment, some of the steps may be unnecessary.
|
||||
Apply your common sense, but if in doubt, err on the side of caution.
|
||||
</p>
|
||||
<p>First, make sure that the commits and branches you are going to push
|
||||
match what you want pushed and that nothing is missing, extraneous or
|
||||
wrong. You can see what will be pushed by running the git push command
|
||||
with –dry-run first. And then inspecting the commits listed with
|
||||
<code>git log -p 1234567..987654</code>. The <code>git status</code> command
|
||||
may help in finding local changes that have been forgotten to be added.
|
||||
</p>
|
||||
<p>Next let the code pass through a full run of our testsuite.
|
||||
</p>
|
||||
<ul>
|
||||
<li> <code>make distclean</code>
|
||||
</li><li> <code>/path/to/ffmpeg/configure</code>
|
||||
</li><li> <code>make check</code>
|
||||
</li><li> if fate fails due to missing samples run <code>make fate-rsync</code> and retry
|
||||
</li></ul>
|
||||
|
||||
<p>Make sure all your changes have been checked before pushing them, the
|
||||
testsuite only checks against regressions and that only to some extend. It does
|
||||
obviously not check newly added features/code to be working unless you have
|
||||
added a test for that (which is recommended).
|
||||
</p>
|
||||
<p>Also note that every single commit should pass the test suite, not just
|
||||
the result of a series of patches.
|
||||
</p>
|
||||
<p>Once everything passed, push the changes to your public ffmpeg clone and post a
|
||||
merge request to ffmpeg-devel. You can also push them directly but this is not
|
||||
recommended.
|
||||
</p>
|
||||
<a name="Server-Issues"></a>
|
||||
<h1 class="chapter"><a href="git-howto.html#toc-Server-Issues">6. Server Issues</a></h1>
|
||||
|
||||
<p>Contact the project admins <a href="mailto:[email protected]">[email protected]</a> if you have technical
|
||||
problems with the GIT server.
|
||||
</p><footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+465
@@ -0,0 +1,465 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle Using Git to develop FFmpeg
|
||||
|
||||
@titlepage
|
||||
@center @titlefont{Using Git to develop FFmpeg}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Introduction
|
||||
|
||||
This document aims in giving some quick references on a set of useful Git
|
||||
commands. You should always use the extensive and detailed documentation
|
||||
provided directly by Git:
|
||||
|
||||
@example
|
||||
git --help
|
||||
man git
|
||||
@end example
|
||||
|
||||
shows you the available subcommands,
|
||||
|
||||
@example
|
||||
git <command> --help
|
||||
man git-<command>
|
||||
@end example
|
||||
|
||||
shows information about the subcommand <command>.
|
||||
|
||||
Additional information could be found on the
|
||||
@url{http://gitref.org, Git Reference} website.
|
||||
|
||||
For more information about the Git project, visit the
|
||||
@url{http://git-scm.com/, Git website}.
|
||||
|
||||
Consult these resources whenever you have problems, they are quite exhaustive.
|
||||
|
||||
What follows now is a basic introduction to Git and some FFmpeg-specific
|
||||
guidelines to ease the contribution to the project.
|
||||
|
||||
@chapter Basics Usage
|
||||
|
||||
@section Get Git
|
||||
|
||||
You can get Git from @url{http://git-scm.com/}
|
||||
Most distribution and operating system provide a package for it.
|
||||
|
||||
|
||||
@section Cloning the source tree
|
||||
|
||||
@example
|
||||
git clone git://source.ffmpeg.org/ffmpeg <target>
|
||||
@end example
|
||||
|
||||
This will put the FFmpeg sources into the directory @var{<target>}.
|
||||
|
||||
@example
|
||||
git clone git@@source.ffmpeg.org:ffmpeg <target>
|
||||
@end example
|
||||
|
||||
This will put the FFmpeg sources into the directory @var{<target>} and let
|
||||
you push back your changes to the remote repository.
|
||||
|
||||
@example
|
||||
git clone gil@@ffmpeg.org:ffmpeg-web <target>
|
||||
@end example
|
||||
|
||||
This will put the source of the FFmpeg website into the directory
|
||||
@var{<target>} and let you push back your changes to the remote repository.
|
||||
(Note that @var{gil} stands for GItoLite and is not a typo of @var{git}.)
|
||||
|
||||
If you don't have write-access to the ffmpeg-web repository, you can
|
||||
create patches after making a read-only ffmpeg-web clone:
|
||||
|
||||
@example
|
||||
git clone git://ffmpeg.org/ffmpeg-web <target>
|
||||
@end example
|
||||
|
||||
Make sure that you do not have Windows line endings in your checkouts,
|
||||
otherwise you may experience spurious compilation failures. One way to
|
||||
achieve this is to run
|
||||
|
||||
@example
|
||||
git config --global core.autocrlf false
|
||||
@end example
|
||||
|
||||
|
||||
@anchor{Updating the source tree to the latest revision}
|
||||
@section Updating the source tree to the latest revision
|
||||
|
||||
@example
|
||||
git pull (--rebase)
|
||||
@end example
|
||||
|
||||
pulls in the latest changes from the tracked branch. The tracked branch
|
||||
can be remote. By default the master branch tracks the branch master in
|
||||
the remote origin.
|
||||
|
||||
@float IMPORTANT
|
||||
@command{--rebase} (see below) is recommended.
|
||||
@end float
|
||||
|
||||
@section Rebasing your local branches
|
||||
|
||||
@example
|
||||
git pull --rebase
|
||||
@end example
|
||||
|
||||
fetches the changes from the main repository and replays your local commits
|
||||
over it. This is required to keep all your local changes at the top of
|
||||
FFmpeg's master tree. The master tree will reject pushes with merge commits.
|
||||
|
||||
|
||||
@section Adding/removing files/directories
|
||||
|
||||
@example
|
||||
git add [-A] <filename/dirname>
|
||||
git rm [-r] <filename/dirname>
|
||||
@end example
|
||||
|
||||
Git needs to get notified of all changes you make to your working
|
||||
directory that makes files appear or disappear.
|
||||
Line moves across files are automatically tracked.
|
||||
|
||||
|
||||
@section Showing modifications
|
||||
|
||||
@example
|
||||
git diff <filename(s)>
|
||||
@end example
|
||||
|
||||
will show all local modifications in your working directory as unified diff.
|
||||
|
||||
|
||||
@section Inspecting the changelog
|
||||
|
||||
@example
|
||||
git log <filename(s)>
|
||||
@end example
|
||||
|
||||
You may also use the graphical tools like @command{gitview} or @command{gitk}
|
||||
or the web interface available at @url{http://source.ffmpeg.org/}.
|
||||
|
||||
@section Checking source tree status
|
||||
|
||||
@example
|
||||
git status
|
||||
@end example
|
||||
|
||||
detects all the changes you made and lists what actions will be taken in case
|
||||
of a commit (additions, modifications, deletions, etc.).
|
||||
|
||||
|
||||
@section Committing
|
||||
|
||||
@example
|
||||
git diff --check
|
||||
@end example
|
||||
|
||||
to double check your changes before committing them to avoid trouble later
|
||||
on. All experienced developers do this on each and every commit, no matter
|
||||
how small.
|
||||
|
||||
Every one of them has been saved from looking like a fool by this many times.
|
||||
It's very easy for stray debug output or cosmetic modifications to slip in,
|
||||
please avoid problems through this extra level of scrutiny.
|
||||
|
||||
For cosmetics-only commits you should get (almost) empty output from
|
||||
|
||||
@example
|
||||
git diff -w -b <filename(s)>
|
||||
@end example
|
||||
|
||||
Also check the output of
|
||||
|
||||
@example
|
||||
git status
|
||||
@end example
|
||||
|
||||
to make sure you don't have untracked files or deletions.
|
||||
|
||||
@example
|
||||
git add [-i|-p|-A] <filenames/dirnames>
|
||||
@end example
|
||||
|
||||
Make sure you have told Git your name and email address
|
||||
|
||||
@example
|
||||
git config --global user.name "My Name"
|
||||
git config --global user.email my@@email.invalid
|
||||
@end example
|
||||
|
||||
Use @option{--global} to set the global configuration for all your Git checkouts.
|
||||
|
||||
Git will select the changes to the files for commit. Optionally you can use
|
||||
the interactive or the patch mode to select hunk by hunk what should be
|
||||
added to the commit.
|
||||
|
||||
|
||||
@example
|
||||
git commit
|
||||
@end example
|
||||
|
||||
Git will commit the selected changes to your current local branch.
|
||||
|
||||
You will be prompted for a log message in an editor, which is either
|
||||
set in your personal configuration file through
|
||||
|
||||
@example
|
||||
git config --global core.editor
|
||||
@end example
|
||||
|
||||
or set by one of the following environment variables:
|
||||
@var{GIT_EDITOR}, @var{VISUAL} or @var{EDITOR}.
|
||||
|
||||
@section Writing a commit message
|
||||
|
||||
Log messages should be concise but descriptive.
|
||||
|
||||
The first line must contain the context, a colon and a very short
|
||||
summary of what the commit does. Details can be added, if necessary,
|
||||
separated by an empty line. These details should not exceed 60-72 characters
|
||||
per line, except when containing code.
|
||||
|
||||
Example of a good commit message:
|
||||
|
||||
@example
|
||||
avcodec/cbs: add a helper to read extradata within packet side data
|
||||
|
||||
Using ff_cbs_read() on the raw buffer will not parse it as extradata,
|
||||
resulting in parsing errors for example when handling ISOBMFF avcC.
|
||||
This helper works around that.
|
||||
@end example
|
||||
|
||||
@example
|
||||
ptr might be NULL
|
||||
@end example
|
||||
|
||||
If the summary on the first line is not enough, in the body of the message,
|
||||
explain why you made a change, what you did will be obvious from the changes
|
||||
themselves most of the time. Saying just "bug fix" or "10l" is bad. Remember
|
||||
that people of varying skill levels look at and educate themselves while
|
||||
reading through your code. Don't include filenames in log messages except in
|
||||
the context, Git provides that information.
|
||||
|
||||
If the commit fixes a registered issue, state it in a separate line of the
|
||||
body: @code{Fix Trac ticket #42.}
|
||||
|
||||
The first line will be used to name
|
||||
the patch by @command{git format-patch}.
|
||||
|
||||
Common mistakes for the first line, as seen in @command{git log --oneline}
|
||||
include: missing context at the beginning; description of what the code did
|
||||
before the patch; line too long or wrapped to the second line.
|
||||
|
||||
@section Preparing a patchset
|
||||
|
||||
@example
|
||||
git format-patch <commit> [-o directory]
|
||||
@end example
|
||||
|
||||
will generate a set of patches for each commit between @var{<commit>} and
|
||||
current @var{HEAD}. E.g.
|
||||
|
||||
@example
|
||||
git format-patch origin/master
|
||||
@end example
|
||||
|
||||
will generate patches for all commits on current branch which are not
|
||||
present in upstream.
|
||||
A useful shortcut is also
|
||||
|
||||
@example
|
||||
git format-patch -n
|
||||
@end example
|
||||
|
||||
which will generate patches from last @var{n} commits.
|
||||
By default the patches are created in the current directory.
|
||||
|
||||
@section Sending patches for review
|
||||
|
||||
@example
|
||||
git send-email <commit list|directory>
|
||||
@end example
|
||||
|
||||
will send the patches created by @command{git format-patch} or directly
|
||||
generates them. All the email fields can be configured in the global/local
|
||||
configuration or overridden by command line.
|
||||
Note that this tool must often be installed separately (e.g. @var{git-email}
|
||||
package on Debian-based distros).
|
||||
|
||||
|
||||
@section Renaming/moving/copying files or contents of files
|
||||
|
||||
Git automatically tracks such changes, making those normal commits.
|
||||
|
||||
@example
|
||||
mv/cp path/file otherpath/otherfile
|
||||
git add [-A] .
|
||||
git commit
|
||||
@end example
|
||||
|
||||
|
||||
@chapter Git configuration
|
||||
|
||||
In order to simplify a few workflows, it is advisable to configure both
|
||||
your personal Git installation and your local FFmpeg repository.
|
||||
|
||||
@section Personal Git installation
|
||||
|
||||
Add the following to your @file{~/.gitconfig} to help @command{git send-email}
|
||||
and @command{git format-patch} detect renames:
|
||||
|
||||
@example
|
||||
[diff]
|
||||
renames = copy
|
||||
@end example
|
||||
|
||||
@section Repository configuration
|
||||
|
||||
In order to have @command{git send-email} automatically send patches
|
||||
to the ffmpeg-devel mailing list, add the following stanza
|
||||
to @file{/path/to/ffmpeg/repository/.git/config}:
|
||||
|
||||
@example
|
||||
[sendemail]
|
||||
to = ffmpeg-devel@@ffmpeg.org
|
||||
@end example
|
||||
|
||||
@chapter FFmpeg specific
|
||||
|
||||
@section Reverting broken commits
|
||||
|
||||
@example
|
||||
git reset <commit>
|
||||
@end example
|
||||
|
||||
@command{git reset} will uncommit the changes till @var{<commit>} rewriting
|
||||
the current branch history.
|
||||
|
||||
@example
|
||||
git commit --amend
|
||||
@end example
|
||||
|
||||
allows one to amend the last commit details quickly.
|
||||
|
||||
@example
|
||||
git rebase -i origin/master
|
||||
@end example
|
||||
|
||||
will replay local commits over the main repository allowing to edit, merge
|
||||
or remove some of them in the process.
|
||||
|
||||
@float NOTE
|
||||
@command{git reset}, @command{git commit --amend} and @command{git rebase}
|
||||
rewrite history, so you should use them ONLY on your local or topic branches.
|
||||
The main repository will reject those changes.
|
||||
@end float
|
||||
|
||||
@example
|
||||
git revert <commit>
|
||||
@end example
|
||||
|
||||
@command{git revert} will generate a revert commit. This will not make the
|
||||
faulty commit disappear from the history.
|
||||
|
||||
@section Pushing changes to remote trees
|
||||
|
||||
@example
|
||||
git push origin master --dry-run
|
||||
@end example
|
||||
|
||||
Will simulate a push of the local master branch to the default remote
|
||||
(@var{origin}). And list which branches and ranges or commits would have been
|
||||
pushed.
|
||||
Git will prevent you from pushing changes if the local and remote trees are
|
||||
out of sync. Refer to @ref{Updating the source tree to the latest revision}.
|
||||
|
||||
@example
|
||||
git remote add <name> <url>
|
||||
@end example
|
||||
|
||||
Will add additional remote with a name reference, it is useful if you want
|
||||
to push your local branch for review on a remote host.
|
||||
|
||||
@example
|
||||
git push <remote> <refspec>
|
||||
@end example
|
||||
|
||||
Will push the changes to the @var{<remote>} repository.
|
||||
Omitting @var{<refspec>} makes @command{git push} update all the remote
|
||||
branches matching the local ones.
|
||||
|
||||
@section Finding a specific svn revision
|
||||
|
||||
Since version 1.7.1 Git supports @samp{:/foo} syntax for specifying commits
|
||||
based on a regular expression. see man gitrevisions
|
||||
|
||||
@example
|
||||
git show :/'as revision 23456'
|
||||
@end example
|
||||
|
||||
will show the svn changeset @samp{r23456}. With older Git versions searching in
|
||||
the @command{git log} output is the easiest option (especially if a pager with
|
||||
search capabilities is used).
|
||||
|
||||
This commit can be checked out with
|
||||
|
||||
@example
|
||||
git checkout -b svn_23456 :/'as revision 23456'
|
||||
@end example
|
||||
|
||||
or for Git < 1.7.1 with
|
||||
|
||||
@example
|
||||
git checkout -b svn_23456 $SHA1
|
||||
@end example
|
||||
|
||||
where @var{$SHA1} is the commit hash from the @command{git log} output.
|
||||
|
||||
|
||||
@chapter Pre-push checklist
|
||||
|
||||
Once you have a set of commits that you feel are ready for pushing,
|
||||
work through the following checklist to doublecheck everything is in
|
||||
proper order. This list tries to be exhaustive. In case you are just
|
||||
pushing a typo in a comment, some of the steps may be unnecessary.
|
||||
Apply your common sense, but if in doubt, err on the side of caution.
|
||||
|
||||
First, make sure that the commits and branches you are going to push
|
||||
match what you want pushed and that nothing is missing, extraneous or
|
||||
wrong. You can see what will be pushed by running the git push command
|
||||
with @option{--dry-run} first. And then inspecting the commits listed with
|
||||
@command{git log -p 1234567..987654}. The @command{git status} command
|
||||
may help in finding local changes that have been forgotten to be added.
|
||||
|
||||
Next let the code pass through a full run of our test suite.
|
||||
|
||||
@itemize
|
||||
@item @command{make distclean}
|
||||
@item @command{/path/to/ffmpeg/configure}
|
||||
@item @command{make fate}
|
||||
@item if fate fails due to missing samples run @command{make fate-rsync} and retry
|
||||
@end itemize
|
||||
|
||||
Make sure all your changes have been checked before pushing them, the
|
||||
test suite only checks against regressions and that only to some extend. It does
|
||||
obviously not check newly added features/code to be working unless you have
|
||||
added a test for that (which is recommended).
|
||||
|
||||
Also note that every single commit should pass the test suite, not just
|
||||
the result of a series of patches.
|
||||
|
||||
Once everything passed, push the changes to your public ffmpeg clone and post a
|
||||
merge request to ffmpeg-devel. You can also push them directly but this is not
|
||||
recommended.
|
||||
|
||||
@chapter Server Issues
|
||||
|
||||
Contact the project admins at @email{root@@ffmpeg.org} if you have technical
|
||||
problems with the Git server.
|
||||
Vendored
+1611
File diff suppressed because it is too large
Load Diff
Vendored
+215
@@ -0,0 +1,215 @@
|
||||
FFmpeg's bug/feature request tracker manual
|
||||
=================================================
|
||||
|
||||
Overview:
|
||||
---------
|
||||
|
||||
FFmpeg uses Trac for tracking issues, new issues and changes to
|
||||
existing issues can be done through a web interface.
|
||||
|
||||
Issues can be different kinds of things we want to keep track of
|
||||
but that do not belong into the source tree itself. This includes
|
||||
bug reports, feature requests and license violations. We
|
||||
might add more items to this list in the future, so feel free to
|
||||
propose a new `type of issue' on the ffmpeg-devel mailing list if
|
||||
you feel it is worth tracking.
|
||||
|
||||
It is possible to subscribe to individual issues by adding yourself to the
|
||||
Cc list or to subscribe to the ffmpeg-trac mailing list which receives
|
||||
a mail for every change to every issue.
|
||||
(the above does all work already after light testing)
|
||||
|
||||
The subscription URL for the ffmpeg-trac list is:
|
||||
https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-trac
|
||||
The URL of the webinterface of the tracker is:
|
||||
https://trac.ffmpeg.org
|
||||
|
||||
Type:
|
||||
-----
|
||||
art
|
||||
Artwork such as photos, music, banners, and logos.
|
||||
|
||||
bug / defect
|
||||
An error, flaw, mistake, failure, or fault in FFmpeg or libav* that
|
||||
prevents it from behaving as intended.
|
||||
|
||||
feature request / enhancement
|
||||
Request of support for encoding or decoding of a new codec, container
|
||||
or variant.
|
||||
Request of support for more, less or plain different output or behavior
|
||||
where the current implementation cannot be considered wrong.
|
||||
|
||||
license violation
|
||||
Ticket to keep track of (L)GPL violations of ffmpeg by others.
|
||||
|
||||
sponsoring request
|
||||
Developer requests for hardware, software, specifications, money,
|
||||
refunds, etc.
|
||||
|
||||
task
|
||||
A task/reminder such as setting up a FATE client, adding filters to
|
||||
Trac, etc.
|
||||
|
||||
Priority:
|
||||
---------
|
||||
critical
|
||||
Bugs about data loss and security issues.
|
||||
No feature request can be critical.
|
||||
|
||||
important
|
||||
Bugs which make FFmpeg unusable for a significant number of users.
|
||||
Examples here might be completely broken MPEG-4 decoding or a build issue
|
||||
on Linux.
|
||||
While broken 4xm decoding or a broken OS/2 build would not be important,
|
||||
the separation to normal is somewhat fuzzy.
|
||||
For feature requests this priority would be used for things many people
|
||||
want.
|
||||
Regressions also should be marked as important, regressions are bugs that
|
||||
don't exist in a past revision or another branch.
|
||||
|
||||
normal
|
||||
Default setting. Use this if the bug does not match the other
|
||||
priorities or if you are unsure of what priority to choose.
|
||||
|
||||
minor
|
||||
Bugs about things like spelling errors, "mp2" instead of
|
||||
"mp3" being shown and such.
|
||||
Feature requests about things few people want or which do not make a big
|
||||
difference.
|
||||
|
||||
wish
|
||||
Something that is desirable to have but that there is no urgency at
|
||||
all to implement, e.g. something completely cosmetic like a website
|
||||
restyle or a personalized doxy template or the FFmpeg logo.
|
||||
This priority is not valid for bugs.
|
||||
|
||||
|
||||
Status:
|
||||
-------
|
||||
new
|
||||
initial state
|
||||
|
||||
open
|
||||
intermediate states
|
||||
|
||||
closed
|
||||
final state
|
||||
|
||||
|
||||
Analyzed flag:
|
||||
--------------
|
||||
Bugs which have been analyzed and where it is understood what causes them
|
||||
and which exact chain of events triggers them. This analysis should be
|
||||
available as a message in the bug report.
|
||||
Note, do not change the status to analyzed without also providing a clear
|
||||
and understandable analysis.
|
||||
This state implicates that the bug either has been reproduced or that
|
||||
reproduction is not needed as the bug is already understood.
|
||||
|
||||
|
||||
Type/Status:
|
||||
----------
|
||||
*/new
|
||||
Initial state of new bugs and feature requests submitted by
|
||||
users.
|
||||
|
||||
*/open
|
||||
Issues which have been briefly looked at and which did not look outright
|
||||
invalid.
|
||||
This implicates that no real more detailed state applies yet. Conversely,
|
||||
the more detailed states below implicate that the issue has been briefly
|
||||
looked at.
|
||||
|
||||
*/closed/duplicate
|
||||
Bugs or feature requests which are duplicates.
|
||||
Note, if you mark something as duplicate, do not forget setting the
|
||||
superseder so bug reports are properly linked.
|
||||
|
||||
*/closed/invalid
|
||||
Bugs caused by user errors, random ineligible or otherwise nonsense stuff.
|
||||
|
||||
*/closed/needs_more_info
|
||||
Issues for which some information has been requested by the developers,
|
||||
but which has not been provided by anyone within reasonable time.
|
||||
|
||||
|
||||
bug/closed/fixed
|
||||
Bugs which have to the best of our knowledge been fixed.
|
||||
|
||||
bug/closed/wontfix
|
||||
Bugs which we will not fix. Possible reasons include legality, high
|
||||
complexity for the sake of supporting obscure corner cases, speed loss
|
||||
for similarly esoteric purposes, et cetera.
|
||||
This also means that we would reject a patch.
|
||||
If we are just too lazy to fix a bug then the correct state is open
|
||||
and unassigned. Closed means that the case is closed which is not
|
||||
the case if we are just waiting for a patch.
|
||||
|
||||
bug/closed/works_for_me
|
||||
Bugs for which sufficient information was provided to reproduce but
|
||||
reproduction failed - that is the code seems to work correctly to the
|
||||
best of our knowledge.
|
||||
|
||||
feature_request/closed/fixed
|
||||
Feature requests which have been implemented.
|
||||
|
||||
feature_request/closed/wontfix
|
||||
Feature requests which will not be implemented. The reasons here could
|
||||
be legal, philosophical or others.
|
||||
|
||||
Note2, if you provide the requested info do not forget to remove the
|
||||
needs_more_info resolution.
|
||||
|
||||
Component:
|
||||
----------
|
||||
|
||||
avcodec
|
||||
issues in libavcodec/*
|
||||
|
||||
avdevice
|
||||
issues in libavdevice/*
|
||||
|
||||
avfilter
|
||||
issues in libavfilter/*
|
||||
|
||||
avformat
|
||||
issues in libavformat/*
|
||||
|
||||
avutil
|
||||
issues in libavutil/*
|
||||
|
||||
build system
|
||||
issues in or related to configure/Makefile
|
||||
|
||||
documentation
|
||||
issues in or related to doc/*
|
||||
|
||||
ffmpeg
|
||||
issues in or related to ffmpeg.c
|
||||
|
||||
ffplay
|
||||
issues in or related to ffplay.c
|
||||
|
||||
ffprobe
|
||||
issues in or related to ffprobe.c
|
||||
|
||||
postproc
|
||||
issues in libpostproc/*
|
||||
|
||||
swresample
|
||||
issues in libswresample/*
|
||||
|
||||
swscale
|
||||
issues in libswscale/*
|
||||
|
||||
trac
|
||||
issues related to our issue tracker
|
||||
|
||||
undetermined
|
||||
default component; choose this if unsure
|
||||
|
||||
website
|
||||
issues related to the website
|
||||
|
||||
wiki
|
||||
issues related to the wiki
|
||||
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
Common abbreviations/shorthands we use that don't need a comment
|
||||
================================================================
|
||||
|
||||
dsp: digital signal processing
|
||||
dst/adst: (asymmetric) discrete sine transform
|
||||
ec: entropy coding or error concealment
|
||||
er: error resilience
|
||||
fdct/idct: forward/inverse discrete cosine transform
|
||||
fft: fast Fourier transform
|
||||
gop: group of pictures
|
||||
hw/sw: hardware/software
|
||||
lp: lowpass
|
||||
lpf: loop filter
|
||||
lut: lookup table
|
||||
mb: macroblock
|
||||
mc: motion compensation
|
||||
me: motion estimation
|
||||
mv: motion vector
|
||||
nal: network abstraction layer
|
||||
pel/qpel/epel/hpel/fpel: pixel / quarter-pixel / eighth-pixel / half-pixel / full-pixel
|
||||
pp: post process
|
||||
qp: quantization parameter
|
||||
rc: rate control
|
||||
sei: supplemental enhancement information
|
||||
sl: slice
|
||||
vlc: variable length coding
|
||||
vq: vector quantization
|
||||
Vendored
+115
@@ -0,0 +1,115 @@
|
||||
CONTEXT
|
||||
=======
|
||||
|
||||
The FFmpeg project merges all the changes from the Libav project
|
||||
(https://libav.org) since the origin of the fork (around 2011).
|
||||
|
||||
With the exceptions of some commits due to technical/political disagreements or
|
||||
issues, the changes are merged on a more or less regular schedule (daily for
|
||||
years thanks to Michael, but more sparse nowadays).
|
||||
|
||||
WHY
|
||||
===
|
||||
|
||||
The majority of the active developers believe the project needs to keep this
|
||||
policy for various reasons.
|
||||
|
||||
The most important one is that we don't want our users to have to choose
|
||||
between two distributors of libraries of the exact same name in order to have a
|
||||
different set of features and bugfixes. By taking the responsibility of
|
||||
unifying the two codebases, we allow users to benefit from the changes from the
|
||||
two teams.
|
||||
|
||||
Today, FFmpeg has a much larger user database (we are distributed by every
|
||||
major distribution), so we consider this mission a priority.
|
||||
|
||||
A different approach to the merge could have been to pick the changes we are
|
||||
interested in and drop most of the cosmetics and other less important changes.
|
||||
Unfortunately, this makes the following picks much harder, especially since the
|
||||
Libav project is involved in various deep API changes. As a result, we decide
|
||||
to virtually take everything done there.
|
||||
|
||||
Any Libav developer is of course welcome anytime to contribute directly to the
|
||||
FFmpeg tree. Of course, we fully understand and are forced to accept that very
|
||||
few Libav developers are interested in doing so, but we still want to recognize
|
||||
their work. This leads us to create merge commits for every single one from
|
||||
Libav. The original commit appears totally unchanged with full authorship in
|
||||
our history (and the conflict are solved in the merge one). That way, not a
|
||||
single thing from Libav will be lost in the future in case some reunification
|
||||
happens, or that project disappears one way or another.
|
||||
|
||||
DOWNSIDES
|
||||
=========
|
||||
|
||||
Of course, there are many downsides to this approach.
|
||||
|
||||
- It causes a non negligible merge commits pollution. We make sure there are
|
||||
not several level of merges entangled (we do a 1:1 merge/commit), but it's
|
||||
still a non-linear history.
|
||||
|
||||
- Many duplicated work. For instance, we added libavresample in our tree to
|
||||
keep compatibility with Libav when our libswresample was already covering the
|
||||
exact same purpose. The same thing happened for various elements such as the
|
||||
ProRes support (but differences in features, bugs, licenses, ...). There are
|
||||
many work to do to unify them, and any help is very much welcome.
|
||||
|
||||
- So much manpower from both FFmpeg and Libav is lost because of this mess. We
|
||||
know it, and we don't know how to fix it. It takes incredible time to do
|
||||
these merges, so we have even less time to work on things we personally care
|
||||
about. The bad vibes also do not help with keeping our developers motivated.
|
||||
|
||||
- There is a growing technical risk factor with the merges due to the codebase
|
||||
differing more and more.
|
||||
|
||||
MERGE GUIDELINES
|
||||
================
|
||||
|
||||
The following gives developer guidelines on how to proceed when merging Libav commits.
|
||||
|
||||
Before starting, you can reduce the risk of errors on merge conflicts by using
|
||||
a different merge conflict style:
|
||||
|
||||
$ git config --global merge.conflictstyle diff3
|
||||
|
||||
tools/libav-merge-next-commit is a script to help merging the next commit in
|
||||
the queue. It assumes a remote named libav. It has two modes: merge, and noop.
|
||||
The noop mode creates a merge with no change to the HEAD. You can pass a hash
|
||||
as extra argument to reference a justification (it is common that we already
|
||||
have the change done in FFmpeg).
|
||||
|
||||
Also see tools/murge, you can copy and paste a 3 way conflict into its stdin
|
||||
and it will display colored diffs. Any arguments to murge (like ones to suppress
|
||||
whitespace differences) are passed into colordiff.
|
||||
|
||||
TODO/FIXME/UNMERGED
|
||||
===================
|
||||
|
||||
Stuff that didn't reach the codebase:
|
||||
-------------------------------------
|
||||
|
||||
- HEVC DSP and x86 MC SIMD improvements from Libav (see https://ffmpeg.org/pipermail/ffmpeg-devel/2015-December/184777.html)
|
||||
- 1f821750f hevcdsp: split the qpel functions by width instead of by the subpixel fraction
|
||||
- 818bfe7f0 hevcdsp: split the epel functions by width
|
||||
- 688417399 hevcdsp: split the pred functions by width
|
||||
- a853388d2 hevc: change the stride of the MC buffer to be in bytes instead of elements
|
||||
- 0cef06df0 checkasm: add HEVC MC tests
|
||||
- e7078e842 hevcdsp: add x86 SIMD for MC
|
||||
- 7993ec19a hevc: Add hevc_get_pixel_4/8/12/16/24/32/48/64
|
||||
- use av_cpu_max_align() instead of hardcoding alignment requirements (see https://ffmpeg.org/pipermail/ffmpeg-devel/2017-September/215834.html)
|
||||
- f44ec22e0 lavc: use av_cpu_max_align() instead of hardcoding alignment requirements
|
||||
- 4de220d2e frame: allow align=0 (meaning automatic) for av_frame_get_buffer()
|
||||
- Support recovery from an already present HLS playlist (see 16cb06bb30)
|
||||
- Remove all output devices (see 8e7e042d41, 8d3db95f20, 6ce13070bd, d46cd24986 and https://ffmpeg.org/pipermail/ffmpeg-devel/2017-September/216904.html)
|
||||
- avcodec/libaomenc: export the Sequence Header OBU as extradata (See a024c3ce9a)
|
||||
|
||||
Collateral damage that needs work locally:
|
||||
------------------------------------------
|
||||
|
||||
- Merge proresenc_anatoliy.c and proresenc_kostya.c
|
||||
- Fix MIPS AC3 downmix
|
||||
|
||||
Extra changes needed to be aligned with Libav:
|
||||
----------------------------------------------
|
||||
|
||||
- Switching our examples to the new encode/decode API (see 67d28f4a0f)
|
||||
- HEVC IDCT bit depth 12-bit support (Libav added 8 and 10 but doesn't have 12)
|
||||
Vendored
-78
@@ -1,78 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : Libavcodec </title>
|
||||
|
||||
<meta name="description" content="Libavcodec Documentation: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : Libavcodec ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">Libavcodec Documentation</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Description" href="#Description">1. Description</a></li>
|
||||
<li><a name="toc-See-Also" href="#See-Also">2. See Also</a></li>
|
||||
<li><a name="toc-Authors" href="#Authors">3. Authors</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="Description"></a>
|
||||
<h1 class="chapter"><a href="libavcodec.html#toc-Description">1. Description</a></h1>
|
||||
|
||||
<p>The libavcodec library provides a generic encoding/decoding framework
|
||||
and contains multiple decoders and encoders for audio, video and
|
||||
subtitle streams, and several bitstream filters.
|
||||
</p>
|
||||
<p>The shared architecture provides various services ranging from bit
|
||||
stream I/O to DSP optimizations, and makes it suitable for
|
||||
implementing robust and fast codecs as well as for experimentation.
|
||||
</p>
|
||||
|
||||
<a name="See-Also"></a>
|
||||
<h1 class="chapter"><a href="libavcodec.html#toc-See-Also">2. See Also</a></h1>
|
||||
|
||||
<p><a href="ffmpeg.html">ffmpeg</a>, <a href="ffplay.html">ffplay</a>, <a href="ffprobe.html">ffprobe</a>, <a href="ffserver.html">ffserver</a>,
|
||||
<a href="ffmpeg-codecs.html">ffmpeg-codecs</a>, <a href="ffmpeg-bitstream-filters.html">bitstream-filters</a>,
|
||||
<a href="libavutil.html">libavutil</a>
|
||||
</p>
|
||||
|
||||
<a name="Authors"></a>
|
||||
<h1 class="chapter"><a href="libavcodec.html#toc-Authors">3. Authors</a></h1>
|
||||
|
||||
<p>The FFmpeg developers.
|
||||
</p>
|
||||
<p>For details about the authorship, see the Git history of the project
|
||||
(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
<code>git log</code> in the FFmpeg source directory, or browsing the
|
||||
online repository at <a href="http://source.ffmpeg.org">http://source.ffmpeg.org</a>.
|
||||
</p>
|
||||
<p>Maintainers for the specific components are listed in the file
|
||||
‘<tt>MAINTAINERS</tt>’ in the source code tree.
|
||||
</p>
|
||||
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+49
@@ -0,0 +1,49 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle Libavcodec Documentation
|
||||
@titlepage
|
||||
@center @titlefont{Libavcodec Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
The libavcodec library provides a generic encoding/decoding framework
|
||||
and contains multiple decoders and encoders for audio, video and
|
||||
subtitle streams, and several bitstream filters.
|
||||
|
||||
The shared architecture provides various services ranging from bit
|
||||
stream I/O to DSP optimizations, and makes it suitable for
|
||||
implementing robust and fast codecs as well as for experimentation.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg-codecs.html,ffmpeg-codecs}, @url{ffmpeg-bitstream-filters.html,bitstream-filters},
|
||||
@url{libavutil.html,libavutil}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1),
|
||||
ffmpeg-codecs(1), ffmpeg-bitstream-filters(1),
|
||||
libavutil(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename libavcodec
|
||||
@settitle media streams decoding and encoding library
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
Vendored
-75
@@ -1,75 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : Libavdevice </title>
|
||||
|
||||
<meta name="description" content="Libavdevice Documentation: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : Libavdevice ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">Libavdevice Documentation</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Description" href="#Description">1. Description</a></li>
|
||||
<li><a name="toc-See-Also" href="#See-Also">2. See Also</a></li>
|
||||
<li><a name="toc-Authors" href="#Authors">3. Authors</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="Description"></a>
|
||||
<h1 class="chapter"><a href="libavdevice.html#toc-Description">1. Description</a></h1>
|
||||
|
||||
<p>The libavdevice library provides a generic framework for grabbing from
|
||||
and rendering to many common multimedia input/output devices, and
|
||||
supports several input and output devices, including Video4Linux2,
|
||||
VfW, DShow, and ALSA.
|
||||
</p>
|
||||
|
||||
<a name="See-Also"></a>
|
||||
<h1 class="chapter"><a href="libavdevice.html#toc-See-Also">2. See Also</a></h1>
|
||||
|
||||
<p><a href="ffmpeg.html">ffmpeg</a>, <a href="ffplay.html">ffplay</a>, <a href="ffprobe.html">ffprobe</a>, <a href="ffserver.html">ffserver</a>,
|
||||
<a href="ffmpeg-devices.html">ffmpeg-devices</a>,
|
||||
<a href="libavutil.html">libavutil</a>, <a href="libavcodec.html">libavcodec</a>, <a href="libavformat.html">libavformat</a>
|
||||
</p>
|
||||
|
||||
<a name="Authors"></a>
|
||||
<h1 class="chapter"><a href="libavdevice.html#toc-Authors">3. Authors</a></h1>
|
||||
|
||||
<p>The FFmpeg developers.
|
||||
</p>
|
||||
<p>For details about the authorship, see the Git history of the project
|
||||
(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
<code>git log</code> in the FFmpeg source directory, or browsing the
|
||||
online repository at <a href="http://source.ffmpeg.org">http://source.ffmpeg.org</a>.
|
||||
</p>
|
||||
<p>Maintainers for the specific components are listed in the file
|
||||
‘<tt>MAINTAINERS</tt>’ in the source code tree.
|
||||
</p>
|
||||
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+46
@@ -0,0 +1,46 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle Libavdevice Documentation
|
||||
@titlepage
|
||||
@center @titlefont{Libavdevice Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
The libavdevice library provides a generic framework for grabbing from
|
||||
and rendering to many common multimedia input/output devices, and
|
||||
supports several input and output devices, including Video4Linux2,
|
||||
VfW, DShow, and ALSA.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg-devices.html,ffmpeg-devices},
|
||||
@url{libavutil.html,libavutil}, @url{libavcodec.html,libavcodec}, @url{libavformat.html,libavformat}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1),
|
||||
ffmpeg-devices(1),
|
||||
libavutil(3), libavcodec(3), libavformat(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename libavdevice
|
||||
@settitle multimedia device handling library
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
Vendored
-74
@@ -1,74 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : Libavfilter </title>
|
||||
|
||||
<meta name="description" content="Libavfilter Documentation: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : Libavfilter ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">Libavfilter Documentation</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Description" href="#Description">1. Description</a></li>
|
||||
<li><a name="toc-See-Also" href="#See-Also">2. See Also</a></li>
|
||||
<li><a name="toc-Authors" href="#Authors">3. Authors</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="Description"></a>
|
||||
<h1 class="chapter"><a href="libavfilter.html#toc-Description">1. Description</a></h1>
|
||||
|
||||
<p>The libavfilter library provides a generic audio/video filtering
|
||||
framework containing several filters, sources and sinks.
|
||||
</p>
|
||||
|
||||
<a name="See-Also"></a>
|
||||
<h1 class="chapter"><a href="libavfilter.html#toc-See-Also">2. See Also</a></h1>
|
||||
|
||||
<p><a href="ffmpeg.html">ffmpeg</a>, <a href="ffplay.html">ffplay</a>, <a href="ffprobe.html">ffprobe</a>, <a href="ffserver.html">ffserver</a>,
|
||||
<a href="ffmpeg-filters.html">ffmpeg-filters</a>,
|
||||
<a href="libavutil.html">libavutil</a>, <a href="libswscale.html">libswscale</a>, <a href="libswresample.html">libswresample</a>,
|
||||
<a href="libavcodec.html">libavcodec</a>, <a href="libavformat.html">libavformat</a>, <a href="libavdevice.html">libavdevice</a>
|
||||
</p>
|
||||
|
||||
<a name="Authors"></a>
|
||||
<h1 class="chapter"><a href="libavfilter.html#toc-Authors">3. Authors</a></h1>
|
||||
|
||||
<p>The FFmpeg developers.
|
||||
</p>
|
||||
<p>For details about the authorship, see the Git history of the project
|
||||
(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
<code>git log</code> in the FFmpeg source directory, or browsing the
|
||||
online repository at <a href="http://source.ffmpeg.org">http://source.ffmpeg.org</a>.
|
||||
</p>
|
||||
<p>Maintainers for the specific components are listed in the file
|
||||
‘<tt>MAINTAINERS</tt>’ in the source code tree.
|
||||
</p>
|
||||
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle Libavfilter Documentation
|
||||
@titlepage
|
||||
@center @titlefont{Libavfilter Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
The libavfilter library provides a generic audio/video filtering
|
||||
framework containing several filters, sources and sinks.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg-filters.html,ffmpeg-filters},
|
||||
@url{libavutil.html,libavutil}, @url{libswscale.html,libswscale}, @url{libswresample.html,libswresample},
|
||||
@url{libavcodec.html,libavcodec}, @url{libavformat.html,libavformat}, @url{libavdevice.html,libavdevice}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1),
|
||||
ffmpeg-filters(1),
|
||||
libavutil(3), libswscale(3), libswresample(3), libavcodec(3), libavformat(3), libavdevice(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename libavfilter
|
||||
@settitle multimedia filtering library
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
Vendored
-78
@@ -1,78 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : Libavformat </title>
|
||||
|
||||
<meta name="description" content="Libavformat Documentation: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : Libavformat ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">Libavformat Documentation</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Description" href="#Description">1. Description</a></li>
|
||||
<li><a name="toc-See-Also" href="#See-Also">2. See Also</a></li>
|
||||
<li><a name="toc-Authors" href="#Authors">3. Authors</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="Description"></a>
|
||||
<h1 class="chapter"><a href="libavformat.html#toc-Description">1. Description</a></h1>
|
||||
|
||||
<p>The libavformat library provides a generic framework for multiplexing
|
||||
and demultiplexing (muxing and demuxing) audio, video and subtitle
|
||||
streams. It encompasses multiple muxers and demuxers for multimedia
|
||||
container formats.
|
||||
</p>
|
||||
<p>It also supports several input and output protocols to access a media
|
||||
resource.
|
||||
</p>
|
||||
|
||||
<a name="See-Also"></a>
|
||||
<h1 class="chapter"><a href="libavformat.html#toc-See-Also">2. See Also</a></h1>
|
||||
|
||||
<p><a href="ffmpeg.html">ffmpeg</a>, <a href="ffplay.html">ffplay</a>, <a href="ffprobe.html">ffprobe</a>, <a href="ffserver.html">ffserver</a>,
|
||||
<a href="ffmpeg-formats.html">ffmpeg-formats</a>, <a href="ffmpeg-protocols.html">ffmpeg-protocols</a>,
|
||||
<a href="libavutil.html">libavutil</a>, <a href="libavcodec.html">libavcodec</a>
|
||||
</p>
|
||||
|
||||
<a name="Authors"></a>
|
||||
<h1 class="chapter"><a href="libavformat.html#toc-Authors">3. Authors</a></h1>
|
||||
|
||||
<p>The FFmpeg developers.
|
||||
</p>
|
||||
<p>For details about the authorship, see the Git history of the project
|
||||
(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
<code>git log</code> in the FFmpeg source directory, or browsing the
|
||||
online repository at <a href="http://source.ffmpeg.org">http://source.ffmpeg.org</a>.
|
||||
</p>
|
||||
<p>Maintainers for the specific components are listed in the file
|
||||
‘<tt>MAINTAINERS</tt>’ in the source code tree.
|
||||
</p>
|
||||
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+49
@@ -0,0 +1,49 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle Libavformat Documentation
|
||||
@titlepage
|
||||
@center @titlefont{Libavformat Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
The libavformat library provides a generic framework for multiplexing
|
||||
and demultiplexing (muxing and demuxing) audio, video and subtitle
|
||||
streams. It encompasses multiple muxers and demuxers for multimedia
|
||||
container formats.
|
||||
|
||||
It also supports several input and output protocols to access a media
|
||||
resource.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg-formats.html,ffmpeg-formats}, @url{ffmpeg-protocols.html,ffmpeg-protocols},
|
||||
@url{libavutil.html,libavutil}, @url{libavcodec.html,libavcodec}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1),
|
||||
ffmpeg-formats(1), ffmpeg-protocols(1),
|
||||
libavutil(3), libavcodec(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename libavformat
|
||||
@settitle multimedia muxing and demuxing library
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
Vendored
-75
@@ -1,75 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : Libavutil </title>
|
||||
|
||||
<meta name="description" content="Libavutil Documentation: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : Libavutil ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">Libavutil Documentation</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Description" href="#Description">1. Description</a></li>
|
||||
<li><a name="toc-See-Also" href="#See-Also">2. See Also</a></li>
|
||||
<li><a name="toc-Authors" href="#Authors">3. Authors</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="Description"></a>
|
||||
<h1 class="chapter"><a href="libavutil.html#toc-Description">1. Description</a></h1>
|
||||
|
||||
<p>The libavutil library is a utility library to aid portable
|
||||
multimedia programming. It contains safe portable string functions,
|
||||
random number generators, data structures, additional mathematics
|
||||
functions, cryptography and multimedia related functionality (like
|
||||
enumerations for pixel and sample formats).
|
||||
</p>
|
||||
|
||||
<a name="See-Also"></a>
|
||||
<h1 class="chapter"><a href="libavutil.html#toc-See-Also">2. See Also</a></h1>
|
||||
|
||||
<p><a href="ffmpeg.html">ffmpeg</a>, <a href="ffplay.html">ffplay</a>, <a href="ffprobe.html">ffprobe</a>, <a href="ffserver.html">ffserver</a>,
|
||||
<a href="ffmpeg-utils.html">ffmpeg-utils</a>
|
||||
</p>
|
||||
|
||||
<a name="Authors"></a>
|
||||
<h1 class="chapter"><a href="libavutil.html#toc-Authors">3. Authors</a></h1>
|
||||
|
||||
<p>The FFmpeg developers.
|
||||
</p>
|
||||
<p>For details about the authorship, see the Git history of the project
|
||||
(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
<code>git log</code> in the FFmpeg source directory, or browsing the
|
||||
online repository at <a href="http://source.ffmpeg.org">http://source.ffmpeg.org</a>.
|
||||
</p>
|
||||
<p>Maintainers for the specific components are listed in the file
|
||||
‘<tt>MAINTAINERS</tt>’ in the source code tree.
|
||||
</p>
|
||||
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+63
@@ -0,0 +1,63 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle Libavutil Documentation
|
||||
@titlepage
|
||||
@center @titlefont{Libavutil Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
The libavutil library is a utility library to aid portable
|
||||
multimedia programming. It contains safe portable string functions,
|
||||
random number generators, data structures, additional mathematics
|
||||
functions, cryptography and multimedia related functionality (like
|
||||
enumerations for pixel and sample formats). It is not a library for
|
||||
code needed by both libavcodec and libavformat.
|
||||
|
||||
The goals for this library is to be:
|
||||
|
||||
@table @strong
|
||||
@item Modular
|
||||
It should have few interdependencies and the possibility of disabling individual
|
||||
parts during @command{./configure}.
|
||||
|
||||
@item Small
|
||||
Both sources and objects should be small.
|
||||
|
||||
@item Efficient
|
||||
It should have low CPU and memory usage.
|
||||
|
||||
@item Useful
|
||||
It should avoid useless features that almost no one needs.
|
||||
@end table
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg-utils.html,ffmpeg-utils}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1),
|
||||
ffmpeg-utils(1)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename libavutil
|
||||
@settitle multimedia-biased utility library
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
Vendored
-100
@@ -1,100 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : Libswresample </title>
|
||||
|
||||
<meta name="description" content="Libswresample Documentation: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : Libswresample ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">Libswresample Documentation</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Description" href="#Description">1. Description</a></li>
|
||||
<li><a name="toc-See-Also" href="#See-Also">2. See Also</a></li>
|
||||
<li><a name="toc-Authors" href="#Authors">3. Authors</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="Description"></a>
|
||||
<h1 class="chapter"><a href="libswresample.html#toc-Description">1. Description</a></h1>
|
||||
|
||||
<p>The libswresample library performs highly optimized audio resampling,
|
||||
rematrixing and sample format conversion operations.
|
||||
</p>
|
||||
<p>Specifically, this library performs the following conversions:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<em>Resampling</em>: is the process of changing the audio rate, for
|
||||
example from a high sample rate of 44100Hz to 8000Hz. Audio
|
||||
conversion from high to low sample rate is a lossy process. Several
|
||||
resampling options and algorithms are available.
|
||||
|
||||
</li><li>
|
||||
<em>Format conversion</em>: is the process of converting the type of
|
||||
samples, for example from 16-bit signed samples to unsigned 8-bit or
|
||||
float samples. It also handles packing conversion, when passing from
|
||||
packed layout (all samples belonging to distinct channels interleaved
|
||||
in the same buffer), to planar layout (all samples belonging to the
|
||||
same channel stored in a dedicated buffer or "plane").
|
||||
|
||||
</li><li>
|
||||
<em>Rematrixing</em>: is the process of changing the channel layout, for
|
||||
example from stereo to mono. When the input channels cannot be mapped
|
||||
to the output streams, the process is lossy, since it involves
|
||||
different gain factors and mixing.
|
||||
</li></ul>
|
||||
|
||||
<p>Various other audio conversions (e.g. stretching and padding) are
|
||||
enabled through dedicated options.
|
||||
</p>
|
||||
|
||||
<a name="See-Also"></a>
|
||||
<h1 class="chapter"><a href="libswresample.html#toc-See-Also">2. See Also</a></h1>
|
||||
|
||||
<p><a href="ffmpeg.html">ffmpeg</a>, <a href="ffplay.html">ffplay</a>, <a href="ffprobe.html">ffprobe</a>, <a href="ffserver.html">ffserver</a>,
|
||||
<a href="ffmpeg-resampler.html">ffmpeg-resampler</a>,
|
||||
<a href="libavutil.html">libavutil</a>
|
||||
</p>
|
||||
|
||||
<a name="Authors"></a>
|
||||
<h1 class="chapter"><a href="libswresample.html#toc-Authors">3. Authors</a></h1>
|
||||
|
||||
<p>The FFmpeg developers.
|
||||
</p>
|
||||
<p>For details about the authorship, see the Git history of the project
|
||||
(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
<code>git log</code> in the FFmpeg source directory, or browsing the
|
||||
online repository at <a href="http://source.ffmpeg.org">http://source.ffmpeg.org</a>.
|
||||
</p>
|
||||
<p>Maintainers for the specific components are listed in the file
|
||||
‘<tt>MAINTAINERS</tt>’ in the source code tree.
|
||||
</p>
|
||||
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+71
@@ -0,0 +1,71 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle Libswresample Documentation
|
||||
@titlepage
|
||||
@center @titlefont{Libswresample Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
The libswresample library performs highly optimized audio resampling,
|
||||
rematrixing and sample format conversion operations.
|
||||
|
||||
Specifically, this library performs the following conversions:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
@emph{Resampling}: is the process of changing the audio rate, for
|
||||
example from a high sample rate of 44100Hz to 8000Hz. Audio
|
||||
conversion from high to low sample rate is a lossy process. Several
|
||||
resampling options and algorithms are available.
|
||||
|
||||
@item
|
||||
@emph{Format conversion}: is the process of converting the type of
|
||||
samples, for example from 16-bit signed samples to unsigned 8-bit or
|
||||
float samples. It also handles packing conversion, when passing from
|
||||
packed layout (all samples belonging to distinct channels interleaved
|
||||
in the same buffer), to planar layout (all samples belonging to the
|
||||
same channel stored in a dedicated buffer or "plane").
|
||||
|
||||
@item
|
||||
@emph{Rematrixing}: is the process of changing the channel layout, for
|
||||
example from stereo to mono. When the input channels cannot be mapped
|
||||
to the output streams, the process is lossy, since it involves
|
||||
different gain factors and mixing.
|
||||
@end itemize
|
||||
|
||||
Various other audio conversions (e.g. stretching and padding) are
|
||||
enabled through dedicated options.
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg-resampler.html,ffmpeg-resampler},
|
||||
@url{libavutil.html,libavutil}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1),
|
||||
ffmpeg-resampler(1),
|
||||
libavutil(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename libswresample
|
||||
@settitle audio resampling library
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
Vendored
-93
@@ -1,93 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Created on January 21, 2014 by texi2html 1.82 -->
|
||||
<!--
|
||||
texi2html was written by:
|
||||
Lionel Cons <[email protected]> (original author)
|
||||
Karl Berry <[email protected]>
|
||||
Olaf Bachmann <[email protected]-kl.de>
|
||||
and many others.
|
||||
Maintained by: Many creative people.
|
||||
Send bugs and suggestions to <texi2html-[email protected]>
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>FFmpeg documentation : Libswscale </title>
|
||||
|
||||
<meta name="description" content="Libswscale Documentation: ">
|
||||
<meta name="keywords" content="FFmpeg documentation : Libswscale ">
|
||||
<meta name="Generator" content="texi2html 1.82">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="default.css" />
|
||||
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
|
||||
<a name="SEC_Top"></a>
|
||||
<h1 class="settitle">Libswscale Documentation</h1>
|
||||
|
||||
<a name="SEC_Contents"></a>
|
||||
<h1>Table of Contents</h1>
|
||||
<div class="contents">
|
||||
|
||||
<ul class="toc">
|
||||
<li><a name="toc-Description" href="#Description">1. Description</a></li>
|
||||
<li><a name="toc-See-Also" href="#See-Also">2. See Also</a></li>
|
||||
<li><a name="toc-Authors" href="#Authors">3. Authors</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a name="Description"></a>
|
||||
<h1 class="chapter"><a href="libswscale.html#toc-Description">1. Description</a></h1>
|
||||
|
||||
<p>The libswscale library performs highly optimized image scaling and
|
||||
colorspace and pixel format conversion operations.
|
||||
</p>
|
||||
<p>Specifically, this library performs the following conversions:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<em>Rescaling</em>: is the process of changing the video size. Several
|
||||
rescaling options and algorithms are available. This is usually a
|
||||
lossy process.
|
||||
|
||||
</li><li>
|
||||
<em>Pixel format conversion</em>: is the process of converting the image
|
||||
format and colorspace of the image, for example from planar YUV420P to
|
||||
RGB24 packed. It also handles packing conversion, that is converts
|
||||
from packed layout (all pixels belonging to distinct planes
|
||||
interleaved in the same buffer), to planar layout (all samples
|
||||
belonging to the same plane stored in a dedicated buffer or "plane").
|
||||
|
||||
<p>This is usually a lossy process in case the source and destination
|
||||
colorspaces differ.
|
||||
</p></li></ul>
|
||||
|
||||
|
||||
<a name="See-Also"></a>
|
||||
<h1 class="chapter"><a href="libswscale.html#toc-See-Also">2. See Also</a></h1>
|
||||
|
||||
<p><a href="ffmpeg.html">ffmpeg</a>, <a href="ffplay.html">ffplay</a>, <a href="ffprobe.html">ffprobe</a>, <a href="ffserver.html">ffserver</a>,
|
||||
<a href="ffmpeg-scaler.html">ffmpeg-scaler</a>,
|
||||
<a href="libavutil.html">libavutil</a>
|
||||
</p>
|
||||
|
||||
<a name="Authors"></a>
|
||||
<h1 class="chapter"><a href="libswscale.html#toc-Authors">3. Authors</a></h1>
|
||||
|
||||
<p>The FFmpeg developers.
|
||||
</p>
|
||||
<p>For details about the authorship, see the Git history of the project
|
||||
(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
<code>git log</code> in the FFmpeg source directory, or browsing the
|
||||
online repository at <a href="http://source.ffmpeg.org">http://source.ffmpeg.org</a>.
|
||||
</p>
|
||||
<p>Maintainers for the specific components are listed in the file
|
||||
‘<tt>MAINTAINERS</tt>’ in the source code tree.
|
||||
</p>
|
||||
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">This document was generated by <em>Kyle Schwarz</em> on <em>January 21, 2014</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.</span></footer></div></div></body>
|
||||
Vendored
+64
@@ -0,0 +1,64 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle Libswscale Documentation
|
||||
@titlepage
|
||||
@center @titlefont{Libswscale Documentation}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
The libswscale library performs highly optimized image scaling and
|
||||
colorspace and pixel format conversion operations.
|
||||
|
||||
Specifically, this library performs the following conversions:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
@emph{Rescaling}: is the process of changing the video size. Several
|
||||
rescaling options and algorithms are available. This is usually a
|
||||
lossy process.
|
||||
|
||||
@item
|
||||
@emph{Pixel format conversion}: is the process of converting the image
|
||||
format and colorspace of the image, for example from planar YUV420P to
|
||||
RGB24 packed. It also handles packing conversion, that is converts
|
||||
from packed layout (all pixels belonging to distinct planes
|
||||
interleaved in the same buffer), to planar layout (all samples
|
||||
belonging to the same plane stored in a dedicated buffer or "plane").
|
||||
|
||||
This is usually a lossy process in case the source and destination
|
||||
colorspaces differ.
|
||||
@end itemize
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg-scaler.html,ffmpeg-scaler},
|
||||
@url{libavutil.html,libavutil}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1),
|
||||
ffmpeg-scaler(1),
|
||||
libavutil(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename libswscale
|
||||
@settitle video scaling and pixel format conversion library
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
+392
@@ -0,0 +1,392 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle FFmpeg Mailing List FAQ
|
||||
@titlepage
|
||||
@center @titlefont{FFmpeg Mailing List FAQ}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@chapter General Questions
|
||||
|
||||
@section What is a mailing list?
|
||||
|
||||
A mailing list is not much different than emailing someone, but the
|
||||
main difference is that your message is received by everyone who
|
||||
subscribes to the list. It is somewhat like a forum but in email form.
|
||||
|
||||
See the @url{https://lists.ffmpeg.org/pipermail/ffmpeg-user/, ffmpeg-user archives}
|
||||
for examples.
|
||||
|
||||
@section What type of questions can I ask?
|
||||
|
||||
@itemize
|
||||
@item
|
||||
@url{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-user/, ffmpeg-user}:
|
||||
For questions involving unscripted usage or compilation of the FFmpeg
|
||||
command-line tools (@command{ffmpeg}, @command{ffprobe}, @command{ffplay}).
|
||||
|
||||
@item
|
||||
@url{https://lists.ffmpeg.org/mailman/listinfo/libav-user/, libav-user}:
|
||||
For questions involving the FFmpeg libav* libraries (libavcodec,
|
||||
libavformat, libavfilter, etc).
|
||||
|
||||
@item
|
||||
@url{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel/, ffmpeg-devel}:
|
||||
For discussions involving the development of FFmpeg and for submitting
|
||||
patches. User questions should be asked at ffmpeg-user or libav-user.
|
||||
@end itemize
|
||||
|
||||
To report a bug see @url{https://ffmpeg.org/bugreports.html}.
|
||||
|
||||
We cannot provide help for scripts and/or third-party tools.
|
||||
|
||||
@anchor{How do I ask a question or send a message to a mailing list?}
|
||||
@section How do I ask a question or send a message to a mailing list?
|
||||
|
||||
First you must @ref{How do I subscribe?, subscribe}. Then all you have to do is
|
||||
send an email:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Email @email{ffmpeg-user@@ffmpeg.org} to send a message to the
|
||||
ffmpeg-user mailing list.
|
||||
|
||||
@item
|
||||
Email @email{libav-user@@ffmpeg.org} to send a message to the
|
||||
libav-user mailing list.
|
||||
|
||||
@item
|
||||
Email @email{ffmpeg-devel@@ffmpeg.org} to send a message to the
|
||||
ffmpeg-devel mailing list.
|
||||
@end itemize
|
||||
|
||||
@chapter Subscribing / Unsubscribing
|
||||
|
||||
@anchor{How do I subscribe?}
|
||||
@section How do I subscribe?
|
||||
|
||||
Email @email{ffmpeg-user-request@@ffmpeg.org} with the subject
|
||||
@emph{subscribe}.
|
||||
|
||||
Or visit the @url{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-user/, ffmpeg-user mailing list info page}
|
||||
and refer to the @emph{Subscribing to ffmpeg-user} section.
|
||||
|
||||
The process is the same for the other mailing lists.
|
||||
|
||||
@section How do I unsubscribe?
|
||||
|
||||
Email @email{ffmpeg-user-request@@ffmpeg.org} with subject @emph{unsubscribe}.
|
||||
|
||||
Or visit the @url{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-user/, ffmpeg-user mailing list info page},
|
||||
scroll to bottom of page, enter your email address in the box, and click
|
||||
the @emph{Unsubscribe or edit options} button.
|
||||
|
||||
The process is the same for the other mailing lists.
|
||||
|
||||
Please avoid asking a mailing list admin to unsubscribe you unless you
|
||||
are absolutely unable to do so by yourself. See @ref{Who do I contact if I have a problem with the mailing list?}
|
||||
|
||||
Note that it is possible to temporarily halt message delivery (vacation mode).
|
||||
See @ref{How do I disable mail delivery without unsubscribing?}
|
||||
|
||||
@chapter Moderation Queue
|
||||
@anchor{Why is my message awaiting moderator approval?}
|
||||
@section Why is my message awaiting moderator approval?
|
||||
|
||||
Some messages are automatically held in the @emph{moderation queue} and
|
||||
must be manually approved by a mailing list admin:
|
||||
|
||||
These are:
|
||||
|
||||
@itemize
|
||||
|
||||
@item
|
||||
Messages that exceed the @ref{What is the message size limit?, message size limit}.
|
||||
|
||||
@item
|
||||
Messages from users whose accounts have been set with the @emph{moderation flag}
|
||||
(very rarely occurs, but may if a user repeatedly ignores the rules
|
||||
or is abusive towards others).
|
||||
@end itemize
|
||||
|
||||
@section How long does it take for my message in the moderation queue to be approved?
|
||||
|
||||
The queue is not checked on a regular basis. You can ask on the
|
||||
@t{#ffmpeg-devel} IRC channel on Libera Chat for someone to approve your message.
|
||||
|
||||
@anchor{How do I delete my message in the moderation queue?}
|
||||
@section How do I delete my message in the moderation queue?
|
||||
|
||||
You should have received an email with the subject @emph{Your message to <mailing list name> awaits moderator approval}.
|
||||
A link is in the message that will allow you to delete your message
|
||||
unless a mailing list admin already approved or rejected it.
|
||||
|
||||
@chapter Archives
|
||||
|
||||
@anchor{Where are the archives?}
|
||||
@section Where are the archives?
|
||||
|
||||
See the @emph{Archives} section on the @url{https://ffmpeg.org/contact.html, FFmpeg Contact}
|
||||
page for links to all FFmpeg mailing list archives.
|
||||
|
||||
Note that the archives are split by month. Discussions that span
|
||||
several months will be split into separate months in the archives.
|
||||
|
||||
@section How do I reply to a message in the archives?
|
||||
|
||||
Click the email link at the top of the message just under the subject
|
||||
title. The link will provide the proper headers to keep the message
|
||||
within the thread.
|
||||
|
||||
Note that you must be subscribed to send a message to the ffmpeg-user or
|
||||
libav-user mailing lists.
|
||||
|
||||
@section How do I search the archives?
|
||||
|
||||
Perform a site search using your favorite search engine. Example:
|
||||
|
||||
@t{site:lists.ffmpeg.org/pipermail/ffmpeg-user/ "search term"}
|
||||
|
||||
@chapter Other
|
||||
|
||||
@section Is there an alternative to the mailing list?
|
||||
|
||||
You can ask for help in the official @t{#ffmpeg} IRC channel on Libera Chat.
|
||||
|
||||
Some users prefer the third-party @url{http://www.ffmpeg-archive.org/, Nabble}
|
||||
interface which presents the mailing lists in a typical forum layout.
|
||||
|
||||
There are also numerous third-party help sites such as
|
||||
@url{https://superuser.com/tags/ffmpeg, Super User} and
|
||||
@url{https://www.reddit.com/r/ffmpeg/, r/ffmpeg on reddit}.
|
||||
|
||||
@anchor{What is top-posting?}
|
||||
@section What is top-posting?
|
||||
|
||||
See @url{https://en.wikipedia.org/wiki/Posting_style#Top-posting}.
|
||||
|
||||
Instead, use trimmed interleaved/inline replies (@url{https://lists.ffmpeg.org/pipermail/ffmpeg-user/2017-April/035849.html, example}).
|
||||
|
||||
@anchor{What is the message size limit?}
|
||||
@section What is the message size limit?
|
||||
|
||||
The message size limit is 1000 kilobytes. Please provide links to larger files
|
||||
instead of attaching them.
|
||||
|
||||
@section Where can I upload sample files?
|
||||
|
||||
Anywhere that is not too annoying for us to use.
|
||||
|
||||
Google Drive and Dropbox are acceptable if you need a file host, and
|
||||
@url{https://0x0.st/, 0x0.st} is good for files under 256 MiB.
|
||||
|
||||
Small, short samples are preferred if possible.
|
||||
|
||||
@section Will I receive spam if I send and/or subscribe to a mailing list?
|
||||
|
||||
Highly unlikely.
|
||||
|
||||
@itemize
|
||||
@item
|
||||
The list of subscribed users is not public.
|
||||
|
||||
@item
|
||||
Email addresses in the archives are obfuscated.
|
||||
|
||||
@item
|
||||
Several unique test email accounts were utilized and none have yet
|
||||
received any spam.
|
||||
@end itemize
|
||||
|
||||
However, you may see a spam in the mailing lists on rare occasions:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Spam in the moderation queue may be accidentally approved due to human
|
||||
error.
|
||||
|
||||
@item
|
||||
There have been a few messages from subscribed users who had their own
|
||||
email addresses hacked and spam messages from (or appearing to be from)
|
||||
the hacked account were sent to their contacts (a mailing list being a
|
||||
contact in these cases).
|
||||
|
||||
@item
|
||||
If you are subscribed to the bug tracker mailing list (ffmpeg-trac) you
|
||||
may see the occasional spam as a false bug report, but we take measures
|
||||
to try to prevent this.
|
||||
@end itemize
|
||||
|
||||
@section How do I filter mailing list messages?
|
||||
|
||||
Use the @emph{List-Id}. For example, the ffmpeg-user mailing list is
|
||||
@t{ffmpeg-user.ffmpeg.org}. You can view the List-Id in the raw message
|
||||
or headers.
|
||||
|
||||
You can then filter the mailing list messages to their own folder.
|
||||
|
||||
@anchor{How do I disable mail delivery without unsubscribing?}
|
||||
@section How do I disable mail delivery without unsubscribing?
|
||||
|
||||
Sometimes you may want to temporarily stop receiving all mailing list
|
||||
messages. This "vacation mode" is simple to do:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Go to the @url{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-user/, ffmpeg-user mailing list info page}
|
||||
|
||||
@item
|
||||
Enter your email address in the box at very bottom of the page and click the
|
||||
@emph{Unsubscribe or edit options} box.
|
||||
|
||||
@item
|
||||
Enter your password and click the @emph{Log in} button.
|
||||
|
||||
@item
|
||||
Look for the @emph{Mail delivery} option. Here you can disable/enable mail
|
||||
delivery. If you check @emph{Set globally} it will apply your choice to all
|
||||
other FFmpeg mailing lists you are subscribed to.
|
||||
@end enumerate
|
||||
|
||||
Alternatively, from your subscribed address, send a message to @email{ffmpeg-user-request@@ffmpeg.org}
|
||||
with the subject @emph{set delivery off}. To re-enable mail delivery send a
|
||||
message to @email{ffmpeg-user-request@@ffmpeg.org} with the subject
|
||||
@emph{set delivery on}.
|
||||
|
||||
@anchor{Why is the mailing list munging my address?}
|
||||
@section Why is the mailing list munging my address?
|
||||
|
||||
This is due to subscribers that use an email service with a DMARC reject policy
|
||||
which adds difficulties to mailing list operators.
|
||||
|
||||
The mailing list must re-write (munge) the @emph{From:} header for such users;
|
||||
otherwise their email service will reject and bounce the message resulting in
|
||||
automatic unsubscribing from the mailing list.
|
||||
|
||||
When sending a message these users will see @emph{via <mailing list name>}
|
||||
added to their name and the @emph{From:} address munged to the address of
|
||||
the particular mailing list.
|
||||
|
||||
If you want to avoid this then please use a different email service.
|
||||
|
||||
Note that ffmpeg-devel does not apply any munging as it causes issues with
|
||||
patch authorship. As a result users with an email service with a DMARC reject
|
||||
policy may be automatically unsubscribed due to rejected and bounced messages.
|
||||
|
||||
@chapter Rules and Etiquette
|
||||
|
||||
@section What are the rules and the proper etiquette?
|
||||
|
||||
There may seem to be many things to remember, but we want to help and
|
||||
following these guidelines will allow you to get answers more quickly
|
||||
and help avoid getting ignored.
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Always show your actual, unscripted @command{ffmpeg} command and the
|
||||
complete, uncut console output from your command.
|
||||
|
||||
@item
|
||||
Use the most simple and minimal command that still shows the issue you
|
||||
are encountering.
|
||||
|
||||
@item
|
||||
Provide all necessary information so others can attempt to duplicate
|
||||
your issue. This includes the actual command, complete uncut console
|
||||
output, and any inputs that are required to duplicate the issue.
|
||||
|
||||
@item
|
||||
Use the latest @command{ffmpeg} build you can get. See the @url{https://ffmpeg.org/download.html, FFmpeg Download}
|
||||
page for links to recent builds for Linux, macOS, and Windows. Or
|
||||
compile from the current git master branch.
|
||||
|
||||
@item
|
||||
Avoid @url{https://en.wikipedia.org/wiki/Posting_style#Top-posting, top-posting}.
|
||||
Also see @ref{What is top-posting?}
|
||||
|
||||
@item
|
||||
Avoid hijacking threads. Thread hijacking is replying to a message and
|
||||
changing the subject line to something unrelated to the original thread.
|
||||
Most email clients will still show the renamed message under the
|
||||
original thread. This can be confusing and these types of messages are
|
||||
often ignored.
|
||||
|
||||
@item
|
||||
Do not send screenshots. Copy and paste console text instead of making
|
||||
screenshots of the text.
|
||||
|
||||
@item
|
||||
Avoid sending email disclaimers and legalese if possible as this is a
|
||||
public list.
|
||||
|
||||
@item
|
||||
Avoid using the @code{-loglevel debug}, @code{-loglevel quiet}, and
|
||||
@command{-hide_banner} options unless requested to do so.
|
||||
|
||||
@item
|
||||
If you attach files avoid compressing small files. Uncompressed is
|
||||
preferred.
|
||||
|
||||
@item
|
||||
Please do not send HTML-only messages. The mailing list will ignore the
|
||||
HTML component of your message. Most mail clients will automatically
|
||||
include a text component: this is what the mailing list will use.
|
||||
|
||||
@item
|
||||
Configuring your mail client to break lines after 70 or so characters is
|
||||
recommended.
|
||||
|
||||
@item
|
||||
Avoid sending the same message to multiple mailing lists.
|
||||
|
||||
@item
|
||||
Please follow our @url{https://ffmpeg.org/developer.html#Code-of-conduct, Code of Conduct}.
|
||||
@end itemize
|
||||
|
||||
@chapter Help
|
||||
|
||||
@section Why am I not receiving any messages?
|
||||
|
||||
Some email providers have blacklists or spam filters that block or mark
|
||||
the mailing list messages as false positives. Unfortunately, the user is
|
||||
often not aware of this and is often out of their control.
|
||||
|
||||
When possible we attempt to notify the provider to be removed from the
|
||||
blacklists or filters.
|
||||
|
||||
@section Why are my sent messages not showing up?
|
||||
|
||||
Excluding @ref{Why is my message awaiting moderator approval?, messages that are held in the moderation queue}
|
||||
there are a few other reasons why your messages may fail to appear:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
HTML-only messages are ignored by the mailing lists. Most mail clients
|
||||
automatically include a text component alongside HTML email: this is what
|
||||
the mailing list will use. If it does not then consider your client to be
|
||||
broken, because sending a text component along with the HTML component to
|
||||
form a multi-part message is recommended by email standards.
|
||||
|
||||
@item
|
||||
Check your spam folder.
|
||||
@end itemize
|
||||
|
||||
@anchor{Why do I keep getting unsubscribed from ffmpeg-devel?}
|
||||
@section Why do I keep getting unsubscribed from ffmpeg-devel?
|
||||
|
||||
Users with an email service that has a DMARC reject or quarantine policy may be
|
||||
automatically unsubscribed from the ffmpeg-devel mailing list due to the mailing
|
||||
list messages being continuously rejected and bounced back.
|
||||
|
||||
Consider using a different email service.
|
||||
|
||||
@anchor{Who do I contact if I have a problem with the mailing list?}
|
||||
@section Who do I contact if I have a problem with the mailing list?
|
||||
|
||||
Send a message to @email{ffmpeg-user-owner@@ffmpeg.org}.
|
||||
|
||||
@bye
|
||||
Vendored
+88
@@ -0,0 +1,88 @@
|
||||
@chapter Metadata
|
||||
@c man begin METADATA
|
||||
|
||||
FFmpeg is able to dump metadata from media files into a simple UTF-8-encoded
|
||||
INI-like text file and then load it back using the metadata muxer/demuxer.
|
||||
|
||||
The file format is as follows:
|
||||
@enumerate
|
||||
|
||||
@item
|
||||
A file consists of a header and a number of metadata tags divided into sections,
|
||||
each on its own line.
|
||||
|
||||
@item
|
||||
The header is a @samp{;FFMETADATA} string, followed by a version number (now 1).
|
||||
|
||||
@item
|
||||
Metadata tags are of the form @samp{key=value}
|
||||
|
||||
@item
|
||||
Immediately after header follows global metadata
|
||||
|
||||
@item
|
||||
After global metadata there may be sections with per-stream/per-chapter
|
||||
metadata.
|
||||
|
||||
@item
|
||||
A section starts with the section name in uppercase (i.e. STREAM or CHAPTER) in
|
||||
brackets (@samp{[}, @samp{]}) and ends with next section or end of file.
|
||||
|
||||
@item
|
||||
At the beginning of a chapter section there may be an optional timebase to be
|
||||
used for start/end values. It must be in form
|
||||
@samp{TIMEBASE=@var{num}/@var{den}}, where @var{num} and @var{den} are
|
||||
integers. If the timebase is missing then start/end times are assumed to
|
||||
be in nanoseconds.
|
||||
|
||||
Next a chapter section must contain chapter start and end times in form
|
||||
@samp{START=@var{num}}, @samp{END=@var{num}}, where @var{num} is a positive
|
||||
integer.
|
||||
|
||||
@item
|
||||
Empty lines and lines starting with @samp{;} or @samp{#} are ignored.
|
||||
|
||||
@item
|
||||
Metadata keys or values containing special characters (@samp{=}, @samp{;},
|
||||
@samp{#}, @samp{\} and a newline) must be escaped with a backslash @samp{\}.
|
||||
|
||||
@item
|
||||
Note that whitespace in metadata (e.g. @samp{foo = bar}) is considered to be
|
||||
a part of the tag (in the example above key is @samp{foo }, value is
|
||||
@samp{ bar}).
|
||||
@end enumerate
|
||||
|
||||
A ffmetadata file might look like this:
|
||||
@example
|
||||
;FFMETADATA1
|
||||
title=bike\\shed
|
||||
;this is a comment
|
||||
artist=FFmpeg troll team
|
||||
|
||||
[CHAPTER]
|
||||
TIMEBASE=1/1000
|
||||
START=0
|
||||
#chapter ends at 0:01:00
|
||||
END=60000
|
||||
title=chapter \#1
|
||||
[STREAM]
|
||||
title=multi\
|
||||
line
|
||||
@end example
|
||||
|
||||
By using the ffmetadata muxer and demuxer it is possible to extract
|
||||
metadata from an input file to an ffmetadata file, and then transcode
|
||||
the file into an output file with the edited ffmetadata file.
|
||||
|
||||
Extracting an ffmetadata file with @file{ffmpeg} goes as follows:
|
||||
@example
|
||||
ffmpeg -i INPUT -f ffmetadata FFMETADATAFILE
|
||||
@end example
|
||||
|
||||
Reinserting edited metadata information from the FFMETADATAFILE file can
|
||||
be done as:
|
||||
@example
|
||||
ffmpeg -i INPUT -i FFMETADATAFILE -map_metadata 1 -codec copy OUTPUT
|
||||
@end example
|
||||
|
||||
@c man end METADATA
|
||||
Vendored
+79
@@ -0,0 +1,79 @@
|
||||
MIPS optimizations info
|
||||
===============================================
|
||||
|
||||
MIPS optimizations of codecs are targeting MIPS 74k family of
|
||||
CPUs. Some of these optimizations are relying more on properties of
|
||||
this architecture and some are relying less (and can be used on most
|
||||
MIPS architectures without degradation in performance).
|
||||
|
||||
Along with FFMPEG copyright notice, there is MIPS copyright notice in
|
||||
all the files that are created by people from MIPS Technologies.
|
||||
|
||||
Example of copyright notice:
|
||||
===============================================
|
||||
/*
|
||||
* Copyright (c) 2012
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Author Name (author_name@@mips.com)
|
||||
*/
|
||||
|
||||
Files that have MIPS copyright notice in them:
|
||||
===============================================
|
||||
* libavutil/mips/
|
||||
float_dsp_mips.c
|
||||
libm_mips.h
|
||||
softfloat_tables.h
|
||||
* libavcodec/
|
||||
fft_fixed_32.c
|
||||
fft_init_table.c
|
||||
fft_table.h
|
||||
mdct_fixed_32.c
|
||||
* libavcodec/mips/
|
||||
aacdec_fixed.c
|
||||
aacsbr_fixed.c
|
||||
aacsbr_template.c
|
||||
aaccoder_mips.c
|
||||
aacpsy_mips.h
|
||||
ac3dsp_mips.c
|
||||
acelp_filters_mips.c
|
||||
acelp_vectors_mips.c
|
||||
amrwbdec_mips.c
|
||||
amrwbdec_mips.h
|
||||
celp_filters_mips.c
|
||||
celp_math_mips.c
|
||||
compute_antialias_fixed.h
|
||||
compute_antialias_float.h
|
||||
lsp_mips.h
|
||||
dsputil_mips.c
|
||||
fft_mips.c
|
||||
fft_table.h
|
||||
fft_init_table.c
|
||||
fmtconvert_mips.c
|
||||
iirfilter_mips.c
|
||||
mpegaudiodsp_mips_fixed.c
|
||||
mpegaudiodsp_mips_float.c
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user