Compare commits
103 Commits
release/0.
...
v0.6
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d7e98ea6ac | ||
![]() |
8182bcae90 | ||
![]() |
522f1861ca | ||
![]() |
44f91788a5 | ||
![]() |
03b47bb8d7 | ||
![]() |
05b4e4fe49 | ||
![]() |
3229bf8573 | ||
![]() |
db06ddf8c6 | ||
![]() |
eb4b8b96fc | ||
![]() |
373010971e | ||
![]() |
c3cd8890fe | ||
![]() |
20d4a1f020 | ||
![]() |
e5880b3f24 | ||
![]() |
4b51239df3 | ||
![]() |
4979362ae4 | ||
![]() |
0546386dff | ||
![]() |
70ea5176a5 | ||
![]() |
661092004f | ||
![]() |
f7f9f18f83 | ||
![]() |
55291e37f5 | ||
![]() |
1f1d2fa75c | ||
![]() |
2a546cecbf | ||
![]() |
8f3504c3ca | ||
![]() |
bf20d5e4bb | ||
![]() |
3fa19f6828 | ||
![]() |
4e62a67389 | ||
![]() |
46ac6315fd | ||
9052b5b73b | |||
![]() |
9181adff9c | ||
![]() |
8261cce1f0 | ||
![]() |
df62b0d9f5 | ||
![]() |
e63d03e7e2 | ||
![]() |
7920dc8802 | ||
![]() |
057287c9cd | ||
![]() |
1746657479 | ||
![]() |
0ff244dea2 | ||
![]() |
0078216f07 | ||
![]() |
12ca60ec15 | ||
![]() |
2c3439b008 | ||
![]() |
cdfe333493 | ||
![]() |
5f1a8c5e80 | ||
![]() |
b5afece607 | ||
![]() |
6ae05f541a | ||
![]() |
9d3bb3501d | ||
![]() |
0b374e40b1 | ||
![]() |
a2a26d108b | ||
![]() |
49aa53f2d7 | ||
![]() |
fb2fc3a4f0 | ||
![]() |
36edfb558b | ||
![]() |
4a7c99d6f3 | ||
![]() |
327afd42b4 | ||
![]() |
a22222dadb | ||
![]() |
28631e9393 | ||
![]() |
f8a6c707a5 | ||
![]() |
c9b841c2b1 | ||
![]() |
15b20ef6f9 | ||
![]() |
1dea5cfbb0 | ||
![]() |
d48539fb85 | ||
![]() |
a14f86aac7 | ||
![]() |
6438cb834c | ||
![]() |
ed2b1f80fa | ||
![]() |
3d24c2ce02 | ||
![]() |
7d8b893b7e | ||
![]() |
e6ef35bc22 | ||
![]() |
3588e6b7c5 | ||
![]() |
34a0dee17e | ||
![]() |
b9a35435a5 | ||
![]() |
85ed859e6b | ||
![]() |
fcaba83909 | ||
![]() |
daf864016d | ||
![]() |
7454142424 | ||
![]() |
a7216204eb | ||
![]() |
cff1f85c3f | ||
![]() |
dd92ff49c9 | ||
![]() |
b12045c8c7 | ||
![]() |
a70e7cc928 | ||
![]() |
6f8fbbf8d7 | ||
![]() |
b68d9df427 | ||
![]() |
26fe0ec7d6 | ||
![]() |
7590718414 | ||
![]() |
37a0852009 | ||
![]() |
b50601e882 | ||
![]() |
d1026ab506 | ||
![]() |
08a441d4ad | ||
![]() |
369e37e900 | ||
![]() |
40630a90ed | ||
![]() |
dc04fb36d7 | ||
![]() |
8740ed496c | ||
![]() |
77a023f422 | ||
![]() |
ba9cecf5e5 | ||
![]() |
8ab1409a59 | ||
![]() |
3589ac6334 | ||
![]() |
dd68bb3cab | ||
![]() |
50dab63690 | ||
![]() |
da8e4f5f79 | ||
![]() |
e0e0283778 | ||
![]() |
1673bf86d6 | ||
![]() |
0db6f6cfed | ||
![]() |
9d08b20fea | ||
![]() |
a03dcb9682 | ||
![]() |
26899578f1 | ||
![]() |
eb9df4ac33 | ||
![]() |
64c2076bfc |
14
Changelog
14
Changelog
@@ -1,8 +1,7 @@
|
||||
Entries are sorted chronologically from oldest to youngest within each release,
|
||||
releases are sorted from youngest to oldest.
|
||||
|
||||
|
||||
version <next>:
|
||||
version 0.6:
|
||||
|
||||
- PB-frame decoding for H.263
|
||||
- deprecated vhook subsystem removed
|
||||
@@ -70,6 +69,17 @@ version <next>:
|
||||
- Psygnosis YOP demuxer and video decoder
|
||||
- spectral extension support in the E-AC-3 decoder
|
||||
- unsharp video filter
|
||||
- RTP hinting in the mov/3gp/mp4 muxer
|
||||
- Dirac in Ogg demuxing
|
||||
- seek to keyframes in Ogg
|
||||
- 4:2:2 and 4:4:4 Theora decoding
|
||||
- 35% faster VP3/Theora decoding
|
||||
- faster AAC decoding
|
||||
- faster H.264 decoding
|
||||
- WebM support in Matroska de/muxer
|
||||
- low overhead Ogg muxing
|
||||
- VP8 de/encoding via libvpx
|
||||
- CODEC_CAP_EXPERIMENTAL added
|
||||
|
||||
|
||||
|
||||
|
96
RELEASE
Normal file
96
RELEASE
Normal file
@@ -0,0 +1,96 @@
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
* 0.6 "Works with HTML5" June, 2010
|
||||
|
||||
General notes
|
||||
-------------
|
||||
|
||||
This release features a lot of improvements that are relevant for HTML5 video.
|
||||
The H.264 and Theora decoders are now significantly faster, the vorbis decoder
|
||||
has seen important updates and this release supports Google's newly released
|
||||
libvpx library for the VP8 codec and WEBM container.
|
||||
|
||||
Other important changes are additions of decoders including, but not limited to,
|
||||
Intel Indeo 5, WMA Pro, WMA Voice and HE-AAC.
|
||||
|
||||
See the Changelog file for a list of significant changes.
|
||||
|
||||
Please note that our policy on bug reports has not changed. We still only accept
|
||||
bug reports against HEAD of the FFmpeg trunk repository. If you are experiencing
|
||||
any issues with any formally released version of FFmpeg, please try a current
|
||||
version of the development code to check if the issue still exists. If it does,
|
||||
make your report against the development code following the usual bug reporting
|
||||
guidelines.
|
||||
|
||||
|
||||
API and other notable Changes
|
||||
-----------------------------
|
||||
|
||||
Please see the file doc/APIchanges for programmer-centric information.
|
||||
|
||||
Notable changes:
|
||||
- deprecated vhook subsystem removed
|
||||
- deprecated old scaler removed
|
||||
- nonfree libamr support for AMR-NB/WB decoding/encoding removed
|
||||
- RTMP support in libavformat
|
||||
- -formats option split into -formats, -codecs, -bsfs, and -protocols
|
||||
- ffprobe tool
|
||||
- RTMP/RTMPT/RTMPS/RTMPE/RTMPTE protocol support via librtmp
|
||||
- CODEC_CAP_EXPERIMENTAL added
|
||||
|
||||
|
||||
Added Codecs:
|
||||
-------------
|
||||
|
||||
- VQF demuxer
|
||||
- PCX encoder
|
||||
- CorePNG decoding support
|
||||
- 8088flex TMV demuxer and decoder
|
||||
- enable symbol versioning by default for linkers that support it
|
||||
- V210 decoder and encoder
|
||||
- QCP demuxer
|
||||
- SoX native format muxer and demuxer
|
||||
- AMR-NB decoding/encoding, AMR-WB decoding via OpenCORE libraries
|
||||
- DPX image decoder
|
||||
- Electronic Arts Madcow decoder
|
||||
- DivX (XSUB) subtitle encoder
|
||||
- experimental AAC encoder
|
||||
- Wave64 demuxer
|
||||
- IEC-61937 compatible Muxer
|
||||
- TwinVQ decoder
|
||||
- Bluray (PGS) subtitle decoder
|
||||
- LPCM support in MPEG-TS (HDMV RID as found on Blu-ray disks)
|
||||
- WMA Pro decoder
|
||||
- Core Audio Format demuxer
|
||||
- Atrac1 decoder
|
||||
- MD STUDIO audio demuxer
|
||||
- RF64 support in WAV demuxer
|
||||
- MPEG-4 Audio Lossless Coding (ALS) decoder
|
||||
- IV8 demuxer
|
||||
- CDG demuxer and decoder
|
||||
- R210 decoder
|
||||
- Auravision Aura 1 and 2 decoders
|
||||
- Deluxe Paint Animation playback system
|
||||
- SIPR decoder
|
||||
- Adobe Filmstrip muxer and demuxer
|
||||
- RTP packetization and depacketization of H.263 and AMR
|
||||
- Bink demuxer and audio/video decoders
|
||||
- IFF PBM/ILBM bitmap decoder
|
||||
- Indeo 5 decoder
|
||||
- WMA Voice decoder
|
||||
- AMR-NB decoder
|
||||
- RTSP muxer
|
||||
- HE-AAC v1 decoder
|
||||
- Kega Game Video (KGV1) decoder
|
||||
- Psygnosis YOP demuxer and video decoder
|
||||
- RTP hinting in the mov/3gp/mp4 muxer
|
||||
- VP8 decoding via libvpx
|
||||
|
||||
|
||||
Notable license related changes
|
||||
-------------------------------
|
||||
|
||||
- remaining GPL parts in AC-3 decoder converted to LGPL
|
||||
- libswscale can now be compiled in LGPL mode
|
||||
- libvpx is considered (L)GPL incompatible
|
21
cmdutils.c
21
cmdutils.c
@@ -292,17 +292,11 @@ void set_context_opts(void *ctx, void *opts_ctx, int flags)
|
||||
void print_error(const char *filename, int err)
|
||||
{
|
||||
char errbuf[128];
|
||||
const char *errbuf_ptr = errbuf;
|
||||
|
||||
switch(err) {
|
||||
#if CONFIG_NETWORK
|
||||
case FF_NETERROR(EPROTONOSUPPORT):
|
||||
fprintf(stderr, "%s: Unsupported network protocol\n", filename);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
av_strerror(err, errbuf, sizeof(errbuf));
|
||||
fprintf(stderr, "%s: %s\n", filename, errbuf);
|
||||
}
|
||||
if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
|
||||
errbuf_ptr = strerror(AVUNERROR(err));
|
||||
fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
|
||||
}
|
||||
|
||||
#define PRINT_LIB_VERSION(outstream,libname,LIBNAME,indent) \
|
||||
@@ -615,6 +609,11 @@ void show_pix_fmts(void)
|
||||
"FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
|
||||
"-----\n");
|
||||
|
||||
#if !CONFIG_SWSCALE
|
||||
# define sws_isSupportedInput(x) 0
|
||||
# define sws_isSupportedOutput(x) 0
|
||||
#endif
|
||||
|
||||
for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
|
||||
const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
|
||||
printf("%c%c%c%c%c %-16s %d %2d\n",
|
||||
@@ -642,7 +641,7 @@ int read_yesno(void)
|
||||
|
||||
int read_file(const char *filename, char **bufptr, size_t *size)
|
||||
{
|
||||
FILE *f = fopen(filename, "r");
|
||||
FILE *f = fopen(filename, "rb");
|
||||
|
||||
if (!f) {
|
||||
fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
|
||||
|
@@ -134,6 +134,15 @@ void parse_options(int argc, char **argv, const OptionDef *options,
|
||||
|
||||
void set_context_opts(void *ctx, void *opts_ctx, int flags);
|
||||
|
||||
/**
|
||||
* Prints an error message to stderr, indicating filename and a human
|
||||
* readable description of the error code err.
|
||||
*
|
||||
* If strerror_r() is not available the use of this function in a
|
||||
* multithreaded application may be unsafe.
|
||||
*
|
||||
* @see av_strerror()
|
||||
*/
|
||||
void print_error(const char *filename, int err);
|
||||
|
||||
void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts);
|
||||
|
34
configure
vendored
34
configure
vendored
@@ -183,6 +183,7 @@ External library support:
|
||||
--enable-libtheora enable Theora encoding via libtheora [no]
|
||||
--enable-libvorbis enable Vorbis encoding via libvorbis,
|
||||
native implementation exists [no]
|
||||
--enable-libvpx enable VP8 support via libvpx [no]
|
||||
--enable-libx264 enable H.264 encoding via x264 [no]
|
||||
--enable-libxvid enable Xvid encoding via xvidcore,
|
||||
native MPEG-4/Xvid encoder exists [no]
|
||||
@@ -252,6 +253,8 @@ EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
quotes='""'
|
||||
|
||||
log(){
|
||||
echo "$@" >> $logfile
|
||||
}
|
||||
@@ -927,6 +930,7 @@ CONFIG_LIST="
|
||||
libspeex
|
||||
libtheora
|
||||
libvorbis
|
||||
libvpx
|
||||
libx264
|
||||
libxvid
|
||||
lpc
|
||||
@@ -1084,6 +1088,9 @@ HAVE_LIST="
|
||||
struct_sockaddr_in6
|
||||
struct_sockaddr_sa_len
|
||||
struct_sockaddr_storage
|
||||
symver
|
||||
symver_gnu_asm
|
||||
symver_asm_label
|
||||
sys_mman_h
|
||||
sys_resource_h
|
||||
sys_select_h
|
||||
@@ -1198,6 +1205,8 @@ fast_unaligned_if_any="armv6 ppc x86"
|
||||
need_memalign="altivec neon sse"
|
||||
inline_asm_deps="!tms470"
|
||||
|
||||
symver_if_any="symver_asm_label symver_gnu_asm"
|
||||
|
||||
# subsystems
|
||||
mdct_select="fft"
|
||||
rdft_select="fft"
|
||||
@@ -1334,7 +1343,7 @@ libdirac_decoder_deps="libdirac !libschroedinger"
|
||||
libdirac_encoder_deps="libdirac"
|
||||
libfaac_encoder_deps="libfaac"
|
||||
libfaad_decoder_deps="libfaad"
|
||||
libfaadbin_decoder_extralibs='$ldl'
|
||||
libfaadbin_extralibs='$ldl'
|
||||
libgsm_decoder_deps="libgsm"
|
||||
libgsm_encoder_deps="libgsm"
|
||||
libgsm_ms_decoder_deps="libgsm"
|
||||
@@ -1349,6 +1358,8 @@ libschroedinger_encoder_deps="libschroedinger"
|
||||
libspeex_decoder_deps="libspeex"
|
||||
libtheora_encoder_deps="libtheora"
|
||||
libvorbis_encoder_deps="libvorbis"
|
||||
libvpx_decoder_deps="libvpx"
|
||||
libvpx_encoder_deps="libvpx"
|
||||
libx264_encoder_deps="libx264"
|
||||
libxvid_encoder_deps="libxvid"
|
||||
|
||||
@@ -2406,11 +2417,6 @@ EOF
|
||||
|
||||
enabled_all armv6t2 shared !pic && enable_pic
|
||||
|
||||
elif enabled ia64; then
|
||||
|
||||
# HACK: currently fails to build if .bss is > 4MB and shared libs are built
|
||||
enabled shared && enable_weak hardcoded_tables
|
||||
|
||||
elif enabled mips; then
|
||||
|
||||
check_asm loongson '"dmult.g $1, $2, $3"'
|
||||
@@ -2611,12 +2617,14 @@ enabled libnut && require libnut libnut.h nut_demuxer_init -lnut
|
||||
enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb -lm
|
||||
enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb -lm
|
||||
enabled libopenjpeg && require libopenjpeg openjpeg.h opj_version -lopenjpeg
|
||||
enabled librtmp && require librtmp librtmp/rtmp.h RTMP_Init -lrtmp
|
||||
enabled librtmp && require librtmp librtmp/rtmp.h RTMP_Init $(pkg-config --libs librtmp)
|
||||
enabled libschroedinger && add_cflags $(pkg-config --cflags schroedinger-1.0) &&
|
||||
require libschroedinger schroedinger/schro.h schro_init $(pkg-config --libs schroedinger-1.0)
|
||||
enabled libspeex && require libspeex speex/speex.h speex_decoder_init -lspeex
|
||||
enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
|
||||
enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
|
||||
enabled libvpx && require2 libvpx "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_dec_init_ver" -lvpx &&
|
||||
require2 libvpx "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_enc_init_ver" -lvpx
|
||||
enabled libx264 && require libx264 x264.h x264_encoder_encode -lx264 -lm &&
|
||||
{ check_cpp_condition x264.h "X264_BUILD >= 83" ||
|
||||
die "ERROR: libx264 version must be >= 0.83."; }
|
||||
@@ -2731,8 +2739,17 @@ check_ldflags '-Wl,-rpath-link,\$(BUILD_ROOT)/libpostproc -Wl,-rpath-link,\$(BUI
|
||||
check_ldflags -Wl,-Bsymbolic
|
||||
|
||||
echo "X{};" > $TMPV
|
||||
test_ldflags -Wl,--version-script,$TMPV &&
|
||||
if test_ldflags -Wl,--version-script,$TMPV; then
|
||||
append SHFLAGS '-Wl,--version-script,\$(SUBDIR)lib\$(NAME).ver'
|
||||
check_cc <<EOF && enable symver_asm_label
|
||||
void ff_foo(void) __asm__ ("av_foo@VERSION");
|
||||
void ff_foo(void) { ${inline_asm+__asm__($quotes);} }
|
||||
EOF
|
||||
check_cc <<EOF && enable symver_gnu_asm
|
||||
__asm__(".symver ff_foo,av_foo@VERSION");
|
||||
void ff_foo(void) {}
|
||||
EOF
|
||||
fi
|
||||
|
||||
if enabled small; then
|
||||
add_cflags $size_cflags
|
||||
@@ -2886,6 +2903,7 @@ echo "libschroedinger enabled ${libschroedinger-no}"
|
||||
echo "libspeex enabled ${libspeex-no}"
|
||||
echo "libtheora enabled ${libtheora-no}"
|
||||
echo "libvorbis enabled ${libvorbis-no}"
|
||||
echo "libvpx enabled ${libvpx-no}"
|
||||
echo "libx264 enabled ${libx264-no}"
|
||||
echo "libxvid enabled ${libxvid-no}"
|
||||
echo "zlib enabled ${zlib-no}"
|
||||
|
@@ -12,6 +12,15 @@ libavutil: 2009-03-08
|
||||
|
||||
API changes, most recent first:
|
||||
|
||||
2010-06-01 - r31301 - lsws 0.11.0 - convertPalette API
|
||||
Add sws_convertPalette8ToPacked32 and sws_convertPalette8ToPacked24
|
||||
|
||||
2010-05-26 - r23334 - lavc 52.72.0 - CODEC_CAP_EXPERIMENTAL
|
||||
Add CODEC_CAP_EXPERIMENTAL flag.
|
||||
|
||||
2010-05-18 - r23161 - lavf 52.63.0 - AVFMT_FLAG_RTP_HINT
|
||||
Add AVFMT_FLAG_RTP_HINT as possible value for AVFormatContext.flags
|
||||
|
||||
2010-05-01 - r23002 - lavf 52.62.0 - probe function
|
||||
Add av_probe_input_format2 to API, it allows ignoring probe
|
||||
results below given score and returns the actual probe score.
|
||||
|
@@ -234,6 +234,7 @@ library:
|
||||
@item VC-1 test bitstream @tab X @tab X
|
||||
@item WAV @tab X @tab X
|
||||
@item WavPack @tab @tab X
|
||||
@item WebM @tab X @tab X
|
||||
@item Wing Commander III movie @tab @tab X
|
||||
@tab Multimedia format used in Origin's Wing Commander III computer game.
|
||||
@item Westwood Studios audio @tab @tab X
|
||||
@@ -436,6 +437,8 @@ following image formats are supported:
|
||||
@tab fourcc: VP50
|
||||
@item On2 VP6 @tab @tab X
|
||||
@tab fourcc: VP60,VP61,VP62
|
||||
@item VP8 @tab X @tab X
|
||||
@tab fourcc: VP80, de/encoding supported through external library libvpx
|
||||
@item planar RGB @tab @tab X
|
||||
@tab fourcc: 8BPS
|
||||
@item Q-team QPEG @tab @tab X
|
||||
|
38
ffmpeg.c
38
ffmpeg.c
@@ -2093,7 +2093,7 @@ static int av_transcode(AVFormatContext **output_files,
|
||||
pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX,
|
||||
i);
|
||||
if (codec->flags & CODEC_FLAG_PASS1) {
|
||||
f = fopen(logfilename, "w");
|
||||
f = fopen(logfilename, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Cannot write log file '%s' for pass-1 encoding: %s\n", logfilename, strerror(errno));
|
||||
av_exit(1);
|
||||
@@ -2912,7 +2912,7 @@ static int opt_input_ts_offset(const char *opt, const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum CodecID find_codec_or_die(const char *name, int type, int encoder)
|
||||
static enum CodecID find_codec_or_die(const char *name, int type, int encoder, int strict)
|
||||
{
|
||||
const char *codec_string = encoder ? "encoder" : "decoder";
|
||||
AVCodec *codec;
|
||||
@@ -2930,6 +2930,19 @@ static enum CodecID find_codec_or_die(const char *name, int type, int encoder)
|
||||
fprintf(stderr, "Invalid %s type '%s'\n", codec_string, name);
|
||||
av_exit(1);
|
||||
}
|
||||
if(codec->capabilities & CODEC_CAP_EXPERIMENTAL &&
|
||||
strict > FF_COMPLIANCE_EXPERIMENTAL) {
|
||||
fprintf(stderr, "%s '%s' is experimental and might produce bad "
|
||||
"results.\nAdd '-strict experimental' if you want to use it.\n",
|
||||
codec_string, codec->name);
|
||||
codec = encoder ?
|
||||
avcodec_find_encoder(codec->id) :
|
||||
avcodec_find_decoder(codec->id);
|
||||
if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL))
|
||||
fprintf(stderr, "Or use the non experimental %s '%s'.\n",
|
||||
codec_string, codec->name);
|
||||
av_exit(1);
|
||||
}
|
||||
return codec->id;
|
||||
}
|
||||
|
||||
@@ -2977,9 +2990,15 @@ static void opt_input_file(const char *filename)
|
||||
|
||||
set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
|
||||
|
||||
ic->video_codec_id = find_codec_or_die(video_codec_name , AVMEDIA_TYPE_VIDEO , 0);
|
||||
ic->audio_codec_id = find_codec_or_die(audio_codec_name , AVMEDIA_TYPE_AUDIO , 0);
|
||||
ic->subtitle_codec_id= find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0);
|
||||
ic->video_codec_id =
|
||||
find_codec_or_die(video_codec_name , AVMEDIA_TYPE_VIDEO , 0,
|
||||
avcodec_opts[AVMEDIA_TYPE_VIDEO ]->strict_std_compliance);
|
||||
ic->audio_codec_id =
|
||||
find_codec_or_die(audio_codec_name , AVMEDIA_TYPE_AUDIO , 0,
|
||||
avcodec_opts[AVMEDIA_TYPE_AUDIO ]->strict_std_compliance);
|
||||
ic->subtitle_codec_id=
|
||||
find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0,
|
||||
avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);
|
||||
ic->flags |= AVFMT_FLAG_NONBLOCK;
|
||||
|
||||
if(pgmyuv_compatibility_hack)
|
||||
@@ -3208,7 +3227,8 @@ static void new_video_stream(AVFormatContext *oc)
|
||||
AVRational fps= frame_rate.num ? frame_rate : (AVRational){25,1};
|
||||
|
||||
if (video_codec_name) {
|
||||
codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1);
|
||||
codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1,
|
||||
video_enc->strict_std_compliance);
|
||||
codec = avcodec_find_encoder_by_name(video_codec_name);
|
||||
output_codecs[nb_ocodecs] = codec;
|
||||
} else {
|
||||
@@ -3339,7 +3359,8 @@ static void new_audio_stream(AVFormatContext *oc)
|
||||
set_context_opts(audio_enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
|
||||
|
||||
if (audio_codec_name) {
|
||||
codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1);
|
||||
codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1,
|
||||
audio_enc->strict_std_compliance);
|
||||
codec = avcodec_find_encoder_by_name(audio_codec_name);
|
||||
output_codecs[nb_ocodecs] = codec;
|
||||
} else {
|
||||
@@ -3399,7 +3420,8 @@ static void new_subtitle_stream(AVFormatContext *oc)
|
||||
st->stream_copy = 1;
|
||||
} else {
|
||||
set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
|
||||
subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1);
|
||||
subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1,
|
||||
subtitle_enc->strict_std_compliance);
|
||||
output_codecs[nb_ocodecs] = avcodec_find_encoder_by_name(subtitle_codec_name);
|
||||
}
|
||||
nb_ocodecs++;
|
||||
|
4
ffplay.c
4
ffplay.c
@@ -1593,7 +1593,9 @@ static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
|
||||
unsigned hshift = i == 0 ? 0 : av_pix_fmt_descriptors[ref->pic->format].log2_chroma_w;
|
||||
unsigned vshift = i == 0 ? 0 : av_pix_fmt_descriptors[ref->pic->format].log2_chroma_h;
|
||||
|
||||
ref->data[i] += (edge >> hshift) + ((edge * ref->linesize[i]) >> vshift);
|
||||
if (ref->data[i]) {
|
||||
ref->data[i] += (edge >> hshift) + ((edge * ref->linesize[i]) >> vshift);
|
||||
}
|
||||
pic->data[i] = ref->data[i];
|
||||
pic->linesize[i] = ref->linesize[i];
|
||||
}
|
||||
|
37
ffserver.c
37
ffserver.c
@@ -847,6 +847,8 @@ static void close_connection(HTTPContext *c)
|
||||
ctx = c->rtp_ctx[i];
|
||||
if (ctx) {
|
||||
av_write_trailer(ctx);
|
||||
av_metadata_free(&ctx->metadata);
|
||||
av_free(ctx->streams[0]);
|
||||
av_free(ctx);
|
||||
}
|
||||
h = c->rtp_handles[i];
|
||||
@@ -2280,6 +2282,7 @@ static int http_prepare_data(HTTPContext *c)
|
||||
http_log("Error writing output header\n");
|
||||
return -1;
|
||||
}
|
||||
av_metadata_free(&c->fmt_ctx.metadata);
|
||||
|
||||
len = url_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
|
||||
c->buffer_ptr = c->pb_buffer;
|
||||
@@ -2343,7 +2346,7 @@ static int http_prepare_data(HTTPContext *c)
|
||||
}
|
||||
}
|
||||
for(i=0;i<c->stream->nb_streams;i++) {
|
||||
if (c->feed_streams[i] == pkt.stream_index) {
|
||||
if (c->stream->feed_streams[i] == pkt.stream_index) {
|
||||
AVStream *st = c->fmt_in->streams[source_index];
|
||||
pkt.stream_index = i;
|
||||
if (pkt.flags & AV_PKT_FLAG_KEY &&
|
||||
@@ -2879,7 +2882,7 @@ static int rtsp_parse_request(HTTPContext *c)
|
||||
if (*p == '\n')
|
||||
p++;
|
||||
while (*p != '\0') {
|
||||
p1 = strchr(p, '\n');
|
||||
p1 = memchr(p, '\n', (char *)c->buffer_ptr - p);
|
||||
if (!p1)
|
||||
break;
|
||||
p2 = p1;
|
||||
@@ -2946,6 +2949,8 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
|
||||
snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
|
||||
inet_ntoa(stream->multicast_ip),
|
||||
stream->multicast_port, stream->multicast_ttl);
|
||||
} else {
|
||||
snprintf(avc->filename, 1024, "rtp://0.0.0.0");
|
||||
}
|
||||
|
||||
for(i = 0; i < stream->nb_streams; i++) {
|
||||
@@ -2954,6 +2959,7 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
|
||||
}
|
||||
*pbuffer = av_mallocz(2048);
|
||||
avf_sdp_create(&avc, 1, *pbuffer, 2048);
|
||||
av_metadata_free(&avc->metadata);
|
||||
av_free(avc);
|
||||
|
||||
return strlen(*pbuffer);
|
||||
@@ -3006,10 +3012,12 @@ static void rtsp_cmd_describe(HTTPContext *c, const char *url)
|
||||
return;
|
||||
}
|
||||
rtsp_reply_header(c, RTSP_STATUS_OK);
|
||||
url_fprintf(c->pb, "Content-Base: %s/\r\n", url);
|
||||
url_fprintf(c->pb, "Content-Type: application/sdp\r\n");
|
||||
url_fprintf(c->pb, "Content-Length: %d\r\n", content_length);
|
||||
url_fprintf(c->pb, "\r\n");
|
||||
put_buffer(c->pb, content, content_length);
|
||||
av_free(content);
|
||||
}
|
||||
|
||||
static HTTPContext *find_rtp_session(const char *session_id)
|
||||
@@ -3376,7 +3384,6 @@ static int rtp_new_av_stream(HTTPContext *c,
|
||||
st = av_mallocz(sizeof(AVStream));
|
||||
if (!st)
|
||||
goto fail;
|
||||
st->codec= avcodec_alloc_context();
|
||||
ctx->nb_streams = 1;
|
||||
ctx->streams[0] = st;
|
||||
|
||||
@@ -3452,16 +3459,28 @@ static int rtp_new_av_stream(HTTPContext *c,
|
||||
/********************************************************************/
|
||||
/* ffserver initialization */
|
||||
|
||||
static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec)
|
||||
static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy)
|
||||
{
|
||||
AVStream *fst;
|
||||
|
||||
fst = av_mallocz(sizeof(AVStream));
|
||||
if (!fst)
|
||||
return NULL;
|
||||
fst->codec= avcodec_alloc_context();
|
||||
if (copy) {
|
||||
fst->codec= avcodec_alloc_context();
|
||||
memcpy(fst->codec, codec, sizeof(AVCodecContext));
|
||||
if (codec->extradata_size) {
|
||||
fst->codec->extradata = av_malloc(codec->extradata_size);
|
||||
memcpy(fst->codec->extradata, codec->extradata,
|
||||
codec->extradata_size);
|
||||
}
|
||||
} else {
|
||||
/* live streams must use the actual feed's codec since it may be
|
||||
* updated later to carry extradata needed by the streams.
|
||||
*/
|
||||
fst->codec = codec;
|
||||
}
|
||||
fst->priv_data = av_mallocz(sizeof(FeedData));
|
||||
memcpy(fst->codec, codec, sizeof(AVCodecContext));
|
||||
fst->index = stream->nb_streams;
|
||||
av_set_pts_info(fst, 33, 1, 90000);
|
||||
stream->streams[stream->nb_streams++] = fst;
|
||||
@@ -3503,7 +3522,7 @@ static int add_av_stream(FFStream *feed, AVStream *st)
|
||||
}
|
||||
}
|
||||
|
||||
fst = add_av_stream1(feed, av);
|
||||
fst = add_av_stream1(feed, av, 0);
|
||||
if (!fst)
|
||||
return -1;
|
||||
return feed->nb_streams - 1;
|
||||
@@ -3614,7 +3633,7 @@ static void build_file_streams(void)
|
||||
extract_mpeg4_header(infile);
|
||||
|
||||
for(i=0;i<infile->nb_streams;i++)
|
||||
add_av_stream1(stream, infile->streams[i]->codec);
|
||||
add_av_stream1(stream, infile->streams[i]->codec, 1);
|
||||
|
||||
av_close_input_file(infile);
|
||||
}
|
||||
@@ -3681,7 +3700,7 @@ static void build_feed_streams(void)
|
||||
ccs = ss->codec;
|
||||
#define CHECK_CODEC(x) (ccf->x != ccs->x)
|
||||
|
||||
if (CHECK_CODEC(codec) || CHECK_CODEC(codec_type)) {
|
||||
if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) {
|
||||
http_log("Codecs do not match for stream %d\n", i);
|
||||
matches = 0;
|
||||
} else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {
|
||||
|
@@ -501,6 +501,8 @@ OBJS-$(CONFIG_OGG_DEMUXER) += flacdec.o flacdata.o flac.o \
|
||||
dirac.o mpeg12data.o
|
||||
OBJS-$(CONFIG_OGG_MUXER) += xiph.o flacdec.o flacdata.o flac.o
|
||||
OBJS-$(CONFIG_RTP_MUXER) += mpegvideo.o
|
||||
OBJS-$(CONFIG_WEBM_MUXER) += xiph.o mpeg4audio.o \
|
||||
flacdec.o flacdata.o flac.o
|
||||
|
||||
# external codec libraries
|
||||
OBJS-$(CONFIG_LIBDIRAC_DECODER) += libdiracdec.o
|
||||
@@ -525,6 +527,8 @@ OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \
|
||||
OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o
|
||||
OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o
|
||||
OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbis.o
|
||||
OBJS-$(CONFIG_LIBVPX_DECODER) += libvpxdec.o
|
||||
OBJS-$(CONFIG_LIBVPX_ENCODER) += libvpxenc.o
|
||||
OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o
|
||||
OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvidff.o libxvid_rc.o
|
||||
|
||||
|
@@ -1954,6 +1954,7 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data,
|
||||
int err, elem_id, data_size_tmp;
|
||||
int buf_consumed;
|
||||
int samples = 1024, multiplier;
|
||||
int buf_offset;
|
||||
|
||||
init_get_bits(&gb, buf, buf_size * 8);
|
||||
|
||||
@@ -2065,7 +2066,11 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data,
|
||||
ac->output_configured = OC_LOCKED;
|
||||
|
||||
buf_consumed = (get_bits_count(&gb) + 7) >> 3;
|
||||
return buf_size > buf_consumed ? buf_consumed : buf_size;
|
||||
for (buf_offset = buf_consumed; buf_offset < buf_size; buf_offset++)
|
||||
if (buf[buf_offset])
|
||||
break;
|
||||
|
||||
return buf_size > buf_offset ? buf_consumed : buf_size;
|
||||
}
|
||||
|
||||
static av_cold int aac_decode_close(AVCodecContext *avccontext)
|
||||
|
@@ -763,7 +763,7 @@ static void search_for_quantizers_faac(AVCodecContext *avctx, AACEncContext *s,
|
||||
const float *scaled = s->scoefs + start;
|
||||
const int size = sce->ics.swb_sizes[g];
|
||||
int scf, prev_scf, step;
|
||||
int min_scf = 0, max_scf = 255;
|
||||
int min_scf = -1, max_scf = 256;
|
||||
float curdiff;
|
||||
if (maxq[w*16+g] < 21.544) {
|
||||
sce->zeroes[w*16+g] = 1;
|
||||
@@ -797,21 +797,23 @@ static void search_for_quantizers_faac(AVCodecContext *avctx, AACEncContext *s,
|
||||
}
|
||||
prev_scf = scf;
|
||||
curdiff = fabsf(dist - uplim[w*16+g]);
|
||||
if (curdiff == 0.0f)
|
||||
if (curdiff <= 1.0f)
|
||||
step = 0;
|
||||
else
|
||||
step = fabsf(log2(curdiff));
|
||||
step = log2(curdiff);
|
||||
if (dist > uplim[w*16+g])
|
||||
step = -step;
|
||||
scf += step;
|
||||
scf = av_clip_uint8(scf);
|
||||
step = scf - prev_scf;
|
||||
if (FFABS(step) <= 1 || (step > 0 && scf >= max_scf) || (step < 0 && scf <= min_scf)) {
|
||||
sce->sf_idx[w*16+g] = scf;
|
||||
sce->sf_idx[w*16+g] = av_clip(scf, min_scf, max_scf);
|
||||
break;
|
||||
}
|
||||
scf += step;
|
||||
if (step > 0)
|
||||
min_scf = scf;
|
||||
min_scf = prev_scf;
|
||||
else
|
||||
max_scf = scf;
|
||||
max_scf = prev_scf;
|
||||
}
|
||||
start += size;
|
||||
}
|
||||
|
@@ -174,6 +174,10 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
|
||||
av_log(avctx, AV_LOG_ERROR, "Unsupported profile %d\n", avctx->profile);
|
||||
return -1;
|
||||
}
|
||||
if (1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * avctx->channels) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Too many bits per frame requested\n");
|
||||
return -1;
|
||||
}
|
||||
s->samplerate_index = i;
|
||||
|
||||
dsputil_init(&s->dsp, avctx);
|
||||
@@ -557,6 +561,7 @@ static int aac_encode_frame(AVCodecContext *avctx,
|
||||
chans = tag == TYPE_CPE ? 2 : 1;
|
||||
cpe = &s->cpe[i];
|
||||
for (j = 0; j < chans; j++) {
|
||||
s->cur_channel = start_ch + j;
|
||||
s->coder->search_for_quantizers(avctx, s, &cpe->ch[j], s->lambda);
|
||||
}
|
||||
cpe->common_window = 0;
|
||||
@@ -572,6 +577,7 @@ static int aac_encode_frame(AVCodecContext *avctx,
|
||||
}
|
||||
}
|
||||
}
|
||||
s->cur_channel = start_ch;
|
||||
if (cpe->common_window && s->coder->search_for_ms)
|
||||
s->coder->search_for_ms(s, cpe, s->lambda);
|
||||
adjust_frame_information(s, cpe, chans);
|
||||
@@ -639,7 +645,7 @@ AVCodec aac_encoder = {
|
||||
aac_encode_init,
|
||||
aac_encode_frame,
|
||||
aac_encode_end,
|
||||
.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
|
||||
.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL,
|
||||
.sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"),
|
||||
};
|
||||
|
@@ -1268,7 +1268,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
|
||||
}
|
||||
|
||||
/* apply spectral extension to high frequency bins */
|
||||
if (s->spx_in_use) {
|
||||
if (s->spx_in_use && CONFIG_EAC3_DECODER) {
|
||||
ff_eac3_apply_spectral_extension(s);
|
||||
}
|
||||
|
||||
|
@@ -253,7 +253,7 @@ void avcodec_register_all(void)
|
||||
REGISTER_DECODER (TTA, tta);
|
||||
REGISTER_DECODER (TWINVQ, twinvq);
|
||||
REGISTER_DECODER (VMDAUDIO, vmdaudio);
|
||||
REGISTER_ENCDEC (VORBIS, vorbis);
|
||||
REGISTER_DECODER (VORBIS, vorbis);
|
||||
REGISTER_DECODER (WAVPACK, wavpack);
|
||||
REGISTER_DECODER (WMAPRO, wmapro);
|
||||
REGISTER_ENCDEC (WMAV1, wmav1);
|
||||
@@ -344,6 +344,7 @@ void avcodec_register_all(void)
|
||||
REGISTER_DECODER (LIBSPEEX, libspeex);
|
||||
REGISTER_ENCODER (LIBTHEORA, libtheora);
|
||||
REGISTER_ENCODER (LIBVORBIS, libvorbis);
|
||||
REGISTER_ENCDEC (LIBVPX, libvpx);
|
||||
REGISTER_ENCODER (LIBX264, libx264);
|
||||
REGISTER_ENCODER (LIBXVID, libxvid);
|
||||
|
||||
|
@@ -39,6 +39,8 @@
|
||||
#include "libavutil/mathematics.h"
|
||||
|
||||
#define INBUF_SIZE 4096
|
||||
#define AUDIO_INBUF_SIZE 20480
|
||||
#define AUDIO_REFILL_THRESH 4096
|
||||
|
||||
/*
|
||||
* Audio encoding example
|
||||
@@ -118,7 +120,7 @@ static void audio_decode_example(const char *outfilename, const char *filename)
|
||||
int out_size, len;
|
||||
FILE *f, *outfile;
|
||||
uint8_t *outbuf;
|
||||
uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
|
||||
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
|
||||
AVPacket avpkt;
|
||||
|
||||
av_init_packet(&avpkt);
|
||||
@@ -155,25 +157,32 @@ static void audio_decode_example(const char *outfilename, const char *filename)
|
||||
|
||||
/* decode until eof */
|
||||
avpkt.data = inbuf;
|
||||
for(;;) {
|
||||
avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
|
||||
if (avpkt.size == 0)
|
||||
break;
|
||||
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
||||
|
||||
avpkt.data = inbuf;
|
||||
while (avpkt.size > 0) {
|
||||
out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
|
||||
len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt);
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "Error while decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
if (out_size > 0) {
|
||||
/* if a frame has been decoded, output it */
|
||||
fwrite(outbuf, 1, out_size, outfile);
|
||||
}
|
||||
avpkt.size -= len;
|
||||
avpkt.data += len;
|
||||
while (avpkt.size > 0) {
|
||||
out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
|
||||
len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt);
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "Error while decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
if (out_size > 0) {
|
||||
/* if a frame has been decoded, output it */
|
||||
fwrite(outbuf, 1, out_size, outfile);
|
||||
}
|
||||
avpkt.size -= len;
|
||||
avpkt.data += len;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -103,9 +103,9 @@ void av_audio_convert_free(AVAudioConvert *ctx);
|
||||
/**
|
||||
* Convert between audio sample formats
|
||||
* @param[in] out array of output buffers for each channel. set to NULL to ignore processing of the given channel.
|
||||
* @param[in] out_stride distance between consecutive input samples (measured in bytes)
|
||||
* @param[in] out_stride distance between consecutive output samples (measured in bytes)
|
||||
* @param[in] in array of input buffers for each channel
|
||||
* @param[in] in_stride distance between consecutive output samples (measured in bytes)
|
||||
* @param[in] in_stride distance between consecutive input samples (measured in bytes)
|
||||
* @param len length of audio frame size (measured in samples)
|
||||
*/
|
||||
int av_audio_convert(AVAudioConvert *ctx,
|
||||
|
@@ -30,8 +30,8 @@
|
||||
#include "libavutil/avutil.h"
|
||||
|
||||
#define LIBAVCODEC_VERSION_MAJOR 52
|
||||
#define LIBAVCODEC_VERSION_MINOR 66
|
||||
#define LIBAVCODEC_VERSION_MICRO 0
|
||||
#define LIBAVCODEC_VERSION_MINOR 72
|
||||
#define LIBAVCODEC_VERSION_MICRO 2
|
||||
|
||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||
LIBAVCODEC_VERSION_MINOR, \
|
||||
@@ -210,6 +210,7 @@ enum CodecID {
|
||||
CODEC_ID_IFF_BYTERUN1,
|
||||
CODEC_ID_KGV1,
|
||||
CODEC_ID_YOP,
|
||||
CODEC_ID_VP8,
|
||||
|
||||
/* various PCM "codecs" */
|
||||
CODEC_ID_PCM_S16LE= 0x10000,
|
||||
@@ -643,6 +644,11 @@ typedef struct RcOverride{
|
||||
* as a last resort.
|
||||
*/
|
||||
#define CODEC_CAP_SUBFRAMES 0x0100
|
||||
/**
|
||||
* Codec is experimental and is thus avoided in favor of non experimental
|
||||
* encoders
|
||||
*/
|
||||
#define CODEC_CAP_EXPERIMENTAL 0x0200
|
||||
|
||||
//The following defines may change, don't expect compatibility if you use them.
|
||||
#define MB_TYPE_INTRA4x4 0x0001
|
||||
@@ -3303,12 +3309,20 @@ unsigned avcodec_get_edge_width(void);
|
||||
* Modifies width and height values so that they will result in a memory
|
||||
* buffer that is acceptable for the codec if you do not use any horizontal
|
||||
* padding.
|
||||
*
|
||||
* May only be used if a codec with CODEC_CAP_DR1 has been opened.
|
||||
* If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased
|
||||
* according to avcodec_get_edge_width() before.
|
||||
*/
|
||||
void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
|
||||
/**
|
||||
* Modifies width and height values so that they will result in a memory
|
||||
* buffer that is acceptable for the codec if you also ensure that all
|
||||
* line sizes are a multiple of the respective linesize_align[i].
|
||||
*
|
||||
* May only be used if a codec with CODEC_CAP_DR1 has been opened.
|
||||
* If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased
|
||||
* according to avcodec_get_edge_width() before.
|
||||
*/
|
||||
void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
|
||||
int linesize_align[4]);
|
||||
@@ -3464,8 +3478,8 @@ attribute_deprecated int avcodec_decode_video(AVCodecContext *avctx, AVFrame *pi
|
||||
*
|
||||
* @param avctx the codec context
|
||||
* @param[out] picture The AVFrame in which the decoded video frame will be stored.
|
||||
* Use avcodec_alloc_frame to get an AVFrame, the codec will call
|
||||
* get_buffer to get memory for the actual image data.
|
||||
* Use avcodec_alloc_frame to get an AVFrame, the codec will
|
||||
* allocate memory for the actual bitmap.
|
||||
* @param[in] avpkt The input AVpacket containing the input buffer.
|
||||
* You can create such packet with av_init_packet() and by then setting
|
||||
* data and size, some decoders might in addition need other fields like
|
||||
|
@@ -428,7 +428,9 @@ retry:
|
||||
if(s->xvid_build==-1 && s->divx_version==-1 && s->lavc_build==-1){
|
||||
if(s->stream_codec_tag == AV_RL32("XVID") ||
|
||||
s->codec_tag == AV_RL32("XVID") || s->codec_tag == AV_RL32("XVIX") ||
|
||||
s->codec_tag == AV_RL32("RMP4"))
|
||||
s->codec_tag == AV_RL32("RMP4") ||
|
||||
s->codec_tag == AV_RL32("SIPP")
|
||||
)
|
||||
s->xvid_build= 0;
|
||||
#if 0
|
||||
if(s->codec_tag == AV_RL32("DIVX") && s->vo_type==0 && s->vol_control_parameters==1
|
||||
|
@@ -55,7 +55,9 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
|
||||
int keyframe) {
|
||||
H264BSFContext *ctx = bsfc->priv_data;
|
||||
uint8_t unit_type;
|
||||
uint32_t nal_size, cumul_size = 0;
|
||||
int32_t nal_size;
|
||||
uint32_t cumul_size = 0;
|
||||
const uint8_t *buf_end = buf + buf_size;
|
||||
|
||||
/* nothing to filter */
|
||||
if (!avctx->extradata || avctx->extradata_size < 6) {
|
||||
@@ -109,6 +111,9 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
|
||||
*poutbuf_size = 0;
|
||||
*poutbuf = NULL;
|
||||
do {
|
||||
if (buf + ctx->length_size > buf_end)
|
||||
goto fail;
|
||||
|
||||
if (ctx->length_size == 1)
|
||||
nal_size = buf[0];
|
||||
else if (ctx->length_size == 2)
|
||||
@@ -119,6 +124,9 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
|
||||
buf += ctx->length_size;
|
||||
unit_type = *buf & 0x1f;
|
||||
|
||||
if (buf + nal_size > buf_end || nal_size < 0)
|
||||
goto fail;
|
||||
|
||||
/* prepend only to the first type 5 NAL unit of an IDR picture */
|
||||
if (ctx->first_idr && unit_type == 5) {
|
||||
alloc_and_copy(poutbuf, poutbuf_size,
|
||||
@@ -139,6 +147,11 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
|
||||
} while (cumul_size < buf_size);
|
||||
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
av_freep(poutbuf);
|
||||
*poutbuf_size = 0;
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
static void h264_mp4toannexb_close(AVBitStreamFilterContext *bsfc)
|
||||
|
@@ -205,6 +205,12 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){
|
||||
sps->num_reorder_frames= get_ue_golomb(&s->gb);
|
||||
get_ue_golomb(&s->gb); /*max_dec_frame_buffering*/
|
||||
|
||||
if(s->gb.size_in_bits < get_bits_count(&s->gb)){
|
||||
av_log(h->s.avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", get_bits_count(&s->gb) - s->gb.size_in_bits);
|
||||
sps->num_reorder_frames=0;
|
||||
sps->bitstream_restriction_flag= 0;
|
||||
}
|
||||
|
||||
if(sps->num_reorder_frames > 16U /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){
|
||||
av_log(h->s.avctx, AV_LOG_ERROR, "illegal num_reorder_frames %d\n", sps->num_reorder_frames);
|
||||
return -1;
|
||||
|
@@ -89,7 +89,7 @@ typedef struct {
|
||||
uint32_t buf_offs; ///< address in the output buffer for this mb
|
||||
uint8_t type; ///< macroblock type: 0 - INTRA, 1 - INTER
|
||||
uint8_t cbp; ///< coded block pattern
|
||||
uint8_t q_delta; ///< quant delta
|
||||
int8_t q_delta; ///< quant delta
|
||||
int8_t mv_x; ///< motion vector (x component)
|
||||
int8_t mv_y; ///< motion vector (y component)
|
||||
} IVIMbInfo;
|
||||
|
124
libavcodec/libvpxdec.c
Normal file
124
libavcodec/libvpxdec.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Google, Inc.
|
||||
*
|
||||
* 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
|
||||
* VP8 decoder support via libvpx
|
||||
*/
|
||||
|
||||
#define VPX_CODEC_DISABLE_COMPAT 1
|
||||
#include <vpx/vpx_decoder.h>
|
||||
#include <vpx/vp8dx.h>
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
typedef struct VP8DecoderContext {
|
||||
struct vpx_codec_ctx decoder;
|
||||
} VP8Context;
|
||||
|
||||
static av_cold int vp8_init(AVCodecContext *avctx)
|
||||
{
|
||||
VP8Context *ctx = avctx->priv_data;
|
||||
const struct vpx_codec_iface *iface = &vpx_codec_vp8_dx_algo;
|
||||
struct vpx_codec_dec_cfg deccfg = {
|
||||
/* token partitions+1 would be a decent choice */
|
||||
.threads = FFMIN(avctx->thread_count, 16)
|
||||
};
|
||||
|
||||
av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str());
|
||||
av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config());
|
||||
|
||||
if (vpx_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) != VPX_CODEC_OK) {
|
||||
const char *error = vpx_codec_error(&ctx->decoder);
|
||||
av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n",
|
||||
error);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
avctx->pix_fmt = PIX_FMT_YUV420P;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vp8_decode(AVCodecContext *avctx,
|
||||
void *data, int *data_size, AVPacket *avpkt)
|
||||
{
|
||||
VP8Context *ctx = avctx->priv_data;
|
||||
AVFrame *picture = data;
|
||||
const void *iter = NULL;
|
||||
struct vpx_image *img;
|
||||
|
||||
if (vpx_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL, 0) !=
|
||||
VPX_CODEC_OK) {
|
||||
const char *error = vpx_codec_error(&ctx->decoder);
|
||||
const char *detail = vpx_codec_error_detail(&ctx->decoder);
|
||||
|
||||
av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n", error);
|
||||
if (detail)
|
||||
av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n",
|
||||
detail);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if ((img = vpx_codec_get_frame(&ctx->decoder, &iter))) {
|
||||
if (img->fmt != VPX_IMG_FMT_I420) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d)\n",
|
||||
img->fmt);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) {
|
||||
av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n",
|
||||
avctx->width, avctx->height, img->d_w, img->d_h);
|
||||
if (avcodec_check_dimensions(avctx, img->d_w, img->d_h))
|
||||
return AVERROR_INVALIDDATA;
|
||||
avcodec_set_dimensions(avctx, img->d_w, img->d_h);
|
||||
}
|
||||
picture->data[0] = img->planes[0];
|
||||
picture->data[1] = img->planes[1];
|
||||
picture->data[2] = img->planes[2];
|
||||
picture->data[3] = NULL;
|
||||
picture->linesize[0] = img->stride[0];
|
||||
picture->linesize[1] = img->stride[1];
|
||||
picture->linesize[2] = img->stride[2];
|
||||
picture->linesize[3] = 0;
|
||||
*data_size = sizeof(AVPicture);
|
||||
}
|
||||
return avpkt->size;
|
||||
}
|
||||
|
||||
static av_cold int vp8_free(AVCodecContext *avctx)
|
||||
{
|
||||
VP8Context *ctx = avctx->priv_data;
|
||||
vpx_codec_destroy(&ctx->decoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec libvpx_decoder = {
|
||||
"libvpx",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_VP8,
|
||||
sizeof(VP8Context),
|
||||
vp8_init,
|
||||
NULL, /* encode */
|
||||
vp8_free,
|
||||
vp8_decode,
|
||||
0, /* capabilities */
|
||||
.long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"),
|
||||
};
|
489
libavcodec/libvpxenc.c
Normal file
489
libavcodec/libvpxenc.c
Normal file
@@ -0,0 +1,489 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Google, Inc.
|
||||
*
|
||||
* 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
|
||||
* VP8 encoder support via libvpx
|
||||
*/
|
||||
|
||||
#define VPX_DISABLE_CTRL_TYPECHECKS 1
|
||||
#define VPX_CODEC_DISABLE_COMPAT 1
|
||||
#include <vpx/vpx_encoder.h>
|
||||
#include <vpx/vp8cx.h>
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "libavutil/base64.h"
|
||||
|
||||
/**
|
||||
* Portion of struct vpx_codec_cx_pkt from vpx_encoder.h.
|
||||
* One encoded frame returned from the library.
|
||||
*/
|
||||
struct FrameListData {
|
||||
void *buf; /**≤ compressed data buffer */
|
||||
size_t sz; /**≤ length of compressed data */
|
||||
int64_t pts; /**≤ time stamp to show frame
|
||||
(in timebase units) */
|
||||
unsigned long duration; /**≤ duration to show frame
|
||||
(in timebase units) */
|
||||
uint32_t flags; /**≤ flags for this frame */
|
||||
struct FrameListData *next;
|
||||
};
|
||||
|
||||
typedef struct VP8EncoderContext {
|
||||
struct vpx_codec_ctx encoder;
|
||||
struct vpx_image rawimg;
|
||||
struct vpx_fixed_buf twopass_stats;
|
||||
unsigned long deadline; //i.e., RT/GOOD/BEST
|
||||
struct FrameListData *coded_frame_list;
|
||||
} VP8Context;
|
||||
|
||||
/** String mappings for enum vp8e_enc_control_id */
|
||||
static const char *ctlidstr[] = {
|
||||
[VP8E_UPD_ENTROPY] = "VP8E_UPD_ENTROPY",
|
||||
[VP8E_UPD_REFERENCE] = "VP8E_UPD_REFERENCE",
|
||||
[VP8E_USE_REFERENCE] = "VP8E_USE_REFERENCE",
|
||||
[VP8E_SET_ROI_MAP] = "VP8E_SET_ROI_MAP",
|
||||
[VP8E_SET_ACTIVEMAP] = "VP8E_SET_ACTIVEMAP",
|
||||
[VP8E_SET_SCALEMODE] = "VP8E_SET_SCALEMODE",
|
||||
[VP8E_SET_CPUUSED] = "VP8E_SET_CPUUSED",
|
||||
[VP8E_SET_ENABLEAUTOALTREF] = "VP8E_SET_ENABLEAUTOALTREF",
|
||||
[VP8E_SET_NOISE_SENSITIVITY] = "VP8E_SET_NOISE_SENSITIVITY",
|
||||
[VP8E_SET_SHARPNESS] = "VP8E_SET_SHARPNESS",
|
||||
[VP8E_SET_STATIC_THRESHOLD] = "VP8E_SET_STATIC_THRESHOLD",
|
||||
[VP8E_SET_TOKEN_PARTITIONS] = "VP8E_SET_TOKEN_PARTITIONS",
|
||||
[VP8E_GET_LAST_QUANTIZER] = "VP8E_GET_LAST_QUANTIZER",
|
||||
[VP8E_SET_ARNR_MAXFRAMES] = "VP8E_SET_ARNR_MAXFRAMES",
|
||||
[VP8E_SET_ARNR_STRENGTH] = "VP8E_SET_ARNR_STRENGTH",
|
||||
[VP8E_SET_ARNR_TYPE] = "VP8E_SET_ARNR_TYPE",
|
||||
};
|
||||
|
||||
static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
|
||||
{
|
||||
VP8Context *ctx = avctx->priv_data;
|
||||
const char *error = vpx_codec_error(&ctx->encoder);
|
||||
const char *detail = vpx_codec_error_detail(&ctx->encoder);
|
||||
|
||||
av_log(avctx, AV_LOG_ERROR, "%s: %s\n", desc, error);
|
||||
if (detail)
|
||||
av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n", detail);
|
||||
}
|
||||
|
||||
static av_cold void dump_enc_cfg(AVCodecContext *avctx,
|
||||
const struct vpx_codec_enc_cfg *cfg)
|
||||
{
|
||||
int width = -30;
|
||||
int level = AV_LOG_DEBUG;
|
||||
|
||||
av_log(avctx, level, "vpx_codec_enc_cfg\n");
|
||||
av_log(avctx, level, "generic settings\n"
|
||||
" %*s%u\n %*s%u\n %*s%u\n %*s%u\n %*s%u\n"
|
||||
" %*s{%u/%u}\n %*s%u\n %*s%d\n %*s%u\n",
|
||||
width, "g_usage:", cfg->g_usage,
|
||||
width, "g_threads:", cfg->g_threads,
|
||||
width, "g_profile:", cfg->g_profile,
|
||||
width, "g_w:", cfg->g_w,
|
||||
width, "g_h:", cfg->g_h,
|
||||
width, "g_timebase:", cfg->g_timebase.num, cfg->g_timebase.den,
|
||||
width, "g_error_resilient:", cfg->g_error_resilient,
|
||||
width, "g_pass:", cfg->g_pass,
|
||||
width, "g_lag_in_frames:", cfg->g_lag_in_frames);
|
||||
av_log(avctx, level, "rate control settings\n"
|
||||
" %*s%u\n %*s%u\n %*s%u\n %*s%u\n"
|
||||
" %*s%d\n %*s%p(%zu)\n %*s%u\n",
|
||||
width, "rc_dropframe_thresh:", cfg->rc_dropframe_thresh,
|
||||
width, "rc_resize_allowed:", cfg->rc_resize_allowed,
|
||||
width, "rc_resize_up_thresh:", cfg->rc_resize_up_thresh,
|
||||
width, "rc_resize_down_thresh:", cfg->rc_resize_down_thresh,
|
||||
width, "rc_end_usage:", cfg->rc_end_usage,
|
||||
width, "rc_twopass_stats_in:", cfg->rc_twopass_stats_in.buf, cfg->rc_twopass_stats_in.sz,
|
||||
width, "rc_target_bitrate:", cfg->rc_target_bitrate);
|
||||
av_log(avctx, level, "quantizer settings\n"
|
||||
" %*s%u\n %*s%u\n",
|
||||
width, "rc_min_quantizer:", cfg->rc_min_quantizer,
|
||||
width, "rc_max_quantizer:", cfg->rc_max_quantizer);
|
||||
av_log(avctx, level, "bitrate tolerance\n"
|
||||
" %*s%u\n %*s%u\n",
|
||||
width, "rc_undershoot_pct:", cfg->rc_undershoot_pct,
|
||||
width, "rc_overshoot_pct:", cfg->rc_overshoot_pct);
|
||||
av_log(avctx, level, "decoder buffer model\n"
|
||||
" %*s%u\n %*s%u\n %*s%u\n",
|
||||
width, "rc_buf_sz:", cfg->rc_buf_sz,
|
||||
width, "rc_buf_initial_sz:", cfg->rc_buf_initial_sz,
|
||||
width, "rc_buf_optimal_sz:", cfg->rc_buf_optimal_sz);
|
||||
av_log(avctx, level, "2 pass rate control settings\n"
|
||||
" %*s%u\n %*s%u\n %*s%u\n",
|
||||
width, "rc_2pass_vbr_bias_pct:", cfg->rc_2pass_vbr_bias_pct,
|
||||
width, "rc_2pass_vbr_minsection_pct:", cfg->rc_2pass_vbr_minsection_pct,
|
||||
width, "rc_2pass_vbr_maxsection_pct:", cfg->rc_2pass_vbr_maxsection_pct);
|
||||
av_log(avctx, level, "keyframing settings\n"
|
||||
" %*s%d\n %*s%u\n %*s%u\n",
|
||||
width, "kf_mode:", cfg->kf_mode,
|
||||
width, "kf_min_dist:", cfg->kf_min_dist,
|
||||
width, "kf_max_dist:", cfg->kf_max_dist);
|
||||
av_log(avctx, level, "\n");
|
||||
}
|
||||
|
||||
static void coded_frame_add(void *list, struct FrameListData *cx_frame)
|
||||
{
|
||||
struct FrameListData **p = list;
|
||||
|
||||
while (*p != NULL)
|
||||
p = &(*p)->next;
|
||||
*p = cx_frame;
|
||||
cx_frame->next = NULL;
|
||||
}
|
||||
|
||||
static av_cold void free_coded_frame(struct FrameListData *cx_frame)
|
||||
{
|
||||
av_freep(&cx_frame->buf);
|
||||
av_freep(&cx_frame);
|
||||
}
|
||||
|
||||
static av_cold void free_frame_list(struct FrameListData *list)
|
||||
{
|
||||
struct FrameListData *p = list;
|
||||
|
||||
while (p) {
|
||||
list = list->next;
|
||||
free_coded_frame(p);
|
||||
p = list;
|
||||
}
|
||||
}
|
||||
|
||||
static av_cold int codecctl_int(AVCodecContext *avctx,
|
||||
enum vp8e_enc_control_id id, int val)
|
||||
{
|
||||
VP8Context *ctx = avctx->priv_data;
|
||||
char buf[80];
|
||||
int width = -30;
|
||||
int res;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]);
|
||||
av_log(avctx, AV_LOG_DEBUG, " %*s%d\n", width, buf, val);
|
||||
|
||||
res = vpx_codec_control(&ctx->encoder, id, val);
|
||||
if (res != VPX_CODEC_OK) {
|
||||
snprintf(buf, sizeof(buf), "Failed to set %s codec control",
|
||||
ctlidstr[id]);
|
||||
log_encoder_error(avctx, buf);
|
||||
}
|
||||
|
||||
return res == VPX_CODEC_OK ? 0 : AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
static av_cold int vp8_free(AVCodecContext *avctx)
|
||||
{
|
||||
VP8Context *ctx = avctx->priv_data;
|
||||
|
||||
vpx_codec_destroy(&ctx->encoder);
|
||||
av_freep(&ctx->twopass_stats.buf);
|
||||
av_freep(&avctx->coded_frame);
|
||||
av_freep(&avctx->stats_out);
|
||||
free_frame_list(ctx->coded_frame_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_cold int vp8_init(AVCodecContext *avctx)
|
||||
{
|
||||
VP8Context *ctx = avctx->priv_data;
|
||||
const struct vpx_codec_iface *iface = &vpx_codec_vp8_cx_algo;
|
||||
int cpuused = 3;
|
||||
struct vpx_codec_enc_cfg enccfg;
|
||||
int res;
|
||||
|
||||
av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str());
|
||||
av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config());
|
||||
|
||||
if ((res = vpx_codec_enc_config_default(iface, &enccfg, 0)) != VPX_CODEC_OK) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Failed to get config: %s\n",
|
||||
vpx_codec_err_to_string(res));
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
dump_enc_cfg(avctx, &enccfg);
|
||||
|
||||
enccfg.g_w = avctx->width;
|
||||
enccfg.g_h = avctx->height;
|
||||
enccfg.g_timebase.num = avctx->time_base.num;
|
||||
enccfg.g_timebase.den = avctx->time_base.den;
|
||||
enccfg.g_threads = avctx->thread_count;
|
||||
|
||||
if (avctx->flags & CODEC_FLAG_PASS1)
|
||||
enccfg.g_pass = VPX_RC_FIRST_PASS;
|
||||
else if (avctx->flags & CODEC_FLAG_PASS2)
|
||||
enccfg.g_pass = VPX_RC_LAST_PASS;
|
||||
else
|
||||
enccfg.g_pass = VPX_RC_ONE_PASS;
|
||||
|
||||
if (avctx->rc_min_rate == avctx->rc_max_rate &&
|
||||
avctx->rc_min_rate == avctx->bit_rate)
|
||||
enccfg.rc_end_usage = VPX_CBR;
|
||||
enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000,
|
||||
AV_ROUND_NEAR_INF);
|
||||
|
||||
//convert [1,51] -> [0,63]
|
||||
enccfg.rc_min_quantizer = ((avctx->qmin * 5 + 1) >> 2) - 1;
|
||||
enccfg.rc_max_quantizer = ((avctx->qmax * 5 + 1) >> 2) - 1;
|
||||
|
||||
if (avctx->keyint_min == avctx->gop_size)
|
||||
enccfg.kf_mode = VPX_KF_FIXED;
|
||||
//_enc_init() will balk if kf_min_dist is set in this case
|
||||
if (enccfg.kf_mode != VPX_KF_AUTO)
|
||||
enccfg.kf_min_dist = avctx->keyint_min;
|
||||
enccfg.kf_max_dist = avctx->gop_size;
|
||||
|
||||
if (enccfg.g_pass == VPX_RC_FIRST_PASS)
|
||||
enccfg.g_lag_in_frames = 0;
|
||||
else if (enccfg.g_pass == VPX_RC_LAST_PASS) {
|
||||
int decode_size;
|
||||
|
||||
if (!avctx->stats_in) {
|
||||
av_log(avctx, AV_LOG_ERROR, "No stats file for second pass\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ctx->twopass_stats.sz = strlen(avctx->stats_in) * 3 / 4;
|
||||
ctx->twopass_stats.buf = av_malloc(ctx->twopass_stats.sz);
|
||||
if (!ctx->twopass_stats.buf) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"Stat buffer alloc (%zu bytes) failed\n",
|
||||
ctx->twopass_stats.sz);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
decode_size = av_base64_decode(ctx->twopass_stats.buf, avctx->stats_in,
|
||||
ctx->twopass_stats.sz);
|
||||
if (decode_size < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Stat buffer decode failed\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ctx->twopass_stats.sz = decode_size;
|
||||
enccfg.rc_twopass_stats_in = ctx->twopass_stats;
|
||||
}
|
||||
|
||||
ctx->deadline = VPX_DL_GOOD_QUALITY;
|
||||
|
||||
dump_enc_cfg(avctx, &enccfg);
|
||||
/* Construct Encoder Context */
|
||||
res = vpx_codec_enc_init(&ctx->encoder, iface, &enccfg, 0);
|
||||
if (res != VPX_CODEC_OK) {
|
||||
log_encoder_error(avctx, "Failed to initialize encoder");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
//codec control failures are currently treated only as warnings
|
||||
av_log(avctx, AV_LOG_DEBUG, "vpx_codec_control\n");
|
||||
codecctl_int(avctx, VP8E_SET_CPUUSED, cpuused);
|
||||
codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction);
|
||||
|
||||
//provide dummy value to initialize wrapper, values will be updated each _encode()
|
||||
vpx_img_wrap(&ctx->rawimg, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1,
|
||||
(unsigned char*)1);
|
||||
|
||||
avctx->coded_frame = avcodec_alloc_frame();
|
||||
if (!avctx->coded_frame) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
|
||||
vp8_free(avctx);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void cx_pktcpy(struct FrameListData *dst,
|
||||
const struct vpx_codec_cx_pkt *src)
|
||||
{
|
||||
dst->pts = src->data.frame.pts;
|
||||
dst->duration = src->data.frame.duration;
|
||||
dst->flags = src->data.frame.flags;
|
||||
dst->sz = src->data.frame.sz;
|
||||
dst->buf = src->data.frame.buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store coded frame information in format suitable for return from encode().
|
||||
*
|
||||
* Write buffer information from @a cx_frame to @a buf & @a buf_size.
|
||||
* Timing/frame details to @a coded_frame.
|
||||
* @return Frame size written to @a buf on success
|
||||
* @return AVERROR(EINVAL) on error
|
||||
*/
|
||||
static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame,
|
||||
uint8_t *buf, int buf_size, AVFrame *coded_frame)
|
||||
{
|
||||
if ((int) cx_frame->sz <= buf_size) {
|
||||
buf_size = cx_frame->sz;
|
||||
memcpy(buf, cx_frame->buf, buf_size);
|
||||
coded_frame->pts = cx_frame->pts;
|
||||
coded_frame->key_frame = !!(cx_frame->flags & VPX_FRAME_IS_KEY);
|
||||
|
||||
if (coded_frame->key_frame)
|
||||
coded_frame->pict_type = FF_I_TYPE;
|
||||
else
|
||||
coded_frame->pict_type = FF_P_TYPE;
|
||||
} else {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"Compressed frame larger than storage provided! (%zu/%d)\n",
|
||||
cx_frame->sz, buf_size);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue multiple output frames from the encoder, returning the front-most.
|
||||
* In cases where vpx_codec_get_cx_data() returns more than 1 frame append
|
||||
* the frame queue. Return the head frame if available.
|
||||
* @return Stored frame size
|
||||
* @return AVERROR(EINVAL) on output size error
|
||||
* @return AVERROR(ENOMEM) on coded frame queue data allocation error
|
||||
*/
|
||||
static int queue_frames(AVCodecContext *avctx, uint8_t *buf, int buf_size,
|
||||
AVFrame *coded_frame)
|
||||
{
|
||||
VP8Context *ctx = avctx->priv_data;
|
||||
const struct vpx_codec_cx_pkt *pkt;
|
||||
const void *iter = NULL;
|
||||
int size = 0;
|
||||
|
||||
if (ctx->coded_frame_list) {
|
||||
struct FrameListData *cx_frame = ctx->coded_frame_list;
|
||||
/* return the leading frame if we've already begun queueing */
|
||||
size = storeframe(avctx, cx_frame, buf, buf_size, coded_frame);
|
||||
if (size < 0)
|
||||
return AVERROR(EINVAL);
|
||||
ctx->coded_frame_list = cx_frame->next;
|
||||
free_coded_frame(cx_frame);
|
||||
}
|
||||
|
||||
/* consume all available output from the encoder before returning. buffers
|
||||
are only good through the next vpx_codec call */
|
||||
while ((pkt = vpx_codec_get_cx_data(&ctx->encoder, &iter))) {
|
||||
switch (pkt->kind) {
|
||||
case VPX_CODEC_CX_FRAME_PKT:
|
||||
if (!size) {
|
||||
struct FrameListData cx_frame;
|
||||
|
||||
/* avoid storing the frame when the list is empty and we haven't yet
|
||||
provided a frame for output */
|
||||
assert(!ctx->coded_frame_list);
|
||||
cx_pktcpy(&cx_frame, pkt);
|
||||
size = storeframe(avctx, &cx_frame, buf, buf_size, coded_frame);
|
||||
if (size < 0)
|
||||
return AVERROR(EINVAL);
|
||||
} else {
|
||||
struct FrameListData *cx_frame =
|
||||
av_malloc(sizeof(struct FrameListData));
|
||||
|
||||
if (!cx_frame) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"Frame queue element alloc failed\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
cx_pktcpy(cx_frame, pkt);
|
||||
cx_frame->buf = av_malloc(cx_frame->sz);
|
||||
|
||||
if (!cx_frame->buf) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"Data buffer alloc (%zu bytes) failed\n",
|
||||
cx_frame->sz);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz);
|
||||
coded_frame_add(&ctx->coded_frame_list, cx_frame);
|
||||
}
|
||||
break;
|
||||
case VPX_CODEC_STATS_PKT: {
|
||||
struct vpx_fixed_buf *stats = &ctx->twopass_stats;
|
||||
stats->buf = av_realloc(stats->buf,
|
||||
stats->sz + pkt->data.twopass_stats.sz);
|
||||
if (!stats->buf) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
memcpy((uint8_t*)stats->buf + stats->sz,
|
||||
pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz);
|
||||
stats->sz += pkt->data.twopass_stats.sz;
|
||||
break;
|
||||
}
|
||||
case VPX_CODEC_PSNR_PKT: //FIXME add support for CODEC_FLAG_PSNR
|
||||
case VPX_CODEC_CUSTOM_PKT:
|
||||
//ignore unsupported/unrecognized packet types
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int vp8_encode(AVCodecContext *avctx, uint8_t *buf, int buf_size,
|
||||
void *data)
|
||||
{
|
||||
VP8Context *ctx = avctx->priv_data;
|
||||
AVFrame *frame = data;
|
||||
struct vpx_image *rawimg = NULL;
|
||||
int64_t timestamp = 0;
|
||||
int res, coded_size;
|
||||
|
||||
if (frame) {
|
||||
rawimg = &ctx->rawimg;
|
||||
rawimg->planes[VPX_PLANE_Y] = frame->data[0];
|
||||
rawimg->planes[VPX_PLANE_U] = frame->data[1];
|
||||
rawimg->planes[VPX_PLANE_V] = frame->data[2];
|
||||
rawimg->stride[VPX_PLANE_Y] = frame->linesize[0];
|
||||
rawimg->stride[VPX_PLANE_U] = frame->linesize[1];
|
||||
rawimg->stride[VPX_PLANE_V] = frame->linesize[2];
|
||||
timestamp = frame->pts;
|
||||
}
|
||||
|
||||
res = vpx_codec_encode(&ctx->encoder, rawimg, timestamp,
|
||||
avctx->ticks_per_frame, 0, ctx->deadline);
|
||||
if (res != VPX_CODEC_OK) {
|
||||
log_encoder_error(avctx, "Error encoding frame");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
coded_size = queue_frames(avctx, buf, buf_size, avctx->coded_frame);
|
||||
|
||||
if (!frame && avctx->flags & CODEC_FLAG_PASS1) {
|
||||
unsigned int b64_size = ((ctx->twopass_stats.sz + 2) / 3) * 4 + 1;
|
||||
|
||||
avctx->stats_out = av_malloc(b64_size);
|
||||
if (!avctx->stats_out) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Stat buffer alloc (%d bytes) failed\n",
|
||||
b64_size);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
av_base64_encode(avctx->stats_out, b64_size, ctx->twopass_stats.buf,
|
||||
ctx->twopass_stats.sz);
|
||||
}
|
||||
return coded_size;
|
||||
}
|
||||
|
||||
AVCodec libvpx_encoder = {
|
||||
"libvpx",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_VP8,
|
||||
sizeof(VP8Context),
|
||||
vp8_init,
|
||||
vp8_encode,
|
||||
vp8_free,
|
||||
NULL,
|
||||
CODEC_CAP_DELAY,
|
||||
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
|
||||
.long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"),
|
||||
};
|
@@ -62,6 +62,9 @@ typedef struct SubStream {
|
||||
//! For each channel output by the matrix, the output channel to map it to
|
||||
uint8_t ch_assign[MAX_CHANNELS];
|
||||
|
||||
//! Channel coding parameters for channels in the substream
|
||||
ChannelParams channel_params[MAX_CHANNELS];
|
||||
|
||||
//! The left shift applied to random noise in 0x31ea substreams.
|
||||
uint8_t noise_shift;
|
||||
//! The current seed value for the pseudorandom noise generator(s).
|
||||
@@ -137,8 +140,6 @@ typedef struct MLPDecodeContext {
|
||||
|
||||
SubStream substream[MAX_SUBSTREAMS];
|
||||
|
||||
ChannelParams channel_params[MAX_CHANNELS];
|
||||
|
||||
int matrix_changed;
|
||||
int filter_changed[MAX_CHANNELS][NUM_FILTERS];
|
||||
|
||||
@@ -173,8 +174,8 @@ static av_cold void init_static(void)
|
||||
static inline int32_t calculate_sign_huff(MLPDecodeContext *m,
|
||||
unsigned int substr, unsigned int ch)
|
||||
{
|
||||
ChannelParams *cp = &m->channel_params[ch];
|
||||
SubStream *s = &m->substream[substr];
|
||||
ChannelParams *cp = &s->channel_params[ch];
|
||||
int lsb_bits = cp->huff_lsbs - s->quant_step_size[ch];
|
||||
int sign_shift = lsb_bits + (cp->codebook ? 2 - cp->codebook : -1);
|
||||
int32_t sign_huff_offset = cp->huff_offset;
|
||||
@@ -202,7 +203,7 @@ static inline int read_huff_channels(MLPDecodeContext *m, GetBitContext *gbp,
|
||||
m->bypassed_lsbs[pos + s->blockpos][mat] = get_bits1(gbp);
|
||||
|
||||
for (channel = s->min_channel; channel <= s->max_channel; channel++) {
|
||||
ChannelParams *cp = &m->channel_params[channel];
|
||||
ChannelParams *cp = &s->channel_params[channel];
|
||||
int codebook = cp->codebook;
|
||||
int quant_step_size = s->quant_step_size[channel];
|
||||
int lsb_bits = cp->huff_lsbs - quant_step_size;
|
||||
@@ -450,7 +451,7 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
|
||||
memset(s->quant_step_size, 0, sizeof(s->quant_step_size));
|
||||
|
||||
for (ch = s->min_channel; ch <= s->max_channel; ch++) {
|
||||
ChannelParams *cp = &m->channel_params[ch];
|
||||
ChannelParams *cp = &s->channel_params[ch];
|
||||
cp->filter_params[FIR].order = 0;
|
||||
cp->filter_params[IIR].order = 0;
|
||||
cp->filter_params[FIR].shift = 0;
|
||||
@@ -472,9 +473,11 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
|
||||
/** Read parameters for one of the prediction filters. */
|
||||
|
||||
static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp,
|
||||
unsigned int channel, unsigned int filter)
|
||||
unsigned int substr, unsigned int channel,
|
||||
unsigned int filter)
|
||||
{
|
||||
FilterParams *fp = &m->channel_params[channel].filter_params[filter];
|
||||
SubStream *s = &m->substream[substr];
|
||||
FilterParams *fp = &s->channel_params[channel].filter_params[filter];
|
||||
const int max_order = filter ? MAX_IIR_ORDER : MAX_FIR_ORDER;
|
||||
const char fchar = filter ? 'I' : 'F';
|
||||
int i, order;
|
||||
@@ -497,7 +500,7 @@ static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp,
|
||||
fp->order = order;
|
||||
|
||||
if (order > 0) {
|
||||
int32_t *fcoeff = m->channel_params[channel].coeff[filter];
|
||||
int32_t *fcoeff = s->channel_params[channel].coeff[filter];
|
||||
int coeff_bits, coeff_shift;
|
||||
|
||||
fp->shift = get_bits(gbp, 4);
|
||||
@@ -610,19 +613,19 @@ static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitCo
|
||||
static int read_channel_params(MLPDecodeContext *m, unsigned int substr,
|
||||
GetBitContext *gbp, unsigned int ch)
|
||||
{
|
||||
ChannelParams *cp = &m->channel_params[ch];
|
||||
SubStream *s = &m->substream[substr];
|
||||
ChannelParams *cp = &s->channel_params[ch];
|
||||
FilterParams *fir = &cp->filter_params[FIR];
|
||||
FilterParams *iir = &cp->filter_params[IIR];
|
||||
SubStream *s = &m->substream[substr];
|
||||
|
||||
if (s->param_presence_flags & PARAM_FIR)
|
||||
if (get_bits1(gbp))
|
||||
if (read_filter_params(m, gbp, ch, FIR) < 0)
|
||||
if (read_filter_params(m, gbp, substr, ch, FIR) < 0)
|
||||
return -1;
|
||||
|
||||
if (s->param_presence_flags & PARAM_IIR)
|
||||
if (get_bits1(gbp))
|
||||
if (read_filter_params(m, gbp, ch, IIR) < 0)
|
||||
if (read_filter_params(m, gbp, substr, ch, IIR) < 0)
|
||||
return -1;
|
||||
|
||||
if (fir->order + iir->order > 8) {
|
||||
@@ -697,7 +700,7 @@ static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp,
|
||||
if (s->param_presence_flags & PARAM_QUANTSTEP)
|
||||
if (get_bits1(gbp))
|
||||
for (ch = 0; ch <= s->max_channel; ch++) {
|
||||
ChannelParams *cp = &m->channel_params[ch];
|
||||
ChannelParams *cp = &s->channel_params[ch];
|
||||
|
||||
s->quant_step_size[ch] = get_bits(gbp, 4);
|
||||
|
||||
@@ -721,12 +724,12 @@ static void filter_channel(MLPDecodeContext *m, unsigned int substr,
|
||||
unsigned int channel)
|
||||
{
|
||||
SubStream *s = &m->substream[substr];
|
||||
const int32_t *fircoeff = m->channel_params[channel].coeff[FIR];
|
||||
const int32_t *fircoeff = s->channel_params[channel].coeff[FIR];
|
||||
int32_t state_buffer[NUM_FILTERS][MAX_BLOCKSIZE + MAX_FIR_ORDER];
|
||||
int32_t *firbuf = state_buffer[FIR] + MAX_BLOCKSIZE;
|
||||
int32_t *iirbuf = state_buffer[IIR] + MAX_BLOCKSIZE;
|
||||
FilterParams *fir = &m->channel_params[channel].filter_params[FIR];
|
||||
FilterParams *iir = &m->channel_params[channel].filter_params[IIR];
|
||||
FilterParams *fir = &s->channel_params[channel].filter_params[FIR];
|
||||
FilterParams *iir = &s->channel_params[channel].filter_params[IIR];
|
||||
unsigned int filter_shift = fir->shift;
|
||||
int32_t mask = MSB_MASK(s->quant_step_size[channel]);
|
||||
|
||||
|
@@ -1315,23 +1315,32 @@ static int mp_decode_layer2(MPADecodeContext *s)
|
||||
return 3 * 12;
|
||||
}
|
||||
|
||||
static inline void lsf_sf_expand(int *slen,
|
||||
#define SPLIT(dst,sf,n)\
|
||||
if(n==3){\
|
||||
int m= (sf*171)>>9;\
|
||||
dst= sf - 3*m;\
|
||||
sf=m;\
|
||||
}else if(n==4){\
|
||||
dst= sf&3;\
|
||||
sf>>=2;\
|
||||
}else if(n==5){\
|
||||
int m= (sf*205)>>10;\
|
||||
dst= sf - 5*m;\
|
||||
sf=m;\
|
||||
}else if(n==6){\
|
||||
int m= (sf*171)>>10;\
|
||||
dst= sf - 6*m;\
|
||||
sf=m;\
|
||||
}else{\
|
||||
dst=0;\
|
||||
}
|
||||
|
||||
static av_always_inline void lsf_sf_expand(int *slen,
|
||||
int sf, int n1, int n2, int n3)
|
||||
{
|
||||
if (n3) {
|
||||
slen[3] = sf % n3;
|
||||
sf /= n3;
|
||||
} else {
|
||||
slen[3] = 0;
|
||||
}
|
||||
if (n2) {
|
||||
slen[2] = sf % n2;
|
||||
sf /= n2;
|
||||
} else {
|
||||
slen[2] = 0;
|
||||
}
|
||||
slen[1] = sf % n1;
|
||||
sf /= n1;
|
||||
SPLIT(slen[3], sf, n3)
|
||||
SPLIT(slen[2], sf, n2)
|
||||
SPLIT(slen[1], sf, n1)
|
||||
slen[0] = sf;
|
||||
}
|
||||
|
||||
|
@@ -724,14 +724,18 @@ av_cold int avcodec_close(AVCodecContext *avctx)
|
||||
|
||||
AVCodec *avcodec_find_encoder(enum CodecID id)
|
||||
{
|
||||
AVCodec *p;
|
||||
AVCodec *p, *experimental=NULL;
|
||||
p = first_avcodec;
|
||||
while (p) {
|
||||
if (p->encode != NULL && p->id == id)
|
||||
return p;
|
||||
if (p->encode != NULL && p->id == id) {
|
||||
if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) {
|
||||
experimental = p;
|
||||
} else
|
||||
return p;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
return NULL;
|
||||
return experimental;
|
||||
}
|
||||
|
||||
AVCodec *avcodec_find_encoder_by_name(const char *name)
|
||||
|
@@ -1099,7 +1099,7 @@ AVCodec vorbis_encoder = {
|
||||
vorbis_encode_init,
|
||||
vorbis_encode_frame,
|
||||
vorbis_encode_close,
|
||||
.capabilities= CODEC_CAP_DELAY,
|
||||
.capabilities= CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL,
|
||||
.sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Vorbis"),
|
||||
};
|
||||
|
@@ -1138,7 +1138,7 @@ static av_noinline void OPNAME ## h264_qpel8_h_lowpass_ ## MMX(uint8_t *dst, uin
|
||||
int h=8;\
|
||||
__asm__ volatile(\
|
||||
"pxor %%mm7, %%mm7 \n\t"\
|
||||
"movq %5, %%mm6 \n\t"\
|
||||
"movq "MANGLE(ff_pw_5)", %%mm6\n\t"\
|
||||
"1: \n\t"\
|
||||
"movq (%0), %%mm0 \n\t"\
|
||||
"movq 1(%0), %%mm2 \n\t"\
|
||||
@@ -1172,7 +1172,7 @@ static av_noinline void OPNAME ## h264_qpel8_h_lowpass_ ## MMX(uint8_t *dst, uin
|
||||
"punpcklbw %%mm7, %%mm5 \n\t"\
|
||||
"paddw %%mm3, %%mm2 \n\t"\
|
||||
"paddw %%mm5, %%mm4 \n\t"\
|
||||
"movq %6, %%mm5 \n\t"\
|
||||
"movq "MANGLE(ff_pw_16)", %%mm5\n\t"\
|
||||
"paddw %%mm5, %%mm2 \n\t"\
|
||||
"paddw %%mm5, %%mm4 \n\t"\
|
||||
"paddw %%mm2, %%mm0 \n\t"\
|
||||
@@ -1186,7 +1186,7 @@ static av_noinline void OPNAME ## h264_qpel8_h_lowpass_ ## MMX(uint8_t *dst, uin
|
||||
"decl %2 \n\t"\
|
||||
" jnz 1b \n\t"\
|
||||
: "+a"(src), "+c"(dst), "+g"(h)\
|
||||
: "d"((x86_reg)srcStride), "S"((x86_reg)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\
|
||||
: "d"((x86_reg)srcStride), "S"((x86_reg)dstStride)\
|
||||
: "memory"\
|
||||
);\
|
||||
}\
|
||||
@@ -1640,7 +1640,7 @@ static av_noinline void OPNAME ## h264_qpel8_h_lowpass_ ## MMX(uint8_t *dst, uin
|
||||
int h=8;\
|
||||
__asm__ volatile(\
|
||||
"pxor %%xmm7, %%xmm7 \n\t"\
|
||||
"movdqa %5, %%xmm6 \n\t"\
|
||||
"movdqa "MANGLE(ff_pw_5)", %%xmm6\n\t"\
|
||||
"1: \n\t"\
|
||||
"lddqu -2(%0), %%xmm1 \n\t"\
|
||||
"movdqa %%xmm1, %%xmm0 \n\t"\
|
||||
@@ -1660,7 +1660,7 @@ static av_noinline void OPNAME ## h264_qpel8_h_lowpass_ ## MMX(uint8_t *dst, uin
|
||||
"paddw %%xmm4, %%xmm1 \n\t"\
|
||||
"psllw $2, %%xmm2 \n\t"\
|
||||
"psubw %%xmm1, %%xmm2 \n\t"\
|
||||
"paddw %6, %%xmm0 \n\t"\
|
||||
"paddw "MANGLE(ff_pw_16)", %%xmm0\n\t"\
|
||||
"pmullw %%xmm6, %%xmm2 \n\t"\
|
||||
"paddw %%xmm0, %%xmm2 \n\t"\
|
||||
"psraw $5, %%xmm2 \n\t"\
|
||||
@@ -1671,8 +1671,7 @@ static av_noinline void OPNAME ## h264_qpel8_h_lowpass_ ## MMX(uint8_t *dst, uin
|
||||
"decl %2 \n\t"\
|
||||
" jnz 1b \n\t"\
|
||||
: "+a"(src), "+c"(dst), "+g"(h)\
|
||||
: "D"((x86_reg)srcStride), "S"((x86_reg)dstStride),\
|
||||
"m"(ff_pw_5), "m"(ff_pw_16)\
|
||||
: "D"((x86_reg)srcStride), "S"((x86_reg)dstStride)\
|
||||
: "memory"\
|
||||
);\
|
||||
}\
|
||||
|
@@ -31,17 +31,17 @@
|
||||
"imull %3 \n\t"\
|
||||
"shrdl %4, %%edx, %%eax \n\t"\
|
||||
: "=a"(rt), "=d"(dummy)\
|
||||
: "a" ((int)ra), "rm" ((int)rb), "i"(shift));\
|
||||
: "a" ((int)(ra)), "rm" ((int)(rb)), "i"(shift));\
|
||||
rt; })
|
||||
|
||||
#define MULH(ra, rb) \
|
||||
({ int rt, dummy;\
|
||||
__asm__ ("imull %3\n\t" : "=d"(rt), "=a"(dummy): "a" ((int)ra), "rm" ((int)rb));\
|
||||
__asm__ ("imull %3\n\t" : "=d"(rt), "=a"(dummy): "a" ((int)(ra)), "rm" ((int)(rb)));\
|
||||
rt; })
|
||||
|
||||
#define MUL64(ra, rb) \
|
||||
({ int64_t rt;\
|
||||
__asm__ ("imull %2\n\t" : "=A"(rt) : "a" ((int)ra), "g" ((int)rb));\
|
||||
__asm__ ("imull %2\n\t" : "=A"(rt) : "a" ((int)(ra)), "g" ((int)(rb)));\
|
||||
rt; })
|
||||
#endif
|
||||
|
||||
|
@@ -114,7 +114,7 @@ OBJS-$(CONFIG_MM_DEMUXER) += mm.o
|
||||
OBJS-$(CONFIG_MMF_DEMUXER) += mmf.o raw.o
|
||||
OBJS-$(CONFIG_MMF_MUXER) += mmf.o riff.o
|
||||
OBJS-$(CONFIG_MOV_DEMUXER) += mov.o riff.o isom.o
|
||||
OBJS-$(CONFIG_MOV_MUXER) += movenc.o riff.o isom.o avc.o
|
||||
OBJS-$(CONFIG_MOV_MUXER) += movenc.o riff.o isom.o avc.o movenchint.o
|
||||
OBJS-$(CONFIG_MP2_MUXER) += mp3.o id3v1.o
|
||||
OBJS-$(CONFIG_MP3_DEMUXER) += mp3.o id3v1.o id3v2.o
|
||||
OBJS-$(CONFIG_MP3_MUXER) += mp3.o id3v1.o id3v2.o
|
||||
@@ -255,6 +255,9 @@ OBJS-$(CONFIG_W64_DEMUXER) += wav.o riff.o raw.o
|
||||
OBJS-$(CONFIG_WAV_DEMUXER) += wav.o riff.o raw.o
|
||||
OBJS-$(CONFIG_WAV_MUXER) += wav.o riff.o
|
||||
OBJS-$(CONFIG_WC3_DEMUXER) += wc3movie.o
|
||||
OBJS-$(CONFIG_WEBM_MUXER) += matroskaenc.o matroska.o \
|
||||
riff.o isom.o avc.o \
|
||||
flacenc_header.o
|
||||
OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood.o
|
||||
OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood.o
|
||||
OBJS-$(CONFIG_WV_DEMUXER) += wv.o apetag.o id3v1.o
|
||||
|
@@ -46,10 +46,9 @@ static int aea_read_probe(AVProbeData *p)
|
||||
/* Check so that the redundant bsm bytes and info bytes are valid
|
||||
* the block size mode bytes have to be the same
|
||||
* the info bytes have to be the same
|
||||
* the block size mode and info byte can't be the same
|
||||
*/
|
||||
if (bsm_s == bsm_e && inb_s == inb_e && bsm_s != inb_s)
|
||||
return AVPROBE_SCORE_MAX / 2;
|
||||
if (bsm_s == bsm_e && inb_s == inb_e)
|
||||
return AVPROBE_SCORE_MAX / 4 + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -203,6 +203,7 @@ void av_register_all(void)
|
||||
REGISTER_DEMUXER (W64, w64);
|
||||
REGISTER_MUXDEMUX (WAV, wav);
|
||||
REGISTER_DEMUXER (WC3, wc3);
|
||||
REGISTER_MUXER (WEBM, webm);
|
||||
REGISTER_DEMUXER (WSAUD, wsaud);
|
||||
REGISTER_DEMUXER (WSVQA, wsvqa);
|
||||
REGISTER_DEMUXER (WV, wv);
|
||||
|
@@ -204,9 +204,10 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
get_byte(pb);
|
||||
memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid));
|
||||
for(;;) {
|
||||
uint64_t gpos= url_ftell(pb);
|
||||
get_guid(pb, &g);
|
||||
gsize = get_le64(pb);
|
||||
dprintf(s, "%08"PRIx64": ", url_ftell(pb) - 24);
|
||||
dprintf(s, "%08"PRIx64": ", gpos);
|
||||
print_guid(&g);
|
||||
dprintf(s, " size=0x%"PRIx64"\n", gsize);
|
||||
if (!guidcmp(&g, &ff_asf_data_header)) {
|
||||
@@ -584,8 +585,10 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
av_log(s, AV_LOG_WARNING, "Digital signature detected, decoding will likely fail!\n");
|
||||
}
|
||||
}
|
||||
url_fseek(pb, gsize - 24, SEEK_CUR);
|
||||
}
|
||||
if(url_ftell(pb) != gpos + gsize)
|
||||
av_log(s, AV_LOG_DEBUG, "gpos mismatch our pos=%"PRIu64", end=%"PRIu64"\n", url_ftell(pb)-gpos, gsize);
|
||||
url_fseek(pb, gpos + gsize, SEEK_SET);
|
||||
}
|
||||
get_guid(pb, &g);
|
||||
get_le64(pb);
|
||||
|
@@ -22,8 +22,8 @@
|
||||
#define AVFORMAT_AVFORMAT_H
|
||||
|
||||
#define LIBAVFORMAT_VERSION_MAJOR 52
|
||||
#define LIBAVFORMAT_VERSION_MINOR 62
|
||||
#define LIBAVFORMAT_VERSION_MICRO 0
|
||||
#define LIBAVFORMAT_VERSION_MINOR 64
|
||||
#define LIBAVFORMAT_VERSION_MICRO 2
|
||||
|
||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||
LIBAVFORMAT_VERSION_MINOR, \
|
||||
@@ -653,6 +653,7 @@ typedef struct AVFormatContext {
|
||||
#define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS
|
||||
#define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container
|
||||
#define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled
|
||||
#define AVFMT_FLAG_RTP_HINT 0x0040 ///< Add RTP hinting to the output file
|
||||
|
||||
int loop_input;
|
||||
/** decoding: size of data to probe; encoding: unused. */
|
||||
|
@@ -650,6 +650,16 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
avi_load_index(s);
|
||||
avi->index_loaded = 1;
|
||||
avi->non_interleaved |= guess_ni_flag(s);
|
||||
for(i=0; i<s->nb_streams; i++){
|
||||
AVStream *st = s->streams[i];
|
||||
if(st->nb_index_entries)
|
||||
break;
|
||||
}
|
||||
if(i==s->nb_streams && avi->non_interleaved) {
|
||||
av_log(s, AV_LOG_WARNING, "non-interleaved AVI without index, switching to interleaved\n");
|
||||
avi->non_interleaved=0;
|
||||
}
|
||||
|
||||
if(avi->non_interleaved) {
|
||||
av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
|
||||
clean_index(s);
|
||||
|
@@ -137,4 +137,21 @@ int ff_url_join(char *str, int size, const char *proto,
|
||||
const char *authorization, const char *hostname,
|
||||
int port, const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* Appends the media-specific SDP fragment for the media stream c
|
||||
* to the buffer buff.
|
||||
*
|
||||
* Note, the buffer needs to be initialized, since it is appended to
|
||||
* existing content.
|
||||
*
|
||||
* @param buff the buffer to append the SDP fragment to
|
||||
* @param size the size of the buff buffer
|
||||
* @param c the AVCodecContext of the media to describe
|
||||
* @param dest_addr the destination address of the media stream, may be NULL
|
||||
* @param port the destination port of the media stream, 0 if unknown
|
||||
* @param ttl the time to live of the stream, 0 if not multicast
|
||||
*/
|
||||
void ff_sdp_write_media(char *buff, int size, AVCodecContext *c,
|
||||
const char *dest_addr, int port, int ttl);
|
||||
|
||||
#endif /* AVFORMAT_INTERNAL_H */
|
||||
|
@@ -76,6 +76,7 @@ const CodecTags ff_mkv_codec_tags[]={
|
||||
{"V_SNOW" , CODEC_ID_SNOW},
|
||||
{"V_THEORA" , CODEC_ID_THEORA},
|
||||
{"V_UNCOMPRESSED" , CODEC_ID_RAWVIDEO},
|
||||
{"V_VP8" , CODEC_ID_VP8},
|
||||
|
||||
{"" , CODEC_ID_NONE}
|
||||
};
|
||||
|
@@ -505,6 +505,8 @@ static EbmlSyntax matroska_clusters[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const char *matroska_doctypes[] = { "matroska", "webm" };
|
||||
|
||||
/*
|
||||
* Return: Whether we reached the end of a level in the hierarchy or not.
|
||||
*/
|
||||
@@ -823,8 +825,7 @@ static void ebml_free(EbmlSyntax *syntax, void *data)
|
||||
static int matroska_probe(AVProbeData *p)
|
||||
{
|
||||
uint64_t total = 0;
|
||||
int len_mask = 0x80, size = 1, n = 1;
|
||||
static const char probe_data[] = "matroska";
|
||||
int len_mask = 0x80, size = 1, n = 1, i;
|
||||
|
||||
/* EBML header? */
|
||||
if (AV_RB32(p->buf) != EBML_ID_HEADER)
|
||||
@@ -846,15 +847,19 @@ static int matroska_probe(AVProbeData *p)
|
||||
if (p->buf_size < 4 + size + total)
|
||||
return 0;
|
||||
|
||||
/* The header must contain the document type 'matroska'. For now,
|
||||
/* The header should contain a known document type. For now,
|
||||
* we don't parse the whole header but simply check for the
|
||||
* availability of that array of characters inside the header.
|
||||
* Not fully fool-proof, but good enough. */
|
||||
for (n = 4+size; n <= 4+size+total-(sizeof(probe_data)-1); n++)
|
||||
if (!memcmp(p->buf+n, probe_data, sizeof(probe_data)-1))
|
||||
return AVPROBE_SCORE_MAX;
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) {
|
||||
int probelen = strlen(matroska_doctypes[i]);
|
||||
for (n = 4+size; n <= 4+size+total-probelen; n++)
|
||||
if (!memcmp(p->buf+n, matroska_doctypes[i], probelen))
|
||||
return AVPROBE_SCORE_MAX;
|
||||
}
|
||||
|
||||
return 0;
|
||||
// probably valid EBML header but no recognized doctype
|
||||
return AVPROBE_SCORE_MAX/2;
|
||||
}
|
||||
|
||||
static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska,
|
||||
@@ -1139,14 +1144,21 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
/* First read the EBML header. */
|
||||
if (ebml_parse(matroska, ebml_syntax, &ebml)
|
||||
|| ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t)
|
||||
|| ebml.id_length > sizeof(uint32_t) || strcmp(ebml.doctype, "matroska")
|
||||
|| ebml.doctype_version > 2) {
|
||||
|| ebml.id_length > sizeof(uint32_t) || ebml.doctype_version > 2) {
|
||||
av_log(matroska->ctx, AV_LOG_ERROR,
|
||||
"EBML header using unsupported features\n"
|
||||
"(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
|
||||
ebml.version, ebml.doctype, ebml.doctype_version);
|
||||
ebml_free(ebml_syntax, &ebml);
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++)
|
||||
if (!strcmp(ebml.doctype, matroska_doctypes[i]))
|
||||
break;
|
||||
if (i >= FF_ARRAY_ELEMS(matroska_doctypes)) {
|
||||
av_log(s, AV_LOG_WARNING, "Unknown EBML doctype '%s'\n", ebml.doctype);
|
||||
}
|
||||
av_metadata_set2(&s->metadata, "doctype", ebml.doctype, 0);
|
||||
ebml_free(ebml_syntax, &ebml);
|
||||
|
||||
/* The next thing is a segment. */
|
||||
@@ -1390,6 +1402,8 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
255);
|
||||
if (st->codec->codec_id != CODEC_ID_H264)
|
||||
st->need_parsing = AVSTREAM_PARSE_HEADERS;
|
||||
if (track->default_duration)
|
||||
st->avg_frame_rate = av_d2q(1000000000.0/track->default_duration, INT_MAX);
|
||||
} else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
|
||||
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||
st->codec->sample_rate = track->audio.out_samplerate;
|
||||
|
@@ -65,7 +65,11 @@ typedef struct {
|
||||
int write_dts;
|
||||
} mkv_track;
|
||||
|
||||
#define MODE_MATROSKAv2 0x01
|
||||
#define MODE_WEBM 0x02
|
||||
|
||||
typedef struct MatroskaMuxContext {
|
||||
int mode;
|
||||
ByteIOContext *dyn_bc;
|
||||
ebml_master segment;
|
||||
int64_t segment_offset;
|
||||
@@ -544,7 +548,6 @@ static int mkv_write_tracks(AVFormatContext *s)
|
||||
put_ebml_uint (pb, MATROSKA_ID_TRACKNUMBER , i + 1);
|
||||
put_ebml_uint (pb, MATROSKA_ID_TRACKUID , i + 1);
|
||||
put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0); // no lacing (yet)
|
||||
put_ebml_float(pb, MATROSKA_ID_TRACKTIMECODESCALE, 1.0);
|
||||
|
||||
if ((tag = av_metadata_get(st->metadata, "title", NULL, 0)))
|
||||
put_ebml_string(pb, MATROSKA_ID_TRACKNAME, tag->value);
|
||||
@@ -564,9 +567,17 @@ static int mkv_write_tracks(AVFormatContext *s)
|
||||
}
|
||||
}
|
||||
|
||||
if (mkv->mode == MODE_WEBM && !(codec->codec_id == CODEC_ID_VP8 ||
|
||||
codec->codec_id == CODEC_ID_VORBIS)) {
|
||||
av_log(s, AV_LOG_ERROR,
|
||||
"Only VP8 video and Vorbis audio are supported for WebM.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
switch (codec->codec_type) {
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO);
|
||||
put_ebml_uint(pb, MATROSKA_ID_TRACKDEFAULTDURATION, av_q2d(codec->time_base)*1E9);
|
||||
|
||||
if (!native_id &&
|
||||
ff_codec_get_tag(codec_movvideo_tags, codec->codec_id) &&
|
||||
@@ -684,6 +695,9 @@ static int mkv_write_header(AVFormatContext *s)
|
||||
AVMetadataTag *tag;
|
||||
int ret;
|
||||
|
||||
if (!strcmp(s->oformat->name, "webm")) mkv->mode = MODE_WEBM;
|
||||
else mkv->mode = MODE_MATROSKAv2;
|
||||
|
||||
mkv->md5_ctx = av_mallocz(av_md5_size);
|
||||
av_md5_init(mkv->md5_ctx);
|
||||
mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks));
|
||||
@@ -693,7 +707,7 @@ static int mkv_write_header(AVFormatContext *s)
|
||||
put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1);
|
||||
put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4);
|
||||
put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8);
|
||||
put_ebml_string (pb, EBML_ID_DOCTYPE , "matroska");
|
||||
put_ebml_string (pb, EBML_ID_DOCTYPE , s->oformat->name);
|
||||
put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 2);
|
||||
put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2);
|
||||
end_ebml_master(pb, ebml_header);
|
||||
@@ -736,8 +750,10 @@ static int mkv_write_header(AVFormatContext *s)
|
||||
ret = mkv_write_tracks(s);
|
||||
if (ret < 0) return ret;
|
||||
|
||||
ret = mkv_write_chapters(s);
|
||||
if (ret < 0) return ret;
|
||||
if (mkv->mode != MODE_WEBM) {
|
||||
ret = mkv_write_chapters(s);
|
||||
if (ret < 0) return ret;
|
||||
}
|
||||
|
||||
if (url_is_streamed(s->pb))
|
||||
mkv_write_seekhead(pb, mkv->main_seekhead);
|
||||
@@ -974,6 +990,7 @@ static int mkv_write_trailer(AVFormatContext *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_MATROSKA_MUXER
|
||||
AVOutputFormat matroska_muxer = {
|
||||
"matroska",
|
||||
NULL_IF_CONFIG_SMALL("Matroska file format"),
|
||||
@@ -989,7 +1006,25 @@ AVOutputFormat matroska_muxer = {
|
||||
.codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
|
||||
.subtitle_codec = CODEC_ID_TEXT,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_WEBM_MUXER
|
||||
AVOutputFormat webm_muxer = {
|
||||
"webm",
|
||||
NULL_IF_CONFIG_SMALL("WebM file format"),
|
||||
"video/webm",
|
||||
"webm",
|
||||
sizeof(MatroskaMuxContext),
|
||||
CODEC_ID_VORBIS,
|
||||
CODEC_ID_VP8,
|
||||
mkv_write_header,
|
||||
mkv_write_packet,
|
||||
mkv_write_trailer,
|
||||
.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_MATROSKA_AUDIO_MUXER
|
||||
AVOutputFormat matroska_audio_muxer = {
|
||||
"matroska",
|
||||
NULL_IF_CONFIG_SMALL("Matroska file format"),
|
||||
@@ -1004,3 +1039,4 @@ AVOutputFormat matroska_audio_muxer = {
|
||||
.flags = AVFMT_GLOBALHEADER,
|
||||
.codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0},
|
||||
};
|
||||
#endif
|
||||
|
@@ -144,7 +144,7 @@ static int mov_read_udta_string(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
|
||||
switch (atom.type) {
|
||||
case MKTAG(0xa9,'n','a','m'): key = "title"; break;
|
||||
case MKTAG(0xa9,'a','u','t'):
|
||||
case MKTAG(0xa9,'A','R','T'): key = "author"; break;
|
||||
case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
|
||||
case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
|
||||
case MKTAG( 'c','p','r','t'):
|
||||
case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
|
||||
|
@@ -21,6 +21,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "movenc.h"
|
||||
#include "avformat.h"
|
||||
#include "riff.h"
|
||||
#include "avio.h"
|
||||
@@ -28,69 +29,12 @@
|
||||
#include "avc.h"
|
||||
#include "libavcodec/get_bits.h"
|
||||
#include "libavcodec/put_bits.h"
|
||||
#include "internal.h"
|
||||
#include "libavutil/avstring.h"
|
||||
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
|
||||
#define MOV_INDEX_CLUSTER_SIZE 16384
|
||||
#define MOV_TIMESCALE 1000
|
||||
|
||||
#define MODE_MP4 0x01
|
||||
#define MODE_MOV 0x02
|
||||
#define MODE_3GP 0x04
|
||||
#define MODE_PSP 0x08 // example working PSP command line:
|
||||
// ffmpeg -i testinput.avi -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
|
||||
#define MODE_3G2 0x10
|
||||
#define MODE_IPOD 0x20
|
||||
|
||||
typedef struct MOVIentry {
|
||||
unsigned int size;
|
||||
uint64_t pos;
|
||||
unsigned int samplesInChunk;
|
||||
unsigned int entries;
|
||||
int cts;
|
||||
int64_t dts;
|
||||
#define MOV_SYNC_SAMPLE 0x0001
|
||||
#define MOV_PARTIAL_SYNC_SAMPLE 0x0002
|
||||
uint32_t flags;
|
||||
} MOVIentry;
|
||||
|
||||
typedef struct MOVIndex {
|
||||
int mode;
|
||||
int entry;
|
||||
unsigned timescale;
|
||||
uint64_t time;
|
||||
int64_t trackDuration;
|
||||
long sampleCount;
|
||||
long sampleSize;
|
||||
int hasKeyframes;
|
||||
#define MOV_TRACK_CTTS 0x0001
|
||||
#define MOV_TRACK_STPS 0x0002
|
||||
uint32_t flags;
|
||||
int language;
|
||||
int trackID;
|
||||
int tag; ///< stsd fourcc
|
||||
AVCodecContext *enc;
|
||||
|
||||
int vosLen;
|
||||
uint8_t *vosData;
|
||||
MOVIentry *cluster;
|
||||
int audio_vbr;
|
||||
int height; ///< active picture (w/o VBI) height for D-10/IMX
|
||||
uint32_t tref_tag;
|
||||
int tref_id; ///< trackID of the referenced track
|
||||
} MOVTrack;
|
||||
|
||||
typedef struct MOVMuxContext {
|
||||
int mode;
|
||||
int64_t time;
|
||||
int nb_streams;
|
||||
int chapter_track; ///< qt chapter track number
|
||||
int64_t mdat_pos;
|
||||
uint64_t mdat_size;
|
||||
MOVTrack *tracks;
|
||||
} MOVMuxContext;
|
||||
|
||||
//FIXME support 64 bit variant with wide placeholders
|
||||
static int64_t updateSize(ByteIOContext *pb, int64_t pos)
|
||||
{
|
||||
@@ -864,6 +808,26 @@ static int mov_write_video_tag(ByteIOContext *pb, MOVTrack *track)
|
||||
return updateSize(pb, pos);
|
||||
}
|
||||
|
||||
static int mov_write_rtp_tag(ByteIOContext *pb, MOVTrack *track)
|
||||
{
|
||||
int64_t pos = url_ftell(pb);
|
||||
put_be32(pb, 0); /* size */
|
||||
put_tag(pb, "rtp ");
|
||||
put_be32(pb, 0); /* Reserved */
|
||||
put_be16(pb, 0); /* Reserved */
|
||||
put_be16(pb, 1); /* Data-reference index */
|
||||
|
||||
put_be16(pb, 1); /* Hint track version */
|
||||
put_be16(pb, 1); /* Highest compatible version */
|
||||
put_be32(pb, track->max_packet_size); /* Max packet size */
|
||||
|
||||
put_be32(pb, 12); /* size */
|
||||
put_tag(pb, "tims");
|
||||
put_be32(pb, track->timescale);
|
||||
|
||||
return updateSize(pb, pos);
|
||||
}
|
||||
|
||||
static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack *track)
|
||||
{
|
||||
int64_t pos = url_ftell(pb);
|
||||
@@ -877,6 +841,8 @@ static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack *track)
|
||||
mov_write_audio_tag(pb, track);
|
||||
else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)
|
||||
mov_write_subtitle_tag(pb, track);
|
||||
else if (track->enc->codec_tag == MKTAG('r','t','p',' '))
|
||||
mov_write_rtp_tag(pb, track);
|
||||
return updateSize(pb, pos);
|
||||
}
|
||||
|
||||
@@ -976,7 +942,8 @@ static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack *track)
|
||||
put_tag(pb, "stbl");
|
||||
mov_write_stsd_tag(pb, track);
|
||||
mov_write_stts_tag(pb, track);
|
||||
if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO &&
|
||||
if ((track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
|
||||
track->enc->codec_tag == MKTAG('r','t','p',' ')) &&
|
||||
track->hasKeyframes && track->hasKeyframes < track->entry)
|
||||
mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
|
||||
if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
|
||||
@@ -1063,6 +1030,9 @@ static int mov_write_hdlr_tag(ByteIOContext *pb, MOVTrack *track)
|
||||
if (track->tag == MKTAG('t','x','3','g')) hdlr_type = "sbtl";
|
||||
else hdlr_type = "text";
|
||||
descr = "SubtitleHandler";
|
||||
} else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
|
||||
hdlr_type = "hint";
|
||||
descr = "HintHandler";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1082,6 +1052,21 @@ static int mov_write_hdlr_tag(ByteIOContext *pb, MOVTrack *track)
|
||||
return updateSize(pb, pos);
|
||||
}
|
||||
|
||||
static int mov_write_hmhd_tag(ByteIOContext *pb)
|
||||
{
|
||||
/* This atom must be present, but leaving the values at zero
|
||||
* seems harmless. */
|
||||
put_be32(pb, 28); /* size */
|
||||
put_tag(pb, "hmhd");
|
||||
put_be32(pb, 0); /* version, flags */
|
||||
put_be16(pb, 0); /* maxPDUsize */
|
||||
put_be16(pb, 0); /* avgPDUsize */
|
||||
put_be32(pb, 0); /* maxbitrate */
|
||||
put_be32(pb, 0); /* avgbitrate */
|
||||
put_be32(pb, 0); /* reserved */
|
||||
return 28;
|
||||
}
|
||||
|
||||
static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack *track)
|
||||
{
|
||||
int64_t pos = url_ftell(pb);
|
||||
@@ -1094,6 +1079,8 @@ static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack *track)
|
||||
else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
if (track->tag == MKTAG('t','e','x','t')) mov_write_gmhd_tag(pb);
|
||||
else mov_write_nmhd_tag(pb);
|
||||
} else if (track->tag == MKTAG('r','t','p',' ')) {
|
||||
mov_write_hmhd_tag(pb);
|
||||
}
|
||||
if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */
|
||||
mov_write_hdlr_tag(pb, NULL);
|
||||
@@ -1249,6 +1236,25 @@ static int mov_write_uuid_tag_psp(ByteIOContext *pb, MOVTrack *mov)
|
||||
return 0x34;
|
||||
}
|
||||
|
||||
static int mov_write_udta_sdp(ByteIOContext *pb, AVCodecContext *ctx, int index)
|
||||
{
|
||||
char buf[1000] = "";
|
||||
int len;
|
||||
|
||||
ff_sdp_write_media(buf, sizeof(buf), ctx, NULL, 0, 0);
|
||||
av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", index);
|
||||
len = strlen(buf);
|
||||
|
||||
put_be32(pb, len + 24);
|
||||
put_tag (pb, "udta");
|
||||
put_be32(pb, len + 16);
|
||||
put_tag (pb, "hnti");
|
||||
put_be32(pb, len + 8);
|
||||
put_tag (pb, "sdp ");
|
||||
put_buffer(pb, buf, len);
|
||||
return len + 24;
|
||||
}
|
||||
|
||||
static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st)
|
||||
{
|
||||
int64_t pos = url_ftell(pb);
|
||||
@@ -1262,6 +1268,8 @@ static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st)
|
||||
mov_write_mdia_tag(pb, track);
|
||||
if (track->mode == MODE_PSP)
|
||||
mov_write_uuid_tag_psp(pb,track); // PSP Movies require this uuid box
|
||||
if (track->tag == MKTAG('r','t','p',' '))
|
||||
mov_write_udta_sdp(pb, track->rtp_ctx->streams[0]->codec, track->trackID);
|
||||
return updateSize(pb, pos);
|
||||
}
|
||||
|
||||
@@ -1444,7 +1452,7 @@ static int mov_write_ilst_tag(ByteIOContext *pb, MOVMuxContext *mov,
|
||||
put_be32(pb, 0); /* size */
|
||||
put_tag(pb, "ilst");
|
||||
mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
|
||||
mov_write_string_metadata(s, pb, "\251ART", "author" , 1);
|
||||
mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
|
||||
mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
|
||||
mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
|
||||
mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
|
||||
@@ -1571,6 +1579,7 @@ static int mov_write_udta_tag(ByteIOContext *pb, MOVMuxContext *mov,
|
||||
return ret;
|
||||
|
||||
if (mov->mode & MODE_3GP) {
|
||||
mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
|
||||
mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
|
||||
mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
|
||||
mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
|
||||
@@ -1676,6 +1685,13 @@ static int mov_write_moov_tag(ByteIOContext *pb, MOVMuxContext *mov,
|
||||
mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
|
||||
mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].trackID;
|
||||
}
|
||||
for (i = 0; i < mov->nb_streams; i++) {
|
||||
if (mov->tracks[i].tag == MKTAG('r','t','p',' ')) {
|
||||
mov->tracks[i].tref_tag = MKTAG('h','i','n','t');
|
||||
mov->tracks[i].tref_id =
|
||||
mov->tracks[mov->tracks[i].src_track].trackID;
|
||||
}
|
||||
}
|
||||
|
||||
mov_write_mvhd_tag(pb, mov);
|
||||
//mov_write_iods_tag(pb, mov);
|
||||
@@ -1843,7 +1859,7 @@ static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
MOVMuxContext *mov = s->priv_data;
|
||||
ByteIOContext *pb = s->pb;
|
||||
@@ -1936,6 +1952,9 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
mov->mdat_size += size;
|
||||
|
||||
put_flush_packet(pb);
|
||||
|
||||
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams)
|
||||
ff_mov_add_hinted_packet(s, pkt, trk->hint_track, trk->entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1968,7 +1987,7 @@ static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
|
||||
pkt.data = av_malloc(pkt.size);
|
||||
AV_WB16(pkt.data, len);
|
||||
memcpy(pkt.data+2, t->value, len);
|
||||
mov_write_packet(s, &pkt);
|
||||
ff_mov_write_packet(s, &pkt);
|
||||
av_freep(&pkt.data);
|
||||
}
|
||||
}
|
||||
@@ -1978,7 +1997,7 @@ static int mov_write_header(AVFormatContext *s)
|
||||
{
|
||||
ByteIOContext *pb = s->pb;
|
||||
MOVMuxContext *mov = s->priv_data;
|
||||
int i;
|
||||
int i, hint_track = 0;
|
||||
|
||||
if (url_is_streamed(s->pb)) {
|
||||
av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
|
||||
@@ -2009,6 +2028,18 @@ static int mov_write_header(AVFormatContext *s)
|
||||
if (mov->mode & (MODE_MOV|MODE_IPOD) && s->nb_chapters)
|
||||
mov->chapter_track = mov->nb_streams++;
|
||||
|
||||
if (s->flags & AVFMT_FLAG_RTP_HINT) {
|
||||
/* Add hint tracks for each audio and video stream */
|
||||
hint_track = mov->nb_streams;
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
AVStream *st = s->streams[i];
|
||||
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
|
||||
st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
mov->nb_streams++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mov->tracks = av_mallocz(mov->nb_streams*sizeof(*mov->tracks));
|
||||
if (!mov->tracks)
|
||||
return AVERROR(ENOMEM);
|
||||
@@ -2029,6 +2060,9 @@ static int mov_write_header(AVFormatContext *s)
|
||||
"codec not currently supported in container\n", i);
|
||||
goto error;
|
||||
}
|
||||
/* If hinting of this track is enabled by a later hint track,
|
||||
* this is updated. */
|
||||
track->hint_track = -1;
|
||||
if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){
|
||||
if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
|
||||
track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
|
||||
@@ -2083,6 +2117,18 @@ static int mov_write_header(AVFormatContext *s)
|
||||
if (mov->chapter_track)
|
||||
mov_create_chapter_track(s, mov->chapter_track);
|
||||
|
||||
if (s->flags & AVFMT_FLAG_RTP_HINT) {
|
||||
/* Initialize the hint tracks for each audio and video stream */
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
AVStream *st = s->streams[i];
|
||||
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
|
||||
st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
ff_mov_init_hinting(s, hint_track, i);
|
||||
hint_track++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
put_flush_packet(pb);
|
||||
|
||||
return 0;
|
||||
@@ -2119,6 +2165,8 @@ static int mov_write_trailer(AVFormatContext *s)
|
||||
av_freep(&mov->tracks[mov->chapter_track].enc);
|
||||
|
||||
for (i=0; i<mov->nb_streams; i++) {
|
||||
if (mov->tracks[i].tag == MKTAG('r','t','p',' '))
|
||||
ff_mov_close_hinting(&mov->tracks[i]);
|
||||
av_freep(&mov->tracks[i].cluster);
|
||||
|
||||
if(mov->tracks[i].vosLen) av_free(mov->tracks[i].vosData);
|
||||
@@ -2142,7 +2190,7 @@ AVOutputFormat mov_muxer = {
|
||||
CODEC_ID_AAC,
|
||||
CODEC_ID_MPEG4,
|
||||
mov_write_header,
|
||||
mov_write_packet,
|
||||
ff_mov_write_packet,
|
||||
mov_write_trailer,
|
||||
.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
|
||||
.codec_tag = (const AVCodecTag* const []){codec_movvideo_tags, codec_movaudio_tags, 0},
|
||||
@@ -2158,7 +2206,7 @@ AVOutputFormat tgp_muxer = {
|
||||
CODEC_ID_AMR_NB,
|
||||
CODEC_ID_H263,
|
||||
mov_write_header,
|
||||
mov_write_packet,
|
||||
ff_mov_write_packet,
|
||||
mov_write_trailer,
|
||||
.flags = AVFMT_GLOBALHEADER,
|
||||
.codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
|
||||
@@ -2174,7 +2222,7 @@ AVOutputFormat mp4_muxer = {
|
||||
CODEC_ID_AAC,
|
||||
CODEC_ID_MPEG4,
|
||||
mov_write_header,
|
||||
mov_write_packet,
|
||||
ff_mov_write_packet,
|
||||
mov_write_trailer,
|
||||
.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
|
||||
.codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
|
||||
@@ -2190,7 +2238,7 @@ AVOutputFormat psp_muxer = {
|
||||
CODEC_ID_AAC,
|
||||
CODEC_ID_MPEG4,
|
||||
mov_write_header,
|
||||
mov_write_packet,
|
||||
ff_mov_write_packet,
|
||||
mov_write_trailer,
|
||||
.flags = AVFMT_GLOBALHEADER,
|
||||
.codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
|
||||
@@ -2206,7 +2254,7 @@ AVOutputFormat tg2_muxer = {
|
||||
CODEC_ID_AMR_NB,
|
||||
CODEC_ID_H263,
|
||||
mov_write_header,
|
||||
mov_write_packet,
|
||||
ff_mov_write_packet,
|
||||
mov_write_trailer,
|
||||
.flags = AVFMT_GLOBALHEADER,
|
||||
.codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
|
||||
@@ -2222,7 +2270,7 @@ AVOutputFormat ipod_muxer = {
|
||||
CODEC_ID_AAC,
|
||||
CODEC_ID_H264,
|
||||
mov_write_header,
|
||||
mov_write_packet,
|
||||
ff_mov_write_packet,
|
||||
mov_write_trailer,
|
||||
.flags = AVFMT_GLOBALHEADER,
|
||||
.codec_tag = (const AVCodecTag* const []){codec_ipod_tags, 0},
|
||||
|
120
libavformat/movenc.h
Normal file
120
libavformat/movenc.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* MOV, 3GP, MP4 muxer
|
||||
* Copyright (c) 2003 Thomas Raivio
|
||||
* Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>
|
||||
* Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVFORMAT_MOVENC_H
|
||||
#define AVFORMAT_MOVENC_H
|
||||
|
||||
#include "avformat.h"
|
||||
|
||||
#define MOV_INDEX_CLUSTER_SIZE 16384
|
||||
#define MOV_TIMESCALE 1000
|
||||
|
||||
#define RTP_MAX_PACKET_SIZE 1450
|
||||
|
||||
#define MODE_MP4 0x01
|
||||
#define MODE_MOV 0x02
|
||||
#define MODE_3GP 0x04
|
||||
#define MODE_PSP 0x08 // example working PSP command line:
|
||||
// ffmpeg -i testinput.avi -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
|
||||
#define MODE_3G2 0x10
|
||||
#define MODE_IPOD 0x20
|
||||
|
||||
typedef struct MOVIentry {
|
||||
unsigned int size;
|
||||
uint64_t pos;
|
||||
unsigned int samplesInChunk;
|
||||
unsigned int entries;
|
||||
int cts;
|
||||
int64_t dts;
|
||||
#define MOV_SYNC_SAMPLE 0x0001
|
||||
#define MOV_PARTIAL_SYNC_SAMPLE 0x0002
|
||||
uint32_t flags;
|
||||
} MOVIentry;
|
||||
|
||||
typedef struct HintSample {
|
||||
uint8_t *data;
|
||||
int size;
|
||||
int sample_number;
|
||||
int offset;
|
||||
int own_data;
|
||||
} HintSample;
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
int len;
|
||||
HintSample *samples;
|
||||
} HintSampleQueue;
|
||||
|
||||
typedef struct MOVIndex {
|
||||
int mode;
|
||||
int entry;
|
||||
unsigned timescale;
|
||||
uint64_t time;
|
||||
int64_t trackDuration;
|
||||
long sampleCount;
|
||||
long sampleSize;
|
||||
int hasKeyframes;
|
||||
#define MOV_TRACK_CTTS 0x0001
|
||||
#define MOV_TRACK_STPS 0x0002
|
||||
uint32_t flags;
|
||||
int language;
|
||||
int trackID;
|
||||
int tag; ///< stsd fourcc
|
||||
AVCodecContext *enc;
|
||||
|
||||
int vosLen;
|
||||
uint8_t *vosData;
|
||||
MOVIentry *cluster;
|
||||
int audio_vbr;
|
||||
int height; ///< active picture (w/o VBI) height for D-10/IMX
|
||||
uint32_t tref_tag;
|
||||
int tref_id; ///< trackID of the referenced track
|
||||
|
||||
int hint_track; ///< the track that hints this track, -1 if no hint track is set
|
||||
int src_track; ///< the track that this hint track describes
|
||||
AVFormatContext *rtp_ctx; ///< the format context for the hinting rtp muxer
|
||||
uint32_t prev_rtp_ts;
|
||||
int64_t cur_rtp_ts_unwrapped;
|
||||
uint32_t max_packet_size;
|
||||
|
||||
HintSampleQueue sample_queue;
|
||||
} MOVTrack;
|
||||
|
||||
typedef struct MOVMuxContext {
|
||||
int mode;
|
||||
int64_t time;
|
||||
int nb_streams;
|
||||
int chapter_track; ///< qt chapter track number
|
||||
int64_t mdat_pos;
|
||||
uint64_t mdat_size;
|
||||
MOVTrack *tracks;
|
||||
} MOVMuxContext;
|
||||
|
||||
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
|
||||
|
||||
int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index);
|
||||
int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt,
|
||||
int track_index, int sample);
|
||||
void ff_mov_close_hinting(MOVTrack *track);
|
||||
|
||||
#endif /* AVFORMAT_MOVENC_H */
|
504
libavformat/movenchint.c
Normal file
504
libavformat/movenchint.c
Normal file
@@ -0,0 +1,504 @@
|
||||
/*
|
||||
* MOV, 3GP, MP4 muxer RTP hinting
|
||||
* Copyright (c) 2010 Martin Storsjo
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "movenc.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
|
||||
int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
|
||||
{
|
||||
MOVMuxContext *mov = s->priv_data;
|
||||
MOVTrack *track = &mov->tracks[index];
|
||||
MOVTrack *src_track = &mov->tracks[src_index];
|
||||
AVStream *src_st = s->streams[src_index];
|
||||
int ret = AVERROR(ENOMEM);
|
||||
AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
|
||||
|
||||
track->tag = MKTAG('r','t','p',' ');
|
||||
track->src_track = src_index;
|
||||
|
||||
if (!rtp_format) {
|
||||
ret = AVERROR(ENOENT);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
track->enc = avcodec_alloc_context();
|
||||
if (!track->enc)
|
||||
goto fail;
|
||||
track->enc->codec_type = AVMEDIA_TYPE_DATA;
|
||||
track->enc->codec_tag = track->tag;
|
||||
|
||||
track->rtp_ctx = avformat_alloc_context();
|
||||
if (!track->rtp_ctx)
|
||||
goto fail;
|
||||
track->rtp_ctx->oformat = rtp_format;
|
||||
if (!av_new_stream(track->rtp_ctx, 0))
|
||||
goto fail;
|
||||
|
||||
/* Copy stream parameters */
|
||||
track->rtp_ctx->streams[0]->sample_aspect_ratio =
|
||||
src_st->sample_aspect_ratio;
|
||||
|
||||
/* Remove the allocated codec context, link to the original one
|
||||
* instead, to give the rtp muxer access to codec parameters. */
|
||||
av_free(track->rtp_ctx->streams[0]->codec);
|
||||
track->rtp_ctx->streams[0]->codec = src_st->codec;
|
||||
|
||||
if ((ret = url_open_dyn_packet_buf(&track->rtp_ctx->pb,
|
||||
RTP_MAX_PACKET_SIZE)) < 0)
|
||||
goto fail;
|
||||
ret = av_write_header(track->rtp_ctx);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/* Copy the RTP AVStream timebase back to the hint AVStream */
|
||||
track->timescale = track->rtp_ctx->streams[0]->time_base.den;
|
||||
|
||||
/* Mark the hinted track that packets written to it should be
|
||||
* sent to this track for hinting. */
|
||||
src_track->hint_track = index;
|
||||
return 0;
|
||||
fail:
|
||||
av_log(s, AV_LOG_WARNING,
|
||||
"Unable to initialize hinting of stream %d\n", src_index);
|
||||
if (track->rtp_ctx && track->rtp_ctx->pb) {
|
||||
uint8_t *buf;
|
||||
url_close_dyn_buf(track->rtp_ctx->pb, &buf);
|
||||
av_free(buf);
|
||||
}
|
||||
if (track->rtp_ctx && track->rtp_ctx->streams[0]) {
|
||||
av_metadata_free(&track->rtp_ctx->streams[0]->metadata);
|
||||
av_free(track->rtp_ctx->streams[0]);
|
||||
}
|
||||
if (track->rtp_ctx) {
|
||||
av_metadata_free(&track->rtp_ctx->metadata);
|
||||
av_free(track->rtp_ctx->priv_data);
|
||||
av_freep(&track->rtp_ctx);
|
||||
}
|
||||
av_freep(&track->enc);
|
||||
/* Set a default timescale, to avoid crashes in dump_format */
|
||||
track->timescale = 90000;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the first sample from the sample queue.
|
||||
*/
|
||||
static void sample_queue_pop(HintSampleQueue *queue)
|
||||
{
|
||||
if (queue->len <= 0)
|
||||
return;
|
||||
if (queue->samples[0].own_data)
|
||||
av_free(queue->samples[0].data);
|
||||
queue->len--;
|
||||
memmove(queue->samples, queue->samples + 1, sizeof(HintSample)*queue->len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty the sample queue, releasing all memory.
|
||||
*/
|
||||
static void sample_queue_free(HintSampleQueue *queue)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < queue->len; i++)
|
||||
if (queue->samples[i].own_data)
|
||||
av_free(queue->samples[i].data);
|
||||
av_freep(&queue->samples);
|
||||
queue->len = 0;
|
||||
queue->size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a reference to the sample data to the sample queue. The data is
|
||||
* not copied. sample_queue_retain should be called before pkt->data
|
||||
* is reused/freed.
|
||||
*/
|
||||
static void sample_queue_push(HintSampleQueue *queue, AVPacket *pkt, int sample)
|
||||
{
|
||||
/* No need to keep track of smaller samples, since describing them
|
||||
* with immediates is more efficient. */
|
||||
if (pkt->size <= 14)
|
||||
return;
|
||||
if (!queue->samples || queue->len >= queue->size) {
|
||||
HintSample* samples;
|
||||
queue->size += 10;
|
||||
samples = av_realloc(queue->samples, sizeof(HintSample)*queue->size);
|
||||
if (!samples)
|
||||
return;
|
||||
queue->samples = samples;
|
||||
}
|
||||
queue->samples[queue->len].data = pkt->data;
|
||||
queue->samples[queue->len].size = pkt->size;
|
||||
queue->samples[queue->len].sample_number = sample;
|
||||
queue->samples[queue->len].offset = 0;
|
||||
queue->samples[queue->len].own_data = 0;
|
||||
queue->len++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make local copies of all referenced sample data in the queue.
|
||||
*/
|
||||
static void sample_queue_retain(HintSampleQueue *queue)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < queue->len; ) {
|
||||
HintSample *sample = &queue->samples[i];
|
||||
if (!sample->own_data) {
|
||||
uint8_t* ptr = av_malloc(sample->size);
|
||||
if (!ptr) {
|
||||
/* Unable to allocate memory for this one, remove it */
|
||||
memmove(queue->samples + i, queue->samples + i + 1,
|
||||
sizeof(HintSample)*(queue->len - i - 1));
|
||||
queue->len--;
|
||||
continue;
|
||||
}
|
||||
memcpy(ptr, sample->data, sample->size);
|
||||
sample->data = ptr;
|
||||
sample->own_data = 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find matches of needle[n_pos ->] within haystack. If a sufficiently
|
||||
* large match is found, matching bytes before n_pos are included
|
||||
* in the match, too (within the limits of the arrays).
|
||||
*
|
||||
* @param haystack buffer that may contain parts of needle
|
||||
* @param h_len length of the haystack buffer
|
||||
* @param needle buffer containing source data that have been used to
|
||||
* construct haystack
|
||||
* @param n_pos start position in needle used for looking for matches
|
||||
* @param n_len length of the needle buffer
|
||||
* @param match_h_offset_ptr offset of the first matching byte within haystack
|
||||
* @param match_n_offset_ptr offset of the first matching byte within needle
|
||||
* @param match_len_ptr length of the matched segment
|
||||
* @return 0 if a match was found, < 0 if no match was found
|
||||
*/
|
||||
static int match_segments(const uint8_t *haystack, int h_len,
|
||||
const uint8_t *needle, int n_pos, int n_len,
|
||||
int *match_h_offset_ptr, int *match_n_offset_ptr,
|
||||
int *match_len_ptr)
|
||||
{
|
||||
int h_pos;
|
||||
for (h_pos = 0; h_pos < h_len; h_pos++) {
|
||||
int match_len = 0;
|
||||
int match_h_pos, match_n_pos;
|
||||
|
||||
/* Check how many bytes match at needle[n_pos] and haystack[h_pos] */
|
||||
while (h_pos + match_len < h_len && n_pos + match_len < n_len &&
|
||||
needle[n_pos + match_len] == haystack[h_pos + match_len])
|
||||
match_len++;
|
||||
if (match_len <= 8)
|
||||
continue;
|
||||
|
||||
/* If a sufficiently large match was found, try to expand
|
||||
* the matched segment backwards. */
|
||||
match_h_pos = h_pos;
|
||||
match_n_pos = n_pos;
|
||||
while (match_n_pos > 0 && match_h_pos > 0 &&
|
||||
needle[match_n_pos - 1] == haystack[match_h_pos - 1]) {
|
||||
match_n_pos--;
|
||||
match_h_pos--;
|
||||
match_len++;
|
||||
}
|
||||
if (match_len <= 14)
|
||||
continue;
|
||||
*match_h_offset_ptr = match_h_pos;
|
||||
*match_n_offset_ptr = match_n_pos;
|
||||
*match_len_ptr = match_len;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for segments in samples in the sample queue matching the data
|
||||
* in ptr. Samples not matching are removed from the queue. If a match
|
||||
* is found, the next time it will look for matches starting from the
|
||||
* end of the previous matched segment.
|
||||
*
|
||||
* @param data data to find matches for in the sample queue
|
||||
* @param len length of the data buffer
|
||||
* @param queue samples used for looking for matching segments
|
||||
* @param pos the offset in data of the matched segment
|
||||
* @param match_sample the number of the sample that contained the match
|
||||
* @param match_offset the offset of the matched segment within the sample
|
||||
* @param match_len the length of the matched segment
|
||||
* @return 0 if a match was found, < 0 if no match was found
|
||||
*/
|
||||
static int find_sample_match(const uint8_t *data, int len,
|
||||
HintSampleQueue *queue, int *pos,
|
||||
int *match_sample, int *match_offset,
|
||||
int *match_len)
|
||||
{
|
||||
while (queue->len > 0) {
|
||||
HintSample *sample = &queue->samples[0];
|
||||
/* If looking for matches in a new sample, skip the first 5 bytes,
|
||||
* since they often may be modified/removed in the output packet. */
|
||||
if (sample->offset == 0 && sample->size > 5)
|
||||
sample->offset = 5;
|
||||
|
||||
if (match_segments(data, len, sample->data, sample->offset,
|
||||
sample->size, pos, match_offset, match_len) == 0) {
|
||||
*match_sample = sample->sample_number;
|
||||
/* Next time, look for matches at this offset, with a little
|
||||
* margin to this match. */
|
||||
sample->offset = *match_offset + *match_len + 5;
|
||||
if (sample->offset + 10 >= sample->size)
|
||||
sample_queue_pop(queue); /* Not enough useful data left */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sample->offset < 10 && sample->size > 20) {
|
||||
/* No match found from the start of the sample,
|
||||
* try from the middle of the sample instead. */
|
||||
sample->offset = sample->size/2;
|
||||
} else {
|
||||
/* No match for this sample, remove it */
|
||||
sample_queue_pop(queue);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void output_immediate(const uint8_t *data, int size,
|
||||
ByteIOContext *out, int *entries)
|
||||
{
|
||||
while (size > 0) {
|
||||
int len = size;
|
||||
if (len > 14)
|
||||
len = 14;
|
||||
put_byte(out, 1); /* immediate constructor */
|
||||
put_byte(out, len); /* amount of valid data */
|
||||
put_buffer(out, data, len);
|
||||
data += len;
|
||||
size -= len;
|
||||
|
||||
for (; len < 14; len++)
|
||||
put_byte(out, 0);
|
||||
|
||||
(*entries)++;
|
||||
}
|
||||
}
|
||||
|
||||
static void output_match(ByteIOContext *out, int match_sample,
|
||||
int match_offset, int match_len, int *entries)
|
||||
{
|
||||
put_byte(out, 2); /* sample constructor */
|
||||
put_byte(out, 0); /* track reference */
|
||||
put_be16(out, match_len);
|
||||
put_be32(out, match_sample);
|
||||
put_be32(out, match_offset);
|
||||
put_be16(out, 1); /* bytes per block */
|
||||
put_be16(out, 1); /* samples per block */
|
||||
(*entries)++;
|
||||
}
|
||||
|
||||
static void describe_payload(const uint8_t *data, int size,
|
||||
ByteIOContext *out, int *entries,
|
||||
HintSampleQueue *queue)
|
||||
{
|
||||
/* Describe the payload using different constructors */
|
||||
while (size > 0) {
|
||||
int match_sample, match_offset, match_len, pos;
|
||||
if (find_sample_match(data, size, queue, &pos, &match_sample,
|
||||
&match_offset, &match_len) < 0)
|
||||
break;
|
||||
output_immediate(data, pos, out, entries);
|
||||
data += pos;
|
||||
size -= pos;
|
||||
output_match(out, match_sample, match_offset, match_len, entries);
|
||||
data += match_len;
|
||||
size -= match_len;
|
||||
}
|
||||
output_immediate(data, size, out, entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an RTP hint (that may contain one or more RTP packets)
|
||||
* for the packets in data. data contains one or more packets with a
|
||||
* BE32 size header.
|
||||
*
|
||||
* @param out buffer where the hints are written
|
||||
* @param data buffer containing RTP packets
|
||||
* @param size the size of the data buffer
|
||||
* @param trk the MOVTrack for the hint track
|
||||
* @param pts pointer where the timestamp for the written RTP hint is stored
|
||||
* @return the number of RTP packets in the written hint
|
||||
*/
|
||||
static int write_hint_packets(ByteIOContext *out, const uint8_t *data,
|
||||
int size, MOVTrack *trk, int64_t *pts)
|
||||
{
|
||||
int64_t curpos;
|
||||
int64_t count_pos, entries_pos;
|
||||
int count = 0, entries;
|
||||
|
||||
count_pos = url_ftell(out);
|
||||
/* RTPsample header */
|
||||
put_be16(out, 0); /* packet count */
|
||||
put_be16(out, 0); /* reserved */
|
||||
|
||||
while (size > 4) {
|
||||
uint32_t packet_len = AV_RB32(data);
|
||||
uint16_t seq;
|
||||
uint32_t ts;
|
||||
|
||||
data += 4;
|
||||
size -= 4;
|
||||
if (packet_len > size || packet_len <= 12)
|
||||
break;
|
||||
if (data[1] >= 200 && data[1] <= 204) {
|
||||
/* RTCP packet, just skip */
|
||||
data += packet_len;
|
||||
size -= packet_len;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (packet_len > trk->max_packet_size)
|
||||
trk->max_packet_size = packet_len;
|
||||
|
||||
seq = AV_RB16(&data[2]);
|
||||
ts = AV_RB32(&data[4]);
|
||||
|
||||
if (trk->prev_rtp_ts == 0)
|
||||
trk->prev_rtp_ts = ts;
|
||||
/* Unwrap the 32-bit RTP timestamp that wraps around often
|
||||
* into a not (as often) wrapping 64-bit timestamp. */
|
||||
trk->cur_rtp_ts_unwrapped += (int32_t) (ts - trk->prev_rtp_ts);
|
||||
trk->prev_rtp_ts = ts;
|
||||
if (*pts == AV_NOPTS_VALUE)
|
||||
*pts = trk->cur_rtp_ts_unwrapped;
|
||||
|
||||
count++;
|
||||
/* RTPpacket header */
|
||||
put_be32(out, 0); /* relative_time */
|
||||
put_buffer(out, data, 2); /* RTP header */
|
||||
put_be16(out, seq); /* RTPsequenceseed */
|
||||
put_be16(out, 0); /* reserved + flags */
|
||||
entries_pos = url_ftell(out);
|
||||
put_be16(out, 0); /* entry count */
|
||||
|
||||
data += 12;
|
||||
size -= 12;
|
||||
packet_len -= 12;
|
||||
|
||||
entries = 0;
|
||||
/* Write one or more constructors describing the payload data */
|
||||
describe_payload(data, packet_len, out, &entries, &trk->sample_queue);
|
||||
data += packet_len;
|
||||
size -= packet_len;
|
||||
|
||||
curpos = url_ftell(out);
|
||||
url_fseek(out, entries_pos, SEEK_SET);
|
||||
put_be16(out, entries);
|
||||
url_fseek(out, curpos, SEEK_SET);
|
||||
}
|
||||
|
||||
curpos = url_ftell(out);
|
||||
url_fseek(out, count_pos, SEEK_SET);
|
||||
put_be16(out, count);
|
||||
url_fseek(out, curpos, SEEK_SET);
|
||||
return count;
|
||||
}
|
||||
|
||||
int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt,
|
||||
int track_index, int sample)
|
||||
{
|
||||
MOVMuxContext *mov = s->priv_data;
|
||||
MOVTrack *trk = &mov->tracks[track_index];
|
||||
AVFormatContext *rtp_ctx = trk->rtp_ctx;
|
||||
uint8_t *buf = NULL;
|
||||
int size;
|
||||
ByteIOContext *hintbuf = NULL;
|
||||
AVPacket hint_pkt;
|
||||
AVPacket local_pkt;
|
||||
int ret = 0, count;
|
||||
|
||||
if (!rtp_ctx)
|
||||
return AVERROR(ENOENT);
|
||||
if (!rtp_ctx->pb)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
sample_queue_push(&trk->sample_queue, pkt, sample);
|
||||
|
||||
/* Feed the packet to the RTP muxer */
|
||||
local_pkt = *pkt;
|
||||
local_pkt.stream_index = 0;
|
||||
local_pkt.pts = av_rescale_q(pkt->pts,
|
||||
s->streams[pkt->stream_index]->time_base,
|
||||
rtp_ctx->streams[0]->time_base);
|
||||
local_pkt.dts = av_rescale_q(pkt->dts,
|
||||
s->streams[pkt->stream_index]->time_base,
|
||||
rtp_ctx->streams[0]->time_base);
|
||||
av_write_frame(rtp_ctx, &local_pkt);
|
||||
|
||||
/* Fetch the output from the RTP muxer, open a new output buffer
|
||||
* for next time. */
|
||||
size = url_close_dyn_buf(rtp_ctx->pb, &buf);
|
||||
if ((ret = url_open_dyn_packet_buf(&rtp_ctx->pb,
|
||||
RTP_MAX_PACKET_SIZE)) < 0)
|
||||
goto done;
|
||||
|
||||
if (size <= 0)
|
||||
goto done;
|
||||
|
||||
/* Open a buffer for writing the hint */
|
||||
if ((ret = url_open_dyn_buf(&hintbuf)) < 0)
|
||||
goto done;
|
||||
av_init_packet(&hint_pkt);
|
||||
count = write_hint_packets(hintbuf, buf, size, trk, &hint_pkt.dts);
|
||||
av_freep(&buf);
|
||||
|
||||
/* Write the hint data into the hint track */
|
||||
hint_pkt.size = size = url_close_dyn_buf(hintbuf, &buf);
|
||||
hint_pkt.data = buf;
|
||||
hint_pkt.pts = hint_pkt.dts;
|
||||
hint_pkt.stream_index = track_index;
|
||||
if (pkt->flags & AV_PKT_FLAG_KEY)
|
||||
hint_pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
if (count > 0)
|
||||
ff_mov_write_packet(s, &hint_pkt);
|
||||
done:
|
||||
av_free(buf);
|
||||
sample_queue_retain(&trk->sample_queue);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ff_mov_close_hinting(MOVTrack *track) {
|
||||
AVFormatContext* rtp_ctx = track->rtp_ctx;
|
||||
uint8_t *ptr;
|
||||
|
||||
av_freep(&track->enc);
|
||||
sample_queue_free(&track->sample_queue);
|
||||
if (!rtp_ctx)
|
||||
return;
|
||||
if (rtp_ctx->pb) {
|
||||
av_write_trailer(rtp_ctx);
|
||||
url_close_dyn_buf(rtp_ctx->pb, &ptr);
|
||||
av_free(ptr);
|
||||
}
|
||||
av_metadata_free(&rtp_ctx->streams[0]->metadata);
|
||||
av_metadata_free(&rtp_ctx->metadata);
|
||||
av_free(rtp_ctx->streams[0]);
|
||||
av_freep(&rtp_ctx);
|
||||
}
|
||||
|
@@ -807,6 +807,16 @@ static int mpegts_push_data(MpegTSFilter *filter,
|
||||
pes->data_index += buf_size;
|
||||
}
|
||||
buf_size = 0;
|
||||
/* emit complete packets with known packet size
|
||||
* decreases demuxer delay for infrequent packets like subtitles from
|
||||
* a couple of seconds to milliseconds for properly muxed files.
|
||||
* total_size is the number of bytes following pes_packet_length
|
||||
* in the pes header, i.e. not counting the first 6 bytes */
|
||||
if (pes->total_size < MAX_PES_PAYLOAD &&
|
||||
pes->pes_header_size + pes->data_index == pes->total_size + 6) {
|
||||
ts->stop_parse = 1;
|
||||
new_pes_packet(pes, ts->pkt);
|
||||
}
|
||||
break;
|
||||
case MPEGTS_SKIP:
|
||||
buf_size = 0;
|
||||
|
@@ -334,7 +334,8 @@ static int decode_stream_header(NUTContext *nut){
|
||||
return -1;
|
||||
}
|
||||
if(class<3 && st->codec->codec_id == CODEC_ID_NONE)
|
||||
av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");
|
||||
av_log(s, AV_LOG_ERROR, "Unknown codec tag '0x%04x' for stream number %d\n",
|
||||
(unsigned int)tmp, stream_id);
|
||||
|
||||
GET_V(stc->time_base_id , tmp < nut->time_base_count);
|
||||
GET_V(stc->msb_pts_shift , tmp < 16);
|
||||
|
@@ -642,4 +642,5 @@ AVInputFormat ogg_demuxer = {
|
||||
ogg_read_timestamp,
|
||||
.extensions = "ogg",
|
||||
.metadata_conv = ff_vorbiscomment_metadata_conv,
|
||||
.flags = AVFMT_GENERIC_INDEX,
|
||||
};
|
||||
|
@@ -27,6 +27,18 @@
|
||||
#include "internal.h"
|
||||
#include "vorbiscomment.h"
|
||||
|
||||
#define MAX_PAGE_SIZE 65025
|
||||
|
||||
typedef struct {
|
||||
int64_t granule;
|
||||
int stream_index;
|
||||
uint8_t flags;
|
||||
uint8_t segments_count;
|
||||
uint8_t segments[255];
|
||||
uint8_t data[MAX_PAGE_SIZE];
|
||||
uint16_t size;
|
||||
} OGGPage;
|
||||
|
||||
typedef struct {
|
||||
int64_t duration;
|
||||
unsigned page_counter;
|
||||
@@ -37,9 +49,19 @@ typedef struct {
|
||||
int64_t last_kf_pts;
|
||||
int vrev;
|
||||
int eos;
|
||||
unsigned packet_count; ///< number of packet buffered
|
||||
unsigned page_count; ///< number of page buffered
|
||||
OGGPage page; ///< current page
|
||||
} OGGStreamContext;
|
||||
|
||||
typedef struct OGGPageList {
|
||||
OGGPage page;
|
||||
struct OGGPageList *next;
|
||||
} OGGPageList;
|
||||
|
||||
typedef struct {
|
||||
OGGPageList *page_list;
|
||||
} OGGContext;
|
||||
|
||||
static void ogg_update_checksum(AVFormatContext *s, int64_t crc_offset)
|
||||
{
|
||||
int64_t pos = url_ftell(s->pb);
|
||||
@@ -49,39 +71,122 @@ static void ogg_update_checksum(AVFormatContext *s, int64_t crc_offset)
|
||||
url_fseek(s->pb, pos, SEEK_SET);
|
||||
}
|
||||
|
||||
static int ogg_write_page(AVFormatContext *s, const uint8_t *data, int size,
|
||||
int64_t granule, int stream_index, int flags)
|
||||
static void ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags)
|
||||
{
|
||||
OGGStreamContext *oggstream = s->streams[stream_index]->priv_data;
|
||||
OGGStreamContext *oggstream = s->streams[page->stream_index]->priv_data;
|
||||
int64_t crc_offset;
|
||||
int page_segments, i;
|
||||
|
||||
if (size >= 255*255) {
|
||||
granule = -1;
|
||||
size = 255*255;
|
||||
} else if (oggstream->eos)
|
||||
flags |= 4;
|
||||
|
||||
page_segments = FFMIN(size/255 + 1, 255);
|
||||
|
||||
init_checksum(s->pb, ff_crc04C11DB7_update, 0);
|
||||
put_tag(s->pb, "OggS");
|
||||
put_byte(s->pb, 0);
|
||||
put_byte(s->pb, flags);
|
||||
put_le64(s->pb, granule);
|
||||
put_le32(s->pb, stream_index);
|
||||
put_byte(s->pb, page->flags | extra_flags);
|
||||
put_le64(s->pb, page->granule);
|
||||
put_le32(s->pb, page->stream_index);
|
||||
put_le32(s->pb, oggstream->page_counter++);
|
||||
crc_offset = url_ftell(s->pb);
|
||||
put_le32(s->pb, 0); // crc
|
||||
put_byte(s->pb, page_segments);
|
||||
for (i = 0; i < page_segments-1; i++)
|
||||
put_byte(s->pb, 255);
|
||||
put_byte(s->pb, size - (page_segments-1)*255);
|
||||
put_buffer(s->pb, data, size);
|
||||
put_byte(s->pb, page->segments_count);
|
||||
put_buffer(s->pb, page->segments, page->segments_count);
|
||||
put_buffer(s->pb, page->data, page->size);
|
||||
|
||||
ogg_update_checksum(s, crc_offset);
|
||||
put_flush_packet(s->pb);
|
||||
return size;
|
||||
oggstream->page_count--;
|
||||
}
|
||||
|
||||
static int64_t ogg_granule_to_timestamp(OGGStreamContext *oggstream, OGGPage *page)
|
||||
{
|
||||
if (oggstream->kfgshift)
|
||||
return (page->granule>>oggstream->kfgshift) +
|
||||
(page->granule & ((1<<oggstream->kfgshift)-1));
|
||||
else
|
||||
return page->granule;
|
||||
}
|
||||
|
||||
static int ogg_compare_granule(AVFormatContext *s, OGGPage *next, OGGPage *page)
|
||||
{
|
||||
AVStream *st2 = s->streams[next->stream_index];
|
||||
AVStream *st = s->streams[page->stream_index];
|
||||
int64_t next_granule, cur_granule;
|
||||
|
||||
if (next->granule == -1 || page->granule == -1)
|
||||
return 0;
|
||||
|
||||
next_granule = av_rescale_q(ogg_granule_to_timestamp(st2->priv_data, next),
|
||||
st2->time_base, AV_TIME_BASE_Q);
|
||||
cur_granule = av_rescale_q(ogg_granule_to_timestamp(st->priv_data, page),
|
||||
st ->time_base, AV_TIME_BASE_Q);
|
||||
return next_granule > cur_granule;
|
||||
}
|
||||
|
||||
static int ogg_reset_cur_page(OGGStreamContext *oggstream)
|
||||
{
|
||||
oggstream->page.granule = -1;
|
||||
oggstream->page.flags = 0;
|
||||
oggstream->page.segments_count = 0;
|
||||
oggstream->page.size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ogg_buffer_page(AVFormatContext *s, OGGStreamContext *oggstream)
|
||||
{
|
||||
OGGContext *ogg = s->priv_data;
|
||||
OGGPageList **p = &ogg->page_list;
|
||||
OGGPageList *l = av_mallocz(sizeof(*l));
|
||||
|
||||
if (!l)
|
||||
return AVERROR(ENOMEM);
|
||||
l->page = oggstream->page;
|
||||
|
||||
oggstream->page_count++;
|
||||
ogg_reset_cur_page(oggstream);
|
||||
|
||||
while (*p) {
|
||||
if (ogg_compare_granule(s, &(*p)->page, &l->page))
|
||||
break;
|
||||
p = &(*p)->next;
|
||||
}
|
||||
l->next = *p;
|
||||
*p = l;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ogg_buffer_data(AVFormatContext *s, AVStream *st,
|
||||
uint8_t *data, unsigned size, int64_t granule)
|
||||
{
|
||||
OGGStreamContext *oggstream = st->priv_data;
|
||||
int total_segments = size / 255 + 1;
|
||||
uint8_t *p = data;
|
||||
int i, segments, len;
|
||||
|
||||
for (i = 0; i < total_segments; ) {
|
||||
OGGPage *page = &oggstream->page;
|
||||
|
||||
segments = FFMIN(total_segments - i, 255 - page->segments_count);
|
||||
|
||||
if (i && !page->segments_count)
|
||||
page->flags |= 1; // continued packet
|
||||
|
||||
memset(page->segments+page->segments_count, 255, segments - 1);
|
||||
page->segments_count += segments - 1;
|
||||
|
||||
len = FFMIN(size, segments*255);
|
||||
page->segments[page->segments_count++] = len - (segments-1)*255;
|
||||
memcpy(page->data+page->size, p, len);
|
||||
p += len;
|
||||
size -= len;
|
||||
i += segments;
|
||||
page->size += len;
|
||||
|
||||
if (i == total_segments)
|
||||
page->granule = granule;
|
||||
|
||||
if (page->segments_count == 255) {
|
||||
ogg_buffer_page(s, oggstream);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t *ogg_write_vorbiscomment(int offset, int bitexact,
|
||||
@@ -195,6 +300,7 @@ static int ogg_write_header(AVFormatContext *s)
|
||||
return -1;
|
||||
}
|
||||
oggstream = av_mallocz(sizeof(*oggstream));
|
||||
oggstream->page.stream_index = i;
|
||||
st->priv_data = oggstream;
|
||||
if (st->codec->codec_id == CODEC_ID_FLAC) {
|
||||
int err = ogg_build_flac_headers(st->codec, oggstream,
|
||||
@@ -232,25 +338,54 @@ static int ogg_write_header(AVFormatContext *s)
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < s->nb_streams; j++) {
|
||||
AVStream *st = s->streams[j];
|
||||
OGGStreamContext *oggstream = st->priv_data;
|
||||
if (oggstream && oggstream->header_len[i]) {
|
||||
ogg_write_page(s, oggstream->header[i], oggstream->header_len[i],
|
||||
0, st->index, i ? 0 : 2); // bos
|
||||
}
|
||||
|
||||
for (j = 0; j < s->nb_streams; j++) {
|
||||
OGGStreamContext *oggstream = s->streams[j]->priv_data;
|
||||
ogg_buffer_data(s, s->streams[j], oggstream->header[0],
|
||||
oggstream->header_len[0], 0);
|
||||
oggstream->page.flags |= 2; // bos
|
||||
ogg_buffer_page(s, oggstream);
|
||||
}
|
||||
for (j = 0; j < s->nb_streams; j++) {
|
||||
AVStream *st = s->streams[j];
|
||||
OGGStreamContext *oggstream = st->priv_data;
|
||||
for (i = 1; i < 3; i++) {
|
||||
if (oggstream && oggstream->header_len[i])
|
||||
ogg_buffer_data(s, st, oggstream->header[i],
|
||||
oggstream->header_len[i], 0);
|
||||
}
|
||||
ogg_buffer_page(s, oggstream);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ogg_write_pages(AVFormatContext *s, int flush)
|
||||
{
|
||||
OGGContext *ogg = s->priv_data;
|
||||
OGGPageList *next, *p;
|
||||
|
||||
if (!ogg->page_list)
|
||||
return;
|
||||
|
||||
for (p = ogg->page_list; p; ) {
|
||||
OGGStreamContext *oggstream =
|
||||
s->streams[p->page.stream_index]->priv_data;
|
||||
if (oggstream->page_count < 2 && !flush)
|
||||
break;
|
||||
ogg_write_page(s, &p->page,
|
||||
flush && oggstream->page_count == 1 ? 4 : 0); // eos
|
||||
next = p->next;
|
||||
av_freep(&p);
|
||||
p = next;
|
||||
}
|
||||
ogg->page_list = p;
|
||||
}
|
||||
|
||||
static int ogg_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
AVStream *st = s->streams[pkt->stream_index];
|
||||
OGGStreamContext *oggstream = st->priv_data;
|
||||
uint8_t *ptr = pkt->data;
|
||||
int ret, size = pkt->size;
|
||||
int ret;
|
||||
int64_t granule;
|
||||
|
||||
if (st->codec->codec_id == CODEC_ID_THEORA) {
|
||||
@@ -268,72 +403,26 @@ static int ogg_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
} else
|
||||
granule = pkt->pts + pkt->duration;
|
||||
oggstream->duration = granule;
|
||||
do {
|
||||
ret = ogg_write_page(s, ptr, size, granule, pkt->stream_index, ptr != pkt->data);
|
||||
ptr += ret; size -= ret;
|
||||
} while (size > 0 || ret == 255*255); // need to output a last nil page
|
||||
|
||||
ret = ogg_buffer_data(s, st, pkt->data, pkt->size, granule);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ogg_write_pages(s, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ogg_compare_granule(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
|
||||
{
|
||||
AVStream *st2 = s->streams[next->stream_index];
|
||||
AVStream *st = s->streams[pkt ->stream_index];
|
||||
|
||||
int64_t next_granule = av_rescale_q(next->pts + next->duration,
|
||||
st2->time_base, AV_TIME_BASE_Q);
|
||||
int64_t cur_granule = av_rescale_q(pkt ->pts + pkt ->duration,
|
||||
st ->time_base, AV_TIME_BASE_Q);
|
||||
return next_granule > cur_granule;
|
||||
}
|
||||
|
||||
static int ogg_interleave_per_granule(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
|
||||
{
|
||||
OGGStreamContext *ogg;
|
||||
int i, stream_count = 0;
|
||||
int interleaved = 0;
|
||||
|
||||
if (pkt) {
|
||||
ff_interleave_add_packet(s, pkt, ogg_compare_granule);
|
||||
ogg = s->streams[pkt->stream_index]->priv_data;
|
||||
ogg->packet_count++;
|
||||
}
|
||||
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
ogg = s->streams[i]->priv_data;
|
||||
stream_count += !!ogg->packet_count;
|
||||
interleaved += ogg->packet_count > 1;
|
||||
}
|
||||
|
||||
if ((s->nb_streams == stream_count && interleaved == stream_count) ||
|
||||
(flush && stream_count)) {
|
||||
AVPacketList *pktl= s->packet_buffer;
|
||||
*out= pktl->pkt;
|
||||
s->packet_buffer = pktl->next;
|
||||
|
||||
ogg = s->streams[out->stream_index]->priv_data;
|
||||
if (flush && ogg->packet_count == 1)
|
||||
ogg->eos = 1;
|
||||
ogg->packet_count--;
|
||||
|
||||
if(!s->packet_buffer)
|
||||
s->packet_buffer_end= NULL;
|
||||
|
||||
if(s->streams[out->stream_index]->last_in_packet_buffer == pktl)
|
||||
s->streams[out->stream_index]->last_in_packet_buffer= NULL;
|
||||
|
||||
av_freep(&pktl);
|
||||
return 1;
|
||||
} else {
|
||||
av_init_packet(out);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int ogg_write_trailer(AVFormatContext *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* flush current page */
|
||||
for (i = 0; i < s->nb_streams; i++)
|
||||
ogg_buffer_page(s, s->streams[i]->priv_data);
|
||||
|
||||
ogg_write_pages(s, 1);
|
||||
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
AVStream *st = s->streams[i];
|
||||
OGGStreamContext *oggstream = st->priv_data;
|
||||
@@ -352,12 +441,11 @@ AVOutputFormat ogg_muxer = {
|
||||
NULL_IF_CONFIG_SMALL("Ogg"),
|
||||
"application/ogg",
|
||||
"ogg,ogv,spx",
|
||||
0,
|
||||
sizeof(OGGContext),
|
||||
CODEC_ID_FLAC,
|
||||
CODEC_ID_THEORA,
|
||||
ogg_write_header,
|
||||
ogg_write_packet,
|
||||
ogg_write_trailer,
|
||||
.interleave_packet = ogg_interleave_per_granule,
|
||||
.metadata_conv = ff_vorbiscomment_metadata_conv,
|
||||
};
|
||||
|
@@ -49,6 +49,7 @@ static const AVOption options[]={
|
||||
{"nofillin", "do not fill in missing values that can be exactly calculated", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_NOFILLIN, INT_MIN, INT_MAX, D, "fflags"},
|
||||
{"noparse", "disable AVParsers, this needs nofillin too", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_NOPARSE, INT_MIN, INT_MAX, D, "fflags"},
|
||||
{"igndts", "ingore dts", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_IGNDTS, INT_MIN, INT_MAX, D, "fflags"},
|
||||
{"rtphint", "add rtp hinting", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_RTP_HINT, INT_MIN, INT_MAX, E, "fflags"},
|
||||
#if LIBAVFORMAT_VERSION_INT < (53<<16)
|
||||
{"track", " set the track number", OFFSET(track), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, E},
|
||||
{"year", "set the year", OFFSET(year), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, E},
|
||||
|
@@ -80,6 +80,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
|
||||
{ CODEC_ID_MPEG4, MKTAG('V', 'S', 'P', 'X') },
|
||||
{ CODEC_ID_MPEG4, MKTAG('U', 'L', 'D', 'X') },
|
||||
{ CODEC_ID_MPEG4, MKTAG('G', 'E', 'O', 'V') },
|
||||
{ CODEC_ID_MPEG4, MKTAG('S', 'I', 'P', 'P') }, /* Samsung SHR-6040 */
|
||||
{ CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '3') }, /* default signature when using MSMPEG4 */
|
||||
{ CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') },
|
||||
{ CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', 'G', '3') },
|
||||
|
@@ -1337,6 +1337,8 @@ static int rtsp_read_play(AVFormatContext *s)
|
||||
RTSPStream *rtsp_st = rt->rtsp_streams[i];
|
||||
RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
|
||||
AVStream *st = NULL;
|
||||
if (!rtpctx)
|
||||
continue;
|
||||
if (rtsp_st->stream_index >= 0)
|
||||
st = s->streams[rtsp_st->stream_index];
|
||||
rtpctx->last_rtcp_ntp_time = AV_NOPTS_VALUE;
|
||||
|
@@ -294,7 +294,7 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
|
||||
return buff;
|
||||
}
|
||||
|
||||
static void sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, int port, int ttl)
|
||||
void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, int port, int ttl)
|
||||
{
|
||||
const char *type;
|
||||
int payload_type;
|
||||
@@ -352,7 +352,7 @@ int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size)
|
||||
resolve_destination(dst, sizeof(dst));
|
||||
}
|
||||
for (j = 0; j < ac[i]->nb_streams; j++) {
|
||||
sdp_write_media(buff, size,
|
||||
ff_sdp_write_media(buff, size,
|
||||
ac[i]->streams[j]->codec, dst[0] ? dst : NULL,
|
||||
(port > 0) ? port + j * 2 : 0, ttl);
|
||||
if (port <= 0) {
|
||||
@@ -369,4 +369,9 @@ int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size)
|
||||
{
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
|
||||
void ff_sdp_write_media(char *buff, int size, AVCodecContext *c,
|
||||
const char *dest_addr, int port, int ttl)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
@@ -282,8 +282,38 @@ AVInputFormat *av_find_input_format(const char *short_name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* memory handling */
|
||||
#if LIBAVFORMAT_VERSION_MAJOR < 53 && CONFIG_SHARED && HAVE_SYMVER
|
||||
FF_SYMVER(void, av_destruct_packet_nofree, (AVPacket *pkt), "LIBAVFORMAT_52")
|
||||
{
|
||||
av_destruct_packet_nofree(pkt);
|
||||
}
|
||||
|
||||
FF_SYMVER(void, av_destruct_packet, (AVPacket *pkt), "LIBAVFORMAT_52")
|
||||
{
|
||||
av_destruct_packet(pkt);
|
||||
}
|
||||
|
||||
FF_SYMVER(int, av_new_packet, (AVPacket *pkt, int size), "LIBAVFORMAT_52")
|
||||
{
|
||||
return av_new_packet(pkt, size);
|
||||
}
|
||||
|
||||
FF_SYMVER(int, av_dup_packet, (AVPacket *pkt), "LIBAVFORMAT_52")
|
||||
{
|
||||
return av_dup_packet(pkt);
|
||||
}
|
||||
|
||||
FF_SYMVER(void, av_free_packet, (AVPacket *pkt), "LIBAVFORMAT_52")
|
||||
{
|
||||
av_free_packet(pkt);
|
||||
}
|
||||
|
||||
FF_SYMVER(void, av_init_packet, (AVPacket *pkt), "LIBAVFORMAT_52")
|
||||
{
|
||||
av_log(NULL, AV_LOG_WARNING, "Diverting av_*_packet function calls to libavcodec. Recompile to improve performance\n");
|
||||
av_init_packet(pkt);
|
||||
}
|
||||
#endif
|
||||
|
||||
int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size)
|
||||
{
|
||||
@@ -2201,7 +2231,7 @@ int av_find_stream_info(AVFormatContext *ic)
|
||||
/* we did not get all the codec info, but we read too much data */
|
||||
if (read_size >= ic->probesize) {
|
||||
ret = count;
|
||||
av_log(ic, AV_LOG_WARNING, "MAX_READ_SIZE:%d reached\n", ic->probesize);
|
||||
av_log(ic, AV_LOG_DEBUG, "Probe buffer size limit %d reached\n", ic->probesize);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -41,7 +41,7 @@
|
||||
|
||||
#define LIBAVUTIL_VERSION_MAJOR 50
|
||||
#define LIBAVUTIL_VERSION_MINOR 15
|
||||
#define LIBAVUTIL_VERSION_MICRO 0
|
||||
#define LIBAVUTIL_VERSION_MICRO 1
|
||||
|
||||
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
|
||||
LIBAVUTIL_VERSION_MINOR, \
|
||||
|
@@ -43,8 +43,8 @@
|
||||
#endif
|
||||
|
||||
#define AV_BSWAP16C(x) (((x) << 8 & 0xff00) | ((x) >> 8 & 0x00ff))
|
||||
#define AV_BSWAP32C(x) (AV_BSWAP16C(x) << 16 | AV_BSWAP16C(x >> 16))
|
||||
#define AV_BSWAP64C(x) (AV_BSWAP32C(x) << 32 | AV_BSWAP32C(x >> 32))
|
||||
#define AV_BSWAP32C(x) (AV_BSWAP16C(x) << 16 | AV_BSWAP16C((x) >> 16))
|
||||
#define AV_BSWAP64C(x) (AV_BSWAP32C(x) << 32 | AV_BSWAP32C((x) >> 32))
|
||||
|
||||
#define AV_BSWAPC(s, x) AV_BSWAP##s##C(x)
|
||||
|
||||
|
@@ -36,8 +36,10 @@ int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
|
||||
} else {
|
||||
#if HAVE_STRERROR_R
|
||||
ret = strerror_r(AVUNERROR(errnum), errbuf, errbuf_size);
|
||||
#else
|
||||
ret = -1;
|
||||
#endif
|
||||
if (!HAVE_STRERROR_R || ret < 0)
|
||||
if (ret < 0)
|
||||
snprintf(errbuf, errbuf_size, "Error number %d occurred", errnum);
|
||||
}
|
||||
|
||||
|
@@ -64,7 +64,8 @@
|
||||
* error message indicating the errnum provided to errbuf.
|
||||
*
|
||||
* @param errbuf_size the size in bytes of errbuf
|
||||
* @return 0 on success, a negative value otherwise
|
||||
* @return 0 on success, a negative value if a description for errnum
|
||||
* cannot be found
|
||||
*/
|
||||
int av_strerror(int errnum, char *errbuf, size_t errbuf_size);
|
||||
|
||||
|
@@ -204,4 +204,15 @@
|
||||
# define NULL_IF_CONFIG_SMALL(x) x
|
||||
#endif
|
||||
|
||||
#if HAVE_SYMVER_ASM_LABEL
|
||||
# define FF_SYMVER(type, name, args, ver) \
|
||||
type ff_##name args __asm__ (EXTERN_PREFIX #name "@" ver); \
|
||||
type ff_##name args
|
||||
#elif HAVE_SYMVER_GNU_ASM
|
||||
# define FF_SYMVER(type, name, args, ver) \
|
||||
__asm__ (".symver ff_" #name "," EXTERN_PREFIX #name "@" ver); \
|
||||
type ff_##name args; \
|
||||
type ff_##name args
|
||||
#endif
|
||||
|
||||
#endif /* AVUTIL_INTERNAL_H */
|
||||
|
@@ -68,8 +68,8 @@ enum PixelFormat {
|
||||
PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
|
||||
PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
|
||||
PIX_FMT_GRAY8, ///< Y , 8bpp
|
||||
PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black
|
||||
PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white
|
||||
PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb
|
||||
PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb
|
||||
PIX_FMT_PAL8, ///< 8 bit with PIX_FMT_RGB32 palette
|
||||
PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG)
|
||||
PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG)
|
||||
@@ -79,12 +79,12 @@ enum PixelFormat {
|
||||
PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
|
||||
PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
|
||||
PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
|
||||
PIX_FMT_BGR4, ///< packed RGB 1:2:1, 4bpp, (msb)1B 2G 1R(lsb)
|
||||
PIX_FMT_BGR4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits
|
||||
PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
|
||||
PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
|
||||
PIX_FMT_RGB4, ///< packed RGB 1:2:1, 4bpp, (msb)1R 2G 1B(lsb)
|
||||
PIX_FMT_RGB4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits
|
||||
PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
|
||||
PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 for UV
|
||||
PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V)
|
||||
PIX_FMT_NV21, ///< as above, but U and V bytes are swapped
|
||||
|
||||
PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
|
||||
@@ -102,8 +102,8 @@ enum PixelFormat {
|
||||
PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
|
||||
PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
|
||||
PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
|
||||
PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, big-endian
|
||||
PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, little-endian
|
||||
PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian
|
||||
PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian
|
||||
|
||||
PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
|
||||
PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
|
||||
|
@@ -98,6 +98,8 @@ AVRational av_d2q(double d, int max){
|
||||
#define LOG2 0.69314718055994530941723212145817656807550013436025
|
||||
int exponent= FFMAX( (int)(log(fabs(d) + 1e-20)/LOG2), 0);
|
||||
int64_t den= 1LL << (61 - exponent);
|
||||
if (isnan(d))
|
||||
return (AVRational){0,0};
|
||||
av_reduce(&a.num, &a.den, (int64_t)(d * den + 0.5), den, max);
|
||||
|
||||
return a;
|
||||
|
@@ -479,9 +479,6 @@ DEFUN(uyvytoyv12, mL3, (const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8
|
||||
|
||||
r1 = [fp + ARG_srcStride];
|
||||
r2 = r0 + r1;
|
||||
r1 += -8; // i0,i1 is pre read need to correct
|
||||
m0 = r1;
|
||||
|
||||
i0 = r0; // uyvy_T even
|
||||
i1 = r2; // uyvy_B odd
|
||||
|
||||
@@ -494,6 +491,12 @@ DEFUN(uyvytoyv12, mL3, (const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8
|
||||
p4 = p4 >> 1;
|
||||
p5 = p5 >> 2;
|
||||
|
||||
r2 = r0 << 1;
|
||||
r1 = r1 << 1;
|
||||
r1 = r1 - r2; // srcStride + (srcStride - 2*width)
|
||||
r1 += -8; // i0,i1 is pre read need to correct
|
||||
m0 = r1;
|
||||
|
||||
r2 = [fp + ARG_chromStride];
|
||||
r0 = r0 >> 1;
|
||||
r2 = r2 - r0;
|
||||
@@ -549,8 +552,6 @@ DEFUN(yuyvtoyv12, mL3, (const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8
|
||||
|
||||
r1 = [fp + ARG_srcStride];
|
||||
r2 = r0 + r1;
|
||||
r1 += -8; // i0,i1 is pre read need to correct
|
||||
m0 = r1;
|
||||
|
||||
i0 = r0; // uyvy_T even
|
||||
i1 = r2; // uyvy_B odd
|
||||
@@ -564,6 +565,12 @@ DEFUN(yuyvtoyv12, mL3, (const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8
|
||||
p4 = p4 >> 1;
|
||||
p5 = p5 >> 2;
|
||||
|
||||
r2 = r0 << 1;
|
||||
r1 = r1 << 1;
|
||||
r1 = r1 - r2; // srcStride + (srcStride - 2*width)
|
||||
r1 += -8; // i0,i1 is pre read need to correct
|
||||
m0 = r1;
|
||||
|
||||
r2 = [fp + ARG_chromStride];
|
||||
r0 = r0 >> 1;
|
||||
r2 = r2 - r0;
|
||||
|
@@ -207,31 +207,15 @@ void sws_rgb2rgb_init(int flags)
|
||||
rgb2rgb_init_C();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the palette to the same packet 32-bit format as the palette
|
||||
*/
|
||||
#if LIBSWSCALE_VERSION_MAJOR < 1
|
||||
void palette8topacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
|
||||
{
|
||||
long i;
|
||||
|
||||
for (i=0; i<num_pixels; i++)
|
||||
((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]];
|
||||
sws_convertPalette8ToPacked32(src, dst, num_pixels, palette);
|
||||
}
|
||||
|
||||
/**
|
||||
* Palette format: ABCD -> dst format: ABC
|
||||
*/
|
||||
void palette8topacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
|
||||
{
|
||||
long i;
|
||||
|
||||
for (i=0; i<num_pixels; i++) {
|
||||
//FIXME slow?
|
||||
dst[0]= palette[src[i]*4+0];
|
||||
dst[1]= palette[src[i]*4+1];
|
||||
dst[2]= palette[src[i]*4+2];
|
||||
dst+= 3;
|
||||
}
|
||||
sws_convertPalette8ToPacked24(src, dst, num_pixels, palette);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,21 +234,7 @@ void palette8tobgr16(const uint8_t *src, uint8_t *dst, long num_pixels, const ui
|
||||
((uint16_t *)dst)[i] = bswap_16(((const uint16_t *)palette)[src[i]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Palette is assumed to contain BGR15, see rgb32to15 to convert the palette.
|
||||
*/
|
||||
void palette8torgb15(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
|
||||
{
|
||||
long i;
|
||||
for (i=0; i<num_pixels; i++)
|
||||
((uint16_t *)dst)[i] = ((const uint16_t *)palette)[src[i]];
|
||||
}
|
||||
void palette8tobgr15(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
|
||||
{
|
||||
long i;
|
||||
for (i=0; i<num_pixels; i++)
|
||||
((uint16_t *)dst)[i] = bswap_16(((const uint16_t *)palette)[src[i]]);
|
||||
}
|
||||
#endif
|
||||
|
||||
void rgb32to24(const uint8_t *src, uint8_t *dst, long src_size)
|
||||
{
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* Software YUV to YUV converter
|
||||
* Software YUV to RGB converter
|
||||
* Written by Nick Kurshev.
|
||||
* palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at)
|
||||
* YUV & runtime CPU stuff by Michael (michaelni@gmx.at)
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
@@ -28,6 +28,9 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "libswscale/swscale.h"
|
||||
#include "libavutil/avutil.h"
|
||||
|
||||
/* A full collection of RGB to RGB(BGR) converters */
|
||||
extern void (*rgb24tobgr32)(const uint8_t *src, uint8_t *dst, long src_size);
|
||||
extern void (*rgb24tobgr16)(const uint8_t *src, uint8_t *dst, long src_size);
|
||||
@@ -66,12 +69,15 @@ void shuffle_bytes_2103(const uint8_t *src, uint8_t *dst, long src_size);
|
||||
void shuffle_bytes_3012(const uint8_t *src, uint8_t *dst, long src_size);
|
||||
void shuffle_bytes_3210(const uint8_t *src, uint8_t *dst, long src_size);
|
||||
|
||||
void palette8topacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
|
||||
void palette8topacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
|
||||
void palette8torgb16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
|
||||
void palette8tobgr16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
|
||||
void palette8torgb15(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
|
||||
void palette8tobgr15(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
|
||||
#if LIBSWSCALE_VERSION_MAJOR < 1
|
||||
/* deprecated, use the public versions in swscale.h */
|
||||
attribute_deprecated void palette8topacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
|
||||
attribute_deprecated void palette8topacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
|
||||
|
||||
/* totally deprecated, please fix code that uses this */
|
||||
attribute_deprecated void palette8torgb16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
|
||||
attribute_deprecated void palette8tobgr16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Height should be a multiple of 2 and width should be a multiple of 16.
|
||||
|
@@ -1424,12 +1424,12 @@ static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[],
|
||||
|
||||
if (usePal(srcFormat)) {
|
||||
switch (dstFormat) {
|
||||
case PIX_FMT_RGB32 : conv = palette8topacked32; break;
|
||||
case PIX_FMT_BGR32 : conv = palette8topacked32; break;
|
||||
case PIX_FMT_BGR32_1: conv = palette8topacked32; break;
|
||||
case PIX_FMT_RGB32_1: conv = palette8topacked32; break;
|
||||
case PIX_FMT_RGB24 : conv = palette8topacked24; break;
|
||||
case PIX_FMT_BGR24 : conv = palette8topacked24; break;
|
||||
case PIX_FMT_RGB32 : conv = sws_convertPalette8ToPacked32; break;
|
||||
case PIX_FMT_BGR32 : conv = sws_convertPalette8ToPacked32; break;
|
||||
case PIX_FMT_BGR32_1: conv = sws_convertPalette8ToPacked32; break;
|
||||
case PIX_FMT_RGB32_1: conv = sws_convertPalette8ToPacked32; break;
|
||||
case PIX_FMT_RGB24 : conv = sws_convertPalette8ToPacked24; break;
|
||||
case PIX_FMT_BGR24 : conv = sws_convertPalette8ToPacked24; break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1962,3 +1962,26 @@ int sws_scale_ordered(SwsContext *c, const uint8_t* const src[], int srcStride[]
|
||||
return sws_scale(c, src, srcStride, srcSliceY, srcSliceH, dst, dstStride);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Convert the palette to the same packed 32-bit format as the palette */
|
||||
void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
|
||||
{
|
||||
long i;
|
||||
|
||||
for (i=0; i<num_pixels; i++)
|
||||
((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]];
|
||||
}
|
||||
|
||||
/* Palette format: ABCD -> dst format: ABC */
|
||||
void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
|
||||
{
|
||||
long i;
|
||||
|
||||
for (i=0; i<num_pixels; i++) {
|
||||
//FIXME slow?
|
||||
dst[0]= palette[src[i]*4+0];
|
||||
dst[1]= palette[src[i]*4+1];
|
||||
dst[2]= palette[src[i]*4+2];
|
||||
dst+= 3;
|
||||
}
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@
|
||||
#include "libavutil/avutil.h"
|
||||
|
||||
#define LIBSWSCALE_VERSION_MAJOR 0
|
||||
#define LIBSWSCALE_VERSION_MINOR 10
|
||||
#define LIBSWSCALE_VERSION_MINOR 11
|
||||
#define LIBSWSCALE_VERSION_MICRO 0
|
||||
|
||||
#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
|
||||
@@ -302,4 +302,29 @@ struct SwsContext *sws_getCachedContext(struct SwsContext *context,
|
||||
int flags, SwsFilter *srcFilter,
|
||||
SwsFilter *dstFilter, const double *param);
|
||||
|
||||
/**
|
||||
* Converts an 8bit paletted frame into a frame with a color depth of 32-bits.
|
||||
*
|
||||
* The output frame will have the same packed format as the palette.
|
||||
*
|
||||
* @param src source frame buffer
|
||||
* @param dst destination frame buffer
|
||||
* @param num_pixels number of pixels to convert
|
||||
* @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src
|
||||
*/
|
||||
void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
|
||||
|
||||
/**
|
||||
* Converts an 8bit paletted frame into a frame with a color depth of 24 bits.
|
||||
*
|
||||
* With the palette format "ABCD", the destination frame ends up with the format "ABC".
|
||||
*
|
||||
* @param src source frame buffer
|
||||
* @param dst destination frame buffer
|
||||
* @param num_pixels number of pixels to convert
|
||||
* @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src
|
||||
*/
|
||||
void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
|
||||
|
||||
|
||||
#endif /* SWSCALE_SWSCALE_H */
|
||||
|
@@ -22,12 +22,12 @@ stddev: 0.00 PSNR:999.99 bytes: 1058444/ 1058444
|
||||
1058444 ./tests/data/acodec/pcm_s16le.wav
|
||||
95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
|
||||
stddev: 0.00 PSNR:999.99 bytes: 1058444/ 1058444
|
||||
33c64392615a70aa1132b6f87215b8a9 *./tests/data/acodec/pcm_s16be.mkv
|
||||
1060705 ./tests/data/acodec/pcm_s16be.mkv
|
||||
43440f8078f2383c0dd618ad606f6830 *./tests/data/acodec/pcm_s16be.mkv
|
||||
1060693 ./tests/data/acodec/pcm_s16be.mkv
|
||||
95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
|
||||
stddev: 0.00 PSNR:999.99 bytes: 1058444/ 1058444
|
||||
ff09423d5ead01dee128b5875682de2a *./tests/data/acodec/pcm_s16le.mkv
|
||||
1060705 ./tests/data/acodec/pcm_s16le.mkv
|
||||
1e63166f1672b7eb00877c697c06743c *./tests/data/acodec/pcm_s16le.mkv
|
||||
1060693 ./tests/data/acodec/pcm_s16le.mkv
|
||||
95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
|
||||
stddev: 0.00 PSNR:999.99 bytes: 1058444/ 1058444
|
||||
07ffe7ffb78f3648b6524debdde5aec1 *./tests/data/acodec/pcm_s24be.mov
|
||||
|
@@ -1,3 +1,3 @@
|
||||
bd21b559633e3789a1fd00da1eb3e6a3 *./tests/data/lavf/lavf.mkv
|
||||
320487 ./tests/data/lavf/lavf.mkv
|
||||
cf230e089e737ed9449fbfb3cb87da92 *./tests/data/lavf/lavf.mkv
|
||||
320471 ./tests/data/lavf/lavf.mkv
|
||||
./tests/data/lavf/lavf.mkv CRC=0x2a83e6b0
|
||||
|
@@ -1,3 +1,3 @@
|
||||
89faca973d88ff2f5dd20992a11de107 *./tests/data/lavf/lavf.ogg
|
||||
14063 ./tests/data/lavf/lavf.ogg
|
||||
364714f1087f3c1320b60f4209191d23 *./tests/data/lavf/lavf.ogg
|
||||
13820 ./tests/data/lavf/lavf.ogg
|
||||
./tests/data/lavf/lavf.ogg CRC=0xf1ae5536
|
||||
|
@@ -1,53 +1,53 @@
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 529 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 513 size: 27837
|
||||
ret: 0 st:-1 flags:0 ts:-1.000000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 529 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 513 size: 27837
|
||||
ret: 0 st:-1 flags:1 ts: 1.894167
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 291918 size: 27834
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 291902 size: 27834
|
||||
ret: 0 st: 0 flags:0 ts: 0.788000
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 291918 size: 27834
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 291902 size: 27834
|
||||
ret: 0 st: 0 flags:1 ts:-0.317000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 529 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 513 size: 27837
|
||||
ret: 0 st: 1 flags:0 ts: 2.577000
|
||||
ret:-EOF
|
||||
ret: 0 st: 1 flags:1 ts: 1.471000
|
||||
ret: 0 st: 1 flags:1 dts: 1.019000 pts: 1.019000 pos: 320191 size: 209
|
||||
ret: 0 st: 1 flags:1 dts: 1.019000 pts: 1.019000 pos: 320175 size: 209
|
||||
ret: 0 st:-1 flags:0 ts: 0.365002
|
||||
ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146703 size: 27925
|
||||
ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146687 size: 27925
|
||||
ret: 0 st:-1 flags:1 ts:-0.740831
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 529 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 513 size: 27837
|
||||
ret: 0 st: 0 flags:0 ts: 2.153000
|
||||
ret:-EOF
|
||||
ret: 0 st: 0 flags:1 ts: 1.048000
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 291918 size: 27834
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 291902 size: 27834
|
||||
ret: 0 st: 1 flags:0 ts:-0.058000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 529 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 513 size: 27837
|
||||
ret: 0 st: 1 flags:1 ts: 2.836000
|
||||
ret: 0 st: 1 flags:1 dts: 1.019000 pts: 1.019000 pos: 320191 size: 209
|
||||
ret: 0 st: 1 flags:1 dts: 1.019000 pts: 1.019000 pos: 320175 size: 209
|
||||
ret: 0 st:-1 flags:0 ts: 1.730004
|
||||
ret:-EOF
|
||||
ret: 0 st:-1 flags:1 ts: 0.624171
|
||||
ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146703 size: 27925
|
||||
ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146687 size: 27925
|
||||
ret: 0 st: 0 flags:0 ts:-0.482000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 529 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 513 size: 27837
|
||||
ret: 0 st: 0 flags:1 ts: 2.413000
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 291918 size: 27834
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 291902 size: 27834
|
||||
ret: 0 st: 1 flags:0 ts: 1.307000
|
||||
ret:-EOF
|
||||
ret: 0 st: 1 flags:1 ts: 0.201000
|
||||
ret: 0 st: 1 flags:1 dts: 0.183000 pts: 0.183000 pos: 72099 size: 209
|
||||
ret: 0 st: 1 flags:1 dts: 0.183000 pts: 0.183000 pos: 72083 size: 209
|
||||
ret: 0 st:-1 flags:0 ts:-0.904994
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 529 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 513 size: 27837
|
||||
ret: 0 st:-1 flags:1 ts: 1.989173
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 291918 size: 27834
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 291902 size: 27834
|
||||
ret: 0 st: 0 flags:0 ts: 0.883000
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 291918 size: 27834
|
||||
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 291902 size: 27834
|
||||
ret: 0 st: 0 flags:1 ts:-0.222000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 529 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 513 size: 27837
|
||||
ret: 0 st: 1 flags:0 ts: 2.672000
|
||||
ret:-EOF
|
||||
ret: 0 st: 1 flags:1 ts: 1.566000
|
||||
ret: 0 st: 1 flags:1 dts: 1.019000 pts: 1.019000 pos: 320191 size: 209
|
||||
ret: 0 st: 1 flags:1 dts: 1.019000 pts: 1.019000 pos: 320175 size: 209
|
||||
ret: 0 st:-1 flags:0 ts: 0.460008
|
||||
ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146703 size: 27925
|
||||
ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146687 size: 27925
|
||||
ret: 0 st:-1 flags:1 ts:-0.645825
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 529 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 513 size: 27837
|
||||
|
@@ -1,40 +1,27 @@
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 125 size: 1364
|
||||
ret: 0 st:-1 flags:0 ts:-1.000000
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 4353 size: 1382
|
||||
ret:-1 st:-1 flags:0 ts:-1.000000
|
||||
ret:-1 st:-1 flags:1 ts: 1.894167
|
||||
ret: 0 st: 0 flags:0 ts: 0.788345
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 11410 size: 1365
|
||||
ret: 0 st: 0 flags:1 ts:-0.317506
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 1522 size: 1381
|
||||
ret:-1 st: 0 flags:0 ts: 0.788345
|
||||
ret:-1 st: 0 flags:1 ts:-0.317506
|
||||
ret:-1 st:-1 flags:0 ts: 2.576668
|
||||
ret:-1 st:-1 flags:1 ts: 1.470835
|
||||
ret: 0 st: 0 flags:0 ts: 0.365011
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 7191 size: 1370
|
||||
ret: 0 st: 0 flags:1 ts:-0.740839
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 1522 size: 1381
|
||||
ret:-1 st: 0 flags:0 ts: 0.365011
|
||||
ret:-1 st: 0 flags:1 ts:-0.740839
|
||||
ret:-1 st:-1 flags:0 ts: 2.153336
|
||||
ret:-1 st:-1 flags:1 ts: 1.047503
|
||||
ret: 0 st: 0 flags:0 ts:-0.058322
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 4353 size: 1382
|
||||
ret:-1 st: 0 flags:0 ts:-0.058322
|
||||
ret:-1 st: 0 flags:1 ts: 2.835828
|
||||
ret:-1 st:-1 flags:0 ts: 1.730004
|
||||
ret: 0 st:-1 flags:1 ts: 0.624171
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 5768 size: 1390
|
||||
ret: 0 st: 0 flags:0 ts:-0.481655
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 4353 size: 1382
|
||||
ret:-1 st:-1 flags:1 ts: 0.624171
|
||||
ret:-1 st: 0 flags:0 ts:-0.481655
|
||||
ret:-1 st: 0 flags:1 ts: 2.412494
|
||||
ret:-1 st:-1 flags:0 ts: 1.306672
|
||||
ret: 0 st:-1 flags:1 ts: 0.200839
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 1522 size: 1381
|
||||
ret: 0 st: 0 flags:0 ts:-0.904989
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 4353 size: 1382
|
||||
ret:-1 st:-1 flags:1 ts: 0.200839
|
||||
ret:-1 st: 0 flags:0 ts:-0.904989
|
||||
ret:-1 st: 0 flags:1 ts: 1.989184
|
||||
ret:-1 st:-1 flags:0 ts: 0.883340
|
||||
ret: 0 st:-1 flags:1 ts:-0.222493
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 1522 size: 1381
|
||||
ret:-1 st:-1 flags:1 ts:-0.222493
|
||||
ret:-1 st: 0 flags:0 ts: 2.671678
|
||||
ret:-1 st: 0 flags:1 ts: 1.565850
|
||||
ret: 0 st:-1 flags:0 ts: 0.460008
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 8594 size: 1381
|
||||
ret: 0 st:-1 flags:1 ts:-0.645825
|
||||
ret: 0 st: 0 flags:1 dts: NOPTS pts: NOPTS pos: 1522 size: 1381
|
||||
ret:-1 st:-1 flags:0 ts: 0.460008
|
||||
ret:-1 st:-1 flags:1 ts:-0.645825
|
||||
|
@@ -1,53 +1,53 @@
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts:-1.000000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts: 1.894167
|
||||
ret: 0 st: 0 flags:1 dts: 1.881000 pts: 1.881000 pos: 332767 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.881000 pts: 1.881000 pos: 332755 size: 4096
|
||||
ret: 0 st: 0 flags:0 ts: 0.788000
|
||||
ret: 0 st: 0 flags:1 dts: 0.789000 pts: 0.789000 pos: 139926 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.789000 pts: 0.789000 pos: 139914 size: 4096
|
||||
ret: 0 st: 0 flags:1 ts:-0.317000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts: 2.576668
|
||||
ret: 0 st: 0 flags:1 dts: 2.577000 pts: 2.577000 pos: 455857 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 2.577000 pts: 2.577000 pos: 455845 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts: 1.470835
|
||||
ret: 0 st: 0 flags:1 dts: 1.463000 pts: 1.463000 pos: 258913 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.463000 pts: 1.463000 pos: 258901 size: 4096
|
||||
ret: 0 st: 0 flags:0 ts: 0.365000
|
||||
ret: 0 st: 0 flags:1 dts: 0.372000 pts: 0.372000 pos: 66072 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.372000 pts: 0.372000 pos: 66060 size: 4096
|
||||
ret: 0 st: 0 flags:1 ts:-0.741000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts: 2.153336
|
||||
ret: 0 st: 0 flags:1 dts: 2.159000 pts: 2.159000 pos: 382003 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 2.159000 pts: 2.159000 pos: 381991 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts: 1.047503
|
||||
ret: 0 st: 0 flags:1 dts: 1.045000 pts: 1.045000 pos: 185059 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.045000 pts: 1.045000 pos: 185047 size: 4096
|
||||
ret: 0 st: 0 flags:0 ts:-0.058000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st: 0 flags:1 ts: 2.836000
|
||||
ret: 0 st: 0 flags:1 dts: 2.833000 pts: 2.833000 pos: 500990 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 2.833000 pts: 2.833000 pos: 500978 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts: 1.730004
|
||||
ret: 0 st: 0 flags:1 dts: 1.741000 pts: 1.741000 pos: 308149 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.741000 pts: 1.741000 pos: 308137 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts: 0.624171
|
||||
ret: 0 st: 0 flags:1 dts: 0.604000 pts: 0.604000 pos: 107102 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.604000 pts: 0.604000 pos: 107090 size: 4096
|
||||
ret: 0 st: 0 flags:0 ts:-0.482000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st: 0 flags:1 ts: 2.413000
|
||||
ret: 0 st: 0 flags:1 dts: 2.392000 pts: 2.392000 pos: 423033 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 2.392000 pts: 2.392000 pos: 423021 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts: 1.306672
|
||||
ret: 0 st: 0 flags:1 dts: 1.324000 pts: 1.324000 pos: 234295 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.324000 pts: 1.324000 pos: 234283 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts: 0.200839
|
||||
ret: 0 st: 0 flags:1 dts: 0.186000 pts: 0.186000 pos: 33248 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.186000 pts: 0.186000 pos: 33236 size: 4096
|
||||
ret: 0 st: 0 flags:0 ts:-0.905000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st: 0 flags:1 ts: 1.989000
|
||||
ret: 0 st: 0 flags:1 dts: 1.974000 pts: 1.974000 pos: 349179 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.974000 pts: 1.974000 pos: 349167 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts: 0.883340
|
||||
ret: 0 st: 0 flags:1 dts: 0.906000 pts: 0.906000 pos: 160441 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.906000 pts: 0.906000 pos: 160429 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts:-0.222493
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st: 0 flags:0 ts: 2.672000
|
||||
ret: 0 st: 0 flags:1 dts: 2.694000 pts: 2.694000 pos: 476372 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 2.694000 pts: 2.694000 pos: 476360 size: 4096
|
||||
ret: 0 st: 0 flags:1 ts: 1.566000
|
||||
ret: 0 st: 0 flags:1 dts: 1.556000 pts: 1.556000 pos: 275325 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.556000 pts: 1.556000 pos: 275313 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts: 0.460008
|
||||
ret: 0 st: 0 flags:1 dts: 0.464000 pts: 0.464000 pos: 82484 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.464000 pts: 0.464000 pos: 82472 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts:-0.645825
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
|
@@ -1,53 +1,53 @@
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts:-1.000000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts: 1.894167
|
||||
ret: 0 st: 0 flags:1 dts: 1.881000 pts: 1.881000 pos: 332767 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.881000 pts: 1.881000 pos: 332755 size: 4096
|
||||
ret: 0 st: 0 flags:0 ts: 0.788000
|
||||
ret: 0 st: 0 flags:1 dts: 0.789000 pts: 0.789000 pos: 139926 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.789000 pts: 0.789000 pos: 139914 size: 4096
|
||||
ret: 0 st: 0 flags:1 ts:-0.317000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts: 2.576668
|
||||
ret: 0 st: 0 flags:1 dts: 2.577000 pts: 2.577000 pos: 455857 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 2.577000 pts: 2.577000 pos: 455845 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts: 1.470835
|
||||
ret: 0 st: 0 flags:1 dts: 1.463000 pts: 1.463000 pos: 258913 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.463000 pts: 1.463000 pos: 258901 size: 4096
|
||||
ret: 0 st: 0 flags:0 ts: 0.365000
|
||||
ret: 0 st: 0 flags:1 dts: 0.372000 pts: 0.372000 pos: 66072 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.372000 pts: 0.372000 pos: 66060 size: 4096
|
||||
ret: 0 st: 0 flags:1 ts:-0.741000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts: 2.153336
|
||||
ret: 0 st: 0 flags:1 dts: 2.159000 pts: 2.159000 pos: 382003 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 2.159000 pts: 2.159000 pos: 381991 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts: 1.047503
|
||||
ret: 0 st: 0 flags:1 dts: 1.045000 pts: 1.045000 pos: 185059 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.045000 pts: 1.045000 pos: 185047 size: 4096
|
||||
ret: 0 st: 0 flags:0 ts:-0.058000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st: 0 flags:1 ts: 2.836000
|
||||
ret: 0 st: 0 flags:1 dts: 2.833000 pts: 2.833000 pos: 500990 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 2.833000 pts: 2.833000 pos: 500978 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts: 1.730004
|
||||
ret: 0 st: 0 flags:1 dts: 1.741000 pts: 1.741000 pos: 308149 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.741000 pts: 1.741000 pos: 308137 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts: 0.624171
|
||||
ret: 0 st: 0 flags:1 dts: 0.604000 pts: 0.604000 pos: 107102 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.604000 pts: 0.604000 pos: 107090 size: 4096
|
||||
ret: 0 st: 0 flags:0 ts:-0.482000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st: 0 flags:1 ts: 2.413000
|
||||
ret: 0 st: 0 flags:1 dts: 2.392000 pts: 2.392000 pos: 423033 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 2.392000 pts: 2.392000 pos: 423021 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts: 1.306672
|
||||
ret: 0 st: 0 flags:1 dts: 1.324000 pts: 1.324000 pos: 234295 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.324000 pts: 1.324000 pos: 234283 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts: 0.200839
|
||||
ret: 0 st: 0 flags:1 dts: 0.186000 pts: 0.186000 pos: 33248 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.186000 pts: 0.186000 pos: 33236 size: 4096
|
||||
ret: 0 st: 0 flags:0 ts:-0.905000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st: 0 flags:1 ts: 1.989000
|
||||
ret: 0 st: 0 flags:1 dts: 1.974000 pts: 1.974000 pos: 349179 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.974000 pts: 1.974000 pos: 349167 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts: 0.883340
|
||||
ret: 0 st: 0 flags:1 dts: 0.906000 pts: 0.906000 pos: 160441 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.906000 pts: 0.906000 pos: 160429 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts:-0.222493
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
ret: 0 st: 0 flags:0 ts: 2.672000
|
||||
ret: 0 st: 0 flags:1 dts: 2.694000 pts: 2.694000 pos: 476372 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 2.694000 pts: 2.694000 pos: 476360 size: 4096
|
||||
ret: 0 st: 0 flags:1 ts: 1.566000
|
||||
ret: 0 st: 0 flags:1 dts: 1.556000 pts: 1.556000 pos: 275325 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 1.556000 pts: 1.556000 pos: 275313 size: 4096
|
||||
ret: 0 st:-1 flags:0 ts: 0.460008
|
||||
ret: 0 st: 0 flags:1 dts: 0.464000 pts: 0.464000 pos: 82484 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.464000 pts: 0.464000 pos: 82472 size: 4096
|
||||
ret: 0 st:-1 flags:1 ts:-0.645825
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 424 size: 4096
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
|
||||
|
@@ -116,6 +116,7 @@ int main(int argc, char *argv[])
|
||||
/* keep ftyp atom */
|
||||
if (atom_type == FTYP_ATOM) {
|
||||
ftyp_atom_size = atom_size;
|
||||
free(ftyp_atom);
|
||||
ftyp_atom = malloc(ftyp_atom_size);
|
||||
if (!ftyp_atom) {
|
||||
printf ("could not allocate %"PRIu64" byte for ftyp atom\n",
|
||||
|
Reference in New Issue
Block a user