summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/4xm.c40
-rw-r--r--libavformat/Makefile38
-rw-r--r--libavformat/a64.c14
-rw-r--r--libavformat/aacdec.c22
-rw-r--r--libavformat/ac3dec.c32
-rw-r--r--libavformat/act.c207
-rw-r--r--libavformat/adts.h8
-rw-r--r--libavformat/adtsenc.c34
-rw-r--r--libavformat/aea.c24
-rw-r--r--libavformat/aiff.h8
-rw-r--r--libavformat/aiffdec.c59
-rw-r--r--libavformat/aiffenc.c35
-rw-r--r--libavformat/allformats.c29
-rw-r--r--libavformat/amr.c42
-rw-r--r--libavformat/anm.c47
-rw-r--r--libavformat/apc.c21
-rw-r--r--libavformat/ape.c41
-rw-r--r--libavformat/apetag.c8
-rw-r--r--libavformat/apetag.h8
-rw-r--r--libavformat/applehttp.c37
-rw-r--r--libavformat/applehttpproto.c10
-rw-r--r--libavformat/asf.c8
-rw-r--r--libavformat/asf.h18
-rw-r--r--libavformat/asfcrypt.c8
-rw-r--r--libavformat/asfcrypt.h8
-rw-r--r--libavformat/asfdec.c91
-rw-r--r--libavformat/asfenc.c68
-rw-r--r--libavformat/assdec.c12
-rw-r--r--libavformat/assenc.c8
-rw-r--r--libavformat/au.c56
-rw-r--r--libavformat/audiointerleave.c8
-rw-r--r--libavformat/audiointerleave.h8
-rw-r--r--libavformat/avc.c8
-rw-r--r--libavformat/avc.h8
-rw-r--r--libavformat/avformat.h262
-rw-r--r--libavformat/avi.c8
-rw-r--r--libavformat/avi.h8
-rw-r--r--libavformat/avidec.c212
-rw-r--r--libavformat/avienc.c43
-rw-r--r--libavformat/avio.c24
-rw-r--r--libavformat/avio.h33
-rw-r--r--libavformat/avio_internal.h8
-rw-r--r--libavformat/aviobuf.c56
-rw-r--r--libavformat/avisynth.c42
-rw-r--r--libavformat/avlanguage.c11
-rw-r--r--libavformat/avlanguage.h8
-rw-r--r--libavformat/avs.c30
-rw-r--r--libavformat/bethsoftvid.c30
-rw-r--r--libavformat/bfi.c30
-rw-r--r--libavformat/bink.c38
-rw-r--r--libavformat/bintext.c375
-rw-r--r--libavformat/bit.c135
-rw-r--r--libavformat/c93.c24
-rw-r--r--libavformat/cache.c144
-rw-r--r--libavformat/caf.c55
-rw-r--r--libavformat/caf.h8
-rw-r--r--libavformat/cafdec.c57
-rw-r--r--libavformat/cafenc.c262
-rw-r--r--libavformat/cavsvideodec.c8
-rw-r--r--libavformat/cdg.c26
-rw-r--r--libavformat/concat.c8
-rw-r--r--libavformat/crcenc.c27
-rw-r--r--libavformat/crypto.c4
-rw-r--r--libavformat/cutils.c29
-rw-r--r--libavformat/daud.c45
-rw-r--r--libavformat/dfa.c21
-rw-r--r--libavformat/diracdec.c8
-rw-r--r--libavformat/dnxhddec.c8
-rw-r--r--libavformat/dsicin.c26
-rw-r--r--libavformat/dtsdec.c19
-rw-r--r--libavformat/dv.c60
-rw-r--r--libavformat/dv.h14
-rw-r--r--libavformat/dvenc.c94
-rw-r--r--libavformat/dxa.c28
-rw-r--r--libavformat/eacdata.c32
-rw-r--r--libavformat/electronicarts.c36
-rw-r--r--libavformat/ffm.h8
-rw-r--r--libavformat/ffmdec.c62
-rw-r--r--libavformat/ffmenc.c30
-rw-r--r--libavformat/ffmeta.h8
-rw-r--r--libavformat/ffmetadec.c16
-rw-r--r--libavformat/ffmetaenc.c8
-rw-r--r--libavformat/file.c14
-rw-r--r--libavformat/filmstripdec.c29
-rw-r--r--libavformat/filmstripenc.c27
-rw-r--r--libavformat/flacdec.c27
-rw-r--r--libavformat/flacenc.c29
-rw-r--r--libavformat/flacenc.h8
-rw-r--r--libavformat/flacenc_header.c10
-rw-r--r--libavformat/flic.c26
-rw-r--r--libavformat/flv.h31
-rw-r--r--libavformat/flvdec.c219
-rw-r--r--libavformat/flvenc.c142
-rw-r--r--libavformat/framecrcenc.c24
-rw-r--r--libavformat/g723_1.c83
-rw-r--r--libavformat/gif.c57
-rw-r--r--libavformat/gopher.c8
-rw-r--r--libavformat/gxf.c61
-rw-r--r--libavformat/gxf.h8
-rw-r--r--libavformat/gxfenc.c58
-rw-r--r--libavformat/h261dec.c8
-rw-r--r--libavformat/h263dec.c8
-rw-r--r--libavformat/h264dec.c10
-rw-r--r--libavformat/http.c12
-rw-r--r--libavformat/http.h8
-rw-r--r--libavformat/httpauth.c8
-rw-r--r--libavformat/httpauth.h8
-rw-r--r--libavformat/id3v1.c8
-rw-r--r--libavformat/id3v1.h8
-rw-r--r--libavformat/id3v2.c447
-rw-r--r--libavformat/id3v2.h38
-rw-r--r--libavformat/idcin.c26
-rw-r--r--libavformat/idroqdec.c26
-rw-r--r--libavformat/idroqenc.c27
-rw-r--r--libavformat/iff.c177
-rw-r--r--libavformat/img2.c71
-rw-r--r--libavformat/ingenientdec.c23
-rw-r--r--libavformat/internal.h23
-rw-r--r--libavformat/ipmovie.c30
-rw-r--r--libavformat/isom.c137
-rw-r--r--libavformat/isom.h11
-rw-r--r--libavformat/iss.c25
-rw-r--r--libavformat/iv8.c21
-rw-r--r--libavformat/ivfdec.c21
-rw-r--r--libavformat/ivfenc.c8
-rw-r--r--libavformat/jvdec.c17
-rw-r--r--libavformat/latmenc.c198
-rw-r--r--libavformat/libavformat.v30
-rw-r--r--libavformat/libmodplug.c367
-rw-r--r--libavformat/libnut.c46
-rw-r--r--libavformat/librtmp.c9
-rw-r--r--libavformat/lmlm4.c23
-rw-r--r--libavformat/loasdec.c88
-rw-r--r--libavformat/lxfdec.c14
-rw-r--r--libavformat/m4vdec.c10
-rw-r--r--libavformat/matroska.c32
-rw-r--r--libavformat/matroska.h22
-rw-r--r--libavformat/matroskadec.c338
-rw-r--r--libavformat/matroskaenc.c228
-rw-r--r--libavformat/md5enc.c44
-rw-r--r--libavformat/md5proto.c8
-rw-r--r--libavformat/metadata-example.c56
-rw-r--r--libavformat/metadata.c8
-rw-r--r--libavformat/metadata.h8
-rw-r--r--libavformat/microdvddec.c129
-rw-r--r--libavformat/microdvdenc.c51
-rw-r--r--libavformat/mm.c24
-rw-r--r--libavformat/mmf.c47
-rw-r--r--libavformat/mms.c8
-rw-r--r--libavformat/mms.h8
-rw-r--r--libavformat/mmsh.c12
-rw-r--r--libavformat/mmst.c10
-rw-r--r--libavformat/mov.c332
-rw-r--r--libavformat/movenc.c216
-rw-r--r--libavformat/movenc.h8
-rw-r--r--libavformat/movenchint.c10
-rw-r--r--libavformat/mp3dec.c31
-rw-r--r--libavformat/mp3enc.c286
-rw-r--r--libavformat/mpc.c42
-rw-r--r--libavformat/mpc8.c34
-rw-r--r--libavformat/mpeg.c58
-rw-r--r--libavformat/mpeg.h8
-rw-r--r--libavformat/mpegenc.c142
-rw-r--r--libavformat/mpegts.c340
-rw-r--r--libavformat/mpegts.h8
-rw-r--r--libavformat/mpegtsenc.c169
-rw-r--r--libavformat/mpegvideodec.c8
-rw-r--r--libavformat/mpjpeg.c27
-rw-r--r--libavformat/msnwc_tcp.c25
-rw-r--r--libavformat/mtv.c30
-rw-r--r--libavformat/mvi.c23
-rw-r--r--libavformat/mxf.c13
-rw-r--r--libavformat/mxf.h8
-rw-r--r--libavformat/mxfdec.c190
-rw-r--r--libavformat/mxfenc.c155
-rw-r--r--libavformat/mxg.c20
-rw-r--r--libavformat/ncdec.c23
-rw-r--r--libavformat/network.h10
-rw-r--r--libavformat/nsvdec.c74
-rw-r--r--libavformat/nullenc.c22
-rw-r--r--libavformat/nut.c8
-rw-r--r--libavformat/nut.h8
-rw-r--r--libavformat/nutdec.c32
-rw-r--r--libavformat/nutenc.c49
-rw-r--r--libavformat/nuv.c111
-rw-r--r--libavformat/oggdec.c57
-rw-r--r--libavformat/oggdec.h2
-rw-r--r--libavformat/oggenc.c63
-rw-r--r--libavformat/oggparsecelt.c95
-rw-r--r--libavformat/oggparsedirac.c10
-rw-r--r--libavformat/oggparseflac.c10
-rw-r--r--libavformat/oggparseskeleton.c8
-rw-r--r--libavformat/oggparsespeex.c20
-rw-r--r--libavformat/oggparsevorbis.c2
-rw-r--r--libavformat/oma.c291
-rw-r--r--libavformat/options.c109
-rw-r--r--libavformat/os_support.c8
-rw-r--r--libavformat/os_support.h8
-rw-r--r--libavformat/output-example.c563
-rw-r--r--libavformat/pcm.c8
-rw-r--r--libavformat/pcm.h8
-rw-r--r--libavformat/pcmdec.c48
-rw-r--r--libavformat/pcmenc.c29
-rw-r--r--libavformat/pmpdec.c172
-rw-r--r--libavformat/psxstr.c82
-rw-r--r--libavformat/pva.c41
-rw-r--r--libavformat/qcp.c17
-rw-r--r--libavformat/qtpalette.h8
-rw-r--r--libavformat/r3d.c31
-rw-r--r--libavformat/rawdec.c137
-rw-r--r--libavformat/rawdec.h23
-rw-r--r--libavformat/rawenc.c284
-rw-r--r--libavformat/rawenc.h8
-rw-r--r--libavformat/rawvideodec.c37
-rw-r--r--libavformat/rdt.c11
-rw-r--r--libavformat/rdt.h22
-rw-r--r--libavformat/riff.c83
-rw-r--r--libavformat/riff.h34
-rw-r--r--libavformat/rl2.c30
-rw-r--r--libavformat/rm.c8
-rw-r--r--libavformat/rm.h8
-rw-r--r--libavformat/rmdec.c173
-rw-r--r--libavformat/rmenc.c28
-rw-r--r--libavformat/rpl.c24
-rw-r--r--libavformat/rso.c8
-rw-r--r--libavformat/rso.h8
-rw-r--r--libavformat/rsodec.c10
-rw-r--r--libavformat/rsoenc.c8
-rw-r--r--libavformat/rtmp.h8
-rw-r--r--libavformat/rtmppkt.c8
-rw-r--r--libavformat/rtmppkt.h8
-rw-r--r--libavformat/rtmpproto.c57
-rw-r--r--libavformat/rtp.c34
-rw-r--r--libavformat/rtp.h18
-rw-r--r--libavformat/rtpdec.c54
-rw-r--r--libavformat/rtpdec.h32
-rw-r--r--libavformat/rtpdec_amr.c8
-rw-r--r--libavformat/rtpdec_asf.c16
-rw-r--r--libavformat/rtpdec_formats.h8
-rw-r--r--libavformat/rtpdec_h263.c8
-rw-r--r--libavformat/rtpdec_h264.c8
-rw-r--r--libavformat/rtpdec_latm.c8
-rw-r--r--libavformat/rtpdec_mpeg4.c8
-rw-r--r--libavformat/rtpdec_qcelp.c8
-rw-r--r--libavformat/rtpdec_qdm2.c8
-rw-r--r--libavformat/rtpdec_qt.c8
-rw-r--r--libavformat/rtpdec_svq3.c10
-rw-r--r--libavformat/rtpdec_vp8.c10
-rw-r--r--libavformat/rtpdec_xiph.c8
-rw-r--r--libavformat/rtpenc.c33
-rw-r--r--libavformat/rtpenc.h12
-rw-r--r--libavformat/rtpenc_aac.c8
-rw-r--r--libavformat/rtpenc_amr.c8
-rw-r--r--libavformat/rtpenc_chain.c24
-rw-r--r--libavformat/rtpenc_chain.h8
-rw-r--r--libavformat/rtpenc_h263.c8
-rw-r--r--libavformat/rtpenc_h264.c40
-rw-r--r--libavformat/rtpenc_latm.c4
-rw-r--r--libavformat/rtpenc_mpv.c10
-rw-r--r--libavformat/rtpenc_vp8.c8
-rw-r--r--libavformat/rtpenc_xiph.c8
-rw-r--r--libavformat/rtpproto.c40
-rw-r--r--libavformat/rtsp.c153
-rw-r--r--libavformat/rtsp.h39
-rw-r--r--libavformat/rtspcodes.h8
-rw-r--r--libavformat/rtspdec.c45
-rw-r--r--libavformat/rtspenc.c35
-rw-r--r--libavformat/sapdec.c28
-rw-r--r--libavformat/sapenc.c26
-rw-r--r--libavformat/sauce.c8
-rw-r--r--libavformat/sauce.h8
-rw-r--r--libavformat/sdp.c17
-rw-r--r--libavformat/seek-test.c133
-rw-r--r--libavformat/seek.c8
-rw-r--r--libavformat/seek.h8
-rw-r--r--libavformat/segafilm.c71
-rw-r--r--libavformat/segment.c234
-rw-r--r--libavformat/sierravmd.c26
-rw-r--r--libavformat/siff.c24
-rw-r--r--libavformat/smacker.c70
-rw-r--r--libavformat/sol.c28
-rw-r--r--libavformat/sox.h8
-rw-r--r--libavformat/soxdec.c30
-rw-r--r--libavformat/soxenc.c31
-rw-r--r--libavformat/spdif.c8
-rw-r--r--libavformat/spdif.h8
-rw-r--r--libavformat/spdifdec.c25
-rw-r--r--libavformat/spdifenc.c49
-rw-r--r--libavformat/srtdec.c12
-rw-r--r--libavformat/swf.h8
-rw-r--r--libavformat/swfdec.c40
-rw-r--r--libavformat/swfenc.c49
-rw-r--r--libavformat/tcp.c10
-rw-r--r--libavformat/thp.c24
-rw-r--r--libavformat/tiertexseq.c26
-rw-r--r--libavformat/timefilter.c151
-rw-r--r--libavformat/timefilter.h97
-rw-r--r--libavformat/tmv.c36
-rw-r--r--libavformat/tta.c28
-rw-r--r--libavformat/tty.c30
-rw-r--r--libavformat/txd.c26
-rw-r--r--libavformat/udp.c141
-rw-r--r--libavformat/url.h14
-rw-r--r--libavformat/utils.c754
-rw-r--r--libavformat/vc1test.c23
-rw-r--r--libavformat/vc1testenc.c28
-rw-r--r--libavformat/version.h37
-rw-r--r--libavformat/voc.c8
-rw-r--r--libavformat/voc.h8
-rw-r--r--libavformat/vocdec.c24
-rw-r--r--libavformat/vocenc.c28
-rw-r--r--libavformat/vorbiscomment.c8
-rw-r--r--libavformat/vorbiscomment.h8
-rw-r--r--libavformat/vqf.c25
-rw-r--r--libavformat/wav.c452
-rw-r--r--libavformat/wc3movie.c30
-rw-r--r--libavformat/westwood.c42
-rw-r--r--libavformat/wtv.c1114
-rw-r--r--libavformat/wtv.h55
-rw-r--r--libavformat/wtvdec.c1038
-rw-r--r--libavformat/wtvenc.c722
-rw-r--r--libavformat/wv.c34
-rw-r--r--libavformat/xa.c22
-rw-r--r--libavformat/xmv.c557
-rw-r--r--libavformat/xwma.c22
-rw-r--r--libavformat/yop.c39
-rw-r--r--libavformat/yuv4mpeg.c46
327 files changed, 13302 insertions, 6828 deletions
diff --git a/libavformat/4xm.c b/libavformat/4xm.c
index 32699da439..3bb8bbdbdc 100644
--- a/libavformat/4xm.c
+++ b/libavformat/4xm.c
@@ -2,20 +2,20 @@
* 4X Technologies .4xm File Demuxer (no muxer)
* Copyright (c) 2003 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -141,7 +141,7 @@ static int fourxm_read_header(AVFormatContext *s,
fourxm->height = AV_RL32(&header[i + 40]);
/* allocate a new AVStream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st){
ret= AVERROR(ENOMEM);
goto fail;
@@ -173,13 +173,16 @@ static int fourxm_read_header(AVFormatContext *s,
goto fail;
}
if (current_track + 1 > fourxm->track_count) {
- fourxm->track_count = current_track + 1;
- fourxm->tracks = av_realloc(fourxm->tracks,
- fourxm->track_count * sizeof(AudioTrack));
+ fourxm->tracks = av_realloc_f(fourxm->tracks,
+ sizeof(AudioTrack),
+ current_track + 1);
if (!fourxm->tracks) {
- ret= AVERROR(ENOMEM);
+ ret = AVERROR(ENOMEM);
goto fail;
}
+ memset(&fourxm->tracks[fourxm->track_count], 0,
+ sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count));
+ fourxm->track_count = current_track + 1;
}
fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]);
fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]);
@@ -196,12 +199,13 @@ static int fourxm_read_header(AVFormatContext *s,
i += 8 + size;
/* allocate a new AVStream */
- st = av_new_stream(s, current_track);
+ st = avformat_new_stream(s, NULL);
if (!st){
ret= AVERROR(ENOMEM);
goto fail;
}
+ st->id = current_track;
av_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);
fourxm->tracks[current_track].stream_index = st->index;
@@ -260,7 +264,7 @@ static int fourxm_read_packet(AVFormatContext *s,
return ret;
fourcc_tag = AV_RL32(&header[0]);
size = AV_RL32(&header[4]);
- if (pb->eof_reached)
+ if (url_feof(pb))
return AVERROR(EIO);
switch (fourcc_tag) {
@@ -345,11 +349,11 @@ static int fourxm_read_close(AVFormatContext *s)
}
AVInputFormat ff_fourxm_demuxer = {
- "4xm",
- NULL_IF_CONFIG_SMALL("4X Technologies format"),
- sizeof(FourxmDemuxContext),
- fourxm_probe,
- fourxm_read_header,
- fourxm_read_packet,
- fourxm_read_close,
+ .name = "4xm",
+ .long_name = NULL_IF_CONFIG_SMALL("4X Technologies format"),
+ .priv_data_size = sizeof(FourxmDemuxContext),
+ .read_probe = fourxm_probe,
+ .read_header = fourxm_read_header,
+ .read_packet = fourxm_read_packet,
+ .read_close = fourxm_read_close,
};
diff --git a/libavformat/Makefile b/libavformat/Makefile
index a20db26b03..15ccb291ed 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -1,3 +1,5 @@
+include $(SUBDIR)../config.mak
+
NAME = avformat
FFLIBS = avcodec avutil
@@ -19,10 +21,12 @@ OBJS-$(CONFIG_A64_MUXER) += a64.o
OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o rawdec.o
OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o
OBJS-$(CONFIG_AC3_MUXER) += rawenc.o
+OBJS-$(CONFIG_ACT_DEMUXER) += act.o
+OBJS-$(CONFIG_ADF_DEMUXER) += bintext.o sauce.o
OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o
OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o
-OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o
-OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o riff.o
+OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o isom.o
+OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o riff.o isom.o
OBJS-$(CONFIG_AMR_DEMUXER) += amr.o
OBJS-$(CONFIG_AMR_MUXER) += amr.o
OBJS-$(CONFIG_ANM_DEMUXER) += anm.o
@@ -44,8 +48,12 @@ OBJS-$(CONFIG_AVS_DEMUXER) += avs.o vocdec.o voc.o
OBJS-$(CONFIG_BETHSOFTVID_DEMUXER) += bethsoftvid.o
OBJS-$(CONFIG_BFI_DEMUXER) += bfi.o
OBJS-$(CONFIG_BINK_DEMUXER) += bink.o
+OBJS-$(CONFIG_BINTEXT_DEMUXER) += bintext.o sauce.o
+OBJS-$(CONFIG_BIT_DEMUXER) += bit.o
+OBJS-$(CONFIG_BIT_MUXER) += bit.o
OBJS-$(CONFIG_C93_DEMUXER) += c93.o vocdec.o voc.o
OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov.o riff.o isom.o
+OBJS-$(CONFIG_CAF_MUXER) += cafenc.o caf.o riff.o isom.o
OBJS-$(CONFIG_CAVSVIDEO_DEMUXER) += cavsvideodec.o rawdec.o
OBJS-$(CONFIG_CAVSVIDEO_MUXER) += rawenc.o
OBJS-$(CONFIG_CDG_DEMUXER) += cdg.o
@@ -90,6 +98,8 @@ OBJS-$(CONFIG_GXF_DEMUXER) += gxf.o
OBJS-$(CONFIG_GXF_MUXER) += gxfenc.o audiointerleave.o
OBJS-$(CONFIG_G722_DEMUXER) += rawdec.o
OBJS-$(CONFIG_G722_MUXER) += rawenc.o
+OBJS-$(CONFIG_G723_1_DEMUXER) += g723_1.o
+OBJS-$(CONFIG_G723_1_MUXER) += rawenc.o
OBJS-$(CONFIG_H261_DEMUXER) += h261dec.o rawdec.o
OBJS-$(CONFIG_H261_MUXER) += rawenc.o
OBJS-$(CONFIG_H263_DEMUXER) += h263dec.o rawdec.o
@@ -97,6 +107,7 @@ OBJS-$(CONFIG_H263_MUXER) += rawenc.o
OBJS-$(CONFIG_H264_DEMUXER) += h264dec.o rawdec.o
OBJS-$(CONFIG_H264_MUXER) += rawenc.o
OBJS-$(CONFIG_IDCIN_DEMUXER) += idcin.o
+OBJS-$(CONFIG_IDF_DEMUXER) += bintext.o
OBJS-$(CONFIG_IFF_DEMUXER) += iff.o
OBJS-$(CONFIG_IMAGE2_DEMUXER) += img2.o
OBJS-$(CONFIG_IMAGE2_MUXER) += img2.o
@@ -109,7 +120,10 @@ OBJS-$(CONFIG_IV8_DEMUXER) += iv8.o
OBJS-$(CONFIG_IVF_DEMUXER) += ivfdec.o riff.o
OBJS-$(CONFIG_IVF_MUXER) += ivfenc.o
OBJS-$(CONFIG_JV_DEMUXER) += jvdec.o
+OBJS-$(CONFIG_LATM_DEMUXER) += rawdec.o
+OBJS-$(CONFIG_LATM_MUXER) += latmenc.o
OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o
+OBJS-$(CONFIG_LOAS_DEMUXER) += loasdec.o
OBJS-$(CONFIG_LXF_DEMUXER) += lxfdec.o
OBJS-$(CONFIG_M4V_DEMUXER) += m4vdec.o rawdec.o
OBJS-$(CONFIG_M4V_MUXER) += rawenc.o
@@ -119,6 +133,8 @@ OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \
riff.o isom.o avc.o \
flacenc_header.o avlanguage.o
OBJS-$(CONFIG_MD5_MUXER) += md5enc.o
+OBJS-$(CONFIG_MICRODVD_DEMUXER) += microdvddec.o
+OBJS-$(CONFIG_MICRODVD_MUXER) += microdvdenc.o rawenc.o
OBJS-$(CONFIG_MJPEG_DEMUXER) += rawdec.o
OBJS-$(CONFIG_MJPEG_MUXER) += rawenc.o
OBJS-$(CONFIG_MLP_DEMUXER) += rawdec.o
@@ -159,6 +175,7 @@ OBJS-$(CONFIG_NUT_DEMUXER) += nutdec.o nut.o riff.o
OBJS-$(CONFIG_NUT_MUXER) += nutenc.o nut.o riff.o
OBJS-$(CONFIG_NUV_DEMUXER) += nuv.o riff.o
OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \
+ oggparsecelt.o \
oggparsedirac.o \
oggparseflac.o \
oggparseogm.o \
@@ -211,6 +228,7 @@ OBJS-$(CONFIG_PCM_U32LE_DEMUXER) += pcmdec.o pcm.o rawdec.o
OBJS-$(CONFIG_PCM_U32LE_MUXER) += pcmenc.o rawenc.o
OBJS-$(CONFIG_PCM_U8_DEMUXER) += pcmdec.o pcm.o rawdec.o
OBJS-$(CONFIG_PCM_U8_MUXER) += pcmenc.o rawenc.o
+OBJS-$(CONFIG_PMP_DEMUXER) += pmpdec.o
OBJS-$(CONFIG_PVA_DEMUXER) += pva.o
OBJS-$(CONFIG_QCP_DEMUXER) += qcp.o
OBJS-$(CONFIG_R3D_DEMUXER) += r3d.o
@@ -257,6 +275,7 @@ OBJS-$(CONFIG_SAP_DEMUXER) += sapdec.o
OBJS-$(CONFIG_SAP_MUXER) += sapenc.o rtpenc_chain.o
OBJS-$(CONFIG_SDP_DEMUXER) += rtsp.o
OBJS-$(CONFIG_SEGAFILM_DEMUXER) += segafilm.o
+OBJS-$(CONFIG_SEGMENT_MUXER) += segment.o
OBJS-$(CONFIG_SHORTEN_DEMUXER) += rawdec.o
OBJS-$(CONFIG_SIFF_DEMUXER) += siff.o
OBJS-$(CONFIG_SMACKER_DEMUXER) += smacker.o
@@ -294,16 +313,20 @@ OBJS-$(CONFIG_WEBM_MUXER) += matroskaenc.o matroska.o \
flacenc_header.o avlanguage.o
OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood.o
OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood.o
-OBJS-$(CONFIG_WTV_DEMUXER) += wtv.o asfdec.o asf.o asfcrypt.o \
+OBJS-$(CONFIG_WTV_DEMUXER) += wtvdec.o wtv.o asfdec.o asf.o asfcrypt.o \
avlanguage.o mpegts.o isom.o riff.o
+OBJS-$(CONFIG_WTV_MUXER) += wtvenc.o wtv.o asf.o riff.o
OBJS-$(CONFIG_WV_DEMUXER) += wv.o apetag.o
OBJS-$(CONFIG_XA_DEMUXER) += xa.o
+OBJS-$(CONFIG_XBIN_DEMUXER) += bintext.o sauce.o
+OBJS-$(CONFIG_XMV_DEMUXER) += xmv.o
OBJS-$(CONFIG_XWMA_DEMUXER) += xwma.o riff.o
OBJS-$(CONFIG_YOP_DEMUXER) += yop.o
OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER) += yuv4mpeg.o
OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER) += yuv4mpeg.o
# external libraries
+OBJS-$(CONFIG_LIBMODPLUG_DEMUXER) += libmodplug.o
OBJS-$(CONFIG_LIBNUT_DEMUXER) += libnut.o riff.o
OBJS-$(CONFIG_LIBNUT_MUXER) += libnut.o riff.o
@@ -311,6 +334,7 @@ OBJS-$(CONFIG_LIBNUT_MUXER) += libnut.o riff.o
OBJS+= avio.o aviobuf.o
OBJS-$(CONFIG_APPLEHTTP_PROTOCOL) += applehttpproto.o
+OBJS-$(CONFIG_CACHE_PROTOCOL) += cache.o
OBJS-$(CONFIG_CONCAT_PROTOCOL) += concat.o
OBJS-$(CONFIG_CRYPTO_PROTOCOL) += crypto.o
OBJS-$(CONFIG_FILE_PROTOCOL) += file.o
@@ -330,12 +354,8 @@ OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o
OBJS-$(CONFIG_TCP_PROTOCOL) += tcp.o
OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o
-# libavdevice dependencies
-OBJS-$(CONFIG_JACK_INDEV) += timefilter.o
-EXAMPLES = metadata output
-TESTPROGS = timefilter
+TESTPROGS = seek
+TOOLS = pktdumper probetest
include $(SRC_PATH)/subdir.mak
-
-$(SUBDIR)output-example$(EXESUF): ELIBS = -lswscale
diff --git a/libavformat/a64.c b/libavformat/a64.c
index 3d313e5fba..edab918129 100644
--- a/libavformat/a64.c
+++ b/libavformat/a64.c
@@ -2,20 +2,20 @@
* a64 muxer
* Copyright (c) 2009 Tobias Bindhammer
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -170,7 +170,7 @@ AVOutputFormat ff_a64_muxer = {
.extensions = "a64, A64",
.priv_data_size = sizeof (A64Context),
.video_codec = CODEC_ID_A64_MULTI,
- a64_write_header,
- a64_write_packet,
- a64_write_trailer
+ .write_header = a64_write_header,
+ .write_packet = a64_write_packet,
+ .write_trailer = a64_write_trailer
};
diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c
index 6a184c77d7..7df11bf95c 100644
--- a/libavformat/aacdec.c
+++ b/libavformat/aacdec.c
@@ -3,20 +3,20 @@
* Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2009 Robert Swain ( rob opendot cl )
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -47,6 +47,7 @@ static int adts_aac_probe(AVProbeData *p)
fsize = (AV_RB32(buf2 + 3) >> 13) & 0x1FFF;
if(fsize < 7)
break;
+ fsize = FFMIN(fsize, end - buf2);
buf2 += fsize;
}
max_frames = FFMAX(max_frames, frames);
@@ -65,7 +66,7 @@ static int adts_aac_read_header(AVFormatContext *s,
{
AVStream *st;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -82,12 +83,11 @@ static int adts_aac_read_header(AVFormatContext *s,
}
AVInputFormat ff_aac_demuxer = {
- "aac",
- NULL_IF_CONFIG_SMALL("raw ADTS AAC"),
- 0,
- adts_aac_probe,
- adts_aac_read_header,
- ff_raw_read_partial_packet,
+ .name = "aac",
+ .long_name = NULL_IF_CONFIG_SMALL("raw ADTS AAC"),
+ .read_probe = adts_aac_probe,
+ .read_header = adts_aac_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "aac",
.value = CODEC_ID_AAC,
diff --git a/libavformat/ac3dec.c b/libavformat/ac3dec.c
index 7ed01029dd..54d4fd2626 100644
--- a/libavformat/ac3dec.c
+++ b/libavformat/ac3dec.c
@@ -2,20 +2,20 @@
* RAW AC-3 and E-AC-3 demuxer
* Copyright (c) 2007 Justin Ruggles <justin.ruggles@gmail.com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -41,7 +41,7 @@ static int ac3_eac3_probe(AVProbeData *p, enum CodecID expected_codec_id)
for(frames = 0; buf2 < end; frames++) {
init_get_bits(&gbc, buf2, 54);
- if(ff_ac3_parse_header(&gbc, &hdr) < 0)
+ if(avpriv_ac3_parse_header(&gbc, &hdr) < 0)
break;
if(buf2 + hdr.frame_size > end ||
av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf2 + 2, hdr.frame_size - 2))
@@ -71,12 +71,11 @@ static int ac3_probe(AVProbeData *p)
}
AVInputFormat ff_ac3_demuxer = {
- "ac3",
- NULL_IF_CONFIG_SMALL("raw AC-3"),
- 0,
- ac3_probe,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
+ .name = "ac3",
+ .long_name = NULL_IF_CONFIG_SMALL("raw AC-3"),
+ .read_probe = ac3_probe,
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "ac3",
.value = CODEC_ID_AC3,
@@ -90,12 +89,11 @@ static int eac3_probe(AVProbeData *p)
}
AVInputFormat ff_eac3_demuxer = {
- "eac3",
- NULL_IF_CONFIG_SMALL("raw E-AC-3"),
- 0,
- eac3_probe,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
+ .name = "eac3",
+ .long_name = NULL_IF_CONFIG_SMALL("raw E-AC-3"),
+ .read_probe = eac3_probe,
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "eac3",
.value = CODEC_ID_EAC3,
diff --git a/libavformat/act.c b/libavformat/act.c
new file mode 100644
index 0000000000..8454cd1fc0
--- /dev/null
+++ b/libavformat/act.c
@@ -0,0 +1,207 @@
+/*
+ * ACT file format demuxer
+ * Copyright (c) 2007-2008 Vladimir Voroshilov
+ *
+ * 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 "avformat.h"
+#include "riff.h"
+#include "libavcodec/get_bits.h"
+
+#define CHUNK_SIZE 512
+#define RIFF_TAG MKTAG('R','I','F','F')
+#define WAVE_TAG MKTAG('W','A','V','E')
+
+typedef struct{
+ int bytes_left_in_chunk;
+ uint8_t audio_buffer[22];///< temporary buffer for ACT frame
+ char second_packet; ///< 1 - if temporary buffer contains valid (second) G.729 packet
+} ACTContext;
+
+static int probe(AVProbeData *p)
+{
+ int i;
+
+ if ((AV_RL32(&p->buf[0]) != RIFF_TAG) ||
+ (AV_RL32(&p->buf[8]) != WAVE_TAG) ||
+ (AV_RL32(&p->buf[16]) != 16))
+ return 0;
+
+ //We cant be sure that this is ACT and not regular WAV
+ if (p->buf_size<512)
+ return 0;
+
+ for(i=44; i<256; i++)
+ if(p->buf[i])
+ return 0;
+
+ if(p->buf[256]!=0x84)
+ return 0;
+
+ for(i=264; i<512; i++)
+ if(p->buf[i])
+ return 0;
+
+ return AVPROBE_SCORE_MAX;
+}
+
+static int read_header(AVFormatContext *s,
+ AVFormatParameters *ap)
+{
+ ACTContext* ctx = s->priv_data;
+ ByteIOContext *pb = s->pb;
+ int size;
+ AVStream* st;
+
+ int min,sec,msec;
+
+ st=av_new_stream(s, 0);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ url_fskip(pb, 16);
+ size=get_le32(pb);
+ ff_get_wav_header(pb, st->codec, size);
+
+ /*
+ 8000Hz (Fine-rec) file format has 10 bytes long
+ packets with 10ms of sound data in them
+ */
+ if (st->codec->sample_rate != 8000) {
+ av_log(s, AV_LOG_ERROR, "Sample rate %d is not supported.\n", st->codec->sample_rate);
+ return AVERROR_INVALIDDATA;
+ }
+
+ st->codec->frame_size=80;
+ st->codec->channels=1;
+ av_set_pts_info(st, 64, 1, 100);
+
+ st->codec->codec_id=CODEC_ID_G729;
+
+ url_fseek(pb, 257, SEEK_SET);
+ msec=get_le16(pb);
+ sec=get_byte(pb);
+ min=get_le32(pb);
+
+ st->duration = av_rescale(1000*(min*60+sec)+msec, st->codec->sample_rate, 1000 * st->codec->frame_size);
+
+ ctx->bytes_left_in_chunk=CHUNK_SIZE;
+
+ url_fseek(pb, 512, SEEK_SET);
+
+ return 0;
+}
+
+
+static int read_packet(AVFormatContext *s,
+ AVPacket *pkt)
+{
+ ACTContext *ctx = s->priv_data;
+ ByteIOContext *pb = s->pb;
+ int ret;
+ int frame_size=s->streams[0]->codec->sample_rate==8000?10:22;
+
+
+ if(s->streams[0]->codec->sample_rate==8000)
+ ret=av_new_packet(pkt, 10);
+ else
+ ret=av_new_packet(pkt, 11);
+
+ if(ret)
+ return ret;
+
+ if(s->streams[0]->codec->sample_rate==4400 && !ctx->second_packet)
+ {
+ ret = get_buffer(pb, ctx->audio_buffer, frame_size);
+
+ if(ret<0)
+ return ret;
+ if(ret!=frame_size)
+ return AVERROR(EIO);
+
+ pkt->data[0]=ctx->audio_buffer[11];
+ pkt->data[1]=ctx->audio_buffer[0];
+ pkt->data[2]=ctx->audio_buffer[12];
+ pkt->data[3]=ctx->audio_buffer[1];
+ pkt->data[4]=ctx->audio_buffer[13];
+ pkt->data[5]=ctx->audio_buffer[2];
+ pkt->data[6]=ctx->audio_buffer[14];
+ pkt->data[7]=ctx->audio_buffer[3];
+ pkt->data[8]=ctx->audio_buffer[15];
+ pkt->data[9]=ctx->audio_buffer[4];
+ pkt->data[10]=ctx->audio_buffer[16];
+
+ ctx->second_packet=1;
+ }
+ else if(s->streams[0]->codec->sample_rate==4400 && ctx->second_packet)
+ {
+ pkt->data[0]=ctx->audio_buffer[5];
+ pkt->data[1]=ctx->audio_buffer[17];
+ pkt->data[2]=ctx->audio_buffer[6];
+ pkt->data[3]=ctx->audio_buffer[18];
+ pkt->data[4]=ctx->audio_buffer[7];
+ pkt->data[5]=ctx->audio_buffer[19];
+ pkt->data[6]=ctx->audio_buffer[8];
+ pkt->data[7]=ctx->audio_buffer[20];
+ pkt->data[8]=ctx->audio_buffer[9];
+ pkt->data[9]=ctx->audio_buffer[21];
+ pkt->data[10]=ctx->audio_buffer[10];
+
+ ctx->second_packet=0;
+ }
+ else // 8000 Hz
+ {
+ ret = get_buffer(pb, ctx->audio_buffer, frame_size);
+
+ if(ret<0)
+ return ret;
+ if(ret!=frame_size)
+ return AVERROR(EIO);
+
+ pkt->data[0]=ctx->audio_buffer[5];
+ pkt->data[1]=ctx->audio_buffer[0];
+ pkt->data[2]=ctx->audio_buffer[6];
+ pkt->data[3]=ctx->audio_buffer[1];
+ pkt->data[4]=ctx->audio_buffer[7];
+ pkt->data[5]=ctx->audio_buffer[2];
+ pkt->data[6]=ctx->audio_buffer[8];
+ pkt->data[7]=ctx->audio_buffer[3];
+ pkt->data[8]=ctx->audio_buffer[9];
+ pkt->data[9]=ctx->audio_buffer[4];
+ }
+
+ ctx->bytes_left_in_chunk -= frame_size;
+
+ if(ctx->bytes_left_in_chunk < frame_size)
+ {
+ url_fskip(pb, ctx->bytes_left_in_chunk);
+ ctx->bytes_left_in_chunk=CHUNK_SIZE;
+ }
+
+ pkt->duration=1;
+
+ return ret;
+}
+
+AVInputFormat ff_act_demuxer = {
+ .name = "act",
+ .long_name = "ACT Voice file format",
+ .priv_data_size = sizeof(ACTContext),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
+};
diff --git a/libavformat/adts.h b/libavformat/adts.h
index 78b42c7101..1da57beff9 100644
--- a/libavformat/adts.h
+++ b/libavformat/adts.h
@@ -3,20 +3,20 @@
* Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@smartjog.com>
* Mans Rullgard <mans@mansr.com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/adtsenc.c b/libavformat/adtsenc.c
index e858a81d92..4b14b95ef4 100644
--- a/libavformat/adtsenc.c
+++ b/libavformat/adtsenc.c
@@ -3,20 +3,20 @@
* Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@smartjog.com>
* Mans Rullgard <mans@mansr.com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -35,7 +35,7 @@ int ff_adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf
int off;
init_get_bits(&gb, buf, size * 8);
- off = ff_mpeg4audio_get_config(&m4ac, buf, size);
+ off = avpriv_mpeg4audio_get_config(&m4ac, buf, size);
if (off < 0)
return off;
skip_bits_long(&gb, off);
@@ -59,11 +59,15 @@ int ff_adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf
av_log(s, AV_LOG_ERROR, "Scalable configurations are not allowed in ADTS\n");
return -1;
}
+ if (get_bits(&gb, 1)) {
+ av_log(s, AV_LOG_ERROR, "Extension flag is not allowed in ADTS\n");
+ return -1;
+ }
if (!adts->channel_conf) {
init_put_bits(&pb, adts->pce_data, MAX_PCE_SIZE);
put_bits(&pb, 3, 5); //ID_PCE
- adts->pce_size = (ff_copy_pce_data(&pb, &gb) + 3) / 8;
+ adts->pce_size = (avpriv_copy_pce_data(&pb, &gb) + 3) / 8;
flush_put_bits(&pb);
}
@@ -138,13 +142,13 @@ static int adts_write_packet(AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_adts_muxer = {
- "adts",
- NULL_IF_CONFIG_SMALL("ADTS AAC"),
- "audio/aac",
- "aac,adts",
- sizeof(ADTSContext),
- CODEC_ID_AAC,
- CODEC_ID_NONE,
- adts_write_header,
- adts_write_packet,
+ .name = "adts",
+ .long_name = NULL_IF_CONFIG_SMALL("ADTS AAC"),
+ .mime_type = "audio/aac",
+ .extensions = "aac,adts",
+ .priv_data_size = sizeof(ADTSContext),
+ .audio_codec = CODEC_ID_AAC,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = adts_write_header,
+ .write_packet = adts_write_packet,
};
diff --git a/libavformat/aea.c b/libavformat/aea.c
index c6dfbb1c83..9fac6c8de6 100644
--- a/libavformat/aea.c
+++ b/libavformat/aea.c
@@ -3,20 +3,20 @@
*
* Copyright (c) 2009 Benjamin Larsson
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -57,7 +57,7 @@ static int aea_read_probe(AVProbeData *p)
static int aea_read_header(AVFormatContext *s,
AVFormatParameters *ap)
{
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -95,14 +95,12 @@ static int aea_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_aea_demuxer = {
- "aea",
- NULL_IF_CONFIG_SMALL("MD STUDIO audio"),
- 0,
- aea_read_probe,
- aea_read_header,
- aea_read_packet,
- 0,
- pcm_read_seek,
+ .name = "aea",
+ .long_name = NULL_IF_CONFIG_SMALL("MD STUDIO audio"),
+ .read_probe = aea_read_probe,
+ .read_header = aea_read_header,
+ .read_packet = aea_read_packet,
+ .read_seek = pcm_read_seek,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "aea",
};
diff --git a/libavformat/aiff.h b/libavformat/aiff.h
index cd2bd256d6..047f81dc1d 100644
--- a/libavformat/aiff.h
+++ b/libavformat/aiff.h
@@ -2,20 +2,20 @@
* AIFF/AIFF-C muxer/demuxer common header
* Copyright (c) 2006 Patrick Guimond
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c
index 0e815421a7..eee9a1c483 100644
--- a/libavformat/aiffdec.c
+++ b/libavformat/aiffdec.c
@@ -2,20 +2,20 @@
* AIFF/AIFF-C demuxer
* Copyright (c) 2006 Patrick Guimond
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -24,6 +24,7 @@
#include "avformat.h"
#include "pcm.h"
#include "aiff.h"
+#include "isom.h"
#define AIFF 0
#define AIFF_C_VERSION1 0xA2805140
@@ -52,7 +53,7 @@ static int get_tag(AVIOContext *pb, uint32_t * tag)
{
int size;
- if (pb->eof_reached)
+ if (url_feof(pb))
return AVERROR(EIO);
*tag = avio_rl32(pb);
@@ -68,19 +69,20 @@ static int get_tag(AVIOContext *pb, uint32_t * tag)
static void get_meta(AVFormatContext *s, const char *key, int size)
{
uint8_t *str = av_malloc(size+1);
- int res;
- if (!str) {
- avio_skip(s->pb, size);
- return;
- }
-
- res = avio_read(s->pb, str, size);
- if (res < 0)
- return;
+ if (str) {
+ int res = avio_read(s->pb, str, size);
+ if (res < 0){
+ av_free(str);
+ return;
+ }
+ size += (size&1)-res;
+ str[res] = 0;
+ av_dict_set(&s->metadata, key, str, AV_METADATA_DONT_STRDUP_VAL);
+ }else
+ size+= size&1;
- str[res] = 0;
- av_dict_set(&s->metadata, key, str, AV_DICT_DONT_STRDUP_VAL);
+ avio_skip(s->pb, size);
}
/* Returns the number of sound data frames or negative on error */
@@ -196,7 +198,7 @@ static int aiff_read_header(AVFormatContext *s,
filesize -= 4;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -254,6 +256,11 @@ static int aiff_read_header(AVFormatContext *s,
st->codec->extradata_size = size;
avio_read(pb, st->codec->extradata, size);
break;
+ case MKTAG('C','H','A','N'):
+ if (size < 12)
+ return AVERROR_INVALIDDATA;
+ ff_mov_read_chan(s, size, st->codec);
+ break;
default: /* Jump */
if (size & 1) /* Always even aligned */
size++;
@@ -268,9 +275,6 @@ static int aiff_read_header(AVFormatContext *s,
got_sound:
/* Now positioned, get the sound data start and end */
- if (st->nb_frames)
- s->file_size = st->nb_frames * st->codec->block_align;
-
av_set_pts_info(st, 64, 1, st->codec->sample_rate);
st->start_time = 0;
st->duration = st->codec->frame_size ?
@@ -313,13 +317,12 @@ static int aiff_read_packet(AVFormatContext *s,
}
AVInputFormat ff_aiff_demuxer = {
- "aiff",
- NULL_IF_CONFIG_SMALL("Audio IFF"),
- sizeof(AIFFInputContext),
- aiff_probe,
- aiff_read_header,
- aiff_read_packet,
- NULL,
- pcm_read_seek,
+ .name = "aiff",
+ .long_name = NULL_IF_CONFIG_SMALL("Audio IFF"),
+ .priv_data_size = sizeof(AIFFInputContext),
+ .read_probe = aiff_probe,
+ .read_header = aiff_read_header,
+ .read_packet = aiff_read_packet,
+ .read_seek = pcm_read_seek,
.codec_tag= (const AVCodecTag* const []){ff_codec_aiff_tags, 0},
};
diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
index 5a64688483..3b2fc38160 100644
--- a/libavformat/aiffenc.c
+++ b/libavformat/aiffenc.c
@@ -2,20 +2,20 @@
* AIFF/AIFF-C muxer
* Copyright (c) 2006 Patrick Guimond
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -23,6 +23,7 @@
#include "avformat.h"
#include "aiff.h"
#include "avio_internal.h"
+#include "isom.h"
typedef struct {
int64_t form;
@@ -62,6 +63,12 @@ static int aiff_write_header(AVFormatContext *s)
avio_wb32(pb, 0xA2805140);
}
+ if (enc->channels > 2 && enc->channel_layout) {
+ ffio_wfourcc(pb, "CHAN");
+ avio_wb32(pb, 12);
+ ff_mov_write_chan(pb, enc->channel_layout);
+ }
+
/* Common chunk */
ffio_wfourcc(pb, "COMM");
avio_wb32(pb, aifc ? 24 : 18); /* size */
@@ -148,15 +155,15 @@ static int aiff_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_aiff_muxer = {
- "aiff",
- NULL_IF_CONFIG_SMALL("Audio IFF"),
- "audio/aiff",
- "aif,aiff,afc,aifc",
- sizeof(AIFFOutputContext),
- CODEC_ID_PCM_S16BE,
- CODEC_ID_NONE,
- aiff_write_header,
- aiff_write_packet,
- aiff_write_trailer,
+ .name = "aiff",
+ .long_name = NULL_IF_CONFIG_SMALL("Audio IFF"),
+ .mime_type = "audio/aiff",
+ .extensions = "aif,aiff,afc,aifc",
+ .priv_data_size = sizeof(AIFFOutputContext),
+ .audio_codec = CODEC_ID_PCM_S16BE,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = aiff_write_header,
+ .write_packet = aiff_write_packet,
+ .write_trailer = aiff_write_trailer,
.codec_tag= (const AVCodecTag* const []){ff_codec_aiff_tags, 0},
};
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index f1c3d3b768..7e0e9cef52 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -2,20 +2,20 @@
* Register all the formats and protocols
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
@@ -51,6 +51,8 @@ void av_register_all(void)
REGISTER_MUXER (A64, a64);
REGISTER_DEMUXER (AAC, aac);
REGISTER_MUXDEMUX (AC3, ac3);
+ REGISTER_DEMUXER (ACT, act);
+ REGISTER_DEMUXER (ADF, adf);
REGISTER_MUXER (ADTS, adts);
REGISTER_DEMUXER (AEA, aea);
REGISTER_MUXDEMUX (AIFF, aiff);
@@ -69,9 +71,11 @@ void av_register_all(void)
REGISTER_DEMUXER (AVS, avs);
REGISTER_DEMUXER (BETHSOFTVID, bethsoftvid);
REGISTER_DEMUXER (BFI, bfi);
+ REGISTER_DEMUXER (BINTEXT, bintext);
REGISTER_DEMUXER (BINK, bink);
+ REGISTER_MUXDEMUX (BIT, bit);
REGISTER_DEMUXER (C93, c93);
- REGISTER_DEMUXER (CAF, caf);
+ REGISTER_MUXDEMUX (CAF, caf);
REGISTER_MUXDEMUX (CAVSVIDEO, cavsvideo);
REGISTER_DEMUXER (CDG, cdg);
REGISTER_MUXER (CRC, crc);
@@ -96,6 +100,7 @@ void av_register_all(void)
REGISTER_MUXER (FRAMECRC, framecrc);
REGISTER_MUXER (FRAMEMD5, framemd5);
REGISTER_MUXDEMUX (G722, g722);
+ REGISTER_MUXDEMUX (G723_1, g723_1);
REGISTER_MUXER (GIF, gif);
REGISTER_DEMUXER (GSM, gsm);
REGISTER_MUXDEMUX (GXF, gxf);
@@ -103,6 +108,7 @@ void av_register_all(void)
REGISTER_MUXDEMUX (H263, h263);
REGISTER_MUXDEMUX (H264, h264);
REGISTER_DEMUXER (IDCIN, idcin);
+ REGISTER_DEMUXER (IDF, idf);
REGISTER_DEMUXER (IFF, iff);
REGISTER_MUXDEMUX (IMAGE2, image2);
REGISTER_MUXDEMUX (IMAGE2PIPE, image2pipe);
@@ -113,12 +119,15 @@ void av_register_all(void)
REGISTER_DEMUXER (IV8, iv8);
REGISTER_MUXDEMUX (IVF, ivf);
REGISTER_DEMUXER (JV, jv);
+ REGISTER_MUXDEMUX (LATM, latm);
REGISTER_DEMUXER (LMLM4, lmlm4);
+ REGISTER_DEMUXER (LOAS, loas);
REGISTER_DEMUXER (LXF, lxf);
REGISTER_MUXDEMUX (M4V, m4v);
REGISTER_MUXER (MD5, md5);
REGISTER_MUXDEMUX (MATROSKA, matroska);
REGISTER_MUXER (MATROSKA_AUDIO, matroska_audio);
+ REGISTER_MUXDEMUX (MICRODVD, microdvd);
REGISTER_MUXDEMUX (MJPEG, mjpeg);
REGISTER_MUXDEMUX (MLP, mlp);
REGISTER_DEMUXER (MM, mm);
@@ -174,6 +183,7 @@ void av_register_all(void)
REGISTER_MUXDEMUX (PCM_U16BE, pcm_u16be);
REGISTER_MUXDEMUX (PCM_U16LE, pcm_u16le);
REGISTER_MUXDEMUX (PCM_U8, pcm_u8);
+ REGISTER_DEMUXER (PMP, pmp);
REGISTER_MUXER (PSP, psp);
REGISTER_DEMUXER (PVA, pva);
REGISTER_DEMUXER (QCP, qcp);
@@ -193,6 +203,7 @@ void av_register_all(void)
av_register_rdt_dynamic_payload_handlers();
#endif
REGISTER_DEMUXER (SEGAFILM, segafilm);
+ REGISTER_MUXER (SEGMENT, segment);
REGISTER_DEMUXER (SHORTEN, shorten);
REGISTER_DEMUXER (SIFF, siff);
REGISTER_DEMUXER (SMACKER, smacker);
@@ -222,18 +233,24 @@ void av_register_all(void)
REGISTER_MUXER (WEBM, webm);
REGISTER_DEMUXER (WSAUD, wsaud);
REGISTER_DEMUXER (WSVQA, wsvqa);
- REGISTER_DEMUXER (WTV, wtv);
+ REGISTER_MUXDEMUX (WTV, wtv);
REGISTER_DEMUXER (WV, wv);
REGISTER_DEMUXER (XA, xa);
+ REGISTER_DEMUXER (XBIN, xbin);
+ REGISTER_DEMUXER (XMV, xmv);
REGISTER_DEMUXER (XWMA, xwma);
REGISTER_DEMUXER (YOP, yop);
REGISTER_MUXDEMUX (YUV4MPEGPIPE, yuv4mpegpipe);
/* external libraries */
+#if CONFIG_LIBMODPLUG
+ REGISTER_DEMUXER (LIBMODPLUG, libmodplug);
+#endif
REGISTER_MUXDEMUX (LIBNUT, libnut);
/* protocols */
REGISTER_PROTOCOL (APPLEHTTP, applehttp);
+ REGISTER_PROTOCOL (CACHE, cache);
REGISTER_PROTOCOL (CONCAT, concat);
REGISTER_PROTOCOL (CRYPTO, crypto);
REGISTER_PROTOCOL (FILE, file);
diff --git a/libavformat/amr.c b/libavformat/amr.c
index 260bd6ada6..8c3b1416c8 100644
--- a/libavformat/amr.c
+++ b/libavformat/amr.c
@@ -2,20 +2,20 @@
* amr file format
* Copyright (c) 2001 ffmpeg project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -84,7 +84,7 @@ static int amr_read_header(AVFormatContext *s,
avio_read(pb, header, 6);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
{
return AVERROR(ENOMEM);
@@ -123,7 +123,7 @@ static int amr_read_packet(AVFormatContext *s,
int read, size = 0, toc, mode;
int64_t pos = avio_tell(s->pb);
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
{
return AVERROR(EIO);
}
@@ -174,27 +174,25 @@ static int amr_read_packet(AVFormatContext *s,
#if CONFIG_AMR_DEMUXER
AVInputFormat ff_amr_demuxer = {
- "amr",
- NULL_IF_CONFIG_SMALL("3GPP AMR file format"),
- 0, /*priv_data_size*/
- amr_probe,
- amr_read_header,
- amr_read_packet,
- NULL,
+ .name = "amr",
+ .long_name = NULL_IF_CONFIG_SMALL("3GPP AMR file format"),
+ .priv_data_size = 0, /*priv_data_size*/
+ .read_probe = amr_probe,
+ .read_header = amr_read_header,
+ .read_packet = amr_read_packet,
.flags = AVFMT_GENERIC_INDEX,
};
#endif
#if CONFIG_AMR_MUXER
AVOutputFormat ff_amr_muxer = {
- "amr",
- NULL_IF_CONFIG_SMALL("3GPP AMR file format"),
- "audio/amr",
- "amr",
- 0,
- CODEC_ID_AMR_NB,
- CODEC_ID_NONE,
- amr_write_header,
- amr_write_packet,
+ .name = "amr",
+ .long_name = NULL_IF_CONFIG_SMALL("3GPP AMR file format"),
+ .mime_type = "audio/amr",
+ .extensions = "amr",
+ .audio_codec = CODEC_ID_AMR_NB,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = amr_write_header,
+ .write_packet = amr_write_packet,
};
#endif
diff --git a/libavformat/anm.c b/libavformat/anm.c
index 4d1b5f7620..99864f6b54 100644
--- a/libavformat/anm.c
+++ b/libavformat/anm.c
@@ -2,20 +2,20 @@
* Deluxe Paint Animation demuxer
* Copyright (c) 2009 Peter Ross
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -97,7 +97,7 @@ static int read_header(AVFormatContext *s,
return AVERROR_INVALIDDATA;
/* video stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -134,18 +134,17 @@ static int read_header(AVFormatContext *s,
/* color cycling and palette data */
st->codec->extradata_size = 16*8 + 4*256;
st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
- if (!st->codec->extradata) {
- ret = AVERROR(ENOMEM);
- goto close_and_return;
- }
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+
ret = avio_read(pb, st->codec->extradata, st->codec->extradata_size);
if (ret < 0)
- goto close_and_return;
+ return ret;
/* read page table */
ret = avio_seek(pb, anm->page_table_offset, SEEK_SET);
if (ret < 0)
- goto close_and_return;
+ return ret;
for (i = 0; i < MAX_PAGES; i++) {
Page *p = &anm->pt[i];
@@ -156,21 +155,15 @@ static int read_header(AVFormatContext *s,
/* find page of first frame */
anm->page = find_record(anm, 0);
- if (anm->page < 0) {
- ret = anm->page;
- goto close_and_return;
- }
+ if (anm->page < 0)
+ return anm->page;
anm->record = -1;
return 0;
invalid:
av_log_ask_for_sample(s, NULL);
- ret = AVERROR_INVALIDDATA;
-
-close_and_return:
- av_close_input_stream(s);
- return ret;
+ return AVERROR_INVALIDDATA;
}
static int read_packet(AVFormatContext *s,
@@ -181,7 +174,7 @@ static int read_packet(AVFormatContext *s,
Page *p;
int tmp, record_size;
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR(EIO);
if (anm->page < 0)
@@ -226,10 +219,10 @@ repeat:
}
AVInputFormat ff_anm_demuxer = {
- "anm",
- NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"),
- sizeof(AnmDemuxContext),
- probe,
- read_header,
- read_packet,
+ .name = "anm",
+ .long_name = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"),
+ .priv_data_size = sizeof(AnmDemuxContext),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
};
diff --git a/libavformat/apc.c b/libavformat/apc.c
index 40c6f0c4ac..5d7bb6f31c 100644
--- a/libavformat/apc.c
+++ b/libavformat/apc.c
@@ -2,20 +2,20 @@
* CRYO APC audio format demuxer
* Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -39,7 +39,7 @@ static int apc_read_header(AVFormatContext *s, AVFormatParameters *ap)
avio_rl32(pb); /* _APC */
avio_rl32(pb); /* 1.20 */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -81,10 +81,9 @@ static int apc_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_apc_demuxer = {
- "apc",
- NULL_IF_CONFIG_SMALL("CRYO APC format"),
- 0,
- apc_probe,
- apc_read_header,
- apc_read_packet,
+ .name = "apc",
+ .long_name = NULL_IF_CONFIG_SMALL("CRYO APC format"),
+ .read_probe = apc_probe,
+ .read_header = apc_read_header,
+ .read_packet = apc_read_packet,
};
diff --git a/libavformat/ape.c b/libavformat/ape.c
index 90b02619e0..93c22af6a2 100644
--- a/libavformat/ape.c
+++ b/libavformat/ape.c
@@ -3,20 +3,20 @@
* Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
* based upon libdemac from Dave Chapman.
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -129,9 +129,11 @@ static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx)
} else {
for (i = 0; i < ape_ctx->seektablelength / sizeof(uint32_t); i++) {
if (i < ape_ctx->totalframes - 1) {
- av_log(s, AV_LOG_DEBUG, "%8d %d (%d bytes)\n", i, ape_ctx->seektable[i], ape_ctx->seektable[i + 1] - ape_ctx->seektable[i]);
+ av_log(s, AV_LOG_DEBUG, "%8d %"PRIu32" (%"PRIu32" bytes)\n",
+ i, ape_ctx->seektable[i],
+ ape_ctx->seektable[i + 1] - ape_ctx->seektable[i]);
} else {
- av_log(s, AV_LOG_DEBUG, "%8d %d\n", i, ape_ctx->seektable[i]);
+ av_log(s, AV_LOG_DEBUG, "%8d %"PRIu32"\n", i, ape_ctx->seektable[i]);
}
}
}
@@ -169,7 +171,7 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
ape->fileversion = avio_rl16(pb);
if (ape->fileversion < APE_MIN_VERSION || ape->fileversion > APE_MAX_VERSION) {
- av_log(s, AV_LOG_ERROR, "Unsupported file version - %"PRId16".%02"PRId16"\n",
+ av_log(s, AV_LOG_ERROR, "Unsupported file version - %d.%02d\n",
ape->fileversion / 1000, (ape->fileversion % 1000) / 10);
return -1;
}
@@ -253,7 +255,8 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
return -1;
}
if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) {
- av_log(s, AV_LOG_ERROR, "Number of seek entries is less than number of frames: %ld vs. %"PRIu32"\n",
+ av_log(s, AV_LOG_ERROR,
+ "Number of seek entries is less than number of frames: %zu vs. %"PRIu32"\n",
ape->seektablelength / sizeof(*ape->seektable), ape->totalframes);
return AVERROR_INVALIDDATA;
}
@@ -270,6 +273,8 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
if (ape->seektablelength > 0) {
ape->seektable = av_malloc(ape->seektablelength);
+ if (!ape->seektable)
+ return AVERROR(ENOMEM);
for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++)
ape->seektable[i] = avio_rl32(pb);
}
@@ -308,7 +313,7 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
ape->compressiontype);
/* now we are ready: build format streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
@@ -350,7 +355,7 @@ static int ape_read_packet(AVFormatContext * s, AVPacket * pkt)
APEContext *ape = s->priv_data;
uint32_t extra_size = 8;
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR(EIO);
if (ape->currentframe > ape->totalframes)
return AVERROR(EIO);
@@ -405,13 +410,13 @@ static int ape_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
}
AVInputFormat ff_ape_demuxer = {
- "ape",
- NULL_IF_CONFIG_SMALL("Monkey's Audio"),
- sizeof(APEContext),
- ape_probe,
- ape_read_header,
- ape_read_packet,
- ape_read_close,
- ape_read_seek,
+ .name = "ape",
+ .long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
+ .priv_data_size = sizeof(APEContext),
+ .read_probe = ape_probe,
+ .read_header = ape_read_header,
+ .read_packet = ape_read_packet,
+ .read_close = ape_read_close,
+ .read_seek = ape_read_seek,
.extensions = "ape,apl,mac"
};
diff --git a/libavformat/apetag.c b/libavformat/apetag.c
index 257ed48970..8d53e4cdf7 100644
--- a/libavformat/apetag.c
+++ b/libavformat/apetag.c
@@ -3,20 +3,20 @@
* Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
* based upon libdemac from Dave Chapman.
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/apetag.h b/libavformat/apetag.h
index 9a39d02a2b..8aaef68c38 100644
--- a/libavformat/apetag.h
+++ b/libavformat/apetag.h
@@ -3,20 +3,20 @@
* Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
* based upon libdemac from Dave Chapman.
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c
index 7e0c930271..432bf4ebcc 100644
--- a/libavformat/applehttp.c
+++ b/libavformat/applehttp.c
@@ -2,20 +2,20 @@
* Apple HTTP Live Streaming demuxer
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -223,7 +223,7 @@ static int parse_playlist(AppleHTTPContext *c, const char *url,
free_segment_list(var);
var->finished = 0;
}
- while (!in->eof_reached) {
+ while (!url_feof(in)) {
read_chomp_line(in, line, sizeof(line));
if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
struct variant_info info = {{0}};
@@ -350,8 +350,8 @@ static int open_input(struct variant *var)
snprintf(url, sizeof(url), "crypto:%s", seg->url);
if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ)) < 0)
return ret;
- av_set_string3(var->input->priv_data, "key", key, 0, NULL);
- av_set_string3(var->input->priv_data, "iv", iv, 0, NULL);
+ av_opt_set(var->input->priv_data, "key", key, 0);
+ av_opt_set(var->input->priv_data, "iv", iv, 0);
if ((ret = ffurl_connect(var->input)) < 0) {
ffurl_close(var->input);
var->input = NULL;
@@ -412,7 +412,7 @@ reload:
c->end_of_segment = 1;
c->cur_seq_no = v->cur_seq_no;
- if (v->ctx) {
+ if (v->ctx && v->ctx->nb_streams) {
v->needed = 0;
for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
i++) {
@@ -505,11 +505,12 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);
/* Create new AVStreams for each stream in this variant */
for (j = 0; j < v->ctx->nb_streams; j++) {
- AVStream *st = av_new_stream(s, i);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st) {
ret = AVERROR(ENOMEM);
goto fail;
}
+ st->id = i;
avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);
if (v->bandwidth)
av_dict_set(&st->metadata, "variant_bitrate", bitrate_str,
@@ -580,7 +581,7 @@ start:
if (var->needed && !var->pkt.data) {
ret = av_read_frame(var->ctx, &var->pkt);
if (ret < 0) {
- if (!var->pb.eof_reached)
+ if (!url_feof(&var->pb))
return ret;
reset_packet(&var->pkt);
}
@@ -668,12 +669,12 @@ static int applehttp_probe(AVProbeData *p)
}
AVInputFormat ff_applehttp_demuxer = {
- "applehttp",
- NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming format"),
- sizeof(AppleHTTPContext),
- applehttp_probe,
- applehttp_read_header,
- applehttp_read_packet,
- applehttp_close,
- applehttp_read_seek,
+ .name = "applehttp",
+ .long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming format"),
+ .priv_data_size = sizeof(AppleHTTPContext),
+ .read_probe = applehttp_probe,
+ .read_header = applehttp_read_header,
+ .read_packet = applehttp_read_packet,
+ .read_close = applehttp_close,
+ .read_seek = applehttp_read_seek,
};
diff --git a/libavformat/applehttpproto.c b/libavformat/applehttpproto.c
index 85f3cfcef4..bb5029d82f 100644
--- a/libavformat/applehttpproto.c
+++ b/libavformat/applehttpproto.c
@@ -2,20 +2,20 @@
* Apple HTTP Live Streaming Protocol Handler
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -123,7 +123,7 @@ static int parse_playlist(URLContext *h, const char *url)
free_segment_list(s);
s->finished = 0;
- while (!in->eof_reached) {
+ while (!url_feof(in)) {
read_chomp_line(in, line, sizeof(line));
if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
struct variant_info info = {{0}};
diff --git a/libavformat/asf.c b/libavformat/asf.c
index cc2833ddf6..1f6af18b29 100644
--- a/libavformat/asf.c
+++ b/libavformat/asf.c
@@ -1,20 +1,20 @@
/*
* Copyright (c) 2000, 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/asf.h b/libavformat/asf.h
index b72445def9..3f6783bf5a 100644
--- a/libavformat/asf.h
+++ b/libavformat/asf.h
@@ -1,20 +1,20 @@
/*
* Copyright (c) 2000, 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -24,6 +24,7 @@
#include <stdint.h>
#include "avformat.h"
#include "metadata.h"
+#include "riff.h"
#define PACKET_SIZE 3200
@@ -48,8 +49,6 @@ typedef struct {
uint32_t palette[256];
} ASFStream;
-typedef uint8_t ff_asf_guid[16];
-
typedef struct {
ff_asf_guid guid; ///< generated by client computer
uint64_t file_size; /**< in bytes
@@ -175,11 +174,4 @@ extern const AVMetadataConv ff_asf_metadata_conv[];
extern AVInputFormat ff_asf_demuxer;
-static av_always_inline int ff_guidcmp(const void *g1, const void *g2)
-{
- return memcmp(g1, g2, sizeof(ff_asf_guid));
-}
-
-void ff_get_guid(AVIOContext *s, ff_asf_guid *g);
-
#endif /* AVFORMAT_ASF_H */
diff --git a/libavformat/asfcrypt.c b/libavformat/asfcrypt.c
index aea3d4f345..750758d822 100644
--- a/libavformat/asfcrypt.c
+++ b/libavformat/asfcrypt.c
@@ -3,20 +3,20 @@
* Copyright (c) 2007 Reimar Doeffinger
* This is a rewrite of code contained in freeme/freeme2
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/asfcrypt.h b/libavformat/asfcrypt.h
index 53388b426e..8b80d63c5d 100644
--- a/libavformat/asfcrypt.h
+++ b/libavformat/asfcrypt.h
@@ -2,20 +2,20 @@
* ASF decryption
* Copyright (c) 2007 Reimar Doeffinger
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index ac559a0edd..6af4439e87 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -2,20 +2,20 @@
* ASF compatible demuxer
* Copyright (c) 2000, 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -132,12 +132,6 @@ static void print_guid(const ff_asf_guid *g)
#define print_guid(g)
#endif
-void ff_get_guid(AVIOContext *s, ff_asf_guid *g)
-{
- assert(sizeof(*g) == 16);
- avio_read(s, *g, sizeof(*g));
-}
-
static int asf_probe(AVProbeData *pd)
{
/* check file header */
@@ -171,6 +165,9 @@ static void get_tag(AVFormatContext *s, const char *key, int type, int len)
if (type == 0) { // UTF16-LE
avio_get_str16le(s->pb, len, value, 2*len + 1);
+ } else if (type == -1) { // ASCII
+ get_buffer(s->pb, value, len);
+ value[len]=0;
} else if (type > 1 && type <= 5) { // boolean or DWORD or QWORD or WORD
uint64_t num = get_value(s->pb, type);
snprintf(value, len, "%"PRIu64, num);
@@ -227,7 +224,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
pos1 = avio_tell(pb);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
@@ -235,7 +232,6 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
if (!asf_st)
return AVERROR(ENOMEM);
st->priv_data = asf_st;
- st->start_time = 0;
start_time = asf->hdr.preroll;
asf_st->stream_language_index = 128; // invalid stream index means no language info
@@ -294,7 +290,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
if (is_dvr_ms_audio) {
// codec_id and codec_tag are unreliable in dvr_ms
// files. Set them later by probing stream.
- st->codec->codec_id = CODEC_ID_PROBE;
+ st->request_probe= 1;
st->codec->codec_tag = 0;
}
if (st->codec->codec_id == CODEC_ID_AAC) {
@@ -573,7 +569,7 @@ static int asf_read_marker(AVFormatContext *s, int64_t size)
name_len = avio_rl32(pb); // name length
if ((ret = avio_get_str16le(pb, name_len * 2, name, sizeof(name))) < name_len)
avio_skip(pb, name_len - ret);
- ff_new_chapter(s, i, (AVRational){1, 10000000}, pres_time, AV_NOPTS_VALUE, name );
+ avpriv_new_chapter(s, i, (AVRational){1, 10000000}, pres_time, AV_NOPTS_VALUE, name );
}
return 0;
@@ -638,16 +634,28 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
continue;
} else if (!ff_guidcmp(&g, &ff_asf_marker_header)) {
asf_read_marker(s, gsize);
- } else if (pb->eof_reached) {
+ } else if (url_feof(pb)) {
return -1;
} else {
if (!s->keylen) {
if (!ff_guidcmp(&g, &ff_asf_content_encryption)) {
+ unsigned int len;
+ AVPacket pkt;
av_log(s, AV_LOG_WARNING, "DRM protected stream detected, decoding will likely fail!\n");
+ len= avio_rl32(pb);
+ av_log(s, AV_LOG_DEBUG, "Secret data:\n");
+ av_get_packet(pb, &pkt, len); av_hex_dump_log(s, AV_LOG_DEBUG, pkt.data, pkt.size); av_free_packet(&pkt);
+ len= avio_rl32(pb);
+ get_tag(s, "ASF_Protection_Type", -1, len);
+ len= avio_rl32(pb);
+ get_tag(s, "ASF_Key_ID", -1, len);
+ len= avio_rl32(pb);
+ get_tag(s, "ASF_License_URL", -1, len);
} else if (!ff_guidcmp(&g, &ff_asf_ext_content_encryption)) {
av_log(s, AV_LOG_WARNING, "Ext DRM protected stream detected, decoding will likely fail!\n");
+ av_dict_set(&s->metadata, "encryption", "ASF Extended Content Encryption", 0);
} else if (!ff_guidcmp(&g, &ff_asf_digital_signature)) {
- av_log(s, AV_LOG_WARNING, "Digital signature detected, decoding will likely fail!\n");
+ av_log(s, AV_LOG_INFO, "Digital signature detected!\n");
}
}
}
@@ -659,7 +667,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
avio_rl64(pb);
avio_r8(pb);
avio_r8(pb);
- if (pb->eof_reached)
+ if (url_feof(pb))
return -1;
asf->data_offset = avio_tell(pb);
asf->packet_size_left = 0;
@@ -744,12 +752,12 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
*/
if (pb->error == AVERROR(EAGAIN))
return AVERROR(EAGAIN);
- if (!pb->eof_reached)
+ if (!url_feof(pb))
av_log(s, AV_LOG_ERROR, "ff asf bad header %x at:%"PRId64"\n", c, avio_tell(pb));
}
if ((c & 0x8f) == 0x82) {
if (d || e) {
- if (!pb->eof_reached)
+ if (!url_feof(pb))
av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");
return -1;
}
@@ -848,6 +856,10 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", asf->packet_replic_size);
return -1;
}
+ if (rsize > asf->packet_size_left) {
+ av_log(s, AV_LOG_ERROR, "packet_replic_size is invalid\n");
+ return -1;
+ }
if (asf->packet_flags & 0x01) {
DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal
if (rsize > asf->packet_size_left) {
@@ -865,10 +877,6 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
}
//printf("Fragsize %d\n", asf->packet_frag_size);
} else {
- if (rsize > asf->packet_size_left) {
- av_log(s, AV_LOG_ERROR, "packet_replic_size is invalid\n");
- return -1;
- }
asf->packet_frag_size = asf->packet_size_left - rsize;
//printf("Using rest %d %d %d\n", asf->packet_frag_size, asf->packet_size_left, rsize);
}
@@ -898,7 +906,7 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
ASFStream *asf_st = 0;
for (;;) {
int ret;
- if(pb->eof_reached)
+ if(url_feof(pb))
return AVERROR_EOF;
if (asf->packet_size_left < FRAME_HEADER_SIZE
|| asf->packet_segments < 1) {
@@ -1162,7 +1170,8 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos,
if (s->packet_size > 0)
pos= (pos+s->packet_size-1-s->data_offset)/s->packet_size*s->packet_size+ s->data_offset;
*ppos= pos;
- avio_seek(s->pb, pos, SEEK_SET);
+ if (avio_seek(s->pb, pos, SEEK_SET) < 0)
+ return AV_NOPTS_VALUE;
//printf("asf_read_pts\n");
asf_reset_header(s);
@@ -1204,15 +1213,20 @@ static void asf_build_simple_index(AVFormatContext *s, int stream_index)
int64_t current_pos= avio_tell(s->pb);
int i;
- avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET);
+ if(avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET) < 0) {
+ asf->index_read= -1;
+ return;
+ }
+
ff_get_guid(s->pb, &g);
/* the data object can be followed by other top-level objects,
skip them until the simple index object is reached */
while (ff_guidcmp(&g, &index_guid)) {
int64_t gsize= avio_rl64(s->pb);
- if (gsize < 24 || s->pb->eof_reached) {
+ if (gsize < 24 || url_feof(s->pb)) {
avio_seek(s->pb, current_pos, SEEK_SET);
+ asf->index_read= -1;
return;
}
avio_skip(s->pb, gsize-24);
@@ -1268,7 +1282,7 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int
if (!asf->index_read)
asf_build_simple_index(s, stream_index);
- if((asf->index_read && st->index_entries)){
+ if((asf->index_read > 0 && st->index_entries)){
index= av_index_search_timestamp(st, pts, flags);
if(index >= 0) {
/* find the position */
@@ -1276,7 +1290,8 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int
/* do the seek */
av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos);
- avio_seek(s->pb, pos, SEEK_SET);
+ if(avio_seek(s->pb, pos, SEEK_SET) < 0)
+ return -1;
asf_reset_header(s);
return 0;
}
@@ -1289,14 +1304,14 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int
}
AVInputFormat ff_asf_demuxer = {
- "asf",
- NULL_IF_CONFIG_SMALL("ASF format"),
- sizeof(ASFContext),
- asf_probe,
- asf_read_header,
- asf_read_packet,
- asf_read_close,
- asf_read_seek,
- asf_read_pts,
+ .name = "asf",
+ .long_name = NULL_IF_CONFIG_SMALL("ASF format"),
+ .priv_data_size = sizeof(ASFContext),
+ .read_probe = asf_probe,
+ .read_header = asf_read_header,
+ .read_packet = asf_read_packet,
+ .read_close = asf_read_close,
+ .read_seek = asf_read_seek,
+ .read_timestamp = asf_read_pts,
.flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH,
};
diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c
index f9b9b3c045..5c6a81fb71 100644
--- a/libavformat/asfenc.c
+++ b/libavformat/asfenc.c
@@ -2,20 +2,20 @@
* ASF muxer
* Copyright (c) 2000, 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
@@ -199,8 +199,8 @@ typedef struct {
/* packet filling */
unsigned char multi_payloads_present;
int packet_size_left;
- int packet_timestamp_start;
- int packet_timestamp_end;
+ int64_t packet_timestamp_start;
+ int64_t packet_timestamp_end;
unsigned int packet_nb_payloads;
uint8_t packet_buf[PACKET_SIZE];
AVIOContext pb;
@@ -215,8 +215,8 @@ typedef struct {
} ASFContext;
static const AVCodecTag codec_asf_bmp_tags[] = {
- { CODEC_ID_MPEG4, MKTAG('M', 'P', '4', 'S') },
{ CODEC_ID_MPEG4, MKTAG('M', '4', 'S', '2') },
+ { CODEC_ID_MPEG4, MKTAG('M', 'P', '4', 'S') },
{ CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') },
{ CODEC_ID_NONE, 0 },
};
@@ -434,10 +434,6 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
/* WAVEFORMATEX header */
int wavsize = ff_put_wav_header(pb, enc);
- if ((enc->codec_id != CODEC_ID_MP3) && (enc->codec_id != CODEC_ID_MP2) && (enc->codec_id != CODEC_ID_ADPCM_IMA_WAV) && (enc->extradata_size==0)) {
- wavsize += 2;
- avio_wl16(pb, 0);
- }
if (wavsize < 0)
return -1;
@@ -684,7 +680,7 @@ static void flush_packet(AVFormatContext *s)
static void put_payload_header(
AVFormatContext *s,
ASFStream *stream,
- int presentation_time,
+ int64_t presentation_time,
int m_obj_size,
int m_obj_offset,
int payload_len,
@@ -711,7 +707,7 @@ static void put_payload_header(
avio_w8(pb, ASF_PAYLOAD_REPLICATED_DATA_LENGTH);
avio_wl32(pb, m_obj_size); //Replicated Data - Media Object Size
- avio_wl32(pb, presentation_time);//Replicated Data - Presentation Time
+ avio_wl32(pb, (uint32_t) presentation_time);//Replicated Data - Presentation Time
if (asf->multi_payloads_present){
avio_wl16(pb, payload_len); //payload length
@@ -722,7 +718,7 @@ static void put_frame(
AVFormatContext *s,
ASFStream *stream,
AVStream *avst,
- int timestamp,
+ int64_t timestamp,
const uint8_t *buf,
int m_obj_size,
int flags
@@ -882,20 +878,20 @@ static int asf_write_trailer(AVFormatContext *s)
#if CONFIG_ASF_MUXER
AVOutputFormat ff_asf_muxer = {
- "asf",
- NULL_IF_CONFIG_SMALL("ASF format"),
- "video/x-ms-asf",
- "asf,wmv,wma",
- sizeof(ASFContext),
+ .name = "asf",
+ .long_name = NULL_IF_CONFIG_SMALL("ASF format"),
+ .mime_type = "video/x-ms-asf",
+ .extensions = "asf,wmv,wma",
+ .priv_data_size = sizeof(ASFContext),
#if CONFIG_LIBMP3LAME
- CODEC_ID_MP3,
+ .audio_codec = CODEC_ID_MP3,
#else
- CODEC_ID_MP2,
+ .audio_codec = CODEC_ID_MP2,
#endif
- CODEC_ID_MSMPEG4V3,
- asf_write_header,
- asf_write_packet,
- asf_write_trailer,
+ .video_codec = CODEC_ID_MSMPEG4V3,
+ .write_header = asf_write_header,
+ .write_packet = asf_write_packet,
+ .write_trailer = asf_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0},
};
@@ -903,20 +899,20 @@ AVOutputFormat ff_asf_muxer = {
#if CONFIG_ASF_STREAM_MUXER
AVOutputFormat ff_asf_stream_muxer = {
- "asf_stream",
- NULL_IF_CONFIG_SMALL("ASF format"),
- "video/x-ms-asf",
- "asf,wmv,wma",
- sizeof(ASFContext),
+ .name = "asf_stream",
+ .long_name = NULL_IF_CONFIG_SMALL("ASF format"),
+ .mime_type = "video/x-ms-asf",
+ .extensions = "asf,wmv,wma",
+ .priv_data_size = sizeof(ASFContext),
#if CONFIG_LIBMP3LAME
- CODEC_ID_MP3,
+ .audio_codec = CODEC_ID_MP3,
#else
- CODEC_ID_MP2,
+ .audio_codec = CODEC_ID_WMAV2,
#endif
- CODEC_ID_MSMPEG4V3,
- asf_write_stream_header,
- asf_write_packet,
- asf_write_trailer,
+ .video_codec = CODEC_ID_MSMPEG4V3,
+ .write_header = asf_write_stream_header,
+ .write_packet = asf_write_packet,
+ .write_trailer = asf_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0},
};
diff --git a/libavformat/assdec.c b/libavformat/assdec.c
index 08b520e656..4f1126cc0e 100644
--- a/libavformat/assdec.c
+++ b/libavformat/assdec.c
@@ -2,20 +2,20 @@
* SSA/ASS demuxer
* Copyright (c) 2008 Michael Niedermayer
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -83,7 +83,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
uint8_t *p, **dst[2]={0};
int pos[2]={0};
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
av_set_pts_info(st, 64, 1, 100);
@@ -93,7 +93,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
header_remaining= INT_MAX;
dst[0] = &st->codec->extradata;
dst[1] = &ass->event_buffer;
- while(!pb->eof_reached){
+ while(!url_feof(pb)){
uint8_t line[MAX_LINESIZE];
len = ff_get_line(pb, line, sizeof(line));
diff --git a/libavformat/assenc.c b/libavformat/assenc.c
index c53af16bbd..b367668d2d 100644
--- a/libavformat/assenc.c
+++ b/libavformat/assenc.c
@@ -2,20 +2,20 @@
* SSA/ASS muxer
* Copyright (c) 2008 Michael Niedermayer
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/au.c b/libavformat/au.c
index 6cffe1c1ce..af00e6d4ff 100644
--- a/libavformat/au.c
+++ b/libavformat/au.c
@@ -2,20 +2,20 @@
* AU muxer and demuxer
* Copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -120,7 +120,7 @@ static int au_probe(AVProbeData *p)
static int au_read_header(AVFormatContext *s,
AVFormatParameters *ap)
{
- int size;
+ int size, bps, data_size = 0;
unsigned int tag;
AVIOContext *pb = s->pb;
unsigned int id, channels, rate;
@@ -132,7 +132,12 @@ static int au_read_header(AVFormatContext *s,
if (tag != MKTAG('.', 's', 'n', 'd'))
return -1;
size = avio_rb32(pb); /* header size */
- avio_rb32(pb); /* data size */
+ data_size = avio_rb32(pb); /* data size in bytes */
+
+ if (data_size < 0 && data_size != AU_UNKNOWN_SIZE) {
+ av_log(s, AV_LOG_ERROR, "Invalid negative data size '%d' found\n", data_size);
+ return AVERROR_INVALIDDATA;
+ }
id = avio_rb32(pb);
rate = avio_rb32(pb);
@@ -140,7 +145,7 @@ static int au_read_header(AVFormatContext *s,
codec = ff_codec_get_id(codec_au_tags, id);
- if (!av_get_bits_per_sample(codec)) {
+ if (!(bps = av_get_bits_per_sample(codec))) {
av_log_ask_for_sample(s, "could not determine bits per sample\n");
return AVERROR_INVALIDDATA;
}
@@ -151,7 +156,7 @@ static int au_read_header(AVFormatContext *s,
}
/* now we are ready: build format streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -159,6 +164,8 @@ static int au_read_header(AVFormatContext *s,
st->codec->codec_id = codec;
st->codec->channels = channels;
st->codec->sample_rate = rate;
+ if (data_size != AU_UNKNOWN_SIZE)
+ st->duration = (((int64_t)data_size)<<3) / (st->codec->channels * bps);
av_set_pts_info(st, 64, 1, rate);
return 0;
}
@@ -185,30 +192,27 @@ static int au_read_packet(AVFormatContext *s,
#if CONFIG_AU_DEMUXER
AVInputFormat ff_au_demuxer = {
- "au",
- NULL_IF_CONFIG_SMALL("SUN AU format"),
- 0,
- au_probe,
- au_read_header,
- au_read_packet,
- NULL,
- pcm_read_seek,
+ .name = "au",
+ .long_name = NULL_IF_CONFIG_SMALL("SUN AU format"),
+ .read_probe = au_probe,
+ .read_header = au_read_header,
+ .read_packet = au_read_packet,
+ .read_seek = pcm_read_seek,
.codec_tag= (const AVCodecTag* const []){codec_au_tags, 0},
};
#endif
#if CONFIG_AU_MUXER
AVOutputFormat ff_au_muxer = {
- "au",
- NULL_IF_CONFIG_SMALL("SUN AU format"),
- "audio/basic",
- "au",
- 0,
- CODEC_ID_PCM_S16BE,
- CODEC_ID_NONE,
- au_write_header,
- au_write_packet,
- au_write_trailer,
+ .name = "au",
+ .long_name = NULL_IF_CONFIG_SMALL("SUN AU format"),
+ .mime_type = "audio/basic",
+ .extensions = "au",
+ .audio_codec = CODEC_ID_PCM_S16BE,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = au_write_header,
+ .write_packet = au_write_packet,
+ .write_trailer = au_write_trailer,
.codec_tag= (const AVCodecTag* const []){codec_au_tags, 0},
};
#endif //CONFIG_AU_MUXER
diff --git a/libavformat/audiointerleave.c b/libavformat/audiointerleave.c
index e48f826e14..844112fcf5 100644
--- a/libavformat/audiointerleave.c
+++ b/libavformat/audiointerleave.c
@@ -3,20 +3,20 @@
*
* Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/audiointerleave.h b/libavformat/audiointerleave.h
index af29629b8a..b37c8aefbd 100644
--- a/libavformat/audiointerleave.h
+++ b/libavformat/audiointerleave.h
@@ -3,20 +3,20 @@
*
* Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/avc.c b/libavformat/avc.c
index 70a05ec5bc..ed2125b527 100644
--- a/libavformat/avc.c
+++ b/libavformat/avc.c
@@ -2,20 +2,20 @@
* AVC helper functions for muxers
* Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@smartjog.com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/avc.h b/libavformat/avc.h
index 56122125a9..46e5e37a54 100644
--- a/libavformat/avc.h
+++ b/libavformat/avc.h
@@ -2,20 +2,20 @@
* AVC helper functions for muxers
* Copyright (c) 2008 Aurelien Jacobs <aurel@gnuage.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 12490c1209..441f85d503 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1,20 +1,20 @@
/*
* copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -53,7 +53,7 @@ struct AVFormatContext;
* @defgroup metadata_api Public Metadata API
* @{
* The metadata API allows libavformat to export metadata tags to a client
- * application using a sequence of key/value pairs. Like all strings in Libav,
+ * application using a sequence of key/value pairs. Like all strings in FFmpeg,
* metadata must be stored as UTF-8 encoded Unicode. Note that metadata
* exported by demuxers isn't checked to be valid UTF-8 in most cases.
* Important concepts to keep in mind:
@@ -274,6 +274,10 @@ typedef struct AVFormatParameters {
#define AVFMT_NOSTREAMS 0x1000 /**< Format does not require any streams */
#define AVFMT_NOBINSEARCH 0x2000 /**< Format does not allow to fallback to binary search via read_timestamp */
#define AVFMT_NOGENSEARCH 0x4000 /**< Format does not allow to fallback to generic search */
+#define AVFMT_NO_BYTE_SEEK 0x8000 /**< Format does not allow seeking by bytes */
+#define AVFMT_TS_NONSTRICT 0x8000000 /**< Format does not require strictly
+ increasing timestamps, but they must
+ still be monotonic */
typedef struct AVOutputFormat {
const char *name;
@@ -301,10 +305,9 @@ typedef struct AVOutputFormat {
* AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS
*/
int flags;
- /**
- * Currently only used to set pixel format if not YUV420P.
- */
- int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *);
+
+ void *dummy;
+
int (*interleave_packet)(struct AVFormatContext *, AVPacket *out,
AVPacket *in, int flush);
@@ -322,6 +325,17 @@ typedef struct AVOutputFormat {
const AVClass *priv_class; ///< AVClass for the private context
+ /**
+ * Test if the given codec can be stored in this container.
+ *
+ * @return 1 if the codec is supported, 0 if it is not.
+ * A negative number if unknown.
+ */
+ int (*query_codec)(enum CodecID id, int std_compliance);
+
+ void (*get_output_timestamp)(struct AVFormatContext *s, int stream,
+ int64_t *dts, int64_t *wall);
+
/* private fields */
struct AVOutputFormat *next;
} AVOutputFormat;
@@ -398,7 +412,9 @@ typedef struct AVInputFormat {
int64_t *pos, int64_t pos_limit);
/**
- * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER.
+ * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS,
+ * AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH,
+ * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK.
*/
int flags;
@@ -456,7 +472,12 @@ enum AVStreamParseType {
typedef struct AVIndexEntry {
int64_t pos;
- int64_t timestamp;
+ int64_t timestamp; /**<
+ * Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are available
+ * when seeking to this entry. That means preferable PTS on keyframe based formats.
+ * But demuxers can choose to store a different timestamp, if it is more convenient for the implementation or nothing better
+ * is known
+ */
#define AVINDEX_KEYFRAME 0x0001
int flags:2;
int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment).
@@ -523,18 +544,22 @@ typedef struct AVStream {
int stream_copy; /**< If set, just copy stream. */
enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed.
+#if FF_API_AVSTREAM_QUALITY
//FIXME move stuff to a flags field?
/**
* Quality, as it has been removed from AVCodecContext and put in AVVideoFrame.
* MN: dunno if that is the right place for it
*/
- float quality;
+ attribute_deprecated float quality;
+#endif
/**
- * Decoding: pts of the first frame of the stream, in stream time base.
+ * Decoding: pts of the first frame of the stream in presentation order, in stream time base.
* Only set this if you are absolutely 100% sure that the value you set
* it to really is the pts of the first frame.
* This may be undefined (AV_NOPTS_VALUE).
+ * @note The ASF header does NOT contain a correct start_time the ASF
+ * demuxer must NOT set this.
*/
int64_t start_time;
@@ -615,6 +640,13 @@ typedef struct AVStream {
int codec_info_nb_frames;
/**
+ * Stream Identifier
+ * This is the MPEG-TS stream identifier +1
+ * 0 means unknown
+ */
+ int stream_identifier;
+
+ /**
* Stream informations used internally by av_find_stream_info()
*/
#define MAX_STD_TIMEBASES (60*12+5)
@@ -622,9 +654,15 @@ typedef struct AVStream {
int64_t last_dts;
int64_t duration_gcd;
int duration_count;
- double duration_error[MAX_STD_TIMEBASES];
+ double duration_error[2][2][MAX_STD_TIMEBASES];
int64_t codec_info_duration;
} *info;
+
+ /**
+ * flag to indicate that probing is requested
+ * NOT PART OF PUBLIC API
+ */
+ int request_probe;
} AVStream;
#define AV_PROGRAM_RUNNING 1
@@ -642,6 +680,10 @@ typedef struct AVProgram {
unsigned int *stream_index;
unsigned int nb_stream_indexes;
AVDictionary *metadata;
+
+ int program_num;
+ int pmt_pid;
+ int pcr_pid;
} AVProgram;
#define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present
@@ -672,7 +714,12 @@ typedef struct AVFormatContext {
AVStream **streams;
char filename[1024]; /**< input or output filename */
/* stream info */
- int64_t timestamp;
+#if FF_API_TIMESTAMP
+ /**
+ * @deprecated use 'creation_time' metadata tag instead
+ */
+ attribute_deprecated int64_t timestamp;
+#endif
int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */
/* private data for pts handling (do not modify directly). */
@@ -698,15 +745,17 @@ typedef struct AVFormatContext {
*/
int64_t duration;
+#if FF_API_FILESIZE
/**
* decoding: total file size, 0 if unknown
*/
- int64_t file_size;
+ attribute_deprecated int64_t file_size;
+#endif
/**
* Decoding: total stream bitrate in bit/s, 0 if not
* available. Never set it directly if the file_size and the
- * duration are known as Libav can compute it automatically.
+ * duration are known as FFmpeg can compute it automatically.
*/
int bit_rate;
@@ -716,17 +765,26 @@ typedef struct AVFormatContext {
/* av_seek_frame() support */
int64_t data_offset; /**< offset of the first packet */
- int mux_rate;
+#if FF_API_MUXRATE
+ /**
+ * use mpeg muxer private options instead
+ */
+ attribute_deprecated int mux_rate;
+#endif
unsigned int packet_size;
int preload;
int max_delay;
+#if FF_API_LOOP_OUTPUT
#define AVFMT_NOOUTPUTLOOP -1
#define AVFMT_INFINITEOUTPUTLOOP 0
/**
* number of times to loop output in formats that support it
+ *
+ * @deprecated use the 'loop' private option in the gif muxer.
*/
- int loop_output;
+ attribute_deprecated int loop_output;
+#endif
int flags;
#define AVFMT_FLAG_GENPTS 0x0001 ///< Generate missing pts even if it requires parsing future frames.
@@ -739,8 +797,18 @@ typedef struct AVFormatContext {
#define AVFMT_FLAG_RTP_HINT 0x0040 ///< Deprecated, use the -movflags rtphint muxer specific AVOption instead
#endif
#define AVFMT_FLAG_CUSTOM_IO 0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
+#define AVFMT_FLAG_DISCARD_CORRUPT 0x0100 ///< Discard frames marked corrupted
+#define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Enable RTP MP4A-LATM payload
+#define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down)
+#define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted)
+#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Dont merge side data but keep it seperate.
- int loop_input;
+#if FF_API_LOOP_INPUT
+ /**
+ * @deprecated, use the 'loop' img2 demuxer private option.
+ */
+ attribute_deprecated int loop_input;
+#endif
/**
* decoding: size of data to probe; encoding: unused.
@@ -837,6 +905,20 @@ typedef struct AVFormatContext {
* decoding: number of frames used to probe fps
*/
int fps_probe_size;
+
+ /**
+ * Error recognition; higher values will detect more errors but may
+ * misdetect some more or less valid parts as errors.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int error_recognition;
+
+ /**
+ * Transport stream id.
+ * This will be moved into demuxer private options. Thus no API/ABI compatibility
+ */
+ int ts_id;
} AVFormatContext;
typedef struct AVPacketList {
@@ -1006,6 +1088,15 @@ AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened);
AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max);
/**
+ * Guess the file format.
+ *
+ * @param is_opened Whether the file is already opened; determines whether
+ * demuxers with or without AVFMT_NOFILE are probed.
+ * @param score_ret The score of the best detection.
+ */
+AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret);
+
+/**
* Probe a bytestream to determine the input format. Each time a probe returns
* with a score that is too low, the probe buffer size is increased and another
* attempt is made. When the maximum probe size is reached, the input format
@@ -1075,6 +1166,8 @@ attribute_deprecated int av_open_input_file(AVFormatContext **ic_ptr, const char
*/
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);
+int av_demuxer_open(AVFormatContext *ic, AVFormatParameters *ap);
+
/**
* Allocate an AVFormatContext.
* avformat_free_context() can be used to free the context and everything
@@ -1082,6 +1175,36 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
*/
AVFormatContext *avformat_alloc_context(void);
+#if FF_API_ALLOC_OUTPUT_CONTEXT
+/**
+ * @deprecated deprecated in favor of avformat_alloc_output_context2()
+ */
+attribute_deprecated
+AVFormatContext *avformat_alloc_output_context(const char *format,
+ AVOutputFormat *oformat,
+ const char *filename);
+#endif
+
+/**
+ * Allocate an AVFormatContext for an output format.
+ * avformat_free_context() can be used to free the context and
+ * everything allocated by the framework within it.
+ *
+ * @param *ctx is set to the created format context, or to NULL in
+ * case of failure
+ * @param oformat format to use for allocating the context, if NULL
+ * format_name and filename are used instead
+ * @param format_name the name of output format to use for allocating the
+ * context, if NULL filename is used instead
+ * @param filename the name of the filename to use for allocating the
+ * context, may be NULL
+ * @return >= 0 in case of success, a negative AVERROR code in case of
+ * failure
+ */
+int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat,
+ const char *format_name, const char *filename);
+
+#if FF_API_FORMAT_PARAMETERS
/**
* Read packets of a media file to get stream information. This
* is useful for file formats with no headers such as MPEG. This
@@ -1094,8 +1217,47 @@ AVFormatContext *avformat_alloc_context(void);
* @return >=0 if OK, AVERROR_xxx on error
* @todo Let the user decide somehow what information is needed so that
* we do not waste time getting stuff the user does not need.
+ *
+ * @deprecated use avformat_find_stream_info.
*/
+attribute_deprecated
int av_find_stream_info(AVFormatContext *ic);
+#endif
+
+/**
+ * Read packets of a media file to get stream information. This
+ * is useful for file formats with no headers such as MPEG. This
+ * function also computes the real framerate in case of MPEG-2 repeat
+ * frame mode.
+ * The logical file position is not changed by this function;
+ * examined packets may be buffered for later processing.
+ *
+ * @param ic media file handle
+ * @param options If non-NULL, an ic.nb_streams long array of pointers to
+ * dictionaries, where i-th member contains options for
+ * codec corresponding to i-th stream.
+ * On return each dictionary will be filled with options that were not found.
+ * @return >=0 if OK, AVERROR_xxx on error
+ *
+ * @note this function isn't guaranteed to open all the codecs, so
+ * options being non-empty at return is a perfectly normal behavior.
+ *
+ * @todo Let the user decide somehow what information is needed so that
+ * we do not waste time getting stuff the user does not need.
+ */
+int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
+
+/**
+ * Find the programs which belong to a given stream.
+ *
+ * @param ic media file handle
+ * @param last the last found program, the search will start after this
+ * program, or from the beginning if it is NULL
+ * @param s stream index
+ * @return the next program which belongs to s, NULL if no program is found or
+ * the last program is not among the programs of ic.
+ */
+AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s);
/**
* Find the "best" stream in the file.
@@ -1240,6 +1402,7 @@ void av_close_input_file(AVFormatContext *s);
*/
void avformat_free_context(AVFormatContext *s);
+#if FF_API_NEW_STREAM
/**
* Add a new stream to a media file.
*
@@ -1250,7 +1413,27 @@ void avformat_free_context(AVFormatContext *s);
* @param s media file handle
* @param id file-format-dependent stream ID
*/
+attribute_deprecated
AVStream *av_new_stream(AVFormatContext *s, int id);
+#endif
+
+/**
+ * Add a new stream to a media file.
+ *
+ * When demuxing, it is called by the demuxer in read_header(). If the
+ * flag AVFMTCTX_NOHEADER is set in s.ctx_flags, then it may also
+ * be called in read_packet().
+ *
+ * When muxing, should be called by the user before avformat_write_header().
+ *
+ * @param c If non-NULL, the AVCodecContext corresponding to the new stream
+ * will be initialized to use this codec. This is needed for e.g. codec-specific
+ * defaults to be set, so codec should be provided if it is known.
+ *
+ * @return newly created stream or NULL on error.
+ */
+AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c);
+
AVProgram *av_new_program(AVFormatContext *s, int id);
/**
@@ -1455,7 +1638,28 @@ int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
*/
int av_write_trailer(AVFormatContext *s);
+/**
+ * Get timing information for the data currently output.
+ * The exact meaning of "currently output" depends on the format.
+ * It is mostly relevant for devices that have an internal buffer and/or
+ * work in real time.
+ * @param s media file handle
+ * @param stream stream in the media file
+ * @param dts[out] DTS of the last packet output for the stream, in stream
+ * time_base units
+ * @param wall[out] absolute time when that packet whas output,
+ * in microsecond
+ * @return 0 if OK, AVERROR(ENOSYS) if the format does not support it
+ * Note: some formats or devices may not allow to measure dts and wall
+ * atomically.
+ */
+int av_get_output_timestamp(struct AVFormatContext *s, int stream,
+ int64_t *dts, int64_t *wall);
+
#if FF_API_DUMP_FORMAT
+/**
+ * @deprecated Deprecated in favor of av_dump_format().
+ */
attribute_deprecated void dump_format(AVFormatContext *ic,
int index,
const char *url,
@@ -1542,4 +1746,22 @@ attribute_deprecated int avf_sdp_create(AVFormatContext *ac[], int n_files, char
*/
int av_match_ext(const char *filename, const char *extensions);
+/**
+ * Test if the given container can store a codec.
+ *
+ * @param std_compliance standards compliance level, one of FF_COMPLIANCE_*
+ *
+ * @return 1 if codec with ID codec_id can be stored in ofmt, 0 if it cannot.
+ * A negative number if this information is not available.
+ */
+int avformat_query_codec(AVOutputFormat *ofmt, enum CodecID codec_id, int std_compliance);
+
+/**
+ * Get the AVClass for AVFormatContext. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *avformat_get_class(void);
+
#endif /* AVFORMAT_AVFORMAT_H */
diff --git a/libavformat/avi.c b/libavformat/avi.c
index 9f36b27f35..705ad03ab0 100644
--- a/libavformat/avi.c
+++ b/libavformat/avi.c
@@ -2,20 +2,20 @@
* AVI common data
* Copyright (c) 2010 Anton Khirnov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/avi.h b/libavformat/avi.h
index 05e02977f6..b4e551971a 100644
--- a/libavformat/avi.h
+++ b/libavformat/avi.h
@@ -1,20 +1,20 @@
/*
* copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index 2ea156e9ec..0995150454 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -2,20 +2,20 @@
* AVI demuxer
* Copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -23,6 +23,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libavutil/bswap.h"
+#include "libavutil/opt.h"
#include "libavutil/dict.h"
#include "avformat.h"
#include "avi.h"
@@ -53,9 +54,12 @@ typedef struct AVIStream {
AVFormatContext *sub_ctx;
AVPacket sub_pkt;
uint8_t *sub_buffer;
+
+ int64_t seek_pos;
} AVIStream;
typedef struct {
+ const AVClass *class;
int64_t riff_end;
int64_t movi_end;
int64_t fsize;
@@ -67,9 +71,25 @@ typedef struct {
int stream_index;
DVDemuxContext* dv_demux;
int odml_depth;
+ int use_odml;
#define MAX_ODML_DEPTH 1000
+ int64_t dts_max;
} AVIContext;
+
+static const AVOption options[] = {
+ { "use_odml", "use odml index", offsetof(AVIContext, use_odml), AV_OPT_TYPE_INT, {.dbl = 1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
+ { NULL },
+};
+
+static const AVClass demuxer_class = {
+ "AVI demuxer",
+ av_default_item_name,
+ options,
+ LIBAVUTIL_VERSION_INT,
+};
+
+
static const char avi_headers[][8] = {
{ 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' },
{ 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' },
@@ -137,7 +157,7 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
AVIStream *ast;
int i;
int64_t last_pos= -1;
- int64_t filesize= avio_size(s->pb);
+ int64_t filesize= avi->fsize;
av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",
longs_pre_entry,index_type, entries_in_use, chunk_id, base);
@@ -172,9 +192,10 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
int key= len >= 0;
len &= 0x7FFFFFFF;
- av_dlog(s, "pos:%"PRId64", len:%X\n", pos, len);
-
- if(pb->eof_reached)
+#ifdef DEBUG_SEEK
+ av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len);
+#endif
+ if(url_feof(pb))
return -1;
if(last_pos == pos || pos == base - 8)
@@ -191,7 +212,7 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
avio_rl32(pb); /* size */
duration = avio_rl32(pb);
- if(pb->eof_reached)
+ if(url_feof(pb))
return -1;
pos = avio_tell(pb);
@@ -201,16 +222,21 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
return -1;
}
- avio_seek(pb, offset+8, SEEK_SET);
+ if(avio_seek(pb, offset+8, SEEK_SET) < 0)
+ return -1;
avi->odml_depth++;
read_braindead_odml_indx(s, frame_num);
avi->odml_depth--;
frame_num += duration;
- avio_seek(pb, pos, SEEK_SET);
+ if(avio_seek(pb, pos, SEEK_SET) < 0) {
+ av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index");
+ return -1;
+ }
+
}
}
- avi->index_loaded=1;
+ avi->index_loaded=2;
return 0;
}
@@ -348,8 +374,10 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (get_riff(s, pb) < 0)
return -1;
+ av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml);
+
avi->fsize = avio_size(pb);
- if(avi->fsize<=0)
+ if(avi->fsize<=0 || avi->fsize < avi->riff_end)
avi->fsize= avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
/* first list tag */
@@ -357,7 +385,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
codec_type = -1;
frame_period = 0;
for(;;) {
- if (pb->eof_reached)
+ if (url_feof(pb))
goto fail;
tag = avio_rl32(pb);
size = avio_rl32(pb);
@@ -375,7 +403,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
avi->movi_list = avio_tell(pb) - 4;
if(size) avi->movi_end = avi->movi_list + size + (size & 1);
- else avi->movi_end = avio_size(pb);
+ else avi->movi_end = avi->fsize;
av_dlog(NULL, "movi end=%"PRIx64"\n", avi->movi_end);
goto end_of_header;
}
@@ -403,7 +431,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
/* AVI header */
/* using frame_period is bad idea */
frame_period = avio_rl32(pb);
- avio_skip(pb, 4);
+ avio_rl32(pb); /* max. bytes per second */
avio_rl32(pb);
avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX;
@@ -426,10 +454,11 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
break;
}else{
stream_index++;
- st = av_new_stream(s, stream_index);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto fail;
+ st->id = stream_index;
ast = av_mallocz(sizeof(AVIStream));
if (!ast)
goto fail;
@@ -461,7 +490,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
av_freep(&s->streams[0]);
s->nb_streams = 0;
if (CONFIG_DV_DEMUXER) {
- avi->dv_demux = dv_init_demux(s);
+ avi->dv_demux = avpriv_dv_init_demux(s);
if (!avi->dv_demux)
goto fail;
}
@@ -533,8 +562,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
codec_type = AVMEDIA_TYPE_DATA;
break;
default:
- av_log(s, AV_LOG_ERROR, "unknown stream type %X\n", tag1);
- goto fail;
+ av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1);
}
if(ast->sample_size == 0)
st->duration = st->nb_frames;
@@ -543,6 +571,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
break;
case MKTAG('s', 't', 'r', 'f'):
/* stream header */
+ if (!size)
+ break;
if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {
avio_skip(pb, size);
} else {
@@ -584,7 +614,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
/* Extract palette from extradata if bpp <= 8. */
/* This code assumes that extradata contains only palette. */
- /* This is true for all paletted codecs implemented in Libav. */
+ /* This is true for all paletted codecs implemented in FFmpeg. */
if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
int pal_size = (1 << st->codec->bits_per_coded_sample) << 2;
const uint8_t *pal_src;
@@ -593,7 +623,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
pal_src = st->codec->extradata + st->codec->extradata_size - pal_size;
#if HAVE_BIGENDIAN
for (i = 0; i < pal_size/4; i++)
- ast->pal[i] = av_bswap32(((uint32_t*)pal_src)[i]);
+ ast->pal[i] = AV_RL32(pal_src+4*i);
#else
memcpy(ast->pal, pal_src, pal_size);
#endif
@@ -614,7 +644,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){
st->codec->extradata_size+= 9;
- st->codec->extradata= av_realloc(st->codec->extradata, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ st->codec->extradata= av_realloc_f(st->codec->extradata, 1, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
if(st->codec->extradata)
memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9);
}
@@ -646,6 +676,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (st->codec->stream_codec_tag == AV_RL32("Axan")){
st->codec->codec_id = CODEC_ID_XAN_DPCM;
st->codec->codec_tag = 0;
+ ast->dshow_block_align = 0;
}
if (amv_file_format){
st->codec->codec_id = CODEC_ID_ADPCM_IMA_AMV;
@@ -654,7 +685,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
break;
case AVMEDIA_TYPE_SUBTITLE:
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
- st->codec->codec_id = CODEC_ID_PROBE;
+ st->request_probe= 1;
break;
default:
st->codec->codec_type = AVMEDIA_TYPE_DATA;
@@ -667,9 +698,9 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
break;
case MKTAG('i', 'n', 'd', 'x'):
i= avio_tell(pb);
- if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX)){
- read_braindead_odml_indx(s, 0);
- }
+ if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) && avi->use_odml &&
+ read_braindead_odml_indx(s, 0) < 0 && s->error_recognition >= FF_ER_EXPLODE){
+ goto fail; }
avio_seek(pb, i+size, SEEK_SET);
break;
case MKTAG('v', 'p', 'r', 'p'):
@@ -706,8 +737,9 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
if(size > 1000000){
av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, "
"I will ignore it and try to continue anyway.\n");
+ if (s->error_recognition >= FF_ER_EXPLODE) goto fail;
avi->movi_list = avio_tell(pb) - 4;
- avi->movi_end = avio_size(pb);
+ avi->movi_end = avi->fsize;
goto end_of_header;
}
/* skip tag */
@@ -725,13 +757,17 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
if(!avi->index_loaded && pb->seekable)
avi_load_index(s);
- avi->index_loaded = 1;
- avi->non_interleaved |= guess_ni_flag(s);
+ avi->index_loaded |= 1;
+ avi->non_interleaved |= guess_ni_flag(s) | (s->flags & AVFMT_FLAG_SORT_DTS);
for(i=0; i<s->nb_streams; i++){
AVStream *st = s->streams[i];
if(st->nb_index_entries)
break;
}
+ // DV-in-AVI cannot be non-interleaved, if set this must be
+ // a mis-detection.
+ if(avi->dv_demux)
+ avi->non_interleaved=0;
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;
@@ -841,13 +877,14 @@ static int avi_sync(AVFormatContext *s, int exit_early)
{
AVIContext *avi = s->priv_data;
AVIOContext *pb = s->pb;
- int n, d[8];
+ int n;
+ unsigned int d[8];
unsigned int size;
int64_t i, sync;
start_sync:
- memset(d, -1, sizeof(int)*8);
- for(i=sync=avio_tell(pb); !pb->eof_reached; i++) {
+ memset(d, -1, sizeof(d));
+ for(i=sync=avio_tell(pb); !url_feof(pb); i++) {
int j;
for(j=0; j<7; j++)
@@ -858,7 +895,7 @@ start_sync:
n= get_stream_idx(d+2);
//av_log(s, AV_LOG_DEBUG, "%X %X %X %X %X %X %X %X %"PRId64" %d %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
- if(i + (uint64_t)size > avi->fsize || d[0]<0)
+ if(i + (uint64_t)size > avi->fsize || d[0] > 127)
continue;
//parse ix##
@@ -975,7 +1012,7 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
void* dstr;
if (CONFIG_DV_DEMUXER && avi->dv_demux) {
- int size = dv_get_packet(avi->dv_demux, pkt);
+ int size = avpriv_dv_get_packet(avi->dv_demux, pkt);
if (size >= 0)
return size;
}
@@ -1010,7 +1047,7 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
}
}
if(!best_st)
- return -1;
+ return AVERROR_EOF;
best_ast = best_st->priv_data;
best_ts = av_rescale_q(best_ts, (AVRational){FFMAX(1, best_ast->sample_size), AV_TIME_BASE}, best_st->time_base);
@@ -1026,7 +1063,8 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
if(i>=0){
int64_t pos= best_st->index_entries[i].pos;
pos += best_ast->packet_size - best_ast->remaining;
- avio_seek(s->pb, pos + 8, SEEK_SET);
+ if(avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
+ return AVERROR_EOF;
// av_log(s, AV_LOG_DEBUG, "pos=%"PRId64"\n", pos);
assert(best_ast->remaining <= best_ast->packet_size);
@@ -1036,6 +1074,8 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
best_ast->packet_size=
best_ast->remaining= best_st->index_entries[i].size;
}
+ else
+ return AVERROR_EOF;
}
resync:
@@ -1075,8 +1115,8 @@ resync:
if (CONFIG_DV_DEMUXER && avi->dv_demux) {
dstr = pkt->destruct;
- size = dv_produce_packet(avi->dv_demux, pkt,
- pkt->data, pkt->size);
+ size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
+ pkt->data, pkt->size, pkt->pos);
pkt->destruct = dstr;
pkt->flags |= AV_PKT_FLAG_KEY;
if (size < 0)
@@ -1105,6 +1145,23 @@ resync:
e= &st->index_entries[index];
if(index >= 0 && e->timestamp == ast->frame_offset){
+ if (index == st->nb_index_entries-1){
+ int key=1;
+ int i;
+ uint32_t state=-1;
+ for(i=0; i<FFMIN(size,256); i++){
+ if(st->codec->codec_id == CODEC_ID_MPEG4){
+ if(state == 0x1B6){
+ key= !(pkt->data[i]&0xC0);
+ break;
+ }
+ }else
+ break;
+ state= (state<<8) + pkt->data[i];
+ }
+ if(!key)
+ e->flags &= ~AVINDEX_KEYFRAME;
+ }
if (e->flags & AVINDEX_KEYFRAME)
pkt->flags |= AV_PKT_FLAG_KEY;
}
@@ -1119,6 +1176,22 @@ resync:
ast->packet_size= 0;
}
+ if(!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos){
+ av_free_packet(pkt);
+ goto resync;
+ }
+ ast->seek_pos= 0;
+
+ if(!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1){
+ int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
+
+ if(avi->dts_max - dts > 2*AV_TIME_BASE){
+ avi->non_interleaved= 1;
+ av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n");
+ }else if(avi->dts_max < dts)
+ avi->dts_max = dts;
+ }
+
return size;
}
@@ -1176,7 +1249,7 @@ static int avi_read_idx1(AVFormatContext *s, int size)
av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
- if(pb->eof_reached)
+ if(url_feof(pb))
return -1;
if(last_pos == pos)
@@ -1232,7 +1305,7 @@ static int avi_load_index(AVFormatContext *s)
goto the_end; // maybe truncated file
av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end);
for(;;) {
- if (pb->eof_reached)
+ if (url_feof(pb))
break;
tag = avio_rl32(pb);
size = avio_rl32(pb);
@@ -1245,6 +1318,7 @@ static int avi_load_index(AVFormatContext *s)
if (tag == MKTAG('i', 'd', 'x', '1') &&
avi_read_idx1(s, size) >= 0) {
+ avi->index_loaded=2;
ret = 0;
break;
}
@@ -1273,13 +1347,13 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
AVIContext *avi = s->priv_data;
AVStream *st;
int i, index;
- int64_t pos;
+ int64_t pos, pos_min;
AVIStream *ast;
if (!avi->index_loaded) {
/* we only load the index on demand */
avi_load_index(s);
- avi->index_loaded = 1;
+ avi->index_loaded |= 1;
}
assert(stream_index>= 0);
@@ -1301,15 +1375,18 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
/* the av_index_search_timestamp call above. */
assert(stream_index == 0);
+ if(avio_seek(s->pb, pos, SEEK_SET) < 0)
+ return -1;
+
/* Feed the DV video stream version of the timestamp to the */
/* DV demux so it can synthesize correct timestamps. */
dv_offset_reset(avi->dv_demux, timestamp);
- avio_seek(s->pb, pos, SEEK_SET);
avi->stream_index= -1;
return 0;
}
+ pos_min= pos;
for(i = 0; i < s->nb_streams; i++) {
AVStream *st2 = s->streams[i];
AVIStream *ast2 = st2->priv_data;
@@ -1330,25 +1407,35 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
index = av_index_search_timestamp(
st2,
av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
- flags | AVSEEK_FLAG_BACKWARD);
+ flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
if(index<0)
index=0;
+ ast2->seek_pos= st2->index_entries[index].pos;
+ pos_min= FFMIN(pos_min,ast2->seek_pos);
+ }
+ for(i = 0; i < s->nb_streams; i++) {
+ AVStream *st2 = s->streams[i];
+ AVIStream *ast2 = st2->priv_data;
- if(!avi->non_interleaved){
- while(index>0 && st2->index_entries[index].pos > pos)
- index--;
- while(index+1 < st2->nb_index_entries && st2->index_entries[index].pos < pos)
- index++;
- }
+ if (ast2->sub_ctx || st2->nb_index_entries <= 0)
+ continue;
-// av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %"PRId64"\n", timestamp, index, st2->index_entries[index].timestamp);
- /* extract the current frame number */
+ index = av_index_search_timestamp(
+ st2,
+ av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
+ flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
+ if(index<0)
+ index=0;
+ while(!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
+ index--;
ast2->frame_offset = st2->index_entries[index].timestamp;
}
/* do the seek */
- avio_seek(s->pb, pos, SEEK_SET);
+ if (avio_seek(s->pb, pos_min, SEEK_SET) < 0)
+ return -1;
avi->stream_index= -1;
+ avi->dts_max= INT_MIN;
return 0;
}
@@ -1389,12 +1476,13 @@ static int avi_probe(AVProbeData *p)
}
AVInputFormat ff_avi_demuxer = {
- "avi",
- NULL_IF_CONFIG_SMALL("AVI format"),
- sizeof(AVIContext),
- avi_probe,
- avi_read_header,
- avi_read_packet,
- avi_read_close,
- avi_read_seek,
+ .name = "avi",
+ .long_name = NULL_IF_CONFIG_SMALL("AVI format"),
+ .priv_data_size = sizeof(AVIContext),
+ .read_probe = avi_probe,
+ .read_header = avi_read_header,
+ .read_packet = avi_read_packet,
+ .read_close = avi_read_close,
+ .read_seek = avi_read_seek,
+ .priv_class = &demuxer_class,
};
diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index 343396cabe..b4dc65c243 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -2,20 +2,20 @@
* AVI muxer
* Copyright (c) 2000 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
@@ -519,16 +519,21 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
AVCodecContext *enc= s->streams[stream_index]->codec;
int size= pkt->size;
-// av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %d\n", pkt->dts, avi->packet_count[stream_index], stream_index);
+// av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %d\n", pkt->dts, avist->packet_count, stream_index);
while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count){
AVPacket empty_packet;
+ if(pkt->dts - avist->packet_count > 60000){
+ av_log(s, AV_LOG_ERROR, "Too large number of skiped frames %Ld\n", pkt->dts - avist->packet_count);
+ return AVERROR(EINVAL);
+ }
+
av_init_packet(&empty_packet);
empty_packet.size= 0;
empty_packet.data= NULL;
empty_packet.stream_index= stream_index;
avi_write_packet(s, &empty_packet);
-// av_log(s, AV_LOG_DEBUG, "dup %"PRId64" %d\n", pkt->dts, avi->packet_count[stream_index]);
+// av_log(s, AV_LOG_DEBUG, "dup %"PRId64" %d\n", pkt->dts, avist->packet_count);
}
avist->packet_count++;
@@ -558,7 +563,7 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE;
int id = idx->entry % AVI_INDEX_CLUSTER_SIZE;
if (idx->ents_allocated <= idx->entry) {
- idx->cluster = av_realloc(idx->cluster, (cl+1)*sizeof(void*));
+ idx->cluster = av_realloc_f(idx->cluster, sizeof(void*), cl+1);
if (!idx->cluster)
return -1;
idx->cluster[cl] = av_malloc(AVI_INDEX_CLUSTER_SIZE*sizeof(AVIIentry));
@@ -639,16 +644,20 @@ static int avi_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_avi_muxer = {
- "avi",
- NULL_IF_CONFIG_SMALL("AVI format"),
- "video/x-msvideo",
- "avi",
- sizeof(AVIContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG4,
- avi_write_header,
- avi_write_packet,
- avi_write_trailer,
+ .name = "avi",
+ .long_name = NULL_IF_CONFIG_SMALL("AVI format"),
+ .mime_type = "video/x-msvideo",
+ .extensions = "avi",
+ .priv_data_size = sizeof(AVIContext),
+#if CONFIG_LIBMP3LAME_ENCODER
+ .audio_codec = CODEC_ID_MP3,
+#else
+ .audio_codec = CODEC_ID_AC3,
+#endif
+ .video_codec = CODEC_ID_MPEG4,
+ .write_header = avi_write_header,
+ .write_packet = avi_write_packet,
+ .write_trailer = avi_write_trailer,
.codec_tag= (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
.flags= AVFMT_VARIABLE_FPS,
};
diff --git a/libavformat/avio.c b/libavformat/avio.c
index ac15407fda..b2926c0f3c 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -2,20 +2,20 @@
* Unbuffered io for ffmpeg system
* Copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -52,21 +52,19 @@ static int default_interrupt_cb(void);
URLProtocol *first_protocol = NULL;
int (*url_interrupt_cb)(void) = default_interrupt_cb;
-#if FF_API_OLD_AVIO
URLProtocol *av_protocol_next(URLProtocol *p)
{
if(p) return p->next;
else return first_protocol;
}
-#endif
const char *avio_enum_protocols(void **opaque, int output)
{
- URLProtocol **p = opaque;
- *p = *p ? (*p)->next : first_protocol;
- if (!*p) return NULL;
- if ((output && (*p)->url_write) || (!output && (*p)->url_read))
- return (*p)->name;
+ URLProtocol *p = *opaque;
+ p = p ? p->next : first_protocol;
+ if (!p) return NULL;
+ if ((output && p->url_write) || (!output && p->url_read))
+ return p->name;
return avio_enum_protocols(opaque, output);
}
@@ -284,7 +282,7 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int
if (ret)
fast_retries = FFMAX(fast_retries, 2);
len += ret;
- if (url_interrupt_cb())
+ if (len < size && url_interrupt_cb())
return AVERROR_EXIT;
}
return len;
@@ -312,7 +310,7 @@ int ffurl_write(URLContext *h, const unsigned char *buf, int size)
if (h->max_packet_size && size > h->max_packet_size)
return AVERROR(EIO);
- return retry_transfer_wrapper(h, buf, size, size, h->prot->url_write);
+ return retry_transfer_wrapper(h, buf, size, size, (void*)h->prot->url_write);
}
int64_t ffurl_seek(URLContext *h, int64_t pos, int whence)
diff --git a/libavformat/avio.h b/libavformat/avio.h
index be14e3c89d..8210cbd1da 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -1,20 +1,20 @@
/*
* copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * 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_AVIO_H
@@ -197,12 +197,13 @@ attribute_deprecated int av_url_read_pause(URLContext *h, int pause);
attribute_deprecated int64_t av_url_read_seek(URLContext *h, int stream_index,
int64_t timestamp, int flags);
attribute_deprecated void url_set_interrupt_cb(int (*interrupt_cb)(void));
+
/**
- * If protocol is NULL, returns the first registered protocol,
- * if protocol is non-NULL, returns the next registered protocol after protocol,
- * or NULL if protocol is the last one.
+ * returns the next registered protocol after the given protocol (the first if
+ * NULL is given), or NULL if protocol is the last one.
*/
-attribute_deprecated URLProtocol *av_protocol_next(URLProtocol *p);
+URLProtocol *av_protocol_next(URLProtocol *p);
+
/**
* Register the URLProtocol protocol.
*
@@ -294,10 +295,6 @@ attribute_deprecated int url_fdopen(AVIOContext **s, URLContext *h);
* @}
*/
-/**
- * @deprecated use AVIOContext.eof_reached
- */
-attribute_deprecated int url_feof(AVIOContext *s);
attribute_deprecated int url_ferror(AVIOContext *s);
attribute_deprecated int udp_set_remote_url(URLContext *h, const char *uri);
@@ -438,10 +435,7 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence);
* Skip given number of bytes forward
* @return new position or AVERROR.
*/
-static av_always_inline int64_t avio_skip(AVIOContext *s, int64_t offset)
-{
- return avio_seek(s, offset, SEEK_CUR);
-}
+int64_t avio_skip(AVIOContext *s, int64_t offset);
/**
* ftell() equivalent for AVIOContext.
@@ -458,6 +452,12 @@ static av_always_inline int64_t avio_tell(AVIOContext *s)
*/
int64_t avio_size(AVIOContext *s);
+/**
+ * feof() equivalent for AVIOContext.
+ * @return non zero if and only if end of file
+ */
+int url_feof(AVIOContext *s);
+
/** @warning currently size is limited */
int avio_printf(AVIOContext *s, const char *fmt, ...) av_printf_format(2, 3);
@@ -585,6 +585,7 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer);
/**
* Iterate through names of available protocols.
+ * @note it is recommanded to use av_protocol_next() instead of this
*
* @param opaque A private pointer representing current protocol.
* It must be a pointer to NULL on first iteration and will
diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h
index 1369c43891..4c80163d31 100644
--- a/libavformat/avio_internal.h
+++ b/libavformat/avio_internal.h
@@ -1,19 +1,19 @@
/*
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index fa63ddf2b9..9fc555ee53 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -2,20 +2,20 @@
* Buffered I/O for ffmpeg system
* Copyright (c) 2000,2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -237,6 +237,11 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
return offset;
}
+int64_t avio_skip(AVIOContext *s, int64_t offset)
+{
+ return avio_seek(s, offset, SEEK_CUR);
+}
+
#if FF_API_OLD_AVIO
int url_fskip(AVIOContext *s, int64_t offset)
{
@@ -269,14 +274,18 @@ int64_t avio_size(AVIOContext *s)
return size;
}
-#if FF_API_OLD_AVIO
int url_feof(AVIOContext *s)
{
if(!s)
return 0;
+ if(s->eof_reached){
+ s->eof_reached=0;
+ fill_buffer(s);
+ }
return s->eof_reached;
}
+#if FF_API_OLD_AVIO
int url_ferror(AVIOContext *s)
{
if(!s)
@@ -548,7 +557,7 @@ static void fill_buffer(AVIOContext *s)
}
/* make buffer smaller in case it ended up large after probing */
- if (s->buffer_size > max_buffer_size) {
+ if (s->read_packet && s->buffer_size > max_buffer_size) {
ffio_set_buf_size(s, max_buffer_size);
s->checksum_ptr = dst = s->buffer;
@@ -658,8 +667,8 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size)
}
}
if (size1 == size) {
- if (s->error) return s->error;
- if (s->eof_reached) return AVERROR_EOF;
+ if (s->error) return s->error;
+ if (url_feof(s)) return AVERROR_EOF;
}
return size1 - size;
}
@@ -681,8 +690,8 @@ int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size)
memcpy(buf, s->buf_ptr, len);
s->buf_ptr += len;
if (!len) {
- if (s->error) return s->error;
- if (s->eof_reached) return AVERROR_EOF;
+ if (s->error) return s->error;
+ if (url_feof(s)) return AVERROR_EOF;
}
return len;
}
@@ -769,13 +778,14 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
{
int i;
+ if (buflen <= 0)
+ return AVERROR(EINVAL);
// reserve 1 byte for terminating 0
buflen = FFMIN(buflen - 1, maxlen);
for (i = 0; i < buflen; i++)
if (!(buf[i] = avio_r8(s)))
return i + 1;
- if (buflen)
- buf[i] = 0;
+ buf[i] = 0;
for (; i < maxlen; i++)
if (!avio_r8(s))
return i + 1;
@@ -787,6 +797,8 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
{\
char* q = buf;\
int ret = 0;\
+ if (buflen <= 0) \
+ return AVERROR(EINVAL); \
while (ret + 1 < maxlen) {\
uint8_t tmp;\
uint32_t ch;\
@@ -838,19 +850,13 @@ int ffio_fdopen(AVIOContext **s, URLContext *h)
if (!buffer)
return AVERROR(ENOMEM);
- *s = av_mallocz(sizeof(AVIOContext));
- if(!*s) {
+ *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
+ ffurl_read, ffurl_write, ffurl_seek);
+ if (!*s) {
av_free(buffer);
return AVERROR(ENOMEM);
}
- if (ffio_init_context(*s, buffer, buffer_size,
- h->flags & AVIO_FLAG_WRITE, h,
- ffurl_read, ffurl_write, ffurl_seek) < 0) {
- av_free(buffer);
- av_freep(s);
- return AVERROR(EIO);
- }
#if FF_API_OLD_AVIO
(*s)->is_streamed = h->is_streamed;
#endif
@@ -912,7 +918,7 @@ int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size
alloc_size = FFMAX(s->buffer_size, new_size);
if (alloc_size > buf_size)
- if (!(buf = av_realloc(buf, alloc_size)))
+ if (!(buf = av_realloc_f(buf, 1, alloc_size)))
return AVERROR(ENOMEM);
if (new_size > buf_size) {
@@ -983,11 +989,11 @@ char *url_fgets(AVIOContext *s, char *buf, int buf_size)
char *q;
c = avio_r8(s);
- if (s->eof_reached)
+ if (url_feof(s))
return NULL;
q = buf;
for(;;) {
- if (s->eof_reached || c == '\n')
+ if (url_feof(s) || c == '\n')
break;
if ((q - buf) < buf_size - 1)
*q++ = c;
@@ -1081,7 +1087,7 @@ static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
}
if (new_allocated_size > d->allocated_size) {
- d->buffer = av_realloc(d->buffer, new_allocated_size);
+ d->buffer = av_realloc_f(d->buffer, 1, new_allocated_size);
if(d->buffer == NULL)
return AVERROR(ENOMEM);
d->allocated_size = new_allocated_size;
diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index 5e6f6bf5b9..3e7dd46924 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -2,20 +2,20 @@
* AVISynth support for ffmpeg system
* Copyright (c) 2006 DivX, Inc.
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -84,7 +84,8 @@ static int avisynth_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (AVIStreamReadFormat(stream->handle, 0, &wvfmt, &struct_size) != S_OK)
continue;
- st = av_new_stream(s, id);
+ st = avformat_new_stream(s, NULL);
+ st->id = id;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->block_align = wvfmt.nBlockAlign;
@@ -110,7 +111,8 @@ static int avisynth_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (AVIStreamReadFormat(stream->handle, 0, &imgfmt, &struct_size) != S_OK)
continue;
- st = av_new_stream(s, id);
+ st = avformat_new_stream(s, NULL);
+ st->id = id;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->r_frame_rate.num = stream->info.dwRate;
st->r_frame_rate.den = stream->info.dwScale;
@@ -122,6 +124,14 @@ static int avisynth_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->bit_rate = (uint64_t)stream->info.dwSampleSize * (uint64_t)stream->info.dwRate * 8 / (uint64_t)stream->info.dwScale;
st->codec->codec_tag = imgfmt.bmiHeader.biCompression;
st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, imgfmt.bmiHeader.biCompression);
+ if (st->codec->codec_id == CODEC_ID_RAWVIDEO && imgfmt.bmiHeader.biCompression== BI_RGB) {
+ st->codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (st->codec->extradata) {
+ st->codec->extradata_size = 9;
+ memcpy(st->codec->extradata, "BottomUp", 9);
+ }
+ }
+
st->duration = stream->info.dwLength;
}
@@ -165,7 +175,6 @@ static int avisynth_read_packet(AVFormatContext *s, AVPacket *pkt)
res = AVIStreamRead(stream->handle, stream->read, stream->chunck_samples, pkt->data, stream->chunck_size, &read_size, NULL);
- pkt->pts = stream->read;
pkt->size = read_size;
stream->read += stream->chunck_samples;
@@ -208,15 +217,12 @@ static int avisynth_read_seek(AVFormatContext *s, int stream_index, int64_t pts,
}
AVInputFormat ff_avisynth_demuxer = {
- "avs",
- NULL_IF_CONFIG_SMALL("AVISynth"),
- sizeof(AVISynthContext),
- NULL,
- avisynth_read_header,
- avisynth_read_packet,
- avisynth_read_close,
- avisynth_read_seek,
- NULL,
- 0,
- "avs",
+ .name = "avs",
+ .long_name = NULL_IF_CONFIG_SMALL("AVISynth"),
+ .priv_data_size = sizeof(AVISynthContext),
+ .read_header = avisynth_read_header,
+ .read_packet = avisynth_read_packet,
+ .read_close = avisynth_read_close,
+ .read_seek = avisynth_read_seek,
+ .extensions = "avs",
};
diff --git a/libavformat/avlanguage.c b/libavformat/avlanguage.c
index 787382ef13..39f2560d94 100644
--- a/libavformat/avlanguage.c
+++ b/libavformat/avlanguage.c
@@ -1,25 +1,26 @@
/*
* Cyril Comparon, Larbi Joubala, Resonate-MP4 2009
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avlanguage.h"
#include "libavutil/avstring.h"
+#include "libavutil/common.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
@@ -736,7 +737,7 @@ const char *av_convert_lang_to(const char *lang, enum AVLangCodespace target_cod
{
int i;
const LangEntry *entry = NULL;
- const int NB_CODESPACES = sizeof(lang_table_counts)/sizeof(*lang_table_counts);
+ const int NB_CODESPACES = FF_ARRAY_ELEMS(lang_table_counts);
if (target_codespace >= NB_CODESPACES)
return NULL;
diff --git a/libavformat/avlanguage.h b/libavformat/avlanguage.h
index 2ec3e2d372..7fb8968810 100644
--- a/libavformat/avlanguage.h
+++ b/libavformat/avlanguage.h
@@ -1,20 +1,20 @@
/*
* Cyril Comparon, Larbi Joubala, Resonate-MP4 2009
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/avs.c b/libavformat/avs.c
index bd9b31d0f4..492cb0b0c6 100644
--- a/libavformat/avs.c
+++ b/libavformat/avs.c
@@ -2,20 +2,20 @@
* AVS demuxer.
* Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -163,10 +163,14 @@ static int avs_read_packet(AVFormatContext * s, AVPacket * pkt)
sub_type = avio_r8(s->pb);
type = avio_r8(s->pb);
size = avio_rl16(s->pb);
+ if (size < 4)
+ return AVERROR_INVALIDDATA;
avs->remaining_frame_size -= size;
switch (type) {
case AVS_PALETTE:
+ if (size - 4 > sizeof(palette))
+ return AVERROR_INVALIDDATA;
ret = avio_read(s->pb, palette, size - 4);
if (ret < size - 4)
return AVERROR(EIO);
@@ -175,7 +179,7 @@ static int avs_read_packet(AVFormatContext * s, AVPacket * pkt)
case AVS_VIDEO:
if (!avs->st_video) {
- avs->st_video = av_new_stream(s, AVS_VIDEO);
+ avs->st_video = avformat_new_stream(s, NULL);
if (avs->st_video == NULL)
return AVERROR(ENOMEM);
avs->st_video->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -192,7 +196,7 @@ static int avs_read_packet(AVFormatContext * s, AVPacket * pkt)
case AVS_AUDIO:
if (!avs->st_audio) {
- avs->st_audio = av_new_stream(s, AVS_AUDIO);
+ avs->st_audio = avformat_new_stream(s, NULL);
if (avs->st_audio == NULL)
return AVERROR(ENOMEM);
avs->st_audio->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -216,11 +220,11 @@ static int avs_read_close(AVFormatContext * s)
}
AVInputFormat ff_avs_demuxer = {
- "avs",
- NULL_IF_CONFIG_SMALL("AVS format"),
- sizeof(AvsFormat),
- avs_probe,
- avs_read_header,
- avs_read_packet,
- avs_read_close,
+ .name = "avs",
+ .long_name = NULL_IF_CONFIG_SMALL("AVS format"),
+ .priv_data_size = sizeof(AvsFormat),
+ .read_probe = avs_probe,
+ .read_header = avs_read_header,
+ .read_packet = avs_read_packet,
+ .read_close = avs_read_close,
};
diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c
index 5e6a776824..384ac0144d 100644
--- a/libavformat/bethsoftvid.c
+++ b/libavformat/bethsoftvid.c
@@ -2,20 +2,20 @@
* Bethsoft VID format Demuxer
* Copyright (c) 2007 Nicholas Tung
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -23,8 +23,8 @@
* @file
* @brief Bethesda Softworks VID (.vid) file demuxer
* @author Nicholas Tung [ntung (at. ntung com] (2007-03)
- * @sa http://wiki.multimedia.cx/index.php?title=Bethsoft_VID
- * @sa http://www.svatopluk.com/andux/docs/dfvid.html
+ * @see http://wiki.multimedia.cx/index.php?title=Bethsoft_VID
+ * @see http://www.svatopluk.com/andux/docs/dfvid.html
*/
#include "libavutil/intreadwrite.h"
@@ -70,7 +70,7 @@ static int vid_read_header(AVFormatContext *s,
avio_skip(pb, 5);
vid->nframes = avio_rl16(pb);
- stream = av_new_stream(s, 0);
+ stream = avformat_new_stream(s, NULL);
if (!stream)
return AVERROR(ENOMEM);
av_set_pts_info(stream, 32, 1, 60); // 16 ms increments, i.e. 60 fps
@@ -83,7 +83,7 @@ static int vid_read_header(AVFormatContext *s,
avio_rl16(pb);
// done with video codec, set up audio codec
- stream = av_new_stream(s, 0);
+ stream = avformat_new_stream(s, NULL);
if (!stream)
return AVERROR(ENOMEM);
stream->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -179,7 +179,7 @@ static int vid_read_packet(AVFormatContext *s,
int audio_length;
int ret_value;
- if(vid->is_finished || pb->eof_reached)
+ if(vid->is_finished || url_feof(pb))
return AVERROR(EIO);
block_type = avio_r8(pb);
@@ -223,10 +223,10 @@ static int vid_read_packet(AVFormatContext *s,
}
AVInputFormat ff_bethsoftvid_demuxer = {
- "bethsoftvid",
- NULL_IF_CONFIG_SMALL("Bethesda Softworks VID format"),
- sizeof(BVID_DemuxContext),
- vid_probe,
- vid_read_header,
- vid_read_packet,
+ .name = "bethsoftvid",
+ .long_name = NULL_IF_CONFIG_SMALL("Bethesda Softworks VID format"),
+ .priv_data_size = sizeof(BVID_DemuxContext),
+ .read_probe = vid_probe,
+ .read_header = vid_read_header,
+ .read_packet = vid_read_packet,
};
diff --git a/libavformat/bfi.c b/libavformat/bfi.c
index bc26d47c9e..c6371049c6 100644
--- a/libavformat/bfi.c
+++ b/libavformat/bfi.c
@@ -2,20 +2,20 @@
* Brute Force & Ignorance (BFI) demuxer
* Copyright (c) 2008 Sisir Koppaka
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -23,7 +23,7 @@
* @file
* @brief Brute Force & Ignorance (.bfi) file demuxer
* @author Sisir Koppaka ( sisir.koppaka at gmail dot com )
- * @sa http://wiki.multimedia.cx/index.php?title=BFI
+ * @see http://wiki.multimedia.cx/index.php?title=BFI
*/
#include "libavutil/intreadwrite.h"
@@ -55,12 +55,12 @@ static int bfi_read_header(AVFormatContext * s, AVFormatParameters * ap)
int fps, chunk_header;
/* Initialize the video codec... */
- vstream = av_new_stream(s, 0);
+ vstream = avformat_new_stream(s, NULL);
if (!vstream)
return AVERROR(ENOMEM);
/* Initialize the audio codec... */
- astream = av_new_stream(s, 0);
+ astream = avformat_new_stream(s, NULL);
if (!astream)
return AVERROR(ENOMEM);
@@ -109,7 +109,7 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt)
BFIContext *bfi = s->priv_data;
AVIOContext *pb = s->pb;
int ret, audio_offset, video_offset, chunk_size, audio_size = 0;
- if (bfi->nframes == 0 || pb->eof_reached) {
+ if (bfi->nframes == 0 || url_feof(pb)) {
return AVERROR(EIO);
}
@@ -117,7 +117,7 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt)
if (!bfi->avflag) {
uint32_t state = 0;
while(state != MKTAG('S','A','V','I')){
- if (pb->eof_reached)
+ if (url_feof(pb))
return AVERROR(EIO);
state = 256*state + avio_r8(pb);
}
@@ -159,10 +159,10 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt)
}
AVInputFormat ff_bfi_demuxer = {
- "bfi",
- NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),
- sizeof(BFIContext),
- bfi_probe,
- bfi_read_header,
- bfi_read_packet,
+ .name = "bfi",
+ .long_name = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),
+ .priv_data_size = sizeof(BFIContext),
+ .read_probe = bfi_probe,
+ .read_header = bfi_read_header,
+ .read_packet = bfi_read_packet,
};
diff --git a/libavformat/bink.c b/libavformat/bink.c
index 76b457c21b..844498e6f8 100644
--- a/libavformat/bink.c
+++ b/libavformat/bink.c
@@ -3,20 +3,20 @@
* Copyright (c) 2008-2010 Peter Ross (pross@xvid.org)
* Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu)
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -78,7 +78,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
uint16_t flags;
int keyframe;
- vst = av_new_stream(s, 0);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
@@ -130,17 +130,22 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
avio_skip(pb, 4 * bink->num_audio_tracks);
for (i = 0; i < bink->num_audio_tracks; i++) {
- ast = av_new_stream(s, 1);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- ast->codec->codec_tag = vst->codec->codec_tag;
+ ast->codec->codec_tag = 0;
ast->codec->sample_rate = avio_rl16(pb);
av_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
flags = avio_rl16(pb);
ast->codec->codec_id = flags & BINK_AUD_USEDCT ?
CODEC_ID_BINKAUDIO_DCT : CODEC_ID_BINKAUDIO_RDFT;
ast->codec->channels = flags & BINK_AUD_STEREO ? 2 : 1;
+ ast->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!ast->codec->extradata)
+ return AVERROR(ENOMEM);
+ ast->codec->extradata_size = 4;
+ AV_WL32(ast->codec->extradata, vst->codec->codec_tag);
}
for (i = 0; i < bink->num_audio_tracks; i++)
@@ -251,7 +256,9 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in
return -1;
/* seek to the first frame */
- avio_seek(s->pb, vst->index_entries[0].pos, SEEK_SET);
+ if (avio_seek(s->pb, vst->index_entries[0].pos, SEEK_SET) < 0)
+ return -1;
+
bink->video_pts = 0;
memset(bink->audio_pts, 0, sizeof(bink->audio_pts));
bink->current_track = -1;
@@ -259,12 +266,11 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in
}
AVInputFormat ff_bink_demuxer = {
- "bink",
- NULL_IF_CONFIG_SMALL("Bink"),
- sizeof(BinkDemuxContext),
- probe,
- read_header,
- read_packet,
- NULL,
- read_seek,
+ .name = "bink",
+ .long_name = NULL_IF_CONFIG_SMALL("Bink"),
+ .priv_data_size = sizeof(BinkDemuxContext),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
+ .read_seek = read_seek,
};
diff --git a/libavformat/bintext.c b/libavformat/bintext.c
new file mode 100644
index 0000000000..e03a31e447
--- /dev/null
+++ b/libavformat/bintext.c
@@ -0,0 +1,375 @@
+/*
+ * Binary text demuxer
+ * eXtended BINary text (XBIN) demuxer
+ * Artworx Data Format demuxer
+ * iCEDraw File demuxer
+ * Copyright (c) 2010 Peter Ross <pross@xvid.org>
+ *
+ * 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
+ * Binary text demuxer
+ * eXtended BINary text (XBIN) demuxer
+ * Artworx Data Format demuxer
+ * iCEDraw File demuxer
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "sauce.h"
+#include "libavcodec/bintext.h"
+
+#define LINE_RATE 6000 /** characters per second */
+
+typedef struct {
+ int chars_per_frame;
+ uint64_t fsize; /**< file size less metadata buffer */
+} BinDemuxContext;
+
+#if CONFIG_BINTEXT_DEMUXER | CONFIG_ADF_DEMUXER | CONFIG_IDF_DEMUXER
+/**
+ * Given filesize and width, calculate height (assume font_height of 16)
+ */
+static void calculate_height(AVCodecContext *avctx, uint64_t fsize)
+{
+ avctx->height = (fsize / ((avctx->width>>3)*2)) << 4;
+}
+#endif
+
+#if CONFIG_BINTEXT_DEMUXER
+static const uint8_t next_magic[]={
+ 0x1A, 0x1B, '[', '0', ';', '3', '0', ';', '4', '0', 'm', 'N', 'E', 'X', 'T', 0x00
+};
+
+static int next_tag_read(AVFormatContext *avctx, uint64_t *fsize)
+{
+ ByteIOContext *pb = avctx->pb;
+ char buf[36];
+ int len;
+ uint64_t start_pos = url_fsize(pb) - 256;
+
+ url_fseek(pb, start_pos, SEEK_SET);
+ if (get_buffer(pb, buf, sizeof(next_magic)) != sizeof(next_magic))
+ return -1;
+ if (memcmp(buf, next_magic, sizeof(next_magic)))
+ return -1;
+ if (get_byte(pb) != 0x01)
+ return -1;
+
+ *fsize -= 256;
+
+#define GET_EFI2_META(name,size) \
+ len = get_byte(pb); \
+ if (len < 1 || len > size) \
+ return -1; \
+ if (get_buffer(pb, buf, size) == size && *buf) { \
+ buf[len] = 0; \
+ av_metadata_set2(&avctx->metadata, name, buf, 0); \
+ }
+
+ GET_EFI2_META("filename", 12)
+ GET_EFI2_META("author", 20)
+ GET_EFI2_META("publisher", 20)
+ GET_EFI2_META("title", 35)
+
+ return 0;
+}
+
+static void predict_width(AVCodecContext *avctx, uint64_t fsize, int got_width)
+{
+ /** attempt to guess width */
+ if (!got_width)
+ avctx->width = fsize > 4000 ? (160<<3) : (80<<3);
+}
+
+static AVStream * init_stream(AVFormatContext *s,
+ AVFormatParameters *ap)
+{
+ BinDemuxContext *bin = s->priv_data;
+ AVStream *st = av_new_stream(s, 0);
+ if (!st)
+ return NULL;
+ st->codec->codec_tag = 0;
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+
+ if (!ap->time_base.num) {
+ av_set_pts_info(st, 60, 1, 25);
+ } else {
+ av_set_pts_info(st, 60, ap->time_base.num, ap->time_base.den);
+ }
+
+ /* simulate tty display speed */
+ bin->chars_per_frame = FFMAX(av_q2d(st->time_base) * (ap->sample_rate ? ap->sample_rate : LINE_RATE), 1);
+
+ st->codec->width = ap->width ? ap->width : (80<<3);
+ st->codec->height = ap->height ? ap->height : (25<<4);
+ return st;
+}
+
+static int bintext_read_header(AVFormatContext *s,
+ AVFormatParameters *ap)
+{
+ BinDemuxContext *bin = s->priv_data;
+ ByteIOContext *pb = s->pb;
+
+ AVStream *st = init_stream(s, ap);
+ if (!st)
+ return AVERROR(ENOMEM);
+ st->codec->codec_id = CODEC_ID_BINTEXT;
+
+ st->codec->extradata_size = 2;
+ st->codec->extradata = av_malloc(st->codec->extradata_size);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+ st->codec->extradata[0] = 16;
+ st->codec->extradata[1] = 0;
+
+ if (!url_is_streamed(pb)) {
+ int got_width = 0;
+ bin->fsize = url_fsize(pb);
+ if (ff_sauce_read(s, &bin->fsize, &got_width, 0) < 0)
+ next_tag_read(s, &bin->fsize);
+ if (!ap->width)
+ predict_width(st->codec, bin->fsize, got_width);
+ if (!ap->height)
+ calculate_height(st->codec, bin->fsize);
+ url_fseek(pb, 0, SEEK_SET);
+ }
+ return 0;
+};
+#endif /* CONFIG_BINTEXT_DEMUXER */
+
+#if CONFIG_XBIN_DEMUXER
+static int xbin_probe(AVProbeData *p)
+{
+ const uint8_t *d = p->buf;
+
+ if (AV_RL32(d) == MKTAG('X','B','I','N') && d[4] == 0x1A &&
+ AV_RL16(d+5) > 0 && AV_RL16(d+5) <= 160 &&
+ d[9] > 0 && d[9] <= 32)
+ return AVPROBE_SCORE_MAX;
+ return 0;
+}
+
+static int xbin_read_header(AVFormatContext *s,
+ AVFormatParameters *ap)
+{
+ BinDemuxContext *bin = s->priv_data;
+ ByteIOContext *pb = s->pb;
+ char fontheight, flags;
+
+ AVStream *st = init_stream(s, ap);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ url_fskip(pb, 5);
+ st->codec->width = get_le16(pb)<<3;
+ st->codec->height = get_le16(pb);
+ fontheight = get_byte(pb);
+ st->codec->height *= fontheight;
+ flags = get_byte(pb);
+
+ st->codec->extradata_size = 2;
+ if ((flags & BINTEXT_PALETTE))
+ st->codec->extradata_size += 48;
+ if ((flags & BINTEXT_FONT))
+ st->codec->extradata_size += fontheight * (flags & 0x10 ? 512 : 256);
+ st->codec->codec_id = flags & 4 ? CODEC_ID_XBIN : CODEC_ID_BINTEXT;
+
+ st->codec->extradata = av_malloc(st->codec->extradata_size);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+ st->codec->extradata[0] = fontheight;
+ st->codec->extradata[1] = flags;
+ if (get_buffer(pb, st->codec->extradata + 2, st->codec->extradata_size - 2) < 0)
+ return AVERROR(EIO);
+
+ if (!url_is_streamed(pb)) {
+ bin->fsize = url_fsize(pb) - 9 - st->codec->extradata_size;
+ ff_sauce_read(s, &bin->fsize, NULL, 0);
+ url_fseek(pb, 9 + st->codec->extradata_size, SEEK_SET);
+ }
+
+ return 0;
+}
+#endif /* CONFIG_XBIN_DEMUXER */
+
+#if CONFIG_ADF_DEMUXER
+static int adf_read_header(AVFormatContext *s,
+ AVFormatParameters *ap)
+{
+ BinDemuxContext *bin = s->priv_data;
+ ByteIOContext *pb = s->pb;
+ AVStream *st;
+
+ if (get_byte(pb) != 1)
+ return AVERROR_INVALIDDATA;
+
+ st = init_stream(s, ap);
+ if (!st)
+ return AVERROR(ENOMEM);
+ st->codec->codec_id = CODEC_ID_BINTEXT;
+
+ st->codec->extradata_size = 2 + 48 + 4096;
+ st->codec->extradata = av_malloc(st->codec->extradata_size);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+ st->codec->extradata[0] = 16;
+ st->codec->extradata[1] = BINTEXT_PALETTE|BINTEXT_FONT;
+
+ if (get_buffer(pb, st->codec->extradata + 2, 24) < 0)
+ return AVERROR(EIO);
+ url_fskip(pb, 144);
+ if (get_buffer(pb, st->codec->extradata + 2 + 24, 24) < 0)
+ return AVERROR(EIO);
+ if (get_buffer(pb, st->codec->extradata + 2 + 48, 4096) < 0)
+ return AVERROR(EIO);
+
+ if (!url_is_streamed(pb)) {
+ int got_width = 0;
+ bin->fsize = url_fsize(pb) - 1 - 192 - 4096;
+ st->codec->width = 80<<3;
+ ff_sauce_read(s, &bin->fsize, &got_width, 0);
+ if (!ap->height)
+ calculate_height(st->codec, bin->fsize);
+ url_fseek(pb, 1 + 192 + 4096, SEEK_SET);
+ }
+ return 0;
+}
+#endif /* CONFIG_ADF_DEMUXER */
+
+#if CONFIG_IDF_DEMUXER
+static const uint8_t idf_magic[] = {
+ 0x04, 0x31, 0x2e, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x15, 0x00
+};
+
+static int idf_probe(AVProbeData *p)
+{
+ if (p->buf_size < sizeof(idf_magic))
+ return 0;
+ if (!memcmp(p->buf, idf_magic, sizeof(idf_magic)))
+ return AVPROBE_SCORE_MAX;
+ return 0;
+}
+
+static int idf_read_header(AVFormatContext *s,
+ AVFormatParameters *ap)
+{
+ BinDemuxContext *bin = s->priv_data;
+ ByteIOContext *pb = s->pb;
+ AVStream *st;
+ int got_width = 0;
+
+ if (url_is_streamed(pb))
+ return AVERROR(EIO);
+
+ st = init_stream(s, ap);
+ if (!st)
+ return AVERROR(ENOMEM);
+ st->codec->codec_id = CODEC_ID_IDF;
+
+ st->codec->extradata_size = 2 + 48 + 4096;
+ st->codec->extradata = av_malloc(st->codec->extradata_size);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+ st->codec->extradata[0] = 16;
+ st->codec->extradata[1] = BINTEXT_PALETTE|BINTEXT_FONT;
+
+ url_fseek(pb, url_fsize(pb) - 4096 - 48, SEEK_SET);
+
+ if (get_buffer(pb, st->codec->extradata + 2 + 48, 4096) < 0)
+ return AVERROR(EIO);
+ if (get_buffer(pb, st->codec->extradata + 2, 48) < 0)
+ return AVERROR(EIO);
+
+ bin->fsize = url_fsize(pb) - 12 - 4096 - 48;
+ ff_sauce_read(s, &bin->fsize, &got_width, 0);
+ if (!ap->height)
+ calculate_height(st->codec, bin->fsize);
+ url_fseek(pb, 12, SEEK_SET);
+ return 0;
+}
+#endif /* CONFIG_IDF_DEMUXER */
+
+static int read_packet(AVFormatContext *s,
+ AVPacket *pkt)
+{
+ BinDemuxContext *bin = s->priv_data;
+
+ if (bin->fsize > 0) {
+ if (av_get_packet(s->pb, pkt, bin->fsize) < 0)
+ return AVERROR(EIO);
+ bin->fsize = -1; /* done */
+ } else if (!bin->fsize) {
+ if (url_feof(s->pb))
+ return AVERROR(EIO);
+ if (av_get_packet(s->pb, pkt, bin->chars_per_frame) < 0)
+ return AVERROR(EIO);
+ } else {
+ return AVERROR(EIO);
+ }
+
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ return 0;
+}
+
+#if CONFIG_BINTEXT_DEMUXER
+AVInputFormat ff_bintext_demuxer = {
+ .name = "bin",
+ .long_name = NULL_IF_CONFIG_SMALL("Binary text"),
+ .priv_data_size = sizeof(BinDemuxContext),
+ .read_header = bintext_read_header,
+ .read_packet = read_packet,
+ .extensions = "bin",
+};
+#endif
+
+#if CONFIG_XBIN_DEMUXER
+AVInputFormat ff_xbin_demuxer = {
+ .name = "xbin",
+ .long_name = NULL_IF_CONFIG_SMALL("eXtended BINary text (XBIN)"),
+ .priv_data_size = sizeof(BinDemuxContext),
+ .read_probe = xbin_probe,
+ .read_header = xbin_read_header,
+ .read_packet = read_packet,
+};
+#endif
+
+#if CONFIG_ADF_DEMUXER
+AVInputFormat ff_adf_demuxer = {
+ .name = "adf",
+ .long_name = NULL_IF_CONFIG_SMALL("Artworx Data Format"),
+ .priv_data_size = sizeof(BinDemuxContext),
+ .read_header = adf_read_header,
+ .read_packet = read_packet,
+ .extensions = "adf",
+};
+#endif
+
+#if CONFIG_IDF_DEMUXER
+AVInputFormat ff_idf_demuxer = {
+ .name = "idf",
+ .long_name = NULL_IF_CONFIG_SMALL("iCE Draw File"),
+ .priv_data_size = sizeof(BinDemuxContext),
+ .read_probe = idf_probe,
+ .read_header = idf_read_header,
+ .read_packet = read_packet,
+ .extensions = "idf",
+};
+#endif
diff --git a/libavformat/bit.c b/libavformat/bit.c
new file mode 100644
index 0000000000..d72d2a8961
--- /dev/null
+++ b/libavformat/bit.c
@@ -0,0 +1,135 @@
+#include "avformat.h"
+#include "libavcodec/get_bits.h"
+#include "libavcodec/put_bits.h"
+
+#define MAX_FRAME_SIZE 10
+
+#define SYNC_WORD 0x6b21
+#define BIT_0 0x7f
+#define BIT_1 0x81
+
+static int probe(AVProbeData *p)
+{
+ int i, j;
+
+ if(p->buf_size < 0x40)
+ return 0;
+
+ for(i=0; i+3<p->buf_size && i< 10*0x50; ){
+ if(AV_RL16(&p->buf[0]) != SYNC_WORD)
+ return 0;
+ j=AV_RL16(&p->buf[2]);
+ if(j!=0x40 && j!=0x50)
+ return 0;
+ i+=j;
+ }
+ return AVPROBE_SCORE_MAX/2;
+}
+
+static int read_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+ AVStream* st;
+
+ st=av_new_stream(s, 0);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id=CODEC_ID_G729;
+ st->codec->sample_rate=8000;
+ st->codec->block_align = 16;
+ st->codec->channels=1;
+
+ av_set_pts_info(st, 64, 1, 100);
+ return 0;
+}
+
+static int read_packet(AVFormatContext *s,
+ AVPacket *pkt)
+{
+ ByteIOContext *pb = s->pb;
+ PutBitContext pbo;
+ uint16_t buf[8 * MAX_FRAME_SIZE + 2];
+ int packet_size;
+ uint16_t* src=buf;
+ int i, j, ret;
+ int64_t pos= avio_tell(pb);
+
+ if(url_feof(pb))
+ return AVERROR_EOF;
+
+ get_le16(pb); // sync word
+ packet_size = get_le16(pb) / 8;
+ if(packet_size > MAX_FRAME_SIZE)
+ return AVERROR_INVALIDDATA;
+
+ ret = get_buffer(pb, (uint8_t*)buf, (8 * packet_size) * sizeof(uint16_t));
+ if(ret<0)
+ return ret;
+ if(ret != 8 * packet_size * sizeof(uint16_t))
+ return AVERROR(EIO);
+
+ av_new_packet(pkt, packet_size);
+
+ init_put_bits(&pbo, pkt->data, packet_size);
+ for(j=0; j < packet_size; j++)
+ for(i=0; i<8;i++)
+ put_bits(&pbo,1, AV_RL16(src++) == BIT_1 ? 1 : 0);
+
+ flush_put_bits(&pbo);
+
+ pkt->duration=1;
+ pkt->pos = pos;
+ return 0;
+}
+
+AVInputFormat ff_bit_demuxer = {
+ .name = "bit",
+ .long_name = NULL_IF_CONFIG_SMALL("G.729 BIT file format"),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
+ .extensions = "bit",
+};
+
+#ifdef CONFIG_MUXERS
+static int write_header(AVFormatContext *s)
+{
+ AVCodecContext *enc = s->streams[0]->codec;
+
+ enc->codec_id = CODEC_ID_G729;
+ enc->channels = 1;
+ enc->bits_per_coded_sample = 16;
+ enc->block_align = (enc->bits_per_coded_sample * enc->channels) >> 3;
+
+ return 0;
+}
+
+static int write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ ByteIOContext *pb = s->pb;
+ GetBitContext gb;
+ int i;
+
+ put_le16(pb, SYNC_WORD);
+ put_le16(pb, 8 * 10);
+
+ init_get_bits(&gb, pkt->data, 8*10);
+ for(i=0; i< 8 * 10; i++)
+ put_le16(pb, get_bits1(&gb) ? BIT_1 : BIT_0);
+ put_flush_packet(pb);
+
+ return 0;
+}
+
+AVOutputFormat ff_bit_muxer = {
+ .name = "bit",
+ .long_name = NULL_IF_CONFIG_SMALL("G.729 BIT file format"),
+ .mime_type = "audio/bit",
+ .extensions = "bit",
+ .audio_codec = CODEC_ID_G729,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = write_header,
+ .write_packet = write_packet,
+};
+#endif
diff --git a/libavformat/c93.c b/libavformat/c93.c
index 097565a335..0f4be89545 100644
--- a/libavformat/c93.c
+++ b/libavformat/c93.c
@@ -2,20 +2,20 @@
* Interplay C93 demuxer
* Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -79,7 +79,7 @@ static int read_header(AVFormatContext *s,
/* Audio streams are added if audio packets are found */
s->ctx_flags |= AVFMTCTX_NOHEADER;
- video = av_new_stream(s, 0);
+ video = avformat_new_stream(s, NULL);
if (!video)
return AVERROR(ENOMEM);
@@ -117,7 +117,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
datasize = avio_rl16(pb);
if (datasize > 42) {
if (!c93->audio) {
- c93->audio = av_new_stream(s, 1);
+ c93->audio = avformat_new_stream(s, NULL);
if (!c93->audio)
return AVERROR(ENOMEM);
c93->audio->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -193,10 +193,10 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_c93_demuxer = {
- "c93",
- NULL_IF_CONFIG_SMALL("Interplay C93"),
- sizeof(C93DemuxContext),
- probe,
- read_header,
- read_packet,
+ .name = "c93",
+ .long_name = NULL_IF_CONFIG_SMALL("Interplay C93"),
+ .priv_data_size = sizeof(C93DemuxContext),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
};
diff --git a/libavformat/cache.c b/libavformat/cache.c
new file mode 100644
index 0000000000..74f008e0d1
--- /dev/null
+++ b/libavformat/cache.c
@@ -0,0 +1,144 @@
+/*
+ * Input cache protocol.
+ * Copyright (c) 2011 Michael Niedermayer
+ *
+ * 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
+ *
+ * Based on file.c by Fabrice Bellard
+ */
+
+/**
+ * @TODO
+ * support non continuous caching
+ * support keeping files
+ * support filling with a background thread
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/file.h"
+#include "avformat.h"
+#include <fcntl.h>
+#if HAVE_SETMODE
+#include <io.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include "os_support.h"
+#include "url.h"
+
+typedef struct Context {
+ int fd;
+ int64_t end;
+ int64_t pos;
+ URLContext *inner;
+} Context;
+
+static int cache_open(URLContext *h, const char *arg, int flags)
+{
+ int access;
+ const char *buffername;
+ Context *c;
+
+ c = av_mallocz(sizeof(Context));
+ if (!c) {
+ return AVERROR(ENOMEM);
+ }
+ h->priv_data = c;
+
+ av_strstart(arg, "cache:", &arg);
+
+ c->fd = av_tempfile("ffcache", &buffername, 0, h);
+ if (c->fd < 0){
+ av_log(h, AV_LOG_ERROR, "Failed to create tempfile\n");
+ return c->fd;
+ }
+
+ unlink(buffername);
+ av_free(buffername);
+
+ return ffurl_open(&c->inner, arg, flags);
+}
+
+static int cache_read(URLContext *h, unsigned char *buf, int size)
+{
+ Context *c= h->priv_data;
+ int r;
+
+ if(c->pos<c->end){
+ r = read(c->fd, buf, FFMIN(size, c->end - c->pos));
+ if(r>0)
+ c->pos += r;
+ return (-1 == r)?AVERROR(errno):r;
+ }else{
+ r = ffurl_read(c->inner, buf, size);
+ if(r > 0){
+ int r2= write(c->fd, buf, r);
+ av_assert0(r2==r); // FIXME handle cache failure
+ c->pos += r;
+ c->end += r;
+ }
+ return r;
+ }
+}
+
+static int64_t cache_seek(URLContext *h, int64_t pos, int whence)
+{
+ Context *c= h->priv_data;
+
+ if (whence == AVSEEK_SIZE) {
+ pos= ffurl_seek(c->inner, pos, whence);
+ if(pos <= 0){
+ pos= ffurl_seek(c->inner, -1, SEEK_END);
+ ffurl_seek(c->inner, c->end, SEEK_SET);
+ if(pos <= 0)
+ return c->end;
+ }
+ return pos;
+ }
+
+ pos= lseek(c->fd, pos, whence);
+ if(pos<0){
+ return pos;
+ }else if(pos <= c->end){
+ c->pos= pos;
+ return pos;
+ }else{
+ lseek(c->fd, c->pos, SEEK_SET);
+ return AVERROR(EPIPE);
+ }
+}
+
+static int cache_close(URLContext *h)
+{
+ Context *c= h->priv_data;
+ close(c->fd);
+ ffurl_close(c->inner);
+
+ av_freep(&h->priv_data);
+
+ return 0;
+}
+
+URLProtocol ff_cache_protocol = {
+ .name = "cache",
+ .url_open = cache_open,
+ .url_read = cache_read,
+ .url_seek = cache_seek,
+ .url_close = cache_close,
+};
diff --git a/libavformat/caf.c b/libavformat/caf.c
index c204c90ad1..054533038f 100644
--- a/libavformat/caf.c
+++ b/libavformat/caf.c
@@ -2,20 +2,20 @@
* CAF common code
* Copyright (c) 2007 Justin Ruggles
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -32,27 +32,34 @@
* Known codec tags for CAF
*/
const AVCodecTag ff_codec_caf_tags[] = {
- { CODEC_ID_AAC, MKBETAG('a','a','c',' ') },
- { CODEC_ID_AC3, MKBETAG('a','c','-','3') },
- { CODEC_ID_ALAC, MKBETAG('a','l','a','c') },
+ { CODEC_ID_AAC, MKTAG('a','a','c',' ') },
+ { CODEC_ID_AC3, MKTAG('a','c','-','3') },
+ { CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') },
+ { CODEC_ID_ADPCM_IMA_WAV, MKTAG('m','s', 0, 17 ) },
+ { CODEC_ID_ADPCM_MS, MKTAG('m','s', 0, 2 ) },
+ { CODEC_ID_ALAC, MKTAG('a','l','a','c') },
+ { CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
/* FIXME: use DV demuxer, as done in MOV */
- /*{ CODEC_ID_DVAUDIO, MKBETAG('v','d','v','a') },*/
- /*{ CODEC_ID_DVAUDIO, MKBETAG('d','v','c','a') },*/
- { CODEC_ID_ADPCM_IMA_QT, MKBETAG('i','m','a','4') },
- { CODEC_ID_MACE3, MKBETAG('M','A','C','3') },
- { CODEC_ID_MACE6, MKBETAG('M','A','C','6') },
- { CODEC_ID_MP3, MKBETAG('.','m','p','3') },
- { CODEC_ID_MP2, MKBETAG('.','m','p','2') },
- { CODEC_ID_MP1, MKBETAG('.','m','p','1') },
- { CODEC_ID_PCM_ALAW, MKBETAG('a','l','a','w') },
- { CODEC_ID_PCM_MULAW, MKBETAG('u','l','a','w') },
- { CODEC_ID_QCELP, MKBETAG('Q','c','l','p') },
- { CODEC_ID_QDM2, MKBETAG('Q','D','M','2') },
- { CODEC_ID_QDM2, MKBETAG('Q','D','M','C') },
+ /*{ CODEC_ID_DVAUDIO, MKTAG('v','d','v','a') },*/
+ /*{ CODEC_ID_DVAUDIO, MKTAG('d','v','c','a') },*/
+ { CODEC_ID_GSM, MKTAG('a','g','s','m') },
+ { CODEC_ID_GSM_MS, MKTAG('m','s', 0, '1') },
+ { CODEC_ID_MACE3, MKTAG('M','A','C','3') },
+ { CODEC_ID_MACE6, MKTAG('M','A','C','6') },
+ { CODEC_ID_MP1, MKTAG('.','m','p','1') },
+ { CODEC_ID_MP2, MKTAG('.','m','p','2') },
+ { CODEC_ID_MP3, MKTAG('.','m','p','3') },
+ { CODEC_ID_MP3, MKTAG('m','s', 0 ,'U') },
+ { CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') },
+ { CODEC_ID_PCM_MULAW, MKTAG('u','l','a','w') },
+ { CODEC_ID_QCELP, MKTAG('Q','c','l','p') },
+ { CODEC_ID_QDM2, MKTAG('Q','D','M','2') },
+ { CODEC_ID_QDM2, MKTAG('Q','D','M','C') },
/* currently unsupported codecs */
- /*{ AC-3 over S/PDIF MKBETAG('c','a','c','3') },*/
- /*{ MPEG4CELP MKBETAG('c','e','l','p') },*/
- /*{ MPEG4HVXC MKBETAG('h','v','x','c') },*/
- /*{ MPEG4TwinVQ MKBETAG('t','w','v','q') },*/
+ /*{ AC-3 over S/PDIF MKTAG('c','a','c','3') },*/
+ /*{ MPEG4CELP MKTAG('c','e','l','p') },*/
+ /*{ MPEG4HVXC MKTAG('h','v','x','c') },*/
+ /*{ MPEG4TwinVQ MKTAG('t','w','v','q') },*/
{ CODEC_ID_NONE, 0 },
};
+
diff --git a/libavformat/caf.h b/libavformat/caf.h
index 7ca4dc5c66..9c25f2c683 100644
--- a/libavformat/caf.h
+++ b/libavformat/caf.h
@@ -2,20 +2,20 @@
* CAF common code
* Copyright (c) 2007 Justin Ruggles
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c
index 68686cab97..2b747ce8c4 100644
--- a/libavformat/cafdec.c
+++ b/libavformat/cafdec.c
@@ -3,20 +3,20 @@
* Copyright (c) 2007 Justin Ruggles
* Copyright (c) 2009 Peter Ross
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -61,14 +61,14 @@ static int read_desc_chunk(AVFormatContext *s)
int flags;
/* new audio stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
/* parse format description */
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->sample_rate = av_int2dbl(avio_rb64(pb));
- st->codec->codec_tag = avio_rb32(pb);
+ st->codec->codec_tag = avio_rl32(pb);
flags = avio_rb32(pb);
caf->bytes_per_packet = avio_rb32(pb);
st->codec->block_align = caf->bytes_per_packet;
@@ -85,7 +85,7 @@ static int read_desc_chunk(AVFormatContext *s)
}
/* determine codec */
- if (st->codec->codec_tag == MKBETAG('l','p','c','m'))
+ if (st->codec->codec_tag == MKTAG('l','p','c','m'))
st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, (flags ^ 0x2) | 0x4);
else
st->codec->codec_id = ff_codec_get_id(ff_codec_caf_tags, st->codec->codec_tag);
@@ -187,8 +187,8 @@ static void read_info_chunk(AVFormatContext *s, int64_t size)
for (i = 0; i < nb_entries; i++) {
char key[32];
char value[1024];
- avio_get_str(pb, INT_MAX, key, sizeof(key));
- avio_get_str(pb, INT_MAX, value, sizeof(value));
+ get_strz(pb, key, sizeof(key));
+ get_strz(pb, value, sizeof(value));
av_dict_set(&s->metadata, key, value, 0);
}
}
@@ -221,7 +221,7 @@ static int read_header(AVFormatContext *s,
/* parse each chunk */
found_data = 0;
- while (!pb->eof_reached) {
+ while (!url_feof(pb)) {
/* stop at data chunk if seeking is not supported or
data chunk size is unknown */
@@ -230,7 +230,7 @@ static int read_header(AVFormatContext *s,
tag = avio_rb32(pb);
size = avio_rb64(pb);
- if (pb->eof_reached)
+ if (url_feof(pb))
break;
switch (tag) {
@@ -259,10 +259,16 @@ static int read_header(AVFormatContext *s,
read_info_chunk(s, size);
break;
+ case MKBETAG('c','h','a','n'):
+ if (size < 12)
+ return AVERROR_INVALIDDATA;
+ ff_mov_read_chan(s, size, st->codec);
+ break;
+
default:
#define _(x) ((x) >= ' ' ? (x) : ' ')
- av_log(s, AV_LOG_WARNING, "skipping CAF chunk: %08X (%c%c%c%c)\n",
- tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF));
+ av_log(s, AV_LOG_WARNING, "skipping CAF chunk: %08X (%c%c%c%c), size %"PRId64"\n",
+ tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF), size);
#undef _
case MKBETAG('f','r','e','e'):
if (size < 0)
@@ -286,8 +292,6 @@ static int read_header(AVFormatContext *s,
"block size or frame size are variable.\n");
return AVERROR_INVALIDDATA;
}
- s->file_size = avio_size(pb);
- s->file_size = FFMAX(0, s->file_size);
av_set_pts_info(st, 64, 1, st->codec->sample_rate);
st->start_time = 0;
@@ -309,7 +313,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
int res, pkt_size = 0, pkt_frames = 0;
int64_t left = CAF_MAX_PKT_SIZE;
- if (pb->eof_reached)
+ if (url_feof(pb))
return AVERROR(EIO);
/* don't read past end of data chunk */
@@ -360,6 +364,7 @@ static int read_seek(AVFormatContext *s, int stream_index,
{
AVStream *st = s->streams[0];
CaffContext *caf = s->priv_data;
+ CaffContext caf2 = *caf;
int64_t pos;
timestamp = FFMAX(timestamp, 0);
@@ -379,18 +384,20 @@ static int read_seek(AVFormatContext *s, int stream_index,
return -1;
}
- avio_seek(s->pb, pos + caf->data_start, SEEK_SET);
+ if (avio_seek(s->pb, pos + caf->data_start, SEEK_SET) < 0) {
+ *caf = caf2;
+ return -1;
+ }
return 0;
}
AVInputFormat ff_caf_demuxer = {
- "caf",
- NULL_IF_CONFIG_SMALL("Apple Core Audio Format"),
- sizeof(CaffContext),
- probe,
- read_header,
- read_packet,
- NULL,
- read_seek,
+ .name = "caf",
+ .long_name = NULL_IF_CONFIG_SMALL("Apple Core Audio Format"),
+ .priv_data_size = sizeof(CaffContext),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
+ .read_seek = read_seek,
.codec_tag = (const AVCodecTag*[]){ff_codec_caf_tags, 0},
};
diff --git a/libavformat/cafenc.c b/libavformat/cafenc.c
new file mode 100644
index 0000000000..0dd4b349ca
--- /dev/null
+++ b/libavformat/cafenc.c
@@ -0,0 +1,262 @@
+/*
+ * Core Audio Format muxer
+ * Copyright (c) 2011 Carl Eugen Hoyos
+ *
+ * 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 "avformat.h"
+#include "caf.h"
+#include "riff.h"
+#include "isom.h"
+#include "avio_internal.h"
+#include "libavutil/intfloat_readwrite.h"
+
+typedef struct {
+ int64_t data;
+ uint8_t *pkt_sizes;
+ int size_buffer_size;
+ int size_entries_used;
+ int packets;
+} CAFContext;
+
+static uint32_t codec_flags(enum CodecID codec_id) {
+ switch (codec_id) {
+ case CODEC_ID_PCM_F32BE:
+ case CODEC_ID_PCM_F64BE:
+ return 1; //< kCAFLinearPCMFormatFlagIsFloat
+ case CODEC_ID_PCM_S16LE:
+ case CODEC_ID_PCM_S24LE:
+ case CODEC_ID_PCM_S32LE:
+ return 2; //< kCAFLinearPCMFormatFlagIsLittleEndian
+ case CODEC_ID_PCM_F32LE:
+ case CODEC_ID_PCM_F64LE:
+ return 3; //< kCAFLinearPCMFormatFlagIsFloat | kCAFLinearPCMFormatFlagIsLittleEndian
+ default:
+ return 0;
+ }
+}
+
+static uint32_t samples_per_packet(enum CodecID codec_id, int channels) {
+ switch (codec_id) {
+ case CODEC_ID_PCM_S8:
+ case CODEC_ID_PCM_S16LE:
+ case CODEC_ID_PCM_S16BE:
+ case CODEC_ID_PCM_S24LE:
+ case CODEC_ID_PCM_S24BE:
+ case CODEC_ID_PCM_S32LE:
+ case CODEC_ID_PCM_S32BE:
+ case CODEC_ID_PCM_F32LE:
+ case CODEC_ID_PCM_F32BE:
+ case CODEC_ID_PCM_F64LE:
+ case CODEC_ID_PCM_F64BE:
+ case CODEC_ID_PCM_ALAW:
+ case CODEC_ID_PCM_MULAW:
+ return 1;
+ case CODEC_ID_MACE3:
+ case CODEC_ID_MACE6:
+ return 6;
+ case CODEC_ID_ADPCM_IMA_QT:
+ return 64;
+ case CODEC_ID_AMR_NB:
+ case CODEC_ID_GSM:
+ case CODEC_ID_QCELP:
+ return 160;
+ case CODEC_ID_GSM_MS:
+ return 320;
+ case CODEC_ID_MP1:
+ return 384;
+ case CODEC_ID_MP2:
+ case CODEC_ID_MP3:
+ return 1152;
+ case CODEC_ID_AC3:
+ return 1536;
+ case CODEC_ID_ALAC:
+ case CODEC_ID_QDM2:
+ return 4096;
+ case CODEC_ID_ADPCM_IMA_WAV:
+ return (1024 - 4 * channels) * 8 / (4 * channels) + 1;
+ case CODEC_ID_ADPCM_MS:
+ return (1024 - 7 * channels) * 2 / channels + 2;
+ default:
+ return 0;
+ }
+}
+
+static int caf_write_header(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ AVCodecContext *enc = s->streams[0]->codec;
+ CAFContext *caf = s->priv_data;
+ unsigned int codec_tag = ff_codec_get_tag(ff_codec_caf_tags, enc->codec_id);
+
+ switch (enc->codec_id) {
+ case CODEC_ID_AAC:
+ case CODEC_ID_AC3:
+ av_log(s, AV_LOG_ERROR, "muxing codec currently unsupported\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ switch (enc->codec_id) {
+ case CODEC_ID_PCM_S8:
+ case CODEC_ID_PCM_S16LE:
+ case CODEC_ID_PCM_S16BE:
+ case CODEC_ID_PCM_S24LE:
+ case CODEC_ID_PCM_S24BE:
+ case CODEC_ID_PCM_S32LE:
+ case CODEC_ID_PCM_S32BE:
+ case CODEC_ID_PCM_F32LE:
+ case CODEC_ID_PCM_F32BE:
+ case CODEC_ID_PCM_F64LE:
+ case CODEC_ID_PCM_F64BE:
+ case CODEC_ID_PCM_ALAW:
+ case CODEC_ID_PCM_MULAW:
+ codec_tag = MKTAG('l','p','c','m');
+ }
+
+ if (!codec_tag) {
+ av_log(s, AV_LOG_ERROR, "unsupported codec\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!enc->block_align && !pb->seekable) {
+ av_log(s, AV_LOG_ERROR, "Muxing variable packet size not supported on non seekable output\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ ffio_wfourcc(pb, "caff"); //< mFileType
+ avio_wb16(pb, 1); //< mFileVersion
+ avio_wb16(pb, 0); //< mFileFlags
+
+ ffio_wfourcc(pb, "desc"); //< Audio Description chunk
+ avio_wb64(pb, 32); //< mChunkSize
+ avio_wb64(pb, av_dbl2int(enc->sample_rate)); //< mSampleRate
+ avio_wl32(pb, codec_tag); //< mFormatID
+ avio_wb32(pb, codec_flags(enc->codec_id)); //< mFormatFlags
+ avio_wb32(pb, enc->block_align); //< mBytesPerPacket
+ avio_wb32(pb, samples_per_packet(enc->codec_id, enc->channels)); //< mFramesPerPacket
+ avio_wb32(pb, enc->channels); //< mChannelsPerFrame
+ avio_wb32(pb, av_get_bits_per_sample(enc->codec_id)); //< mBitsPerChannel
+
+ if (enc->channel_layout) {
+ ffio_wfourcc(pb, "chan");
+ avio_wb64(pb, 12);
+ ff_mov_write_chan(pb, enc->channel_layout);
+ }
+
+ if (enc->codec_id == CODEC_ID_ALAC) {
+ ffio_wfourcc(pb, "kuki");
+ avio_wb64(pb, 12 + enc->extradata_size);
+ avio_write(pb, "\0\0\0\14frmaalac", 12);
+ avio_write(pb, enc->extradata, enc->extradata_size);
+ } else if (enc->codec_id == CODEC_ID_AMR_NB) {
+ ffio_wfourcc(pb, "kuki");
+ avio_wb64(pb, 29);
+ avio_write(pb, "\0\0\0\14frmasamr", 12);
+ avio_wb32(pb, 0x11); /* size */
+ avio_write(pb, "samrFFMP", 8);
+ avio_w8(pb, 0); /* decoder version */
+
+ avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
+ avio_w8(pb, 0x00); /* Mode change period (no restriction) */
+ avio_w8(pb, 0x01); /* Frames per sample */
+ } else if (enc->codec_id == CODEC_ID_QDM2) {
+ ffio_wfourcc(pb, "kuki");
+ avio_wb64(pb, enc->extradata_size);
+ avio_write(pb, enc->extradata, enc->extradata_size);
+ }
+
+ ffio_wfourcc(pb, "data"); //< Audio Data chunk
+ caf->data = avio_tell(pb);
+ avio_wb64(pb, -1); //< mChunkSize
+ avio_wb32(pb, 0); //< mEditCount
+
+ avio_flush(pb);
+ return 0;
+}
+
+static int caf_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ CAFContext *caf = s->priv_data;
+
+ avio_write(s->pb, pkt->data, pkt->size);
+ if (!s->streams[0]->codec->block_align) {
+ void *pkt_sizes = caf->pkt_sizes;
+ int i, alloc_size = caf->size_entries_used + 5;
+ if (alloc_size < 0) {
+ caf->pkt_sizes = NULL;
+ } else {
+ caf->pkt_sizes = av_fast_realloc(caf->pkt_sizes,
+ &caf->size_buffer_size,
+ alloc_size);
+ }
+ if (!caf->pkt_sizes) {
+ av_free(pkt_sizes);
+ return AVERROR(ENOMEM);
+ }
+ for (i = 4; i > 0; i--) {
+ unsigned top = pkt->size >> i * 7;
+ if (top)
+ caf->pkt_sizes[caf->size_entries_used++] = 128 | top;
+ }
+ caf->pkt_sizes[caf->size_entries_used++] = pkt->size & 127;
+ caf->packets++;
+ }
+ return 0;
+}
+
+static int caf_write_trailer(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ AVCodecContext *enc = s->streams[0]->codec;
+
+ if (pb->seekable) {
+ CAFContext *caf = s->priv_data;
+ int64_t file_size = avio_tell(pb);
+
+ avio_seek(pb, caf->data, SEEK_SET);
+ avio_wb64(pb, file_size - caf->data - 8);
+ avio_seek(pb, file_size, SEEK_SET);
+ if (!enc->block_align) {
+ ffio_wfourcc(pb, "pakt");
+ avio_wb64(pb, caf->size_entries_used + 24);
+ avio_wb64(pb, caf->packets); ///< mNumberPackets
+ avio_wb64(pb, caf->packets * samples_per_packet(enc->codec_id, enc->channels)); ///< mNumberValidFrames
+ avio_wb32(pb, 0); ///< mPrimingFrames
+ avio_wb32(pb, 0); ///< mRemainderFrames
+ avio_write(pb, caf->pkt_sizes, caf->size_entries_used);
+ av_freep(&caf->pkt_sizes);
+ caf->size_buffer_size = 0;
+ }
+ avio_flush(pb);
+ }
+ return 0;
+}
+
+AVOutputFormat ff_caf_muxer = {
+ "caf",
+ NULL_IF_CONFIG_SMALL("Apple Core Audio Format"),
+ "audio/x-caf",
+ "caf",
+ sizeof(CAFContext),
+ CODEC_ID_PCM_S16BE,
+ CODEC_ID_NONE,
+ caf_write_header,
+ caf_write_packet,
+ caf_write_trailer,
+ .codec_tag= (const AVCodecTag* const []){ff_codec_caf_tags, 0},
+};
diff --git a/libavformat/cavsvideodec.c b/libavformat/cavsvideodec.c
index 9aa9413f4c..4a399a26d1 100644
--- a/libavformat/cavsvideodec.c
+++ b/libavformat/cavsvideodec.c
@@ -2,20 +2,20 @@
* RAW Chinese AVS video demuxer
* Copyright (c) 2009 Stefan Gehrer <stefan.gehrer@gmx.de>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/cdg.c b/libavformat/cdg.c
index b47a20e06a..75f1fb24c9 100644
--- a/libavformat/cdg.c
+++ b/libavformat/cdg.c
@@ -2,20 +2,20 @@
* CD Graphics Demuxer
* Copyright (c) 2009 Michael Tison
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -28,7 +28,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
AVStream *vst;
int ret;
- vst = av_new_stream(s, 0);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
@@ -52,15 +52,19 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
ret = av_get_packet(s->pb, pkt, CDG_PACKET_SIZE);
pkt->stream_index = 0;
+ pkt->dts=pkt->pts= s->streams[0]->cur_dts;
+
+ if(ret>5 && (pkt->data[0]&0x3F) == 9 && (pkt->data[1]&0x3F)==1 && !(pkt->data[2+2+1] & 0x0F)){
+ pkt->flags = AV_PKT_FLAG_KEY;
+ }
return ret;
}
AVInputFormat ff_cdg_demuxer = {
- "cdg",
- NULL_IF_CONFIG_SMALL("CD Graphics Format"),
- 0,
- NULL,
- read_header,
- read_packet,
+ .name = "cdg",
+ .long_name = NULL_IF_CONFIG_SMALL("CD Graphics Format"),
+ .read_header = read_header,
+ .read_packet = read_packet,
+ .flags= AVFMT_GENERIC_INDEX,
.extensions = "cdg"
};
diff --git a/libavformat/concat.c b/libavformat/concat.c
index da9bee2cc4..ba1b6a544a 100644
--- a/libavformat/concat.c
+++ b/libavformat/concat.c
@@ -4,20 +4,20 @@
* Copyright (c) 2007 Wolfram Gloger
* Copyright (c) 2010 Michele Orrù
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/crcenc.c b/libavformat/crcenc.c
index 55c99d9d88..f596e665d1 100644
--- a/libavformat/crcenc.c
+++ b/libavformat/crcenc.c
@@ -2,20 +2,20 @@
* CRC encoder (for codec/format testing)
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -55,14 +55,13 @@ static int crc_write_trailer(struct AVFormatContext *s)
}
AVOutputFormat ff_crc_muxer = {
- "crc",
- NULL_IF_CONFIG_SMALL("CRC testing format"),
- NULL,
- "",
- sizeof(CRCState),
- CODEC_ID_PCM_S16LE,
- CODEC_ID_RAWVIDEO,
- crc_write_header,
- crc_write_packet,
- crc_write_trailer,
+ .name = "crc",
+ .long_name = NULL_IF_CONFIG_SMALL("CRC testing format"),
+ .extensions = "",
+ .priv_data_size = sizeof(CRCState),
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_header = crc_write_header,
+ .write_packet = crc_write_packet,
+ .write_trailer = crc_write_trailer,
};
diff --git a/libavformat/crypto.c b/libavformat/crypto.c
index 5e7ee1eba3..b9d3e0326f 100644
--- a/libavformat/crypto.c
+++ b/libavformat/crypto.c
@@ -46,8 +46,8 @@ typedef struct {
#define OFFSET(x) offsetof(CryptoContext, x)
static const AVOption options[] = {
- {"key", "AES decryption key", OFFSET(key), FF_OPT_TYPE_BINARY },
- {"iv", "AES decryption initialization vector", OFFSET(iv), FF_OPT_TYPE_BINARY },
+ {"key", "AES decryption key", OFFSET(key), AV_OPT_TYPE_BINARY },
+ {"iv", "AES decryption initialization vector", OFFSET(iv), AV_OPT_TYPE_BINARY },
{ NULL }
};
diff --git a/libavformat/cutils.c b/libavformat/cutils.c
index 092aa8a1a9..76aba56150 100644
--- a/libavformat/cutils.c
+++ b/libavformat/cutils.c
@@ -2,46 +2,25 @@
* Various simple utilities for ffmpeg system
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
#include "internal.h"
-/* add one element to a dynamic array */
-void ff_dynarray_add(intptr_t **tab_ptr, int *nb_ptr, intptr_t elem)
-{
- /* see similar ffmpeg.c:grow_array() */
- int nb, nb_alloc;
- intptr_t *tab;
-
- nb = *nb_ptr;
- tab = *tab_ptr;
- if ((nb & (nb - 1)) == 0) {
- if (nb == 0)
- nb_alloc = 1;
- else
- nb_alloc = nb * 2;
- tab = av_realloc(tab, nb_alloc * sizeof(intptr_t));
- *tab_ptr = tab;
- }
- tab[nb++] = elem;
- *nb_ptr = nb;
-}
-
#define ISLEAP(y) (((y) % 4 == 0) && (((y) % 100) != 0 || ((y) % 400) == 0))
#define LEAPS_COUNT(y) ((y)/4 - (y)/100 + (y)/400)
diff --git a/libavformat/daud.c b/libavformat/daud.c
index 1b3cfcf2d9..aa70800085 100644
--- a/libavformat/daud.c
+++ b/libavformat/daud.c
@@ -2,26 +2,26 @@
* D-Cinema audio demuxer
* Copyright (c) 2005 Reimar Döffinger
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
static int daud_header(AVFormatContext *s, AVFormatParameters *ap) {
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -38,7 +38,7 @@ static int daud_header(AVFormatContext *s, AVFormatParameters *ap) {
static int daud_packet(AVFormatContext *s, AVPacket *pkt) {
AVIOContext *pb = s->pb;
int ret, size;
- if (pb->eof_reached)
+ if (url_feof(pb))
return AVERROR(EIO);
size = avio_rb16(pb);
avio_rb16(pb); // unknown
@@ -71,30 +71,23 @@ static int daud_write_packet(struct AVFormatContext *s, AVPacket *pkt)
#if CONFIG_DAUD_DEMUXER
AVInputFormat ff_daud_demuxer = {
- "daud",
- NULL_IF_CONFIG_SMALL("D-Cinema audio format"),
- 0,
- NULL,
- daud_header,
- daud_packet,
- NULL,
- NULL,
+ .name = "daud",
+ .long_name = NULL_IF_CONFIG_SMALL("D-Cinema audio format"),
+ .read_header = daud_header,
+ .read_packet = daud_packet,
.extensions = "302",
};
#endif
#if CONFIG_DAUD_MUXER
-AVOutputFormat ff_daud_muxer =
-{
- "daud",
- NULL_IF_CONFIG_SMALL("D-Cinema audio format"),
- NULL,
- "302",
- 0,
- CODEC_ID_PCM_S24DAUD,
- CODEC_ID_NONE,
- daud_write_header,
- daud_write_packet,
- .flags= AVFMT_NOTIMESTAMPS,
+AVOutputFormat ff_daud_muxer = {
+ .name = "daud",
+ .long_name = NULL_IF_CONFIG_SMALL("D-Cinema audio format"),
+ .extensions = "302",
+ .audio_codec = CODEC_ID_PCM_S24DAUD,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = daud_write_header,
+ .write_packet = daud_write_packet,
+ .flags = AVFMT_NOTIMESTAMPS,
};
#endif
diff --git a/libavformat/dfa.c b/libavformat/dfa.c
index 810853568d..a109a2d2b7 100644
--- a/libavformat/dfa.c
+++ b/libavformat/dfa.c
@@ -2,20 +2,20 @@
* Chronomaster DFA Format Demuxer
* Copyright (c) 2011 Konstantin Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -45,7 +45,7 @@ static int dfa_read_header(AVFormatContext *s,
avio_skip(pb, 2); // unused
frames = avio_rl16(pb);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -109,11 +109,10 @@ static int dfa_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_dfa_demuxer = {
- "dfa",
- NULL_IF_CONFIG_SMALL("Chronomaster DFA"),
- 0,
- dfa_probe,
- dfa_read_header,
- dfa_read_packet,
+ .name = "dfa",
+ .long_name = NULL_IF_CONFIG_SMALL("Chronomaster DFA"),
+ .read_probe = dfa_probe,
+ .read_header = dfa_read_header,
+ .read_packet = dfa_read_packet,
.flags = AVFMT_GENERIC_INDEX,
};
diff --git a/libavformat/diracdec.c b/libavformat/diracdec.c
index 8cbd5b5146..6afda533dc 100644
--- a/libavformat/diracdec.c
+++ b/libavformat/diracdec.c
@@ -2,20 +2,20 @@
* RAW Dirac demuxer
* Copyright (c) 2007 Marco Gerards <marco@gnu.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/dnxhddec.c b/libavformat/dnxhddec.c
index 2aa8017ad4..f89782a880 100644
--- a/libavformat/dnxhddec.c
+++ b/libavformat/dnxhddec.c
@@ -3,20 +3,20 @@
* Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@gmail.com>
* Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/dsicin.c b/libavformat/dsicin.c
index d02de46e0f..09e80e944f 100644
--- a/libavformat/dsicin.c
+++ b/libavformat/dsicin.c
@@ -2,20 +2,20 @@
* Delphine Software International CIN File Demuxer
* Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -107,7 +107,7 @@ static int cin_read_header(AVFormatContext *s, AVFormatParameters *ap)
cin->audio_buffer_size = 0;
/* initialize the video decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -120,7 +120,7 @@ static int cin_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->height = hdr->video_frame_height;
/* initialize the audio decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -147,7 +147,7 @@ static int cin_read_frame_header(CinDemuxContext *cin, AVIOContext *pb) {
hdr->video_frame_size = avio_rl32(pb);
hdr->audio_frame_size = avio_rl32(pb);
- if (pb->eof_reached || pb->error)
+ if (url_feof(pb) || pb->error)
return AVERROR(EIO);
if (avio_rl32(pb) != 0xAA55AA55)
@@ -217,10 +217,10 @@ static int cin_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_dsicin_demuxer = {
- "dsicin",
- NULL_IF_CONFIG_SMALL("Delphine Software International CIN format"),
- sizeof(CinDemuxContext),
- cin_probe,
- cin_read_header,
- cin_read_packet,
+ .name = "dsicin",
+ .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN format"),
+ .priv_data_size = sizeof(CinDemuxContext),
+ .read_probe = cin_probe,
+ .read_header = cin_read_header,
+ .read_packet = cin_read_packet,
};
diff --git a/libavformat/dtsdec.c b/libavformat/dtsdec.c
index 943f6a5d5a..e762b85e19 100644
--- a/libavformat/dtsdec.c
+++ b/libavformat/dtsdec.c
@@ -2,20 +2,20 @@
* RAW DTS demuxer
* Copyright (c) 2008 Benjamin Larsson
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -66,12 +66,11 @@ static int dts_probe(AVProbeData *p)
}
AVInputFormat ff_dts_demuxer = {
- "dts",
- NULL_IF_CONFIG_SMALL("raw DTS"),
- 0,
- dts_probe,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
+ .name = "dts",
+ .long_name = NULL_IF_CONFIG_SMALL("raw DTS"),
+ .read_probe = dts_probe,
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "dts",
.value = CODEC_ID_DTS,
diff --git a/libavformat/dv.c b/libavformat/dv.c
index f38b954605..378f29f0f3 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -12,20 +12,20 @@
* Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
* Funded by BBC Research & Development
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <time.h>
@@ -211,7 +211,7 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
/* Dynamic handling of the audio streams in DV */
for (i = 0; i < ach; i++) {
if (!c->ast[i]) {
- c->ast[i] = av_new_stream(c->fctx, 0);
+ c->ast[i] = avformat_new_stream(c->fctx, NULL);
if (!c->ast[i])
break;
av_set_pts_info(c->ast[i], 64, 1, 30000);
@@ -270,7 +270,7 @@ static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
* The following 3 functions constitute our interface to the world
*/
-DVDemuxContext* dv_init_demux(AVFormatContext *s)
+DVDemuxContext* avpriv_dv_init_demux(AVFormatContext *s)
{
DVDemuxContext *c;
@@ -278,7 +278,7 @@ DVDemuxContext* dv_init_demux(AVFormatContext *s)
if (!c)
return NULL;
- c->vst = av_new_stream(s, 0);
+ c->vst = avformat_new_stream(s, NULL);
if (!c->vst) {
av_free(c);
return NULL;
@@ -299,7 +299,7 @@ DVDemuxContext* dv_init_demux(AVFormatContext *s)
return c;
}
-int dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
+int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
{
int size = -1;
int i;
@@ -316,14 +316,14 @@ int dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
return size;
}
-int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
- uint8_t* buf, int buf_size)
+int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
+ uint8_t* buf, int buf_size, int64_t pos)
{
int size, i;
uint8_t *ppcm[4] = {0};
if (buf_size < DV_PROFILE_BYTES ||
- !(c->sys = ff_dv_frame_profile(c->sys, buf, buf_size)) ||
+ !(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) ||
buf_size < c->sys->frame_size) {
return -1; /* Broken frame, or not enough data */
}
@@ -332,6 +332,7 @@ int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
/* FIXME: in case of no audio/bad audio we have to do something */
size = dv_extract_audio_info(c, buf);
for (i = 0; i < c->ach; i++) {
+ c->audio_pkt[i].pos = pos;
c->audio_pkt[i].size = size;
c->audio_pkt[i].pts = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate;
ppcm[i] = c->audio_buf[i];
@@ -355,6 +356,7 @@ int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
size = dv_extract_video_info(c, buf);
av_init_packet(pkt);
pkt->data = buf;
+ pkt->pos = pos;
pkt->size = size;
pkt->flags |= AV_PKT_FLAG_KEY;
pkt->stream_index = c->vst->id;
@@ -369,7 +371,7 @@ static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
int64_t timestamp, int flags)
{
// FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk)
- const DVprofile* sys = ff_dv_codec_profile(c->vst->codec);
+ const DVprofile* sys = avpriv_dv_codec_profile(c->vst->codec);
int64_t offset;
int64_t size = avio_size(s->pb) - s->data_offset;
int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size;
@@ -407,13 +409,13 @@ static int dv_read_header(AVFormatContext *s,
unsigned state, marker_pos = 0;
RawDVContext *c = s->priv_data;
- c->dv_demux = dv_init_demux(s);
+ c->dv_demux = avpriv_dv_init_demux(s);
if (!c->dv_demux)
return -1;
state = avio_rb32(s->pb);
while ((state & 0xffffff7f) != 0x1f07003f) {
- if (s->pb->eof_reached) {
+ if (url_feof(s->pb)) {
av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n");
return -1;
}
@@ -432,7 +434,7 @@ static int dv_read_header(AVFormatContext *s,
avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0)
return AVERROR(EIO);
- c->dv_demux->sys = ff_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES);
+ c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES);
if (!c->dv_demux->sys) {
av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n");
return -1;
@@ -450,16 +452,17 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
int size;
RawDVContext *c = s->priv_data;
- size = dv_get_packet(c->dv_demux, pkt);
+ size = avpriv_dv_get_packet(c->dv_demux, pkt);
if (size < 0) {
+ int64_t pos = avio_tell(s->pb);
if (!c->dv_demux->sys)
return AVERROR(EIO);
size = c->dv_demux->sys->frame_size;
if (avio_read(s->pb, c->buf, size) <= 0)
return AVERROR(EIO);
- size = dv_produce_packet(c->dv_demux, pkt, c->buf, size);
+ size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size, pos);
}
return size;
@@ -472,10 +475,11 @@ static int dv_read_seek(AVFormatContext *s, int stream_index,
DVDemuxContext *c = r->dv_demux;
int64_t offset = dv_frame_offset(s, c, timestamp, flags);
- dv_offset_reset(c, offset / c->sys->frame_size);
+ if (avio_seek(s->pb, offset, SEEK_SET) < 0)
+ return -1;
- offset = avio_seek(s->pb, offset, SEEK_SET);
- return (offset < 0) ? offset : 0;
+ dv_offset_reset(c, offset / c->sys->frame_size);
+ return 0;
}
static int dv_read_close(AVFormatContext *s)
@@ -520,14 +524,14 @@ static int dv_probe(AVProbeData *p)
#if CONFIG_DV_DEMUXER
AVInputFormat ff_dv_demuxer = {
- "dv",
- NULL_IF_CONFIG_SMALL("DV video format"),
- sizeof(RawDVContext),
- dv_probe,
- dv_read_header,
- dv_read_packet,
- dv_read_close,
- dv_read_seek,
+ .name = "dv",
+ .long_name = NULL_IF_CONFIG_SMALL("DV video format"),
+ .priv_data_size = sizeof(RawDVContext),
+ .read_probe = dv_probe,
+ .read_header = dv_read_header,
+ .read_packet = dv_read_packet,
+ .read_close = dv_read_close,
+ .read_seek = dv_read_seek,
.extensions = "dv,dif",
};
#endif
diff --git a/libavformat/dv.h b/libavformat/dv.h
index 650699d2d7..722067f206 100644
--- a/libavformat/dv.h
+++ b/libavformat/dv.h
@@ -8,20 +8,20 @@
* Raw DV format
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -31,9 +31,9 @@
#include "avformat.h"
typedef struct DVDemuxContext DVDemuxContext;
-DVDemuxContext* dv_init_demux(AVFormatContext* s);
-int dv_get_packet(DVDemuxContext*, AVPacket *);
-int dv_produce_packet(DVDemuxContext*, AVPacket*, uint8_t*, int);
+DVDemuxContext* avpriv_dv_init_demux(AVFormatContext* s);
+int avpriv_dv_get_packet(DVDemuxContext*, AVPacket *);
+int avpriv_dv_produce_packet(DVDemuxContext*, AVPacket*, uint8_t*, int, int64_t);
void dv_offset_reset(DVDemuxContext *c, int64_t frame_offset);
typedef struct DVMuxContext DVMuxContext;
diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c
index 504e3ee26f..ce6568b5eb 100644
--- a/libavformat/dvenc.c
+++ b/libavformat/dvenc.c
@@ -11,20 +11,20 @@
* 50 Mbps (DVCPRO50) support
* Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <time.h>
@@ -33,20 +33,25 @@
#include "avformat.h"
#include "internal.h"
#include "libavcodec/dvdata.h"
+#include "libavcodec/timecode.h"
#include "dv.h"
#include "libavutil/fifo.h"
#include "libavutil/mathematics.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
struct DVMuxContext {
+ AVClass *av_class;
const DVprofile* sys; /* current DV profile, e.g.: 525/60, 625/50 */
int n_ast; /* number of stereo audio streams (up to 2) */
AVStream *ast[2]; /* stereo audio streams */
AVFifoBuffer *audio_data[2]; /* FIFO for storing excessive amounts of PCM */
int frames; /* current frame number */
- time_t start_time; /* recording start time */
+ int64_t start_time; /* recording start time */
int has_audio; /* frame under contruction has audio */
int has_video; /* frame under contruction has video */
uint8_t frame_buf[DV_MAX_FRAME_SIZE]; /* frame under contruction */
+ struct ff_timecode tc;
};
static const int dv_aaux_packs_dist[12][9] = {
@@ -75,33 +80,23 @@ static int dv_write_pack(enum dv_pack_type pack_id, DVMuxContext *c, uint8_t* bu
struct tm tc;
time_t ct;
int ltc_frame;
+ uint32_t timecode;
va_list ap;
buf[0] = (uint8_t)pack_id;
switch (pack_id) {
case dv_timecode:
- ct = (time_t)av_rescale_rnd(c->frames, c->sys->time_base.num,
- c->sys->time_base.den, AV_ROUND_DOWN);
- brktimegm(ct, &tc);
/*
* LTC drop-frame frame counter drops two frames (0 and 1) every
* minute, unless it is exactly divisible by 10
*/
- ltc_frame = (c->frames + 2 * ct / 60 - 2 * ct / 600) % c->sys->ltc_divisor;
- buf[1] = (0 << 7) | /* color frame: 0 - unsync; 1 - sync mode */
- (1 << 6) | /* drop frame timecode: 0 - nondrop; 1 - drop */
- ((ltc_frame / 10) << 4) | /* tens of frames */
- (ltc_frame % 10); /* units of frames */
- buf[2] = (1 << 7) | /* biphase mark polarity correction: 0 - even; 1 - odd */
- ((tc.tm_sec / 10) << 4) | /* tens of seconds */
- (tc.tm_sec % 10); /* units of seconds */
- buf[3] = (1 << 7) | /* binary group flag BGF0 */
- ((tc.tm_min / 10) << 4) | /* tens of minutes */
- (tc.tm_min % 10); /* units of minutes */
- buf[4] = (1 << 7) | /* binary group flag BGF2 */
- (1 << 6) | /* binary group flag BGF1 */
- ((tc.tm_hour / 10) << 4) | /* tens of hours */
- (tc.tm_hour % 10); /* units of hours */
+ ltc_frame = c->tc.start + c->frames;
+ if (c->tc.drop)
+ ltc_frame = ff_framenum_to_drop_timecode(ltc_frame);
+ timecode = ff_framenum_to_smtpe_timecode(ltc_frame, c->sys->ltc_divisor,
+ c->tc.drop);
+ timecode |= 1<<23 | 1<<15 | 1<<7 | 1<<6; // biphase and binary group flags
+ AV_WB32(buf + 1, timecode);
break;
case dv_audio_source: /* AAUX source pack */
va_start(ap, buf);
@@ -192,8 +187,8 @@ static void dv_inject_audio(DVMuxContext *c, int channel, uint8_t* frame_ptr)
if (of*2 >= size)
continue;
- frame_ptr[d] = av_fifo_peek(c->audio_data[channel], of*2+1); // FIXME: maybe we have to admit
- frame_ptr[d+1] = av_fifo_peek(c->audio_data[channel], of*2); // that DV is a big-endian PCM
+ frame_ptr[d] = *av_fifo_peek2(c->audio_data[channel], of*2+1); // FIXME: maybe we have to admit
+ frame_ptr[d+1] = *av_fifo_peek2(c->audio_data[channel], of*2); // that DV is a big-endian PCM
}
frame_ptr += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
}
@@ -290,6 +285,7 @@ static DVMuxContext* dv_init_mux(AVFormatContext* s)
{
DVMuxContext *c = s->priv_data;
AVStream *vst = NULL;
+ AVDictionaryEntry *t;
int i;
/* we support at most 1 video and 2 audio streams */
@@ -324,7 +320,7 @@ static DVMuxContext* dv_init_mux(AVFormatContext* s)
c->ast[i]->codec->channels != 2))
goto bail_out;
}
- c->sys = ff_dv_codec_profile(vst->codec);
+ c->sys = avpriv_dv_codec_profile(vst->codec);
if (!c->sys)
goto bail_out;
@@ -337,7 +333,13 @@ static DVMuxContext* dv_init_mux(AVFormatContext* s)
c->frames = 0;
c->has_audio = 0;
c->has_video = 0;
- c->start_time = (time_t)s->timestamp;
+#if FF_API_TIMESTAMP
+ if (s->timestamp)
+ c->start_time = s->timestamp;
+ else
+#endif
+ if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+ c->start_time = ff_iso8601_to_unix_time(t->value);
for (i=0; i < c->n_ast; i++) {
if (c->ast[i] && !(c->audio_data[i]=av_fifo_alloc(100*AVCODEC_MAX_AUDIO_FRAME_SIZE))) {
@@ -364,6 +366,8 @@ static void dv_delete_mux(DVMuxContext *c)
static int dv_write_header(AVFormatContext *s)
{
+ DVMuxContext *dvc = s->priv_data;
+
if (!dv_init_mux(s)) {
av_log(s, AV_LOG_ERROR, "Can't initialize DV format!\n"
"Make sure that you supply exactly two streams:\n"
@@ -371,6 +375,12 @@ static int dv_write_header(AVFormatContext *s)
" (50Mbps allows an optional second audio stream)\n");
return -1;
}
+ if (dvc->tc.str) {
+ dvc->tc.rate.num = dvc->sys->time_base.den;
+ dvc->tc.rate.den = dvc->sys->time_base.num;
+ if (ff_init_smtpe_timecode(s, &dvc->tc) < 0)
+ return -1;
+ }
return 0;
}
@@ -400,15 +410,25 @@ static int dv_write_trailer(struct AVFormatContext *s)
return 0;
}
+static const AVClass class = {
+ .class_name = "dv",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+ .option = (const AVOption[]){
+ {TIMECODE_OPT(DVMuxContext, AV_OPT_FLAG_ENCODING_PARAM)},
+ {NULL},
+ },
+};
+
AVOutputFormat ff_dv_muxer = {
- "dv",
- NULL_IF_CONFIG_SMALL("DV video format"),
- NULL,
- "dv",
- sizeof(DVMuxContext),
- CODEC_ID_PCM_S16LE,
- CODEC_ID_DVVIDEO,
- dv_write_header,
- dv_write_packet,
- dv_write_trailer,
+ .name = "dv",
+ .long_name = NULL_IF_CONFIG_SMALL("DV video format"),
+ .extensions = "dv",
+ .priv_data_size = sizeof(DVMuxContext),
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_DVVIDEO,
+ .write_header = dv_write_header,
+ .write_packet = dv_write_packet,
+ .write_trailer = dv_write_trailer,
+ .priv_class = &class,
};
diff --git a/libavformat/dxa.c b/libavformat/dxa.c
index 1e1d50581c..65a61159bc 100644
--- a/libavformat/dxa.c
+++ b/libavformat/dxa.c
@@ -2,20 +2,20 @@
* DXA demuxer
* Copyright (c) 2007 Konstantin Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -87,7 +87,7 @@ static int dxa_read_header(AVFormatContext *s, AVFormatParameters *ap)
h = avio_rb16(pb);
c->has_sound = 0;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
@@ -100,14 +100,14 @@ static int dxa_read_header(AVFormatContext *s, AVFormatParameters *ap)
avio_skip(pb, 16);
fsize = avio_rl32(pb);
- ast = av_new_stream(s, 0);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return -1;
ret = ff_get_wav_header(pb, ast->codec, fsize);
if (ret < 0)
return ret;
// find 'data' chunk
- while(avio_tell(pb) < c->vidpos && !pb->eof_reached){
+ while(avio_tell(pb) < c->vidpos && !url_feof(pb)){
tag = avio_rl32(pb);
fsize = avio_rl32(pb);
if(tag == MKTAG('d', 'a', 't', 'a')) break;
@@ -165,7 +165,7 @@ static int dxa_read_packet(AVFormatContext *s, AVPacket *pkt)
return 0;
}
avio_seek(s->pb, c->vidpos, SEEK_SET);
- while(!s->pb->eof_reached && c->frames){
+ while(!url_feof(s->pb) && c->frames){
avio_read(s->pb, buf, 4);
switch(AV_RL32(buf)){
case MKTAG('N', 'U', 'L', 'L'):
@@ -213,10 +213,10 @@ static int dxa_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_dxa_demuxer = {
- "dxa",
- NULL_IF_CONFIG_SMALL("DXA"),
- sizeof(DXAContext),
- dxa_probe,
- dxa_read_header,
- dxa_read_packet,
+ .name = "dxa",
+ .long_name = NULL_IF_CONFIG_SMALL("DXA"),
+ .priv_data_size = sizeof(DXAContext),
+ .read_probe = dxa_probe,
+ .read_header = dxa_read_header,
+ .read_packet = dxa_read_packet,
};
diff --git a/libavformat/eacdata.c b/libavformat/eacdata.c
index 5c89559ed1..adf48c6a19 100644
--- a/libavformat/eacdata.c
+++ b/libavformat/eacdata.c
@@ -2,20 +2,20 @@
* Electronic Arts .cdata file Demuxer
* Copyright (c) 2007 Peter Ross
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -39,7 +39,7 @@ static int cdata_probe(AVProbeData *p)
{
const uint8_t *b = p->buf;
- if (b[0] == 0x04 && (b[1] == 0x00 || b[1] == 0x04 || b[1] == 0x0C))
+ if (b[0] == 0x04 && (b[1] == 0x00 || b[1] == 0x04 || b[1] == 0x0C || b[1] == 0x14))
return AVPROBE_SCORE_MAX/8;
return 0;
}
@@ -50,28 +50,32 @@ static int cdata_read_header(AVFormatContext *s, AVFormatParameters *ap)
AVIOContext *pb = s->pb;
unsigned int sample_rate, header;
AVStream *st;
+ int64_t channel_layout = 0;
header = avio_rb16(pb);
switch (header) {
case 0x0400: cdata->channels = 1; break;
case 0x0404: cdata->channels = 2; break;
- case 0x040C: cdata->channels = 4; break;
+ case 0x040C: cdata->channels = 4; channel_layout = AV_CH_LAYOUT_QUAD; break;
+ case 0x0414: cdata->channels = 6; channel_layout = AV_CH_LAYOUT_5POINT1_BACK; break;
default:
av_log(s, AV_LOG_INFO, "unknown header 0x%04x\n", header);
return -1;
};
sample_rate = avio_rb16(pb);
- avio_skip(pb, 12);
+ avio_skip(pb, (avio_r8(pb) & 0x20) ? 15 : 11);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_tag = 0; /* no fourcc */
st->codec->codec_id = CODEC_ID_ADPCM_EA_XAS;
st->codec->channels = cdata->channels;
+ st->codec->channel_layout = channel_layout;
st->codec->sample_rate = sample_rate;
+ st->codec->sample_fmt = AV_SAMPLE_FMT_S16;
av_set_pts_info(st, 64, 1, sample_rate);
cdata->audio_pts = 0;
@@ -91,11 +95,11 @@ static int cdata_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_ea_cdata_demuxer = {
- "ea_cdata",
- NULL_IF_CONFIG_SMALL("Electronic Arts cdata"),
- sizeof(CdataDemuxContext),
- cdata_probe,
- cdata_read_header,
- cdata_read_packet,
+ .name = "ea_cdata",
+ .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts cdata"),
+ .priv_data_size = sizeof(CdataDemuxContext),
+ .read_probe = cdata_probe,
+ .read_header = cdata_read_header,
+ .read_packet = cdata_read_packet,
.extensions = "cdata",
};
diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
index 06689ddfb7..0508a06cc4 100644
--- a/libavformat/electronicarts.c
+++ b/libavformat/electronicarts.c
@@ -2,20 +2,20 @@
* Copyright (c) 2004 The ffmpeg Project
* Copyright (c) 2006-2008 Peter Ross
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -109,7 +109,7 @@ static int process_audio_header_elements(AVFormatContext *s)
ea->sample_rate = -1;
ea->num_channels = 1;
- while (!pb->eof_reached && inHeader) {
+ while (!url_feof(pb) && inHeader) {
int inSubheader;
uint8_t byte;
byte = avio_r8(pb);
@@ -118,7 +118,7 @@ static int process_audio_header_elements(AVFormatContext *s)
case 0xFD:
av_log (s, AV_LOG_DEBUG, "entered audio subheader\n");
inSubheader = 1;
- while (!pb->eof_reached && inSubheader) {
+ while (!url_feof(pb) && inSubheader) {
uint8_t subbyte;
subbyte = avio_r8(pb);
@@ -330,12 +330,10 @@ static int process_ea_header(AVFormatContext *s) {
case MVIh_TAG :
ea->video_codec = CODEC_ID_CMV;
- ea->time_base = (AVRational){0,0};
break;
case kVGT_TAG:
ea->video_codec = CODEC_ID_TGV;
- ea->time_base = (AVRational){0,0};
break;
case mTCD_TAG :
@@ -410,14 +408,18 @@ static int ea_read_header(AVFormatContext *s,
if (ea->video_codec) {
/* initialize the video decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
ea->video_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = ea->video_codec;
+ // parsing is necessary to make FFmpeg generate correct timestamps
+ if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO)
+ st->need_parsing = AVSTREAM_PARSE_HEADERS;
st->codec->codec_tag = 0; /* no fourcc */
- st->codec->time_base = ea->time_base;
+ if (ea->time_base.num)
+ av_set_pts_info(st, 64, ea->time_base.num, ea->time_base.den);
st->codec->width = ea->width;
st->codec->height = ea->height;
}
@@ -435,7 +437,7 @@ static int ea_read_header(AVFormatContext *s,
}
/* initialize the audio decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 33, 1, ea->sample_rate);
@@ -569,10 +571,10 @@ get_video_packet:
}
AVInputFormat ff_ea_demuxer = {
- "ea",
- NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia Format"),
- sizeof(EaDemuxContext),
- ea_probe,
- ea_read_header,
- ea_read_packet,
+ .name = "ea",
+ .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia Format"),
+ .priv_data_size = sizeof(EaDemuxContext),
+ .read_probe = ea_probe,
+ .read_header = ea_read_header,
+ .read_packet = ea_read_packet,
};
diff --git a/libavformat/ffm.h b/libavformat/ffm.h
index 89a14a5a88..04f19cc88e 100644
--- a/libavformat/ffm.h
+++ b/libavformat/ffm.h
@@ -2,20 +2,20 @@
* FFM (ffserver live feed) common header
* Copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c
index 91ab2e4370..b8cf119cb3 100644
--- a/libavformat/ffmdec.c
+++ b/libavformat/ffmdec.c
@@ -2,20 +2,20 @@
* FFM (ffserver live feed) demuxer
* Copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -92,7 +92,7 @@ static int ffm_resync(AVFormatContext *s, int state)
{
av_log(s, AV_LOG_ERROR, "resyncing\n");
while (state != PACKET_ID) {
- if (s->pb->eof_reached) {
+ if (url_feof(s->pb)) {
av_log(s, AV_LOG_ERROR, "cannot find FFM syncword\n");
return -1;
}
@@ -121,6 +121,11 @@ static int ffm_read_data(AVFormatContext *s,
if (avio_tell(pb) == ffm->file_size)
avio_seek(pb, ffm->packet_size, SEEK_SET);
retry_read:
+ if (pb->buffer_size != ffm->packet_size) {
+ int64_t tell = avio_tell(pb);
+ url_setbufsize(pb, ffm->packet_size);
+ avio_seek(pb, tell, SEEK_SET);
+ }
id = avio_rb16(pb); /* PACKET_ID */
if (id != PACKET_ID)
if (ffm_resync(s, id) < 0)
@@ -166,7 +171,7 @@ static int ffm_read_data(AVFormatContext *s,
/* ensure that acutal seeking happens between FFM_PACKET_SIZE
and file_size - FFM_PACKET_SIZE */
-static void ffm_seek1(AVFormatContext *s, int64_t pos1)
+static int64_t ffm_seek1(AVFormatContext *s, int64_t pos1)
{
FFMContext *ffm = s->priv_data;
AVIOContext *pb = s->pb;
@@ -175,7 +180,7 @@ static void ffm_seek1(AVFormatContext *s, int64_t pos1)
pos = FFMIN(pos1, ffm->file_size - FFM_PACKET_SIZE);
pos = FFMAX(pos, FFM_PACKET_SIZE);
av_dlog(s, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos);
- avio_seek(pb, pos, SEEK_SET);
+ return avio_seek(pb, pos, SEEK_SET);
}
static int64_t get_dts(AVFormatContext *s, int64_t pos)
@@ -290,7 +295,7 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap)
for(i=0;i<nb_streams;i++) {
char rc_eq_buf[128];
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto fail;
@@ -301,7 +306,6 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap)
codec->codec_id = avio_rb32(pb);
codec->codec_type = avio_r8(pb); /* codec_type */
codec->bit_rate = avio_rb32(pb);
- st->quality = avio_rb32(pb);
codec->flags = avio_rb32(pb);
codec->flags2 = avio_rb32(pb);
codec->debug = avio_rb32(pb);
@@ -320,8 +324,7 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap)
codec->qcompress = avio_rb16(pb) / 10000.0;
codec->qblur = avio_rb16(pb) / 10000.0;
codec->bit_rate_tolerance = avio_rb32(pb);
- avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf));
- codec->rc_eq = av_strdup(rc_eq_buf);
+ codec->rc_eq = av_strdup(get_strz(pb, rc_eq_buf, sizeof(rc_eq_buf)));
codec->rc_max_rate = avio_rb32(pb);
codec->rc_min_rate = avio_rb32(pb);
codec->rc_buffer_size = avio_rb32(pb);
@@ -463,11 +466,25 @@ static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, in
av_dlog(s, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0);
/* find the position using linear interpolation (better than
dichotomy in typical cases) */
- pos_min = FFM_PACKET_SIZE;
- pos_max = ffm->file_size - FFM_PACKET_SIZE;
+ if (ffm->write_index && ffm->write_index < ffm->file_size) {
+ if (get_dts(s, FFM_PACKET_SIZE) < wanted_pts) {
+ pos_min = FFM_PACKET_SIZE;
+ pos_max = ffm->write_index - FFM_PACKET_SIZE;
+ } else {
+ pos_min = ffm->write_index;
+ pos_max = ffm->file_size - FFM_PACKET_SIZE;
+ }
+ } else {
+ pos_min = FFM_PACKET_SIZE;
+ pos_max = ffm->file_size - FFM_PACKET_SIZE;
+ }
while (pos_min <= pos_max) {
pts_min = get_dts(s, pos_min);
pts_max = get_dts(s, pos_max);
+ if (pts_min > wanted_pts || pts_max < wanted_pts) {
+ pos = pts_min > wanted_pts ? pos_min : pos_max;
+ goto found;
+ }
/* linear interpolation */
pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) /
(double)(pts_max - pts_min);
@@ -489,7 +506,8 @@ static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, in
pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max;
found:
- ffm_seek1(s, pos);
+ if (ffm_seek1(s, pos) < 0)
+ return -1;
/* reset read state */
ffm->read_state = READ_HEADER;
@@ -510,12 +528,12 @@ static int ffm_probe(AVProbeData *p)
}
AVInputFormat ff_ffm_demuxer = {
- "ffm",
- NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"),
- sizeof(FFMContext),
- ffm_probe,
- ffm_read_header,
- ffm_read_packet,
- ffm_close,
- ffm_seek,
+ .name = "ffm",
+ .long_name = NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"),
+ .priv_data_size = sizeof(FFMContext),
+ .read_probe = ffm_probe,
+ .read_header = ffm_read_header,
+ .read_packet = ffm_read_packet,
+ .read_close = ffm_close,
+ .read_seek = ffm_seek,
};
diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c
index 9a3eb40ad7..99d2e98dbf 100644
--- a/libavformat/ffmenc.c
+++ b/libavformat/ffmenc.c
@@ -2,20 +2,20 @@
* FFM (ffserver live feed) muxer
* Copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -114,7 +114,6 @@ static int ffm_write_header(AVFormatContext *s)
avio_wb32(pb, codec->codec_id);
avio_w8(pb, codec->codec_type);
avio_wb32(pb, codec->bit_rate);
- avio_wb32(pb, st->quality);
avio_wb32(pb, codec->flags);
avio_wb32(pb, codec->flags2);
avio_wb32(pb, codec->debug);
@@ -242,15 +241,14 @@ static int ffm_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_ffm_muxer = {
- "ffm",
- NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"),
- "",
- "ffm",
- sizeof(FFMContext),
- /* not really used */
- CODEC_ID_MP2,
- CODEC_ID_MPEG1VIDEO,
- ffm_write_header,
- ffm_write_packet,
- ffm_write_trailer,
+ .name = "ffm",
+ .long_name = NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"),
+ .mime_type = "",
+ .extensions = "ffm",
+ .priv_data_size = sizeof(FFMContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG1VIDEO,
+ .write_header = ffm_write_header,
+ .write_packet = ffm_write_packet,
+ .write_trailer = ffm_write_trailer,
};
diff --git a/libavformat/ffmeta.h b/libavformat/ffmeta.h
index a5380ca13d..ae8778d614 100644
--- a/libavformat/ffmeta.h
+++ b/libavformat/ffmeta.h
@@ -2,20 +2,20 @@
* Common data for metadata muxer/demuxer
* Copyright (c) 2010 Anton Khirnov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/ffmetadec.c b/libavformat/ffmetadec.c
index 73d3b83ed7..1d223fb9e0 100644
--- a/libavformat/ffmetadec.c
+++ b/libavformat/ffmetadec.c
@@ -2,20 +2,20 @@
* Metadata demuxer
* Copyright (c) 2010 Anton Khirnov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -50,7 +50,7 @@ static void get_line(AVIOContext *s, uint8_t *buf, int size)
buf[i++] = c;
}
buf[i] = 0;
- } while (!s->eof_reached && (buf[0] == ';' || buf[0] == '#' || buf[0] == 0));
+ } while (!url_feof(s) && (buf[0] == ';' || buf[0] == '#' || buf[0] == 0));
}
static AVChapter *read_chapter(AVFormatContext *s)
@@ -75,7 +75,7 @@ static AVChapter *read_chapter(AVFormatContext *s)
end = AV_NOPTS_VALUE;
}
- return ff_new_chapter(s, s->nb_chapters, tb, start, end, NULL);
+ return avpriv_new_chapter(s, s->nb_chapters, tb, start, end, NULL);
}
static uint8_t *unescape(uint8_t *buf, int size)
@@ -128,11 +128,11 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
AVDictionary **m = &s->metadata;
uint8_t line[1024];
- while(!s->pb->eof_reached) {
+ while(!url_feof(s->pb)) {
get_line(s->pb, line, sizeof(line));
if (!memcmp(line, ID_STREAM, strlen(ID_STREAM))) {
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return -1;
diff --git a/libavformat/ffmetaenc.c b/libavformat/ffmetaenc.c
index 0aadb8a9cc..200c9940a4 100644
--- a/libavformat/ffmetaenc.c
+++ b/libavformat/ffmetaenc.c
@@ -2,20 +2,20 @@
* Metadata muxer
* Copyright (c) 2010 Anton Khirnov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/file.c b/libavformat/file.c
index 649640a927..ffbccba0a4 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -2,20 +2,20 @@
* Buffered file io for ffmpeg system
* Copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -37,13 +37,15 @@
static int file_read(URLContext *h, unsigned char *buf, int size)
{
int fd = (intptr_t) h->priv_data;
- return read(fd, buf, size);
+ int r = read(fd, buf, size);
+ return (-1 == r)?AVERROR(errno):r;
}
static int file_write(URLContext *h, const unsigned char *buf, int size)
{
int fd = (intptr_t) h->priv_data;
- return write(fd, buf, size);
+ int r = write(fd, buf, size);
+ return (-1 == r)?AVERROR(errno):r;
}
static int file_get_handle(URLContext *h)
diff --git a/libavformat/filmstripdec.c b/libavformat/filmstripdec.c
index 095bf9e809..8aa8ee0dee 100644
--- a/libavformat/filmstripdec.c
+++ b/libavformat/filmstripdec.c
@@ -2,20 +2,20 @@
* Adobe Filmstrip demuxer
* Copyright (c) 2010 Peter Ross
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -49,7 +49,7 @@ static int read_header(AVFormatContext *s,
return AVERROR_INVALIDDATA;
}
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -80,7 +80,7 @@ static int read_packet(AVFormatContext *s,
FilmstripDemuxContext *film = s->priv_data;
AVStream *st = s->streams[0];
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR(EIO);
pkt->dts = avio_tell(s->pb) / (st->codec->width * (st->codec->height + film->leading) * 4);
pkt->size = av_get_packet(s->pb, pkt, st->codec->width * st->codec->height * 4);
@@ -94,18 +94,17 @@ static int read_packet(AVFormatContext *s,
static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
{
AVStream *st = s->streams[stream_index];
- avio_seek(s->pb, FFMAX(timestamp, 0) * st->codec->width * st->codec->height * 4, SEEK_SET);
+ if (avio_seek(s->pb, FFMAX(timestamp, 0) * st->codec->width * st->codec->height * 4, SEEK_SET) < 0)
+ return -1;
return 0;
}
AVInputFormat ff_filmstrip_demuxer = {
- "filmstrip",
- NULL_IF_CONFIG_SMALL("Adobe Filmstrip"),
- sizeof(FilmstripDemuxContext),
- NULL,
- read_header,
- read_packet,
- NULL,
- read_seek,
+ .name = "filmstrip",
+ .long_name = NULL_IF_CONFIG_SMALL("Adobe Filmstrip"),
+ .priv_data_size = sizeof(FilmstripDemuxContext),
+ .read_header = read_header,
+ .read_packet = read_packet,
+ .read_seek = read_seek,
.extensions = "flm",
};
diff --git a/libavformat/filmstripenc.c b/libavformat/filmstripenc.c
index 21f47550af..3862cb1dba 100644
--- a/libavformat/filmstripenc.c
+++ b/libavformat/filmstripenc.c
@@ -2,20 +2,20 @@
* Adobe Filmstrip muxer
* Copyright (c) 2010 Peter Ross
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -72,14 +72,13 @@ static int write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_filmstrip_muxer = {
- "filmstrip",
- NULL_IF_CONFIG_SMALL("Adobe Filmstrip"),
- NULL,
- "flm",
- sizeof(FilmstripMuxContext),
- CODEC_ID_NONE,
- CODEC_ID_RAWVIDEO,
- write_header,
- write_packet,
- write_trailer,
+ .name = "filmstrip",
+ .long_name = NULL_IF_CONFIG_SMALL("Adobe Filmstrip"),
+ .extensions = "flm",
+ .priv_data_size = sizeof(FilmstripMuxContext),
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_header = write_header,
+ .write_packet = write_packet,
+ .write_trailer = write_trailer,
};
diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
index 02452b4c7c..a5a32131a7 100644
--- a/libavformat/flacdec.c
+++ b/libavformat/flacdec.c
@@ -2,20 +2,20 @@
* Raw FLAC demuxer
* Copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -31,7 +31,7 @@ static int flac_read_header(AVFormatContext *s,
int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
uint8_t header[4];
uint8_t *buffer=NULL;
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -46,9 +46,9 @@ static int flac_read_header(AVFormatContext *s,
}
/* process metadata blocks */
- while (!s->pb->eof_reached && !metadata_last) {
+ while (!url_feof(s->pb) && !metadata_last) {
avio_read(s->pb, header, 4);
- ff_flac_parse_block_header(header, &metadata_last, &metadata_type,
+ avpriv_flac_parse_block_header(header, &metadata_last, &metadata_type,
&metadata_size);
switch (metadata_type) {
/* allocate and read metadata block for supported types */
@@ -87,7 +87,7 @@ static int flac_read_header(AVFormatContext *s,
buffer = NULL;
/* get codec params from STREAMINFO header */
- ff_flac_parse_streaminfo(st->codec, &si, st->codec->extradata);
+ avpriv_flac_parse_streaminfo(st->codec, &si, st->codec->extradata);
/* set time base and duration */
if (si.samplerate > 0) {
@@ -124,12 +124,11 @@ static int flac_probe(AVProbeData *p)
}
AVInputFormat ff_flac_demuxer = {
- "flac",
- NULL_IF_CONFIG_SMALL("raw FLAC"),
- 0,
- flac_probe,
- flac_read_header,
- ff_raw_read_partial_packet,
+ .name = "flac",
+ .long_name = NULL_IF_CONFIG_SMALL("raw FLAC"),
+ .read_probe = flac_probe,
+ .read_header = flac_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "flac",
.value = CODEC_ID_FLAC,
diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
index fb28a6ed4c..e7bbb783ab 100644
--- a/libavformat/flacenc.c
+++ b/libavformat/flacenc.c
@@ -2,20 +2,20 @@
* raw FLAC muxer
* Copyright (c) 2006-2009 Justin Ruggles
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -94,7 +94,7 @@ static int flac_write_trailer(struct AVFormatContext *s)
enum FLACExtradataFormat format;
int64_t file_size;
- if (!ff_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo))
+ if (!avpriv_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo))
return -1;
if (pb->seekable) {
@@ -118,15 +118,14 @@ static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_flac_muxer = {
- "flac",
- NULL_IF_CONFIG_SMALL("raw FLAC"),
- "audio/x-flac",
- "flac",
- 0,
- CODEC_ID_FLAC,
- CODEC_ID_NONE,
- flac_write_header,
- flac_write_packet,
- flac_write_trailer,
+ .name = "flac",
+ .long_name = NULL_IF_CONFIG_SMALL("raw FLAC"),
+ .mime_type = "audio/x-flac",
+ .extensions = "flac",
+ .audio_codec = CODEC_ID_FLAC,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = flac_write_header,
+ .write_packet = flac_write_packet,
+ .write_trailer = flac_write_trailer,
.flags= AVFMT_NOTIMESTAMPS,
};
diff --git a/libavformat/flacenc.h b/libavformat/flacenc.h
index 2edda67043..e83ee32aeb 100644
--- a/libavformat/flacenc.h
+++ b/libavformat/flacenc.h
@@ -2,20 +2,20 @@
* raw FLAC muxer
* Copyright (C) 2009 Justin Ruggles
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/flacenc_header.c b/libavformat/flacenc_header.c
index 90c5a776d3..cfbdc890af 100644
--- a/libavformat/flacenc_header.c
+++ b/libavformat/flacenc_header.c
@@ -2,20 +2,20 @@
* raw FLAC muxer
* Copyright (C) 2009 Justin Ruggles
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -34,7 +34,7 @@ int ff_flac_write_header(AVIOContext *pb, AVCodecContext *codec,
enum FLACExtradataFormat format;
header[4] = last_block ? 0x80 : 0x00;
- if (!ff_flac_is_extradata_valid(codec, &format, &streaminfo))
+ if (!avpriv_flac_is_extradata_valid(codec, &format, &streaminfo))
return -1;
/* write "fLaC" stream marker and first metadata block header if needed */
diff --git a/libavformat/flic.c b/libavformat/flic.c
index fcdf4c8040..f4c1a1b9fa 100644
--- a/libavformat/flic.c
+++ b/libavformat/flic.c
@@ -2,20 +2,20 @@
* FLI/FLC Animation File Demuxer
* Copyright (c) 2003 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -105,7 +105,7 @@ static int flic_read_header(AVFormatContext *s,
speed = FLIC_DEFAULT_SPEED;
/* initialize the decoder streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
flic->video_stream_index = st->index;
@@ -117,7 +117,7 @@ static int flic_read_header(AVFormatContext *s,
if (!st->codec->width || !st->codec->height) {
/* Ugly hack needed for the following sample: */
- /* http://samples.libav.org/fli-flc/fli-bugs/specular.flc */
+ /* http://samples.mplayerhq.hu/fli-flc/fli-bugs/specular.flc */
av_log(s, AV_LOG_WARNING,
"File with no specified width/height. Trying 640x480.\n");
st->codec->width = 640;
@@ -145,7 +145,7 @@ static int flic_read_header(AVFormatContext *s,
*/
if (AV_RL16(&preamble[4]) == FLIC_TFTD_CHUNK_AUDIO) {
/* TFTD videos have an extra 22050 Hz 8-bit mono audio stream */
- ast = av_new_stream(s, 1);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
@@ -261,10 +261,10 @@ static int flic_read_packet(AVFormatContext *s,
}
AVInputFormat ff_flic_demuxer = {
- "flic",
- NULL_IF_CONFIG_SMALL("FLI/FLC/FLX animation format"),
- sizeof(FlicDemuxContext),
- flic_probe,
- flic_read_header,
- flic_read_packet,
+ .name = "flic",
+ .long_name = NULL_IF_CONFIG_SMALL("FLI/FLC/FLX animation format"),
+ .priv_data_size = sizeof(FlicDemuxContext),
+ .read_probe = flic_probe,
+ .read_header = flic_read_header,
+ .read_packet = flic_read_packet,
};
diff --git a/libavformat/flv.h b/libavformat/flv.h
index c86e20a7cf..2165357b6b 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -1,26 +1,30 @@
-/**
- * @file
+/*
* FLV common header
*
- * Copyright (c) 2006 The Libav Project
+ * Copyright (c) 2006 The FFmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * FLV common header
+ */
+
#ifndef AVFORMAT_FLV_H
#define AVFORMAT_FLV_H
@@ -42,6 +46,11 @@
#define AMF_END_OF_OBJECT 0x09
+#define KEYFRAMES_TAG "keyframes"
+#define KEYFRAMES_TIMESTAMP_TAG "times"
+#define KEYFRAMES_BYTEOFFSET_TAG "filepositions"
+
+
enum {
FLV_HEADER_FLAG_HASVIDEO = 1,
FLV_HEADER_FLAG_HASAUDIO = 4,
@@ -54,6 +63,12 @@ enum {
};
enum {
+ FLV_STREAM_TYPE_VIDEO,
+ FLV_STREAM_TYPE_AUDIO,
+ FLV_STREAM_TYPE_DATA,
+};
+
+enum {
FLV_MONO = 0,
FLV_STEREO = 1,
};
@@ -89,6 +104,8 @@ enum {
FLV_CODECID_VP6A = 5,
FLV_CODECID_SCREEN2 = 6,
FLV_CODECID_H264 = 7,
+ FLV_CODECID_REALH263= 8,
+ FLV_CODECID_MPEG4 = 9,
};
enum {
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 3b7db0e6ca..d48d367500 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -1,42 +1,39 @@
/*
* FLV demuxer
- * Copyright (c) 2003 The Libav Project
+ * Copyright (c) 2003 The FFmpeg Project
*
* This demuxer will generate a 1 byte extradata for VP6F content.
* It is composed of:
* - upper 4bits: difference between encoded width and visible width
* - lower 4bits: difference between encoded height and visible height
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
#include "libavutil/intfloat_readwrite.h"
+#include "libavutil/mathematics.h"
#include "libavcodec/bytestream.h"
#include "libavcodec/mpeg4audio.h"
#include "avformat.h"
#include "avio_internal.h"
#include "flv.h"
-#define KEYFRAMES_TAG "keyframes"
-#define KEYFRAMES_TIMESTAMP_TAG "times"
-#define KEYFRAMES_BYTEOFFSET_TAG "filepositions"
-
typedef struct {
int wrong_dts; ///< wrong dts due to negative cts
} FLVContext;
@@ -94,6 +91,7 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_co
AVCodecContext *vcodec = vstream->codec;
switch(flv_codecid) {
case FLV_CODECID_H263 : vcodec->codec_id = CODEC_ID_FLV1 ; break;
+ case FLV_CODECID_REALH263: vcodec->codec_id = CODEC_ID_H263 ; break; // Really mean it this time
case FLV_CODECID_SCREEN: vcodec->codec_id = CODEC_ID_FLASHSV; break;
case FLV_CODECID_SCREEN2: vcodec->codec_id = CODEC_ID_FLASHSV2; break;
case FLV_CODECID_VP6 : vcodec->codec_id = CODEC_ID_VP6F ;
@@ -109,6 +107,9 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_co
case FLV_CODECID_H264:
vcodec->codec_id = CODEC_ID_H264;
return 3; // not 4, reading packet type will consume one byte
+ case FLV_CODECID_MPEG4:
+ vcodec->codec_id = CODEC_ID_MPEG4;
+ return 3;
default:
av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
vcodec->codec_tag = flv_codecid;
@@ -132,48 +133,55 @@ static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) {
}
static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream *vstream, int64_t max_pos) {
- unsigned int arraylen = 0, timeslen = 0, fileposlen = 0, i;
- double num_val;
+ unsigned int timeslen = 0, fileposlen = 0, i;
char str_val[256];
int64_t *times = NULL;
int64_t *filepositions = NULL;
int ret = AVERROR(ENOSYS);
int64_t initial_pos = avio_tell(ioc);
+ AVDictionaryEntry *creator = av_dict_get(s->metadata, "metadatacreator",
+ NULL, 0);
+
+ if (creator && !strcmp(creator->value, "MEGA")) {
+ /* Files with this metadatacreator tag seem to have filepositions
+ * pointing at the 4 trailer bytes of the previous packet,
+ * which isn't the norm (nor what we expect here, nor what
+ * jwplayer + lighttpd expect, nor what flvtool2 produces).
+ * Just ignore the index in this case, instead of risking trying
+ * to adjust it to something that might or might not work. */
+ return 0;
+ }
while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
- int64_t* current_array;
+ int64_t** current_array;
+ unsigned int arraylen;
// Expect array object in context
if (avio_r8(ioc) != AMF_DATA_TYPE_ARRAY)
break;
arraylen = avio_rb32(ioc);
- /*
- * Expect only 'times' or 'filepositions' sub-arrays in other case refuse to use such metadata
- * for indexing
- */
- if (!strcmp(KEYFRAMES_TIMESTAMP_TAG, str_val) && !times) {
- if (!(times = av_mallocz(sizeof(*times) * arraylen))) {
- ret = AVERROR(ENOMEM);
- goto finish;
- }
- timeslen = arraylen;
- current_array = times;
- } else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && !filepositions) {
- if (!(filepositions = av_mallocz(sizeof(*filepositions) * arraylen))) {
- ret = AVERROR(ENOMEM);
- goto finish;
- }
- fileposlen = arraylen;
- current_array = filepositions;
- } else // unexpected metatag inside keyframes, will not use such metadata for indexing
+ if(arraylen>>28)
break;
+ if (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times){
+ current_array= &times;
+ timeslen= arraylen;
+ }else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && !filepositions){
+ current_array= &filepositions;
+ fileposlen= arraylen;
+ }else // unexpected metatag inside keyframes, will not use such metadata for indexing
+ break;
+
+ if (!(*current_array = av_mallocz(sizeof(**current_array) * arraylen))) {
+ ret = AVERROR(ENOMEM);
+ goto finish;
+ }
+
for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) {
if (avio_r8(ioc) != AMF_DATA_TYPE_NUMBER)
goto finish;
- num_val = av_int2dbl(avio_rb64(ioc));
- current_array[i] = num_val;
+ current_array[0][i] = av_int2dbl(avio_rb64(ioc));
}
if (times && filepositions) {
// All done, exiting at a position allowing amf_parse_object
@@ -183,19 +191,16 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
}
}
- if (timeslen == fileposlen)
- for(i = 0; i < arraylen; i++)
+ if (timeslen == fileposlen) {
+ for(i = 0; i < timeslen; i++)
av_add_index_entry(vstream, filepositions[i], times[i]*1000, 0, 0, AVINDEX_KEYFRAME);
- else
+ } else
av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n");
finish:
av_freep(&times);
av_freep(&filepositions);
- // If we got unexpected data, but successfully reset back to
- // the start pos, the caller can continue parsing
- if (ret < 0 && avio_seek(ioc, initial_pos, SEEK_SET) > 0)
- return 0;
+ avio_seek(ioc, initial_pos, SEEK_SET);
return ret;
}
@@ -223,9 +228,10 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
case AMF_DATA_TYPE_OBJECT: {
unsigned int keylen;
- if (key && !strcmp(KEYFRAMES_TAG, key) && depth == 1)
- if (parse_keyframes_index(s, ioc, vstream, max_pos) < 0)
- return -1;
+ if ((vstream || astream) && ioc->seekable && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1)
+ if (parse_keyframes_index(s, ioc, vstream ? vstream : astream,
+ max_pos) < 0)
+ av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n");
while(avio_tell(ioc) < max_pos - 2 && (keylen = avio_rb16(ioc))) {
avio_skip(ioc, keylen); //skip key string
@@ -271,17 +277,39 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
acodec = astream ? astream->codec : NULL;
vcodec = vstream ? vstream->codec : NULL;
+ if (amf_type == AMF_DATA_TYPE_NUMBER) {
+ if (!strcmp(key, "duration"))
+ s->duration = num_val * AV_TIME_BASE;
+ else if (!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
+ vcodec->bit_rate = num_val * 1024.0;
+ else if (!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0))
+ acodec->bit_rate = num_val * 1024.0;
+ }
+
+ if (!strcmp(key, "duration") ||
+ !strcmp(key, "filesize") ||
+ !strcmp(key, "width") ||
+ !strcmp(key, "height") ||
+ !strcmp(key, "videodatarate") ||
+ !strcmp(key, "framerate") ||
+ !strcmp(key, "videocodecid") ||
+ !strcmp(key, "audiodatarate") ||
+ !strcmp(key, "audiosamplerate") ||
+ !strcmp(key, "audiosamplesize") ||
+ !strcmp(key, "stereo") ||
+ !strcmp(key, "audiocodecid"))
+ return 0;
+
if(amf_type == AMF_DATA_TYPE_BOOL) {
av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val));
av_dict_set(&s->metadata, key, str_val, 0);
} else if(amf_type == AMF_DATA_TYPE_NUMBER) {
snprintf(str_val, sizeof(str_val), "%.f", num_val);
av_dict_set(&s->metadata, key, str_val, 0);
- if(!strcmp(key, "duration")) s->duration = num_val * AV_TIME_BASE;
- else if(!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
- vcodec->bit_rate = num_val * 1024.0;
- else if(!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0))
- acodec->bit_rate = num_val * 1024.0;
+ } else if(amf_type == AMF_DATA_TYPE_OBJECT){
+ if(s->nb_streams==1 && ((!acodec && !strcmp(key, "audiocodecid")) || (!vcodec && !strcmp(key, "videocodecid")))){
+ s->ctx_flags &= ~AVFMTCTX_NOHEADER; //If there is either audio/video missing, codecid will be an empty object
+ }
} else if (amf_type == AMF_DATA_TYPE_STRING)
av_dict_set(&s->metadata, key, str_val, 0);
}
@@ -291,13 +319,12 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
AMFDataType type;
- AVStream *stream, *astream, *vstream;
+ AVStream *stream, *astream, *vstream, *dstream;
AVIOContext *ioc;
int i;
char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want.
- astream = NULL;
- vstream = NULL;
+ vstream = astream = dstream = NULL;
ioc = s->pb;
//first object needs to be "onMetaData" string
@@ -308,8 +335,9 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
//find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called.
for(i = 0; i < s->nb_streams; i++) {
stream = s->streams[i];
- if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream;
- else if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream;
+ if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream;
+ else if(stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream;
+ else if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) dstream = stream;
}
//parse the second object (we want a mixed array)
@@ -319,11 +347,19 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
return 0;
}
-static AVStream *create_stream(AVFormatContext *s, int is_audio){
- AVStream *st = av_new_stream(s, is_audio);
+static AVStream *create_stream(AVFormatContext *s, int stream_type){
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return NULL;
- st->codec->codec_type = is_audio ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO;
+ st->id = stream_type;
+ switch(stream_type) {
+ case FLV_STREAM_TYPE_VIDEO: st->codec->codec_type = AVMEDIA_TYPE_VIDEO; break;
+ case FLV_STREAM_TYPE_AUDIO: st->codec->codec_type = AVMEDIA_TYPE_AUDIO; break;
+ case FLV_STREAM_TYPE_DATA:
+ st->codec->codec_type = AVMEDIA_TYPE_DATA;
+ st->codec->codec_id = CODEC_ID_NONE; // Going to rely on copy for now
+ av_log(s, AV_LOG_DEBUG, "Data stream created\n");
+ }
av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
return st;
}
@@ -347,13 +383,15 @@ static int flv_read_header(AVFormatContext *s,
s->ctx_flags |= AVFMTCTX_NOHEADER;
if(flags & FLV_HEADER_FLAG_HASVIDEO){
- if(!create_stream(s, 0))
+ if(!create_stream(s, FLV_STREAM_TYPE_VIDEO))
return AVERROR(ENOMEM);
}
if(flags & FLV_HEADER_FLAG_HASAUDIO){
- if(!create_stream(s, 1))
+ if(!create_stream(s, FLV_STREAM_TYPE_AUDIO))
return AVERROR(ENOMEM);
}
+ // Flag doesn't indicate whether or not there is script-data present. Must
+ // create that stream if it's encountered.
offset = avio_rb32(s->pb);
avio_seek(s->pb, offset, SEEK_SET);
@@ -378,7 +416,8 @@ static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size)
static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
{
FLVContext *flv = s->priv_data;
- int ret, i, type, size, flags, is_audio;
+ int ret, i, type, size, flags;
+ int stream_type=-1;
int64_t next, pos;
int64_t dts, pts = AV_NOPTS_VALUE;
AVStream *st = NULL;
@@ -390,7 +429,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
dts = avio_rb24(s->pb);
dts |= avio_r8(s->pb) << 24;
av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts);
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR_EOF;
avio_skip(s->pb, 3); /* stream id, always 0 */
flags = 0;
@@ -401,20 +440,26 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
next= size + avio_tell(s->pb);
if (type == FLV_TAG_TYPE_AUDIO) {
- is_audio=1;
+ stream_type=FLV_STREAM_TYPE_AUDIO;
flags = avio_r8(s->pb);
size--;
} else if (type == FLV_TAG_TYPE_VIDEO) {
- is_audio=0;
+ stream_type=FLV_STREAM_TYPE_VIDEO;
flags = avio_r8(s->pb);
size--;
if ((flags & 0xf0) == 0x50) /* video info / command frame */
goto skip;
- } else {
- if (type == FLV_TAG_TYPE_META && size > 13+1+4)
+ } else if (type == FLV_TAG_TYPE_META) {
+ if (size > 13+1+4 && dts == 0) { // Header-type metadata stuff
flv_read_metabody(s, next);
- else /* skip packet */
- av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
+ goto skip;
+ } else if (dts != 0) { // Script-data "special" metadata frames - don't skip
+ stream_type=FLV_STREAM_TYPE_DATA;
+ } else {
+ goto skip;
+ }
+ } else {
+ av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
skip:
avio_seek(s->pb, next, SEEK_SET);
continue;
@@ -427,17 +472,17 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
/* now find stream */
for(i=0;i<s->nb_streams;i++) {
st = s->streams[i];
- if (st->id == is_audio)
+ if (st->id == stream_type)
break;
}
if(i == s->nb_streams){
- av_log(s, AV_LOG_ERROR, "invalid stream\n");
- st= create_stream(s, is_audio);
+ av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n");
+ st= create_stream(s, stream_type);
s->ctx_flags &= ~AVFMTCTX_NOHEADER;
}
- av_dlog(s, "%d %X %d \n", is_audio, flags, st->discard);
- if( (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || is_audio))
- ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && !is_audio))
+ av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard);
+ if( (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO)))
+ ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO)))
|| st->discard >= AVDISCARD_ALL
){
avio_seek(s->pb, next, SEEK_SET);
@@ -464,7 +509,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
avio_seek(s->pb, pos, SEEK_SET);
}
- if(is_audio){
+ if(stream_type == FLV_STREAM_TYPE_AUDIO){
if(!st->codec->channels || !st->codec->sample_rate || !st->codec->bits_per_coded_sample) {
st->codec->channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
st->codec->sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3);
@@ -473,15 +518,16 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
if(!st->codec->codec_id){
flv_set_audio_codec(s, st, flags & FLV_AUDIO_CODECID_MASK);
}
- }else{
+ } else if(stream_type == FLV_STREAM_TYPE_VIDEO) {
size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK);
}
if (st->codec->codec_id == CODEC_ID_AAC ||
- st->codec->codec_id == CODEC_ID_H264) {
+ st->codec->codec_id == CODEC_ID_H264 ||
+ st->codec->codec_id == CODEC_ID_MPEG4) {
int type = avio_r8(s->pb);
size--;
- if (st->codec->codec_id == CODEC_ID_H264) {
+ if (st->codec->codec_id == CODEC_ID_H264 || st->codec->codec_id == CODEC_ID_MPEG4) {
int32_t cts = (avio_rb24(s->pb)+0xff800000)^0xff800000; // sign extension
pts = dts + cts;
if (cts < 0) { // dts are wrong
@@ -491,12 +537,13 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
if (flv->wrong_dts)
dts = AV_NOPTS_VALUE;
}
- if (type == 0) {
+
+ if (type == 0 && !st->codec->extradata) {
if ((ret = flv_get_extradata(s, st, size)) < 0)
return ret;
if (st->codec->codec_id == CODEC_ID_AAC) {
MPEG4AudioConfig cfg;
- ff_mpeg4audio_get_config(&cfg, st->codec->extradata,
+ avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
st->codec->extradata_size);
st->codec->channels = cfg.channels;
if (cfg.ext_sample_rate)
@@ -529,7 +576,9 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;
pkt->stream_index = st->index;
- if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY))
+ if ( stream_type == FLV_STREAM_TYPE_AUDIO ||
+ ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) ||
+ stream_type == FLV_STREAM_TYPE_DATA)
pkt->flags |= AV_PKT_FLAG_KEY;
leave:
@@ -571,12 +620,12 @@ static int flv_read_seek2(AVFormatContext *s, int stream_index,
#endif
AVInputFormat ff_flv_demuxer = {
- "flv",
- NULL_IF_CONFIG_SMALL("FLV format"),
- sizeof(FLVContext),
- flv_probe,
- flv_read_header,
- flv_read_packet,
+ .name = "flv",
+ .long_name = NULL_IF_CONFIG_SMALL("FLV format"),
+ .priv_data_size = sizeof(FLVContext),
+ .read_probe = flv_probe,
+ .read_header = flv_read_header,
+ .read_packet = flv_read_packet,
.read_seek = flv_read_seek,
#if 0
.read_seek2 = flv_read_seek2,
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index a3e7e25692..627bb6d3ab 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -1,24 +1,25 @@
/*
* FLV muxer
- * Copyright (c) 2003 The Libav Project
+ * Copyright (c) 2003 The FFmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat_readwrite.h"
#include "avformat.h"
#include "flv.h"
@@ -32,6 +33,8 @@
static const AVCodecTag flv_video_codec_ids[] = {
{CODEC_ID_FLV1, FLV_CODECID_H263 },
+ {CODEC_ID_H263, FLV_CODECID_REALH263},
+ {CODEC_ID_MPEG4, FLV_CODECID_MPEG4 },
{CODEC_ID_FLASHSV, FLV_CODECID_SCREEN},
{CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2},
{CODEC_ID_VP6F, FLV_CODECID_VP6 },
@@ -57,10 +60,13 @@ typedef struct FLVContext {
int64_t duration_offset;
int64_t filesize_offset;
int64_t duration;
- int delay; ///< first dts delay for AVC
- int64_t last_video_ts;
} FLVContext;
+typedef struct FLVStreamContext {
+ int delay; ///< first dts delay for each stream (needed for AVC & Speex)
+ int64_t last_ts; ///< last timestamp for each stream
+} FLVStreamContext;
+
static int get_audio_flags(AVCodecContext *enc){
int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT;
@@ -75,11 +81,6 @@ static int get_audio_flags(AVCodecContext *enc){
av_log(enc, AV_LOG_ERROR, "flv only supports mono Speex audio\n");
return -1;
}
- if (enc->frame_size / 320 > 8) {
- av_log(enc, AV_LOG_WARNING, "Warning: Speex stream has more than "
- "8 frames per packet. Adobe Flash "
- "Player cannot handle this!\n");
- }
return FLV_CODECID_SPEEX | FLV_SAMPLERATE_11025HZ | FLV_SAMPLESSIZE_16BIT;
} else {
switch (enc->sample_rate) {
@@ -177,13 +178,14 @@ static int flv_write_header(AVFormatContext *s)
AVIOContext *pb = s->pb;
FLVContext *flv = s->priv_data;
AVCodecContext *audio_enc = NULL, *video_enc = NULL;
- int i;
+ int i, metadata_count = 0;
double framerate = 0.0;
- int metadata_size_pos, data_size;
+ int64_t metadata_size_pos, data_size, metadata_count_pos;
AVDictionaryEntry *tag = NULL;
for(i=0; i<s->nb_streams; i++){
AVCodecContext *enc = s->streams[i]->codec;
+ FLVStreamContext *sc;
if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) {
framerate = av_q2d(s->streams[i]->r_frame_rate);
@@ -195,12 +197,18 @@ static int flv_write_header(AVFormatContext *s)
av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n");
return -1;
}
- } else {
+ } else if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
audio_enc = enc;
if(get_audio_flags(enc)<0)
return -1;
}
av_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */
+
+ sc = av_mallocz(sizeof(FLVStreamContext));
+ if (!sc)
+ return AVERROR(ENOMEM);
+ s->streams[i]->priv_data = sc;
+ sc->last_ts = -1;
}
avio_write(pb, "FLV", 3);
avio_w8(pb,1);
@@ -220,8 +228,6 @@ static int flv_write_header(AVFormatContext *s)
}
}
- flv->last_video_ts = -1;
-
/* write meta_tag */
avio_w8(pb, 18); // tag type META
metadata_size_pos= avio_tell(pb);
@@ -237,7 +243,9 @@ static int flv_write_header(AVFormatContext *s)
/* mixed array (hash) with size and string/type/data tuples */
avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
- avio_wb32(pb, 5*!!video_enc + 5*!!audio_enc + 2); // +2 for duration and file size
+ metadata_count_pos = avio_tell(pb);
+ metadata_count = 5*!!video_enc + 5*!!audio_enc + 2; // +2 for duration and file size
+ avio_wb32(pb, metadata_count);
put_amf_string(pb, "duration");
flv->duration_offset= avio_tell(pb);
@@ -278,9 +286,26 @@ static int flv_write_header(AVFormatContext *s)
}
while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+ if( !strcmp(tag->key, "width")
+ ||!strcmp(tag->key, "height")
+ ||!strcmp(tag->key, "videodatarate")
+ ||!strcmp(tag->key, "framerate")
+ ||!strcmp(tag->key, "videocodecid")
+ ||!strcmp(tag->key, "audiodatarate")
+ ||!strcmp(tag->key, "audiosamplerate")
+ ||!strcmp(tag->key, "audiosamplesize")
+ ||!strcmp(tag->key, "stereo")
+ ||!strcmp(tag->key, "audiocodecid")
+ ||!strcmp(tag->key, "duration")
+ ||!strcmp(tag->key, "onMetaData")
+ ){
+ av_log(s, AV_LOG_DEBUG, "ignoring metadata for %s\n", tag->key);
+ continue;
+ }
put_amf_string(pb, tag->key);
avio_w8(pb, AMF_DATA_TYPE_STRING);
put_amf_string(pb, tag->value);
+ metadata_count++;
}
put_amf_string(pb, "filesize");
@@ -292,6 +317,10 @@ static int flv_write_header(AVFormatContext *s)
/* write total size of tag */
data_size= avio_tell(pb) - metadata_size_pos - 10;
+
+ avio_seek(pb, metadata_count_pos, SEEK_SET);
+ avio_wb32(pb, metadata_count);
+
avio_seek(pb, metadata_size_pos, SEEK_SET);
avio_wb24(pb, data_size);
avio_skip(pb, data_size + 10 - 3);
@@ -299,7 +328,7 @@ static int flv_write_header(AVFormatContext *s)
for (i = 0; i < s->nb_streams; i++) {
AVCodecContext *enc = s->streams[i]->codec;
- if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) {
+ if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264 || enc->codec_id == CODEC_ID_MPEG4) {
int64_t pos;
avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ?
FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
@@ -340,9 +369,10 @@ static int flv_write_trailer(AVFormatContext *s)
/* Add EOS tag */
for (i = 0; i < s->nb_streams; i++) {
AVCodecContext *enc = s->streams[i]->codec;
+ FLVStreamContext *sc = s->streams[i]->priv_data;
if (enc->codec_type == AVMEDIA_TYPE_VIDEO &&
- enc->codec_id == CODEC_ID_H264) {
- put_avc_eos_tag(pb, flv->last_video_ts);
+ (enc->codec_id == CODEC_ID_H264 || enc->codec_id == CODEC_ID_MPEG4)) {
+ put_avc_eos_tag(pb, sc->last_ts);
}
}
@@ -363,6 +393,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
AVIOContext *pb = s->pb;
AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
FLVContext *flv = s->priv_data;
+ FLVStreamContext *sc = s->streams[pkt->stream_index]->priv_data;
unsigned ts;
int size= pkt->size;
uint8_t *data= NULL;
@@ -373,7 +404,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if(enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F ||
enc->codec_id == CODEC_ID_AAC)
flags_size= 2;
- else if(enc->codec_id == CODEC_ID_H264)
+ else if(enc->codec_id == CODEC_ID_H264 || enc->codec_id == CODEC_ID_MPEG4)
flags_size= 5;
else
flags_size= 1;
@@ -383,47 +414,66 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
flags = enc->codec_tag;
if(flags == 0) {
- av_log(enc, AV_LOG_ERROR, "video codec %X not compatible with flv\n",enc->codec_id);
+ av_log(enc, AV_LOG_ERROR, "video codec %s not compatible with flv\n", avcodec_get_name(enc->codec_id));
return -1;
}
flags |= pkt->flags & AV_PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER;
- } else {
- assert(enc->codec_type == AVMEDIA_TYPE_AUDIO);
+ } else if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
flags = get_audio_flags(enc);
assert(size);
avio_w8(pb, FLV_TAG_TYPE_AUDIO);
+ } else {
+ // In-band flv metadata ("scriptdata")
+ assert(enc->codec_type == AVMEDIA_TYPE_DATA);
+ avio_w8(pb, FLV_TAG_TYPE_META);
+ flags_size = 0;
+ flags = NULL;
}
- if (enc->codec_id == CODEC_ID_H264) {
+ if (enc->codec_id == CODEC_ID_H264 || enc->codec_id == CODEC_ID_MPEG4) {
/* check if extradata looks like mp4 formated */
if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) {
if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0)
return -1;
}
- if (!flv->delay && pkt->dts < 0)
- flv->delay = -pkt->dts;
+ } else if (enc->codec_id == CODEC_ID_AAC && pkt->size > 2 &&
+ (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
+ av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n");
+ return -1;
}
+ if (!sc->delay && pkt->dts < 0)
+ sc->delay = -pkt->dts;
- ts = pkt->dts + flv->delay; // add delay to force positive dts
- if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (flv->last_video_ts < ts)
- flv->last_video_ts = ts;
+ ts = pkt->dts + sc->delay; // add delay to force positive dts
+
+ /* check Speex packet duration */
+ if (enc->codec_id == CODEC_ID_SPEEX && ts - sc->last_ts > 160) {
+ av_log(s, AV_LOG_WARNING, "Warning: Speex stream has more than "
+ "8 frames per packet. Adobe Flash "
+ "Player cannot handle this!\n");
}
+
+ if (sc->last_ts < ts)
+ sc->last_ts = ts;
+
avio_wb24(pb,size + flags_size);
avio_wb24(pb,ts);
avio_w8(pb,(ts >> 24) & 0x7F); // timestamps are 32bits _signed_
avio_wb24(pb,flv->reserved);
- avio_w8(pb,flags);
+
+ if(flags_size)
+ avio_w8(pb,flags);
+
if (enc->codec_id == CODEC_ID_VP6)
avio_w8(pb,0);
if (enc->codec_id == CODEC_ID_VP6F)
avio_w8(pb, enc->extradata_size ? enc->extradata[0] : 0);
else if (enc->codec_id == CODEC_ID_AAC)
avio_w8(pb,1); // AAC raw
- else if (enc->codec_id == CODEC_ID_H264) {
+ else if (enc->codec_id == CODEC_ID_H264 || enc->codec_id == CODEC_ID_MPEG4) {
avio_w8(pb,1); // AVC NALU
avio_wb24(pb,pkt->pts - pkt->dts);
}
@@ -431,7 +481,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
avio_write(pb, data ? data : pkt->data, size);
avio_wb32(pb,size+flags_size+11); // previous tag size
- flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration);
+ flv->duration = FFMAX(flv->duration, pkt->pts + sc->delay + pkt->duration);
avio_flush(pb);
@@ -441,20 +491,20 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_flv_muxer = {
- "flv",
- NULL_IF_CONFIG_SMALL("FLV format"),
- "video/x-flv",
- "flv",
- sizeof(FLVContext),
+ .name = "flv",
+ .long_name = NULL_IF_CONFIG_SMALL("FLV format"),
+ .mime_type = "video/x-flv",
+ .extensions = "flv",
+ .priv_data_size = sizeof(FLVContext),
#if CONFIG_LIBMP3LAME
- CODEC_ID_MP3,
+ .audio_codec = CODEC_ID_MP3,
#else // CONFIG_LIBMP3LAME
- CODEC_ID_ADPCM_SWF,
+ .audio_codec = CODEC_ID_ADPCM_SWF,
#endif // CONFIG_LIBMP3LAME
- CODEC_ID_FLV1,
- flv_write_header,
- flv_write_packet,
- flv_write_trailer,
+ .video_codec = CODEC_ID_FLV1,
+ .write_header = flv_write_header,
+ .write_packet = flv_write_packet,
+ .write_trailer = flv_write_trailer,
.codec_tag= (const AVCodecTag* const []){flv_video_codec_ids, flv_audio_codec_ids, 0},
.flags= AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
};
diff --git a/libavformat/framecrcenc.c b/libavformat/framecrcenc.c
index 2bd3f547d3..65ca670bbd 100644
--- a/libavformat/framecrcenc.c
+++ b/libavformat/framecrcenc.c
@@ -2,20 +2,20 @@
* frame CRC encoder (for codec/format testing)
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -34,14 +34,10 @@ static int framecrc_write_packet(struct AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_framecrc_muxer = {
- "framecrc",
- NULL_IF_CONFIG_SMALL("framecrc testing format"),
- NULL,
- "",
- 0,
- CODEC_ID_PCM_S16LE,
- CODEC_ID_RAWVIDEO,
- NULL,
- framecrc_write_packet,
- NULL,
+ .name = "framecrc",
+ .long_name = NULL_IF_CONFIG_SMALL("framecrc testing format"),
+ .extensions = "",
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_packet = framecrc_write_packet,
};
diff --git a/libavformat/g723_1.c b/libavformat/g723_1.c
new file mode 100644
index 0000000000..19441a1b19
--- /dev/null
+++ b/libavformat/g723_1.c
@@ -0,0 +1,83 @@
+/*
+ * G.723.1 demuxer
+ * Copyright (c) 2010 Mohamed Naufal Basheer
+ *
+ * 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
+ * G.723.1 demuxer
+ */
+
+#include "avformat.h"
+
+static const uint8_t frame_size[4] = {24, 20, 4, 1};
+
+static int g723_1_init(AVFormatContext *s, AVFormatParameters *ap)
+{
+ AVStream *st;
+
+ st = av_new_stream(s, 0);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = CODEC_ID_G723_1;
+ st->codec->channels = 1;
+ st->codec->sample_rate = 8000;
+
+ av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+
+ return 0;
+}
+
+static int g723_1_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ int size, byte, ret;
+
+ pkt->pos = url_ftell(s->pb);
+ byte = get_byte(s->pb);
+ size = frame_size[byte & 3];
+
+ ret = av_new_packet(pkt, size);
+ if (ret < 0)
+ return ret;
+
+ pkt->data[0] = byte;
+ pkt->duration = 240;
+ pkt->stream_index = 0;
+
+ ret = get_buffer(s->pb, pkt->data + 1, size - 1);
+ if (ret < size - 1) {
+ av_free_packet(pkt);
+ return ret < 0 ? ret : AVERROR_EOF;
+ }
+
+ return pkt->size;
+}
+
+AVInputFormat ff_g723_1_demuxer = {
+ "g723_1",
+ NULL_IF_CONFIG_SMALL("G.723.1 format"),
+ 0,
+ NULL,
+ g723_1_init,
+ g723_1_read_packet,
+ .extensions = "tco,rco",
+ .flags = AVFMT_GENERIC_INDEX
+};
diff --git a/libavformat/gif.c b/libavformat/gif.c
index 55deb4d207..200bc70573 100644
--- a/libavformat/gif.c
+++ b/libavformat/gif.c
@@ -2,20 +2,20 @@
* Animated GIF muxer
* Copyright (c) 2000 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -40,6 +40,8 @@
*/
#include "avformat.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
/* The GIF format uses reversed order for bitstreams... */
/* at least they don't use PDP_ENDIAN :) */
@@ -245,8 +247,10 @@ static int gif_image_write_image(AVIOContext *pb,
}
typedef struct {
+ AVClass *class; /** Class for private options. */
int64_t time, file_time;
uint8_t buffer[100]; /* data chunks */
+ int loop;
} GIFContext;
static int gif_write_header(AVFormatContext *s)
@@ -254,7 +258,7 @@ static int gif_write_header(AVFormatContext *s)
GIFContext *gif = s->priv_data;
AVIOContext *pb = s->pb;
AVCodecContext *enc, *video_enc;
- int i, width, height, loop_count /*, rate*/;
+ int i, width, height /*, rate*/;
/* XXX: do we reject audio streams or just ignore them ?
if(s->nb_streams > 1)
@@ -276,7 +280,6 @@ static int gif_write_header(AVFormatContext *s)
} else {
width = video_enc->width;
height = video_enc->height;
- loop_count = s->loop_output;
// rate = video_enc->time_base.den;
}
@@ -285,7 +288,12 @@ static int gif_write_header(AVFormatContext *s)
return AVERROR(EIO);
}
- gif_image_write_header(pb, width, height, loop_count, NULL);
+#if FF_API_LOOP_OUTPUT
+ if (s->loop_output)
+ gif->loop = s->loop_output;
+#endif
+
+ gif_image_write_header(pb, width, height, gif->loop, NULL);
avio_flush(s->pb);
return 0;
@@ -340,15 +348,30 @@ static int gif_write_trailer(AVFormatContext *s)
return 0;
}
+#define OFFSET(x) offsetof(GIFContext, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "loop", "Number of times to loop the output.", OFFSET(loop), AV_OPT_TYPE_INT, {0}, 0, 65535, ENC },
+ { NULL },
+};
+
+static const AVClass gif_muxer_class = {
+ .class_name = "GIF muxer",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+ .option = options,
+};
+
AVOutputFormat ff_gif_muxer = {
- "gif",
- NULL_IF_CONFIG_SMALL("GIF Animation"),
- "image/gif",
- "gif",
- sizeof(GIFContext),
- CODEC_ID_NONE,
- CODEC_ID_RAWVIDEO,
- gif_write_header,
- gif_write_packet,
- gif_write_trailer,
+ .name = "gif",
+ .long_name = NULL_IF_CONFIG_SMALL("GIF Animation"),
+ .mime_type = "image/gif",
+ .extensions = "gif",
+ .priv_data_size = sizeof(GIFContext),
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_header = gif_write_header,
+ .write_packet = gif_write_packet,
+ .write_trailer = gif_write_trailer,
+ .priv_class = &gif_muxer_class,
};
diff --git a/libavformat/gopher.c b/libavformat/gopher.c
index 79d1feba6b..9eeffaca28 100644
--- a/libavformat/gopher.c
+++ b/libavformat/gopher.c
@@ -5,20 +5,20 @@
*
* based on libavformat/http.c, Copyright (c) 2000, 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/gxf.c b/libavformat/gxf.c
index 54fdadfc32..d42c3fd307 100644
--- a/libavformat/gxf.c
+++ b/libavformat/gxf.c
@@ -2,20 +2,20 @@
* GXF demuxer.
* Copyright (c) 2006 Reimar Doeffinger
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -81,9 +81,10 @@ static int get_sindex(AVFormatContext *s, int id, int format) {
i = ff_find_stream_index(s, id);
if (i >= 0)
return i;
- st = av_new_stream(s, id);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
+ st->id = id;
switch (format) {
case 3:
case 4:
@@ -184,9 +185,9 @@ static void gxf_material_tags(AVIOContext *pb, int *len, struct gxf_stream_info
* @return fps as AVRational, or 0 / 0 if unknown
*/
static AVRational fps_tag2avr(int32_t fps) {
- extern const AVRational ff_frame_rate_tab[];
+ extern const AVRational avpriv_frame_rate_tab[];
if (fps < 1 || fps > 9) fps = 9;
- return ff_frame_rate_tab[9 - fps]; // values have opposite order
+ return avpriv_frame_rate_tab[9 - fps]; // values have opposite order
}
/**
@@ -264,7 +265,7 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
int map_len;
int len;
AVRational main_timebase = {0, 0};
- struct gxf_stream_info si;
+ struct gxf_stream_info *si = s->priv_data;
int i;
if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) {
av_log(s, AV_LOG_ERROR, "map packet not found\n");
@@ -282,7 +283,7 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
return 0;
}
map_len -= len;
- gxf_material_tags(pb, &len, &si);
+ gxf_material_tags(pb, &len, si);
avio_skip(pb, len);
map_len -= 2;
len = avio_rb16(pb); // length of track description
@@ -300,7 +301,7 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
track_id = avio_r8(pb);
track_len = avio_rb16(pb);
len -= track_len;
- gxf_track_tags(pb, &track_len, &si);
+ gxf_track_tags(pb, &track_len, si);
avio_skip(pb, track_len);
if (!(track_type & 0x80)) {
av_log(s, AV_LOG_ERROR, "invalid track type %x\n", track_type);
@@ -316,12 +317,12 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
if (idx < 0) continue;
st = s->streams[idx];
if (!main_timebase.num || !main_timebase.den) {
- main_timebase.num = si.frames_per_second.den;
- main_timebase.den = si.frames_per_second.num * 2;
+ main_timebase.num = si->frames_per_second.den;
+ main_timebase.den = si->frames_per_second.num * 2;
}
- st->start_time = si.first_field;
- if (si.first_field != AV_NOPTS_VALUE && si.last_field != AV_NOPTS_VALUE)
- st->duration = si.last_field - si.first_field;
+ st->start_time = si->first_field;
+ if (si->first_field != AV_NOPTS_VALUE && si->last_field != AV_NOPTS_VALUE)
+ st->duration = si->last_field - si->first_field;
}
if (len < 0)
av_log(s, AV_LOG_ERROR, "invalid track description length specified\n");
@@ -346,6 +347,8 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
avio_skip(pb, 0x30); // payload description
fps = fps_umf2avr(avio_rl32(pb));
if (!main_timebase.num || !main_timebase.den) {
+ av_log(s, AV_LOG_WARNING, "No FPS track tag, using UMF fps tag."
+ " This might give wrong results.\n");
// this may not always be correct, but simply the best we can get
main_timebase.num = fps.den;
main_timebase.den = fps.num * 2;
@@ -368,7 +371,7 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
#define READ_ONE() \
{ \
- if (!max_interval-- || pb->eof_reached) \
+ if (!max_interval-- || url_feof(pb)) \
goto out; \
tmp = tmp << 8 | avio_r8(pb); \
}
@@ -422,13 +425,15 @@ static int gxf_packet(AVFormatContext *s, AVPacket *pkt) {
AVIOContext *pb = s->pb;
GXFPktType pkt_type;
int pkt_len;
+ struct gxf_stream_info *si = s->priv_data;
+
while (!pb->eof_reached) {
AVStream *st;
int track_type, track_id, ret;
int field_nr, field_info, skip = 0;
int stream_index;
if (!parse_packet_header(pb, &pkt_type, &pkt_len)) {
- if (!pb->eof_reached)
+ if (!url_feof(pb))
av_log(s, AV_LOG_ERROR, "sync lost\n");
return -1;
}
@@ -473,6 +478,11 @@ static int gxf_packet(AVFormatContext *s, AVPacket *pkt) {
avio_skip(pb, skip);
pkt->stream_index = stream_index;
pkt->dts = field_nr;
+
+ //set duration manually for DV or else lavf misdetects the frame rate
+ if (st->codec->codec_id == CODEC_ID_DVVIDEO)
+ pkt->duration = si->fields_per_frame;
+
return ret;
}
return AVERROR(EIO);
@@ -516,13 +526,12 @@ static int64_t gxf_read_timestamp(AVFormatContext *s, int stream_index,
}
AVInputFormat ff_gxf_demuxer = {
- "gxf",
- NULL_IF_CONFIG_SMALL("GXF format"),
- 0,
- gxf_probe,
- gxf_header,
- gxf_packet,
- NULL,
- gxf_seek,
- gxf_read_timestamp,
+ .name = "gxf",
+ .long_name = NULL_IF_CONFIG_SMALL("GXF format"),
+ .priv_data_size = sizeof(struct gxf_stream_info),
+ .read_probe = gxf_probe,
+ .read_header = gxf_header,
+ .read_packet = gxf_packet,
+ .read_seek = gxf_seek,
+ .read_timestamp = gxf_read_timestamp,
};
diff --git a/libavformat/gxf.h b/libavformat/gxf.h
index c1ac399458..dcdcdefc2d 100644
--- a/libavformat/gxf.h
+++ b/libavformat/gxf.h
@@ -2,20 +2,20 @@
* GXF demuxer
* copyright (c) 2006 Reimar Doeffinger
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c
index 5a3ff39ab2..3d56eba287 100644
--- a/libavformat/gxfenc.c
+++ b/libavformat/gxfenc.c
@@ -2,20 +2,20 @@
* GXF muxer.
* Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -342,8 +342,9 @@ static int gxf_write_map_packet(AVFormatContext *s, int rewrite)
if (!rewrite) {
if (!(gxf->map_offsets_nb % 30)) {
- gxf->map_offsets = av_realloc(gxf->map_offsets,
- (gxf->map_offsets_nb+30)*sizeof(*gxf->map_offsets));
+ gxf->map_offsets = av_realloc_f(gxf->map_offsets,
+ sizeof(*gxf->map_offsets),
+ gxf->map_offsets_nb+30);
if (!gxf->map_offsets) {
av_log(s, AV_LOG_ERROR, "could not realloc map offsets\n");
return -1;
@@ -394,9 +395,20 @@ static int gxf_write_umf_material_description(AVFormatContext *s)
GXFContext *gxf = s->priv_data;
AVIOContext *pb = s->pb;
int timecode_base = gxf->time_base.den == 60000 ? 60 : 50;
+ int64_t timestamp = 0;
+ AVDictionaryEntry *t;
+ uint32_t timecode;
+
+#if FF_API_TIMESTAMP
+ if (s->timestamp)
+ timestamp = s->timestamp;
+ else
+#endif
+ if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+ timestamp = ff_iso8601_to_unix_time(t->value);
// XXX drop frame
- uint32_t timecode =
+ timecode =
gxf->nb_fields / (timecode_base * 3600) % 24 << 24 | // hours
gxf->nb_fields / (timecode_base * 60) % 60 << 16 | // minutes
gxf->nb_fields / timecode_base % 60 << 8 | // seconds
@@ -409,8 +421,8 @@ static int gxf_write_umf_material_description(AVFormatContext *s)
avio_wl32(pb, gxf->nb_fields); /* mark out */
avio_wl32(pb, 0); /* timecode mark in */
avio_wl32(pb, timecode); /* timecode mark out */
- avio_wl64(pb, s->timestamp); /* modification time */
- avio_wl64(pb, s->timestamp); /* creation time */
+ avio_wl64(pb, timestamp); /* modification time */
+ avio_wl64(pb, timestamp); /* creation time */
avio_wl16(pb, 0); /* reserved */
avio_wl16(pb, 0); /* reserved */
avio_wl16(pb, gxf->audio_tracks);
@@ -878,8 +890,9 @@ static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
if (!(gxf->flt_entries_nb % 500)) {
- gxf->flt_entries = av_realloc(gxf->flt_entries,
- (gxf->flt_entries_nb+500)*sizeof(*gxf->flt_entries));
+ gxf->flt_entries = av_realloc_f(gxf->flt_entries,
+ sizeof(*gxf->flt_entries),
+ gxf->flt_entries_nb+500);
if (!gxf->flt_entries) {
av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n");
return -1;
@@ -933,17 +946,14 @@ static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pk
}
AVOutputFormat ff_gxf_muxer = {
- "gxf",
- NULL_IF_CONFIG_SMALL("GXF format"),
- NULL,
- "gxf",
- sizeof(GXFContext),
- CODEC_ID_PCM_S16LE,
- CODEC_ID_MPEG2VIDEO,
- gxf_write_header,
- gxf_write_packet,
- gxf_write_trailer,
- 0,
- NULL,
- gxf_interleave_packet,
+ .name = "gxf",
+ .long_name = NULL_IF_CONFIG_SMALL("GXF format"),
+ .extensions = "gxf",
+ .priv_data_size = sizeof(GXFContext),
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = gxf_write_header,
+ .write_packet = gxf_write_packet,
+ .write_trailer = gxf_write_trailer,
+ .interleave_packet = gxf_interleave_packet,
};
diff --git a/libavformat/h261dec.c b/libavformat/h261dec.c
index 1b416d4fc7..354a7c78c1 100644
--- a/libavformat/h261dec.c
+++ b/libavformat/h261dec.c
@@ -2,20 +2,20 @@
* RAW H.261 video demuxer
* Copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/h263dec.c b/libavformat/h263dec.c
index b9185cbcb6..b07e9782b8 100644
--- a/libavformat/h263dec.c
+++ b/libavformat/h263dec.c
@@ -2,20 +2,20 @@
* RAW H.263 video demuxer
* Copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/h264dec.c b/libavformat/h264dec.c
index f9086476d5..e7c6d70deb 100644
--- a/libavformat/h264dec.c
+++ b/libavformat/h264dec.c
@@ -2,20 +2,20 @@
* RAW H.264 video demuxer
* Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -54,7 +54,7 @@ static int h264_probe(AVProbeData *p)
case 1: sli++; break;
case 5: idr++; break;
case 7:
- if(p->buf[i+2]&0x0F)
+ if(p->buf[i+2]&0x03)
return 0;
sps++;
break;
diff --git a/libavformat/http.c b/libavformat/http.c
index aa8c6657db..265aff27e0 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -2,20 +2,20 @@
* HTTP protocol for ffmpeg client
* Copyright (c) 2000, 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -54,7 +54,7 @@ typedef struct {
#define OFFSET(x) offsetof(HTTPContext, x)
static const AVOption options[] = {
-{"chunksize", "use chunked transfer-encoding for posts, -1 disables it, 0 enables it", OFFSET(chunksize), FF_OPT_TYPE_INT64, {.dbl = 0}, -1, 0 }, /* Default to 0, for chunked POSTs */
+{"chunksize", "use chunked transfer-encoding for posts, -1 disables it, 0 enables it", OFFSET(chunksize), AV_OPT_TYPE_INT64, {.dbl = 0}, -1, 0 }, /* Default to 0, for chunked POSTs */
{NULL}
};
static const AVClass httpcontext_class = {
@@ -265,6 +265,8 @@ static int process_line(URLContext *h, char *line, int line_count,
s->filesize = atoll(slash+1);
}
h->is_streamed = 0; /* we _can_ in fact seek */
+ } else if (!strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) {
+ h->is_streamed = 0;
} else if (!strcasecmp (tag, "Transfer-Encoding") && !strncasecmp(p, "chunked", 7)) {
s->filesize = -1;
s->chunksize = 0;
diff --git a/libavformat/http.h b/libavformat/http.h
index c5ff5e134c..d01a004e9f 100644
--- a/libavformat/http.h
+++ b/libavformat/http.h
@@ -2,20 +2,20 @@
* HTTP definitions
* Copyright (c) 2010 Josh Allmann
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/httpauth.c b/libavformat/httpauth.c
index 1dda1ac8f0..58e0e82ed1 100644
--- a/libavformat/httpauth.c
+++ b/libavformat/httpauth.c
@@ -2,20 +2,20 @@
* HTTP authentication
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/httpauth.h b/libavformat/httpauth.h
index d2a4a55305..ebab3fca29 100644
--- a/libavformat/httpauth.h
+++ b/libavformat/httpauth.h
@@ -2,20 +2,20 @@
* HTTP authentication
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/id3v1.c b/libavformat/id3v1.c
index 87930ff361..2d1e806920 100644
--- a/libavformat/id3v1.c
+++ b/libavformat/id3v1.c
@@ -2,20 +2,20 @@
* ID3v1 header parser
* Copyright (c) 2003 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/id3v1.h b/libavformat/id3v1.h
index 4842f16f53..8eb58be2d1 100644
--- a/libavformat/id3v1.h
+++ b/libavformat/id3v1.h
@@ -2,20 +2,20 @@
* ID3v1 header parser
* Copyright (c) 2003 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index be6c03bbe5..32870648cf 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -1,24 +1,31 @@
/*
- * ID3v2 header parser
* Copyright (c) 2003 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * ID3v2 header parser
+ *
+ * Specifications available at:
+ * http://id3.org/Developer_Information
+ */
+
#include "id3v2.h"
#include "id3v1.h"
#include "libavutil/avstring.h"
@@ -26,6 +33,66 @@
#include "libavutil/dict.h"
#include "avio_internal.h"
+const AVMetadataConv ff_id3v2_34_metadata_conv[] = {
+ { "TALB", "album"},
+ { "TCOM", "composer"},
+ { "TCON", "genre"},
+ { "TCOP", "copyright"},
+ { "TENC", "encoded_by"},
+ { "TIT2", "title"},
+ { "TLAN", "language"},
+ { "TPE1", "artist"},
+ { "TPE2", "album_artist"},
+ { "TPE3", "performer"},
+ { "TPOS", "disc"},
+ { "TPUB", "publisher"},
+ { "TRCK", "track"},
+ { "TSSE", "encoder"},
+ { 0 }
+};
+
+const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
+ { "TDRL", "date"},
+ { "TDRC", "date"},
+ { "TDEN", "creation_time"},
+ { "TSOA", "album-sort"},
+ { "TSOP", "artist-sort"},
+ { "TSOT", "title-sort"},
+ { 0 }
+};
+
+static const AVMetadataConv id3v2_2_metadata_conv[] = {
+ { "TAL", "album"},
+ { "TCO", "genre"},
+ { "TT2", "title"},
+ { "TEN", "encoded_by"},
+ { "TP1", "artist"},
+ { "TP2", "album_artist"},
+ { "TP3", "performer"},
+ { "TRK", "track"},
+ { 0 }
+};
+
+
+const char ff_id3v2_tags[][4] = {
+ "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
+ "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
+ "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
+ "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
+ { 0 },
+};
+
+const char ff_id3v2_4_tags[][4] = {
+ "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
+ "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
+ { 0 },
+};
+
+const char ff_id3v2_3_tags[][4] = {
+ "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
+ { 0 },
+};
+
int ff_id3v2_match(const uint8_t *buf, const char * magic)
{
return buf[0] == magic[0] &&
@@ -59,81 +126,220 @@ static unsigned int get_size(AVIOContext *s, int len)
return v;
}
-static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *key)
+/**
+ * Free GEOB type extra metadata.
+ */
+static void free_geobtag(void *obj)
{
- char *q, dst[512];
- const char *val = NULL;
- int len, dstlen = sizeof(dst) - 1;
- unsigned genre;
- unsigned int (*get)(AVIOContext*) = avio_rb16;
+ ID3v2ExtraMetaGEOB *geob = obj;
+ av_free(geob->mime_type);
+ av_free(geob->file_name);
+ av_free(geob->description);
+ av_free(geob->data);
+ av_free(geob);
+}
- dst[0] = 0;
- if (taglen < 1)
- return;
+/**
+ * Decode characters to UTF-8 according to encoding type. The decoded buffer is
+ * always null terminated. Stop reading when either *maxread bytes are read from
+ * pb or U+0000 character is found.
+ *
+ * @param dst Pointer where the address of the buffer with the decoded bytes is
+ * stored. Buffer must be freed by caller.
+ * @param maxread Pointer to maximum number of characters to read from the
+ * AVIOContext. After execution the value is decremented by the number of bytes
+ * actually read.
+ * @returns 0 if no error occured, dst is uninitialized on error
+ */
+static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
+ uint8_t **dst, int *maxread)
+{
+ int ret;
+ uint8_t tmp;
+ uint32_t ch = 1;
+ int left = *maxread;
+ unsigned int (*get)(AVIOContext*) = avio_rb16;
+ AVIOContext *dynbuf;
- taglen--; /* account for encoding type byte */
+ if ((ret = avio_open_dyn_buf(&dynbuf)) < 0) {
+ av_log(s, AV_LOG_ERROR, "Error opening memory stream\n");
+ return ret;
+ }
- switch (avio_r8(pb)) { /* encoding type */
+ switch (encoding) {
case ID3v2_ENCODING_ISO8859:
- q = dst;
- while (taglen-- && q - dst < dstlen - 7) {
- uint8_t tmp;
- PUT_UTF8(avio_r8(pb), tmp, *q++ = tmp;)
+ while (left && ch) {
+ ch = avio_r8(pb);
+ PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
+ left--;
}
- *q = 0;
break;
case ID3v2_ENCODING_UTF16BOM:
- taglen -= 2;
+ if ((left -= 2) < 0) {
+ av_log(s, AV_LOG_ERROR, "Cannot read BOM value, input too short\n");
+ avio_close_dyn_buf(dynbuf, dst);
+ av_freep(dst);
+ return AVERROR_INVALIDDATA;
+ }
switch (avio_rb16(pb)) {
case 0xfffe:
get = avio_rl16;
case 0xfeff:
break;
default:
- av_log(s, AV_LOG_ERROR, "Incorrect BOM value in tag %s.\n", key);
- return;
+ av_log(s, AV_LOG_ERROR, "Incorrect BOM value\n");
+ avio_close_dyn_buf(dynbuf, dst);
+ av_freep(dst);
+ *maxread = left;
+ return AVERROR_INVALIDDATA;
}
// fall-through
case ID3v2_ENCODING_UTF16BE:
- q = dst;
- while (taglen > 1 && q - dst < dstlen - 7) {
- uint32_t ch;
- uint8_t tmp;
-
- GET_UTF16(ch, ((taglen -= 2) >= 0 ? get(pb) : 0), break;)
- PUT_UTF8(ch, tmp, *q++ = tmp;)
+ while ((left > 1) && ch) {
+ GET_UTF16(ch, ((left -= 2) >= 0 ? get(pb) : 0), break;)
+ PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
}
- *q = 0;
+ if (left < 0)
+ left += 2; /* did not read last char from pb */
break;
case ID3v2_ENCODING_UTF8:
- len = FFMIN(taglen, dstlen);
- avio_read(pb, dst, len);
- dst[len] = 0;
+ while (left && ch) {
+ ch = avio_r8(pb);
+ avio_w8(dynbuf, ch);
+ left--;
+ }
break;
default:
- av_log(s, AV_LOG_WARNING, "Unknown encoding in tag %s.\n", key);
+ av_log(s, AV_LOG_WARNING, "Unknown encoding\n");
+ }
+
+ if (ch)
+ avio_w8(dynbuf, 0);
+
+ avio_close_dyn_buf(dynbuf, dst);
+ *maxread = left;
+
+ return 0;
+}
+
+/**
+ * Parse a text tag.
+ */
+static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *key)
+{
+ uint8_t *dst;
+ int encoding, dict_flags = AV_DICT_DONT_OVERWRITE;
+ unsigned genre;
+
+ if (taglen < 1)
+ return;
+
+ encoding = avio_r8(pb);
+ taglen--; /* account for encoding type byte */
+
+ if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
+ av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key);
+ return;
}
if (!(strcmp(key, "TCON") && strcmp(key, "TCO"))
&& (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1)
- && genre <= ID3v1_GENRE_MAX)
- val = ff_id3v1_genre_str[genre];
- else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) {
- /* dst now contains two 0-terminated strings */
- dst[dstlen] = 0;
- len = strlen(dst);
+ && genre <= ID3v1_GENRE_MAX) {
+ av_freep(&dst);
+ dst = ff_id3v1_genre_str[genre];
+ } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) {
+ /* dst now contains the key, need to get value */
key = dst;
- val = dst + FFMIN(len + 1, dstlen);
+ if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
+ av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key);
+ av_freep(&key);
+ return;
+ }
+ dict_flags |= AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_STRDUP_KEY;
}
else if (*dst)
- val = dst;
+ dict_flags |= AV_DICT_DONT_STRDUP_VAL;
- if (val)
- av_dict_set(&s->metadata, key, val, AV_DICT_DONT_OVERWRITE);
+ if (dst)
+ av_dict_set(&s->metadata, key, dst, dict_flags);
+}
+
+/**
+ * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
+ */
+static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)
+{
+ ID3v2ExtraMetaGEOB *geob_data = NULL;
+ ID3v2ExtraMeta *new_extra = NULL;
+ char encoding;
+ unsigned int len;
+
+ if (taglen < 1)
+ return;
+
+ geob_data = av_mallocz(sizeof(ID3v2ExtraMetaGEOB));
+ if (!geob_data) {
+ av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMetaGEOB));
+ return;
+ }
+
+ new_extra = av_mallocz(sizeof(ID3v2ExtraMeta));
+ if (!new_extra) {
+ av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMeta));
+ goto fail;
+ }
+
+ /* read encoding type byte */
+ encoding = avio_r8(pb);
+ taglen--;
+
+ /* read MIME type (always ISO-8859) */
+ if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type, &taglen) < 0
+ || taglen <= 0)
+ goto fail;
+
+ /* read file name */
+ if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0
+ || taglen <= 0)
+ goto fail;
+
+ /* read content description */
+ if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0
+ || taglen < 0)
+ goto fail;
+
+ if (taglen) {
+ /* save encapsulated binary data */
+ geob_data->data = av_malloc(taglen);
+ if (!geob_data->data) {
+ av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", taglen);
+ goto fail;
+ }
+ if ((len = avio_read(pb, geob_data->data, taglen)) < taglen)
+ av_log(s, AV_LOG_WARNING, "Error reading GEOB frame, data truncated.\n");
+ geob_data->datasize = len;
+ } else {
+ geob_data->data = NULL;
+ geob_data->datasize = 0;
+ }
+
+ /* add data to the list */
+ new_extra->tag = "GEOB";
+ new_extra->data = geob_data;
+ new_extra->next = *extra_meta;
+ *extra_meta = new_extra;
+
+ return;
+
+fail:
+ av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", tag);
+ free_geobtag(geob_data);
+ av_free(new_extra);
+ return;
}
static int is_number(const char *str)
@@ -182,16 +388,50 @@ finish:
av_dict_set(m, "date", date, 0);
}
-static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags)
+typedef struct ID3v2EMFunc {
+ const char *tag3;
+ const char *tag4;
+ void (*read)(AVFormatContext*, AVIOContext*, int, char*, ID3v2ExtraMeta **);
+ void (*free)(void *);
+} ID3v2EMFunc;
+
+static const ID3v2EMFunc id3v2_extra_meta_funcs[] = {
+ { "GEO", "GEOB", read_geobtag, free_geobtag },
+ { NULL }
+};
+
+/**
+ * Get the corresponding ID3v2EMFunc struct for a tag.
+ * @param isv34 Determines if v2.2 or v2.3/4 strings are used
+ * @return A pointer to the ID3v2EMFunc struct if found, NULL otherwise.
+ */
+static const ID3v2EMFunc *get_extra_meta_func(const char *tag, int isv34)
+{
+ int i = 0;
+ while (id3v2_extra_meta_funcs[i].tag3) {
+ if (!memcmp(tag,
+ (isv34 ? id3v2_extra_meta_funcs[i].tag4 :
+ id3v2_extra_meta_funcs[i].tag3),
+ (isv34 ? 4 : 3)))
+ return &id3v2_extra_meta_funcs[i];
+ i++;
+ }
+ return &id3v2_extra_meta_funcs[i];
+}
+
+static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags, ID3v2ExtraMeta **extra_meta)
{
- int isv34, tlen, unsync;
+ int isv34, unsync;
+ unsigned tlen;
char tag[5];
int64_t next, end = avio_tell(s->pb) + len;
int taghdrlen;
const char *reason = NULL;
AVIOContext pb;
+ AVIOContext *pbx;
unsigned char *buffer = NULL;
int buffer_size = 0;
+ const ID3v2EMFunc *extra_func;
switch (version) {
case 2:
@@ -237,14 +477,24 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
tag[3] = 0;
tlen = avio_rb24(s->pb);
}
- if (tlen <= 0 || tlen > len - taghdrlen) {
- av_log(s, AV_LOG_WARNING, "Invalid size in frame %s, skipping the rest of tag.\n", tag);
+ if (tlen > (1<<28))
break;
- }
len -= taghdrlen + tlen;
+
+ if (len < 0)
+ break;
+
next = avio_tell(s->pb) + tlen;
+ if (!tlen) {
+ if (tag[0])
+ av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n", tag);
+ continue;
+ }
+
if (tflags & ID3v2_FLAG_DATALEN) {
+ if (tlen < 4)
+ break;
avio_rb32(s->pb);
tlen -= 4;
}
@@ -252,7 +502,8 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
if (tflags & (ID3v2_FLAG_ENCRYPTION | ID3v2_FLAG_COMPRESSION)) {
av_log(s, AV_LOG_WARNING, "Skipping encrypted/compressed ID3v2 frame %s.\n", tag);
avio_skip(s->pb, tlen);
- } else if (tag[0] == 'T') {
+ /* check for text tag or supported special meta tag */
+ } else if (tag[0] == 'T' || (extra_meta && (extra_func = get_extra_meta_func(tag, isv34)))) {
if (unsync || tunsync) {
int i, j;
av_fast_malloc(&buffer, &buffer_size, tlen);
@@ -268,10 +519,17 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
}
}
ffio_init_context(&pb, buffer, j, 0, NULL, NULL, NULL, NULL);
- read_ttag(s, &pb, j, tag);
+ tlen = j;
+ pbx = &pb; // read from sync buffer
} else {
- read_ttag(s, s->pb, tlen, tag);
+ pbx = s->pb; // read straight from input
}
+ if (tag[0] == 'T')
+ /* parse text tag */
+ read_ttag(s, pbx, tlen, tag);
+ else
+ /* parse special meta tag */
+ extra_func->read(s, pbx, tlen, tag, extra_meta);
}
else if (!tag[0]) {
if (tag[1])
@@ -295,7 +553,7 @@ seek:
return;
}
-void ff_id3v2_read(AVFormatContext *s, const char *magic)
+void ff_id3v2_read_all(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta)
{
int len, ret;
uint8_t buf[ID3v2_HEADER_SIZE];
@@ -315,73 +573,32 @@ void ff_id3v2_read(AVFormatContext *s, const char *magic)
((buf[7] & 0x7f) << 14) |
((buf[8] & 0x7f) << 7) |
(buf[9] & 0x7f);
- ff_id3v2_parse(s, len, buf[3], buf[5]);
+ ff_id3v2_parse(s, len, buf[3], buf[5], extra_meta);
} else {
avio_seek(s->pb, off, SEEK_SET);
}
} while (found_header);
ff_metadata_conv(&s->metadata, NULL, ff_id3v2_34_metadata_conv);
- ff_metadata_conv(&s->metadata, NULL, ff_id3v2_2_metadata_conv);
+ ff_metadata_conv(&s->metadata, NULL, id3v2_2_metadata_conv);
ff_metadata_conv(&s->metadata, NULL, ff_id3v2_4_metadata_conv);
merge_date(&s->metadata);
}
-const AVMetadataConv ff_id3v2_34_metadata_conv[] = {
- { "TALB", "album"},
- { "TCOM", "composer"},
- { "TCON", "genre"},
- { "TCOP", "copyright"},
- { "TENC", "encoded_by"},
- { "TIT2", "title"},
- { "TLAN", "language"},
- { "TPE1", "artist"},
- { "TPE2", "album_artist"},
- { "TPE3", "performer"},
- { "TPOS", "disc"},
- { "TPUB", "publisher"},
- { "TRCK", "track"},
- { "TSSE", "encoder"},
- { 0 }
-};
-
-const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
- { "TDRL", "date"},
- { "TDRC", "date"},
- { "TDEN", "creation_time"},
- { "TSOA", "album-sort"},
- { "TSOP", "artist-sort"},
- { "TSOT", "title-sort"},
- { 0 }
-};
-
-const AVMetadataConv ff_id3v2_2_metadata_conv[] = {
- { "TAL", "album"},
- { "TCO", "genre"},
- { "TT2", "title"},
- { "TEN", "encoded_by"},
- { "TP1", "artist"},
- { "TP2", "album_artist"},
- { "TP3", "performer"},
- { "TRK", "track"},
- { 0 }
-};
-
-
-const char ff_id3v2_tags[][4] = {
- "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
- "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
- "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
- "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
- { 0 },
-};
-
-const char ff_id3v2_4_tags[][4] = {
- "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
- "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
- { 0 },
-};
+void ff_id3v2_read(AVFormatContext *s, const char *magic)
+{
+ ff_id3v2_read_all(s, magic, NULL);
+}
-const char ff_id3v2_3_tags[][4] = {
- "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
- { 0 },
-};
+void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)
+{
+ ID3v2ExtraMeta *current = *extra_meta, *next;
+ const ID3v2EMFunc *extra_func;
+
+ while (current) {
+ if ((extra_func = get_extra_meta_func(current->tag, 1)))
+ extra_func->free(current->data);
+ next = current->next;
+ av_freep(&current);
+ current = next;
+ }
+}
diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h
index 3e0e65a92e..58cacdfeda 100644
--- a/libavformat/id3v2.h
+++ b/libavformat/id3v2.h
@@ -2,20 +2,20 @@
* ID3v2 header parser
* Copyright (c) 2003 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -45,6 +45,20 @@ enum ID3v2Encoding {
ID3v2_ENCODING_UTF8 = 3,
};
+typedef struct ID3v2ExtraMeta {
+ const char *tag;
+ void *data;
+ struct ID3v2ExtraMeta *next;
+} ID3v2ExtraMeta;
+
+typedef struct ID3v2ExtraMetaGEOB {
+ uint32_t datasize;
+ uint8_t *mime_type;
+ uint8_t *file_name;
+ uint8_t *description;
+ uint8_t *data;
+} ID3v2ExtraMetaGEOB;
+
/**
* Detect ID3v2 Header.
* @param buf must be ID3v2_HEADER_SIZE byte long
@@ -61,13 +75,25 @@ int ff_id3v2_match(const uint8_t *buf, const char *magic);
int ff_id3v2_tag_len(const uint8_t *buf);
/**
- * Read an ID3v2 tag
+ * Read an ID3v2 tag (text tags only)
*/
void ff_id3v2_read(AVFormatContext *s, const char *magic);
+/**
+ * Read an ID3v2 tag, including supported extra metadata (currently only GEOB)
+ * @param extra_meta If not NULL, extra metadata is parsed into a list of
+ * ID3v2ExtraMeta structs and *extra_meta points to the head of the list
+ */
+void ff_id3v2_read_all(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta);
+
+/**
+ * Free memory allocated parsing special (non-text) metadata.
+ * @param extra_meta Pointer to a pointer to the head of a ID3v2ExtraMeta list, *extra_meta is set to NULL.
+ */
+void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta);
+
extern const AVMetadataConv ff_id3v2_34_metadata_conv[];
extern const AVMetadataConv ff_id3v2_4_metadata_conv[];
-extern const AVMetadataConv ff_id3v2_2_metadata_conv[];
/**
* A list of text information frames allowed in both ID3 v2.3 and v2.4
diff --git a/libavformat/idcin.c b/libavformat/idcin.c
index 04ae687c6c..9d28043572 100644
--- a/libavformat/idcin.c
+++ b/libavformat/idcin.c
@@ -2,20 +2,20 @@
* id Quake II CIN File Demuxer
* Copyright (c) 2003 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -153,7 +153,7 @@ static int idcin_read_header(AVFormatContext *s,
bytes_per_sample = avio_rl32(pb);
channels = avio_rl32(pb);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 33, 1, IDCIN_FPS);
@@ -174,7 +174,7 @@ static int idcin_read_header(AVFormatContext *s,
/* if sample rate is 0, assume no audio */
if (sample_rate) {
idcin->audio_present = 1;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 33, 1, IDCIN_FPS);
@@ -224,7 +224,7 @@ static int idcin_read_packet(AVFormatContext *s,
unsigned char palette_buffer[768];
uint32_t palette[256];
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR(EIO);
if (idcin->next_chunk_is_video) {
@@ -292,10 +292,10 @@ static int idcin_read_packet(AVFormatContext *s,
}
AVInputFormat ff_idcin_demuxer = {
- "idcin",
- NULL_IF_CONFIG_SMALL("id Cinematic format"),
- sizeof(IdcinDemuxContext),
- idcin_probe,
- idcin_read_header,
- idcin_read_packet,
+ .name = "idcin",
+ .long_name = NULL_IF_CONFIG_SMALL("id Cinematic format"),
+ .priv_data_size = sizeof(IdcinDemuxContext),
+ .read_probe = idcin_probe,
+ .read_header = idcin_read_header,
+ .read_packet = idcin_read_packet,
};
diff --git a/libavformat/idroqdec.c b/libavformat/idroqdec.c
index d9315966ea..63ba5917a5 100644
--- a/libavformat/idroqdec.c
+++ b/libavformat/idroqdec.c
@@ -2,20 +2,20 @@
* id RoQ (.roq) File Demuxer
* Copyright (c) 2003 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -84,7 +84,7 @@ static int roq_read_header(AVFormatContext *s,
roq->audio_frame_count = 0;
roq->audio_stream_index = -1;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 63, 1, framerate);
@@ -111,7 +111,7 @@ static int roq_read_packet(AVFormatContext *s,
while (!packet_read) {
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR(EIO);
/* get the next chunk preamble */
@@ -166,7 +166,7 @@ static int roq_read_packet(AVFormatContext *s,
case RoQ_SOUND_MONO:
case RoQ_SOUND_STEREO:
if (roq->audio_stream_index == -1) {
- AVStream *st = av_new_stream(s, 1);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 32, 1, RoQ_AUDIO_SAMPLE_RATE);
@@ -216,10 +216,10 @@ static int roq_read_packet(AVFormatContext *s,
}
AVInputFormat ff_roq_demuxer = {
- "RoQ",
- NULL_IF_CONFIG_SMALL("id RoQ format"),
- sizeof(RoqDemuxContext),
- roq_probe,
- roq_read_header,
- roq_read_packet,
+ .name = "RoQ",
+ .long_name = NULL_IF_CONFIG_SMALL("id RoQ format"),
+ .priv_data_size = sizeof(RoqDemuxContext),
+ .read_probe = roq_probe,
+ .read_header = roq_read_header,
+ .read_packet = roq_read_packet,
};
diff --git a/libavformat/idroqenc.c b/libavformat/idroqenc.c
index 688d58d1ab..b8305261fd 100644
--- a/libavformat/idroqenc.c
+++ b/libavformat/idroqenc.c
@@ -2,20 +2,20 @@
* id RoQ (.roq) File muxer
* Copyright (c) 2007 Vitor Sessak
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -35,15 +35,12 @@ static int roq_write_header(struct AVFormatContext *s)
return 0;
}
-AVOutputFormat ff_roq_muxer =
-{
- "RoQ",
- NULL_IF_CONFIG_SMALL("raw id RoQ format"),
- NULL,
- "roq",
- 0,
- CODEC_ID_ROQ_DPCM,
- CODEC_ID_ROQ,
- roq_write_header,
- ff_raw_write_packet,
+AVOutputFormat ff_roq_muxer = {
+ .name = "RoQ",
+ .long_name = NULL_IF_CONFIG_SMALL("raw id RoQ format"),
+ .extensions = "roq",
+ .audio_codec = CODEC_ID_ROQ_DPCM,
+ .video_codec = CODEC_ID_ROQ,
+ .write_header = roq_write_header,
+ .write_packet = ff_raw_write_packet,
};
diff --git a/libavformat/iff.c b/libavformat/iff.c
index 2b84986aff..2283ed505a 100644
--- a/libavformat/iff.c
+++ b/libavformat/iff.c
@@ -1,23 +1,22 @@
/*
- * IFF (.iff) file demuxer
* Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
* Copyright (c) 2010 Peter Ross <pross@xvid.org>
* Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -29,6 +28,7 @@
* http://wiki.multimedia.cx/index.php?title=IFF
*/
+#include "libavcodec/bytestream.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "avformat.h"
@@ -41,6 +41,7 @@
#define ID_PBM MKTAG('P','B','M',' ')
#define ID_ILBM MKTAG('I','L','B','M')
#define ID_BMHD MKTAG('B','M','H','D')
+#define ID_CAMG MKTAG('C','A','M','G')
#define ID_CMAP MKTAG('C','M','A','P')
#define ID_FORM MKTAG('F','O','R','M')
@@ -59,7 +60,15 @@
#define RIGHT 4
#define STEREO 6
-#define PACKET_SIZE 1024
+/**
+ * This number of bytes if added at the beginning of each AVPacket
+ * which contain additional information about video properties
+ * which has to be shared between demuxer and decoder.
+ * This number may change between frames, e.g. the demuxer might
+ * set it to smallest possible size of 2 to indicate that there's
+ * no extradata changing in this frame.
+ */
+#define IFF_EXTRA_VIDEO_SIZE 9
typedef enum {
COMP_NONE,
@@ -76,22 +85,15 @@ typedef struct {
uint64_t body_pos;
uint32_t body_size;
uint32_t sent_bytes;
- uint32_t audio_frame_count;
+ svx8_compression_type svx8_compression;
+ bitmap_compression_type bitmap_compression; ///< delta compression method used
+ unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
+ unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
+ unsigned flags; ///< 1 for EHB, 0 is no extra half darkening
+ unsigned transparency; ///< transparency color index in palette
+ unsigned masking; ///< masking method used
} IffDemuxContext;
-
-static void interleave_stereo(const uint8_t *src, uint8_t *dest, int size)
-{
- uint8_t *end = dest + size;
- size = size>>1;
-
- while(dest < end) {
- *dest++ = *src;
- *dest++ = *(src+size);
- src++;
- }
-}
-
/* Metadata string read */
static int get_metadata(AVFormatContext *s,
const char *const tag,
@@ -127,10 +129,13 @@ static int iff_read_header(AVFormatContext *s,
IffDemuxContext *iff = s->priv_data;
AVIOContext *pb = s->pb;
AVStream *st;
+ uint8_t *buf;
uint32_t chunk_id, data_size;
- int compression = -1;
+ uint32_t screenmode = 0;
+ unsigned transparency = 0;
+ unsigned masking = 0; // no mask
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -139,7 +144,7 @@ static int iff_read_header(AVFormatContext *s,
// codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content
st->codec->codec_tag = avio_rl32(pb);
- while(!pb->eof_reached) {
+ while(!url_feof(pb)) {
uint64_t orig_pos;
int res;
const char *metadata_tag = NULL;
@@ -157,7 +162,7 @@ static int iff_read_header(AVFormatContext *s,
st->codec->sample_rate = avio_rb16(pb);
if (data_size >= 16) {
avio_skip(pb, 1);
- compression = avio_r8(pb);
+ iff->svx8_compression = avio_r8(pb);
}
break;
@@ -172,16 +177,23 @@ static int iff_read_header(AVFormatContext *s,
st->codec->channels = (avio_rb32(pb) < 6) ? 1 : 2;
break;
+ case ID_CAMG:
+ if (data_size < 4)
+ return AVERROR_INVALIDDATA;
+ screenmode = avio_rb32(pb);
+ break;
+
case ID_CMAP:
- st->codec->extradata_size = data_size;
- st->codec->extradata = av_malloc(data_size);
+ st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE;
+ st->codec->extradata = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata)
return AVERROR(ENOMEM);
- if (avio_read(pb, st->codec->extradata, data_size) < 0)
+ if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0)
return AVERROR(EIO);
break;
case ID_BMHD:
+ iff->bitmap_compression = -1;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
if (data_size <= 8)
return AVERROR_INVALIDDATA;
@@ -189,33 +201,25 @@ static int iff_read_header(AVFormatContext *s,
st->codec->height = avio_rb16(pb);
avio_skip(pb, 4); // x, y offset
st->codec->bits_per_coded_sample = avio_r8(pb);
- if (data_size >= 11) {
- avio_skip(pb, 1); // masking
- compression = avio_r8(pb);
+ if (data_size >= 10)
+ masking = avio_r8(pb);
+ if (data_size >= 11)
+ iff->bitmap_compression = avio_r8(pb);
+ if (data_size >= 14) {
+ avio_skip(pb, 1); // padding
+ transparency = avio_rb16(pb);
}
if (data_size >= 16) {
- avio_skip(pb, 3); // paddding, transparent
st->sample_aspect_ratio.num = avio_r8(pb);
st->sample_aspect_ratio.den = avio_r8(pb);
}
break;
case ID_ANNO:
- case ID_TEXT:
- metadata_tag = "comment";
- break;
-
- case ID_AUTH:
- metadata_tag = "artist";
- break;
-
- case ID_COPYRIGHT:
- metadata_tag = "copyright";
- break;
-
- case ID_NAME:
- metadata_tag = "title";
- break;
+ case ID_TEXT: metadata_tag = "comment"; break;
+ case ID_AUTH: metadata_tag = "artist"; break;
+ case ID_COPYRIGHT: metadata_tag = "copyright"; break;
+ case ID_NAME: metadata_tag = "title"; break;
}
if (metadata_tag) {
@@ -233,9 +237,9 @@ static int iff_read_header(AVFormatContext *s,
case AVMEDIA_TYPE_AUDIO:
av_set_pts_info(st, 32, 1, st->codec->sample_rate);
- switch(compression) {
+ switch (iff->svx8_compression) {
case COMP_NONE:
- st->codec->codec_id = CODEC_ID_PCM_S8;
+ st->codec->codec_id = CODEC_ID_8SVX_RAW;
break;
case COMP_FIB:
st->codec->codec_id = CODEC_ID_8SVX_FIB;
@@ -244,17 +248,42 @@ static int iff_read_header(AVFormatContext *s,
st->codec->codec_id = CODEC_ID_8SVX_EXP;
break;
default:
- av_log(s, AV_LOG_ERROR, "unknown compression method\n");
+ av_log(s, AV_LOG_ERROR,
+ "Unknown SVX8 compression method '%d'\n", iff->svx8_compression);
return -1;
}
- st->codec->bits_per_coded_sample = 8;
+ st->codec->bits_per_coded_sample = iff->svx8_compression == COMP_NONE ? 8 : 4;
st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample;
st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
break;
case AVMEDIA_TYPE_VIDEO:
- switch (compression) {
+ iff->bpp = st->codec->bits_per_coded_sample;
+ if ((screenmode & 0x800 /* Hold And Modify */) && iff->bpp <= 8) {
+ iff->ham = iff->bpp > 6 ? 6 : 4;
+ st->codec->bits_per_coded_sample = 24;
+ }
+ iff->flags = (screenmode & 0x80 /* Extra HalfBrite */) && iff->bpp <= 8;
+ iff->masking = masking;
+ iff->transparency = transparency;
+
+ if (!st->codec->extradata) {
+ st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE;
+ st->codec->extradata = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+ }
+ buf = st->codec->extradata;
+ bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE);
+ bytestream_put_byte(&buf, iff->bitmap_compression);
+ bytestream_put_byte(&buf, iff->bpp);
+ bytestream_put_byte(&buf, iff->ham);
+ bytestream_put_byte(&buf, iff->flags);
+ bytestream_put_be16(&buf, iff->transparency);
+ bytestream_put_byte(&buf, iff->masking);
+
+ switch (iff->bitmap_compression) {
case BITMAP_RAW:
st->codec->codec_id = CODEC_ID_IFF_ILBM;
break;
@@ -262,7 +291,8 @@ static int iff_read_header(AVFormatContext *s,
st->codec->codec_id = CODEC_ID_IFF_BYTERUN1;
break;
default:
- av_log(s, AV_LOG_ERROR, "unknown compression method\n");
+ av_log(s, AV_LOG_ERROR,
+ "Unknown bitmap compression method '%d'\n", iff->bitmap_compression);
return AVERROR_INVALIDDATA;
}
break;
@@ -282,44 +312,37 @@ static int iff_read_packet(AVFormatContext *s,
int ret;
if(iff->sent_bytes >= iff->body_size)
- return AVERROR(EIO);
+ return AVERROR_EOF;
- if(st->codec->channels == 2) {
- uint8_t sample_buffer[PACKET_SIZE];
+ if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ ret = av_get_packet(pb, pkt, iff->body_size);
+ } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ uint8_t *buf;
- ret = avio_read(pb, sample_buffer, PACKET_SIZE);
- if(av_new_packet(pkt, PACKET_SIZE) < 0) {
- av_log(s, AV_LOG_ERROR, "cannot allocate packet\n");
+ if (av_new_packet(pkt, iff->body_size + 2) < 0) {
return AVERROR(ENOMEM);
}
- interleave_stereo(sample_buffer, pkt->data, PACKET_SIZE);
- } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- ret = av_get_packet(pb, pkt, iff->body_size);
+
+ buf = pkt->data;
+ bytestream_put_be16(&buf, 2);
+ ret = avio_read(pb, buf, iff->body_size);
} else {
- ret = av_get_packet(pb, pkt, PACKET_SIZE);
+ av_abort();
}
if(iff->sent_bytes == 0)
pkt->flags |= AV_PKT_FLAG_KEY;
+ iff->sent_bytes = iff->body_size;
- if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- iff->sent_bytes += PACKET_SIZE;
- } else {
- iff->sent_bytes = iff->body_size;
- }
pkt->stream_index = 0;
- if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- pkt->pts = iff->audio_frame_count;
- iff->audio_frame_count += ret / st->codec->channels;
- }
return ret;
}
AVInputFormat ff_iff_demuxer = {
- "IFF",
- NULL_IF_CONFIG_SMALL("IFF format"),
- sizeof(IffDemuxContext),
- iff_probe,
- iff_read_header,
- iff_read_packet,
+ .name = "IFF",
+ .long_name = NULL_IF_CONFIG_SMALL("IFF format"),
+ .priv_data_size = sizeof(IffDemuxContext),
+ .read_probe = iff_probe,
+ .read_header = iff_read_header,
+ .read_packet = iff_read_packet,
};
diff --git a/libavformat/img2.c b/libavformat/img2.c
index 4eef62371d..7b89a9c980 100644
--- a/libavformat/img2.c
+++ b/libavformat/img2.c
@@ -3,20 +3,20 @@
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
* Copyright (c) 2004 Michael Niedermayer
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -38,10 +38,12 @@ typedef struct {
int img_number;
int img_count;
int is_pipe;
+ int split_planes; /**< use independent file for each Y, U, V plane */
char path[1024];
char *pixel_format; /**< Set by a private option. */
char *video_size; /**< Set by a private option. */
char *framerate; /**< Set by a private option. */
+ int loop;
} VideoData;
typedef struct {
@@ -53,6 +55,7 @@ static const IdStrMap img_tags[] = {
{ CODEC_ID_MJPEG , "jpeg"},
{ CODEC_ID_MJPEG , "jpg"},
{ CODEC_ID_LJPEG , "ljpg"},
+ { CODEC_ID_JPEGLS , "jls"},
{ CODEC_ID_PNG , "png"},
{ CODEC_ID_PNG , "mng"},
{ CODEC_ID_PPM , "ppm"},
@@ -66,6 +69,7 @@ static const IdStrMap img_tags[] = {
{ CODEC_ID_MPEG4 , "mpg4-img"},
{ CODEC_ID_FFV1 , "ffv1-img"},
{ CODEC_ID_RAWVIDEO , "y"},
+ { CODEC_ID_RAWVIDEO , "raw"},
{ CODEC_ID_BMP , "bmp"},
{ CODEC_ID_GIF , "gif"},
{ CODEC_ID_TARGA , "tga"},
@@ -81,6 +85,7 @@ static const IdStrMap img_tags[] = {
{ CODEC_ID_SUNRAST , "im8"},
{ CODEC_ID_SUNRAST , "im24"},
{ CODEC_ID_SUNRAST , "sunras"},
+ { CODEC_ID_JPEG2000 , "j2k"},
{ CODEC_ID_JPEG2000 , "jp2"},
{ CODEC_ID_JPEG2000 , "jpc"},
{ CODEC_ID_DPX , "dpx"},
@@ -215,7 +220,7 @@ static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
s1->ctx_flags |= AVFMTCTX_NOHEADER;
- st = av_new_stream(s1, 0);
+ st = avformat_new_stream(s1, NULL);
if (!st) {
return AVERROR(ENOMEM);
}
@@ -232,15 +237,10 @@ static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
av_log(s, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s->framerate);
return ret;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->pix_fmt != PIX_FMT_NONE)
- pix_fmt = ap->pix_fmt;
- if (ap->width > 0)
- width = ap->width;
- if (ap->height > 0)
- height = ap->height;
- if (ap->time_base.num)
- framerate = (AVRational){ap->time_base.den, ap->time_base.num};
+
+#if FF_API_LOOP_INPUT
+ if (s1->loop_input)
+ s->loop = s1->loop_input;
#endif
av_strlcpy(s->path, s1->filename, sizeof(s->path));
@@ -280,6 +280,8 @@ static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = s1->audio_codec_id;
}else{
+ const char *str= strrchr(s->path, '.');
+ s->split_planes = str && !strcasecmp(str + 1, "y");
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = av_str2id(img_tags, s->path);
}
@@ -300,7 +302,7 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt)
if (!s->is_pipe) {
/* loop over input */
- if (s1->loop_input && s->img_number > s->img_last) {
+ if (s->loop && s->img_number > s->img_last) {
s->img_number = s->img_first;
}
if (s->img_number > s->img_last)
@@ -317,7 +319,7 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt)
}
size[i]= avio_size(f[i]);
- if(codec->codec_id != CODEC_ID_RAWVIDEO)
+ if(!s->split_planes)
break;
filename[ strlen(filename) - 1 ]= 'U' + i;
}
@@ -326,7 +328,7 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt)
infer_size(&codec->width, &codec->height, size[0]);
} else {
f[0] = s1->pb;
- if (f[0]->eof_reached)
+ if (url_feof(f[0]))
return AVERROR(EIO);
size[0]= 4096;
}
@@ -363,6 +365,7 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt)
static int write_header(AVFormatContext *s)
{
VideoData *img = s->priv_data;
+ const char *str;
img->img_number = 1;
av_strlcpy(img->path, s->filename, sizeof(img->path));
@@ -373,6 +376,8 @@ static int write_header(AVFormatContext *s)
else
img->is_pipe = 1;
+ str = strrchr(img->path, '.');
+ img->split_planes = str && !strcasecmp(str + 1, "y");
return 0;
}
@@ -390,7 +395,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
av_log(s, AV_LOG_ERROR,
"Could not get frame filename number %d from pattern '%s'\n",
img->img_number, img->path);
- return AVERROR(EIO);
+ return AVERROR(EINVAL);
}
for(i=0; i<3; i++){
if (avio_open(&pb[i], filename, AVIO_FLAG_WRITE) < 0) {
@@ -398,7 +403,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR(EIO);
}
- if(codec->codec_id != CODEC_ID_RAWVIDEO)
+ if(!img->split_planes)
break;
filename[ strlen(filename) - 1 ]= 'U' + i;
}
@@ -406,7 +411,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
pb[0] = s->pb;
}
- if(codec->codec_id == CODEC_ID_RAWVIDEO){
+ if(img->split_planes){
int ysize = codec->width * codec->height;
avio_write(pb[0], pkt->data , ysize);
avio_write(pb[1], pkt->data + ysize, (pkt->size - ysize)/2);
@@ -431,11 +436,13 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
avio_wb32(pb[0], 0);
ffio_wfourcc(pb[0], "jp2 ");
avio_write(pb[0], st->codec->extradata, st->codec->extradata_size);
+ }else if(pkt->size >= 8 && AV_RB32(pkt->data) == 0xFF4FFF51){
+ //jpeg2000 codestream
}else if(pkt->size < 8 ||
(!st->codec->extradata_size &&
AV_RL32(pkt->data+4) != MKTAG('j','P',' ',' '))){ // signature
error:
- av_log(s, AV_LOG_ERROR, "malformated jpeg2000 codestream\n");
+ av_log(s, AV_LOG_ERROR, "malformated jpeg2000 codestream %X\n", AV_RB32(pkt->data));
return -1;
}
}
@@ -455,21 +462,21 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
#define OFFSET(x) offsetof(VideoData, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- { "pixel_format", "", OFFSET(pixel_format), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
- { "video_size", "", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
- { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+ { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "video_size", "", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+ { "loop", "", OFFSET(loop), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, DEC },
{ NULL },
};
+/* input */
+#if CONFIG_IMAGE2_DEMUXER
static const AVClass img2_class = {
.class_name = "image2 demuxer",
.item_name = av_default_item_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
};
-
-/* input */
-#if CONFIG_IMAGE2_DEMUXER
AVInputFormat ff_image2_demuxer = {
.name = "image2",
.long_name = NULL_IF_CONFIG_SMALL("image2 sequence"),
@@ -482,13 +489,19 @@ AVInputFormat ff_image2_demuxer = {
};
#endif
#if CONFIG_IMAGE2PIPE_DEMUXER
+static const AVClass img2pipe_class = {
+ .class_name = "image2pipe demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
AVInputFormat ff_image2pipe_demuxer = {
.name = "image2pipe",
.long_name = NULL_IF_CONFIG_SMALL("piped image2 sequence"),
.priv_data_size = sizeof(VideoData),
.read_header = read_header,
.read_packet = read_packet,
- .priv_class = &img2_class,
+ .priv_class = &img2pipe_class,
};
#endif
@@ -497,7 +510,7 @@ AVInputFormat ff_image2pipe_demuxer = {
AVOutputFormat ff_image2_muxer = {
.name = "image2",
.long_name = NULL_IF_CONFIG_SMALL("image2 sequence"),
- .extensions = "bmp,dpx,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
+ .extensions = "bmp,dpx,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
"ppm,sgi,tga,tif,tiff,jp2",
.priv_data_size = sizeof(VideoData),
.video_codec = CODEC_ID_MJPEG,
diff --git a/libavformat/ingenientdec.c b/libavformat/ingenientdec.c
index febeb2ec35..97774abbcd 100644
--- a/libavformat/ingenientdec.c
+++ b/libavformat/ingenientdec.c
@@ -2,20 +2,20 @@
* RAW Ingenient MJPEG demuxer
* Copyright (c) 2005 Alex Beregszaszi
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -58,15 +58,16 @@ static int ingenient_read_packet(AVFormatContext *s, AVPacket *pkt)
return ret;
}
+FF_RAWVIDEO_DEMUXER_CLASS(ingenient)
+
AVInputFormat ff_ingenient_demuxer = {
- "ingenient",
- NULL_IF_CONFIG_SMALL("raw Ingenient MJPEG"),
- sizeof(FFRawVideoDemuxerContext),
- NULL,
- ff_raw_video_read_header,
- ingenient_read_packet,
+ .name = "ingenient",
+ .long_name = NULL_IF_CONFIG_SMALL("raw Ingenient MJPEG"),
+ .priv_data_size = sizeof(FFRawVideoDemuxerContext),
+ .read_header = ff_raw_video_read_header,
+ .read_packet = ingenient_read_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "cgi", // FIXME
.value = CODEC_ID_MJPEG,
- .priv_class = &ff_rawvideo_demuxer_class,
+ .priv_class = &ingenient_demuxer_class,
};
diff --git a/libavformat/internal.h b/libavformat/internal.h
index aba890def4..a2e80f2de3 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -1,20 +1,20 @@
/*
* copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -37,20 +37,18 @@ typedef struct AVCodecTag {
unsigned int tag;
} AVCodecTag;
-void ff_dynarray_add(intptr_t **tab_ptr, int *nb_ptr, intptr_t elem);
-
#ifdef __GNUC__
#define dynarray_add(tab, nb_ptr, elem)\
do {\
__typeof__(tab) _tab = (tab);\
__typeof__(elem) _elem = (elem);\
(void)sizeof(**_tab == _elem); /* check that types are compatible */\
- ff_dynarray_add((intptr_t **)_tab, nb_ptr, (intptr_t)_elem);\
+ av_dynarray_add(_tab, nb_ptr, _elem);\
} while(0)
#else
#define dynarray_add(tab, nb_ptr, elem)\
do {\
- ff_dynarray_add((intptr_t **)(tab), nb_ptr, (intptr_t)(elem));\
+ av_dynarray_add((tab), nb_ptr, (elem));\
} while(0)
#endif
@@ -225,8 +223,8 @@ int ff_add_index_entry(AVIndexEntry **index_entries,
*
* @return AVChapter or NULL on error
*/
-AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base,
- int64_t start, int64_t end, const char *title);
+AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base,
+ int64_t start, int64_t end, const char *title);
/**
* Ensure the index uses less memory than the maximum specified in
@@ -248,4 +246,9 @@ void ff_make_absolute_url(char *buf, int size, const char *base,
enum CodecID ff_guess_image2_codec(const char *filename);
+/**
+ * Convert a date string in ISO8601 format to Unix timestamp.
+ */
+int64_t ff_iso8601_to_unix_time(const char *datestr);
+
#endif /* AVFORMAT_INTERNAL_H */
diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c
index e8ba0643f6..562b19a29c 100644
--- a/libavformat/ipmovie.c
+++ b/libavformat/ipmovie.c
@@ -2,20 +2,20 @@
* Interplay MVE File Demuxer
* Copyright (c) 2003 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -224,7 +224,7 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
return chunk_type;
/* read the next chunk, wherever the file happens to be pointing */
- if (pb->eof_reached)
+ if (url_feof(pb))
return CHUNK_EOF;
if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) !=
CHUNK_PREAMBLE_SIZE)
@@ -270,7 +270,7 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
while ((chunk_size > 0) && (chunk_type != CHUNK_BAD)) {
/* read the next chunk, wherever the file happens to be pointing */
- if (pb->eof_reached) {
+ if (url_feof(pb)) {
chunk_type = CHUNK_EOF;
break;
}
@@ -530,7 +530,7 @@ static int ipmovie_read_header(AVFormatContext *s,
while (memcmp(signature_buffer, signature, sizeof(signature))) {
memmove(signature_buffer, signature_buffer + 1, sizeof(signature_buffer) - 1);
signature_buffer[sizeof(signature_buffer) - 1] = avio_r8(pb);
- if (pb->eof_reached)
+ if (url_feof(pb))
return AVERROR_EOF;
}
/* initialize private context members */
@@ -559,7 +559,7 @@ static int ipmovie_read_header(AVFormatContext *s,
return AVERROR_INVALIDDATA;
/* initialize the stream decoders */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 63, 1, 1000000);
@@ -572,7 +572,7 @@ static int ipmovie_read_header(AVFormatContext *s,
st->codec->bits_per_coded_sample = ipmovie->video_bpp;
if (ipmovie->audio_type) {
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 32, 1, ipmovie->audio_sample_rate);
@@ -616,10 +616,10 @@ static int ipmovie_read_packet(AVFormatContext *s,
}
AVInputFormat ff_ipmovie_demuxer = {
- "ipmovie",
- NULL_IF_CONFIG_SMALL("Interplay MVE format"),
- sizeof(IPMVEContext),
- ipmovie_probe,
- ipmovie_read_header,
- ipmovie_read_packet,
+ .name = "ipmovie",
+ .long_name = NULL_IF_CONFIG_SMALL("Interplay MVE format"),
+ .priv_data_size = sizeof(IPMVEContext),
+ .read_probe = ipmovie_probe,
+ .read_header = ipmovie_read_header,
+ .read_packet = ipmovie_read_packet,
};
diff --git a/libavformat/isom.c b/libavformat/isom.c
index eb17e25474..81a89fa405 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -4,20 +4,20 @@
* Copyright (c) 2002 Francois Revol <revol@free.fr>
* Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -137,11 +137,18 @@ const AVCodecTag codec_movvideo_tags[] = {
{ CODEC_ID_RAWVIDEO, MKTAG('W', 'R', 'A', 'W') },
{ CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */
- { CODEC_ID_H264, MKTAG('a', 'i', '5', '5') }, /* AVC Intra 50 / 1080 interlace */
- { CODEC_ID_H264, MKTAG('a', 'i', '5', 'q') }, /* AVC Intra 50 / 720 */
- { CODEC_ID_H264, MKTAG('a', 'i', '1', '5') }, /* AVC Intra 100 / 1080 interlace */
- { CODEC_ID_H264, MKTAG('a', 'i', '1', 'q') }, /* AVC Intra 100 / 720 */
- { CODEC_ID_H264, MKTAG('a', 'i', '1', '2') }, /* AVC Intra 100 / 1080 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '5', 'p') }, /* AVC-Intra 50M 720p24/30/60 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '5', 'q') }, /* AVC-Intra 50M 720p25/50 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '5', '2') }, /* AVC-Intra 50M 1080p25/50 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '5', '3') }, /* AVC-Intra 50M 1080p24/30/60 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '5', '5') }, /* AVC-Intra 50M 1080i50 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '5', '6') }, /* AVC-Intra 50M 1080i60 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '1', 'p') }, /* AVC-Intra 100M 720p24/30/60 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '1', 'q') }, /* AVC-Intra 100M 720p25/50 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '1', '2') }, /* AVC-Intra 100M 1080p25/50 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '1', '3') }, /* AVC-Intra 100M 1080p24/30/60 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '1', '5') }, /* AVC-Intra 100M 1080i50 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '1', '6') }, /* AVC-Intra 100M 1080i60 */
{ CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', '1') }, /* Apple MPEG-1 Camcorder */
{ CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */
@@ -197,6 +204,8 @@ const AVCodecTag codec_movvideo_tags[] = {
{ CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
{ CODEC_ID_DNXHD, MKTAG('A', 'V', 'd', 'n') }, /* AVID DNxHD */
+// { CODEC_ID_FLV1, MKTAG('H', '2', '6', '3') }, /* Flash Media Server */
+ { CODEC_ID_MSMPEG4V3, MKTAG('3', 'I', 'V', 'D') }, /* 3ivx DivX Doctor */
{ CODEC_ID_RAWVIDEO, MKTAG('A', 'V', '1', 'x') }, /* AVID 1:1x */
{ CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'u', 'p') },
{ CODEC_ID_SGI, MKTAG('s', 'g', 'i', ' ') }, /* SGI */
@@ -247,11 +256,13 @@ const AVCodecTag codec_movaudio_tags[] = {
{ CODEC_ID_AC3, MKTAG('s', 'a', 'c', '3') }, /* Nero Recode */
{ CODEC_ID_DTS, MKTAG('d', 't', 's', 'c') }, /* mp4ra.org */
{ CODEC_ID_DTS, MKTAG('D', 'T', 'S', ' ') }, /* non-standard */
+ { CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F */
{ CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */
{ CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */
{ CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') },
+ { CODEC_ID_NELLYMOSER, MKTAG('n', 'm', 'o', 's') }, /* Flash Media Server */
{ CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') }, /* Apple Lossless */
{ CODEC_ID_QCELP, MKTAG('Q','c','l','p') },
@@ -264,6 +275,8 @@ const AVCodecTag codec_movaudio_tags[] = {
{ CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') },
{ CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') },
+ { CODEC_ID_SPEEX, MKTAG('s','p','e','x') }, /* Flash Media Server */
+
{ CODEC_ID_WMAV2, MKTAG('W', 'M', 'A', '2') },
{ CODEC_ID_NONE, 0 },
@@ -372,6 +385,22 @@ int ff_mp4_read_descr(AVFormatContext *fc, AVIOContext *pb, int *tag)
return len;
}
+void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id)
+{
+ int flags;
+ if (es_id) *es_id = avio_rb16(pb);
+ else avio_rb16(pb);
+ flags = avio_r8(pb);
+ if (flags & 0x80) //streamDependenceFlag
+ avio_rb16(pb);
+ if (flags & 0x40) { //URL_Flag
+ int len = avio_r8(pb);
+ avio_skip(pb, len);
+ }
+ if (flags & 0x20) //OCRstreamFlag
+ avio_rb16(pb);
+}
+
static const AVCodecTag mp4_audio_types[] = {
{ CODEC_ID_MP3ON4, AOT_PS }, /* old mp3on4 draft */
{ CODEC_ID_MP3ON4, AOT_L1 }, /* layer 1 */
@@ -395,7 +424,7 @@ int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext
len = ff_mp4_read_descr(fc, pb, &tag);
if (tag == MP4DecSpecificDescrTag) {
av_dlog(fc, "Specific MPEG4 header len=%d\n", len);
- if((uint64_t)len > (1<<30))
+ if (!len || (uint64_t)len > (1<<30))
return -1;
av_free(st->codec->extradata);
st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
@@ -405,11 +434,11 @@ int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext
st->codec->extradata_size = len;
if (st->codec->codec_id == CODEC_ID_AAC) {
MPEG4AudioConfig cfg;
- ff_mpeg4audio_get_config(&cfg, st->codec->extradata,
+ avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
st->codec->extradata_size);
st->codec->channels = cfg.channels;
if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4
- st->codec->sample_rate = ff_mpa_freq_tab[cfg.sampling_index];
+ st->codec->sample_rate = avpriv_mpa_freq_tab[cfg.sampling_index];
else if (cfg.ext_sample_rate)
st->codec->sample_rate = cfg.ext_sample_rate;
else
@@ -425,3 +454,87 @@ int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext
}
return 0;
}
+
+typedef struct MovChannelLayout {
+ int64_t channel_layout;
+ uint32_t layout_tag;
+} MovChannelLayout;
+
+static const MovChannelLayout mov_channel_layout[] = {
+ { AV_CH_LAYOUT_MONO, (100<<16) | 1}, // kCAFChannelLayoutTag_Mono
+ { AV_CH_LAYOUT_STEREO, (101<<16) | 2}, // kCAFChannelLayoutTag_Stereo
+ { AV_CH_LAYOUT_STEREO, (102<<16) | 2}, // kCAFChannelLayoutTag_StereoHeadphones
+ { AV_CH_LAYOUT_2_1, (131<<16) | 3}, // kCAFChannelLayoutTag_ITU_2_1
+ { AV_CH_LAYOUT_QUAD, (132<<16) | 4}, // kCAFChannelLayoutTag_ITU_2_2
+ { AV_CH_LAYOUT_2_2, (132<<16) | 4}, // kCAFChannelLayoutTag_ITU_2_2
+ { AV_CH_LAYOUT_QUAD, (108<<16) | 4}, // kCAFChannelLayoutTag_Quadraphonic
+ { AV_CH_LAYOUT_SURROUND, (113<<16) | 3}, // kCAFChannelLayoutTag_MPEG_3_0_A
+ { AV_CH_LAYOUT_4POINT0, (115<<16) | 4}, // kCAFChannelLayoutTag_MPEG_4_0_A
+ { AV_CH_LAYOUT_5POINT0_BACK, (117<<16) | 5}, // kCAFChannelLayoutTag_MPEG_5_0_A
+ { AV_CH_LAYOUT_5POINT0, (117<<16) | 5}, // kCAFChannelLayoutTag_MPEG_5_0_A
+ { AV_CH_LAYOUT_5POINT1_BACK, (121<<16) | 6}, // kCAFChannelLayoutTag_MPEG_5_1_A
+ { AV_CH_LAYOUT_5POINT1, (121<<16) | 6}, // kCAFChannelLayoutTag_MPEG_5_1_A
+ { AV_CH_LAYOUT_7POINT1, (128<<16) | 8}, // kCAFChannelLayoutTag_MPEG_7_1_C
+ { AV_CH_LAYOUT_7POINT1_WIDE, (126<<16) | 8}, // kCAFChannelLayoutTag_MPEG_7_1_A
+ { AV_CH_LAYOUT_5POINT1_BACK|AV_CH_LAYOUT_STEREO_DOWNMIX, (130<<16) | 8}, // kCAFChannelLayoutTag_SMPTE_DTV
+ { AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY, (133<<16) | 3}, // kCAFChannelLayoutTag_DVD_4
+ { AV_CH_LAYOUT_2_1|AV_CH_LOW_FREQUENCY, (134<<16) | 4}, // kCAFChannelLayoutTag_DVD_5
+ { AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY, (135<<16) | 4}, // kCAFChannelLayoutTag_DVD_6
+ { AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY, (135<<16) | 4}, // kCAFChannelLayoutTag_DVD_6
+ { AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY, (136<<16) | 4}, // kCAFChannelLayoutTag_DVD_10
+ { AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY, (137<<16) | 5}, // kCAFChannelLayoutTag_DVD_11
+ { 0, 0},
+};
+
+void ff_mov_read_chan(AVFormatContext *s, int64_t size, AVCodecContext *codec)
+{
+ uint32_t layout_tag;
+ AVIOContext *pb = s->pb;
+ const MovChannelLayout *layouts = mov_channel_layout;
+ layout_tag = avio_rb32(pb);
+ size -= 4;
+ if (layout_tag == 0) { // kCAFChannelLayoutTag_UseChannelDescriptions
+ // Channel descriptions not implemented
+ av_log_ask_for_sample(s, "Unimplemented container channel layout.\n");
+ avio_skip(pb, size);
+ return;
+ }
+ if (layout_tag == 0x10000) { // kCAFChannelLayoutTag_UseChannelBitmap
+ codec->channel_layout = avio_rb32(pb);
+ size -= 4;
+ avio_skip(pb, size);
+ return;
+ }
+ while (layouts->channel_layout) {
+ if (layout_tag == layouts->layout_tag) {
+ codec->channel_layout = layouts->channel_layout;
+ break;
+ }
+ layouts++;
+ }
+ if (!codec->channel_layout)
+ av_log(s, AV_LOG_WARNING, "Unknown container channel layout.\n");
+ avio_skip(pb, size);
+}
+
+void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout)
+{
+ const MovChannelLayout *layouts;
+ uint32_t layout_tag = 0;
+
+ for (layouts = mov_channel_layout; layouts->channel_layout; layouts++)
+ if (channel_layout == layouts->channel_layout) {
+ layout_tag = layouts->layout_tag;
+ break;
+ }
+
+ if (layout_tag) {
+ avio_wb32(pb, layout_tag); // mChannelLayoutTag
+ avio_wb32(pb, 0); // mChannelBitmap
+ } else {
+ avio_wb32(pb, 0x10000); // kCAFChannelLayoutTag_UseChannelBitmap
+ avio_wb32(pb, channel_layout);
+ }
+ avio_wb32(pb, 0); // mNumberChannelDescriptions
+}
+
diff --git a/libavformat/isom.h b/libavformat/isom.h
index ef3fe1484f..7fc2b546f8 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -4,20 +4,20 @@
* copyright (c) 2002 Francois Revol <revol@free.fr>
* copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -146,6 +146,7 @@ typedef struct MOVContext {
int ff_mp4_read_descr_len(AVIOContext *pb);
int ff_mp4_read_descr(AVFormatContext *fc, AVIOContext *pb, int *tag);
int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb);
+void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id);
#define MP4IODescrTag 0x02
#define MP4ESDescrTag 0x03
@@ -156,5 +157,7 @@ int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom);
enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags);
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries);
+void ff_mov_read_chan(AVFormatContext *s, int64_t size, AVCodecContext *codec);
+void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout);
#endif /* AVFORMAT_ISOM_H */
diff --git a/libavformat/iss.c b/libavformat/iss.c
index fe5203dbcd..4b6314d5b9 100644
--- a/libavformat/iss.c
+++ b/libavformat/iss.c
@@ -2,20 +2,20 @@
* ISS (.iss) file demuxer
* Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -23,8 +23,7 @@
* @file
* Funcom ISS file demuxer
* @author Jaikrishnan Menon
- * for more information on the .iss file format, visit:
- * http://wiki.multimedia.cx/index.php?title=FunCom_ISS
+ * @see http://wiki.multimedia.cx/index.php?title=FunCom_ISS
*/
#include "avformat.h"
@@ -89,7 +88,7 @@ static av_cold int iss_read_header(AVFormatContext *s, AVFormatParameters *ap)
iss->sample_start_pos = avio_tell(pb);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -123,11 +122,11 @@ static int iss_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_iss_demuxer = {
- "ISS",
- NULL_IF_CONFIG_SMALL("Funcom ISS format"),
- sizeof(IssDemuxContext),
- iss_probe,
- iss_read_header,
- iss_read_packet,
+ .name = "ISS",
+ .long_name = NULL_IF_CONFIG_SMALL("Funcom ISS format"),
+ .priv_data_size = sizeof(IssDemuxContext),
+ .read_probe = iss_probe,
+ .read_header = iss_read_header,
+ .read_packet = iss_read_packet,
};
diff --git a/libavformat/iv8.c b/libavformat/iv8.c
index 22e60cf8f0..03593982bf 100644
--- a/libavformat/iv8.c
+++ b/libavformat/iv8.c
@@ -1,20 +1,20 @@
/*
* Copyright (c) 2009 Michael Niedermayer
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -40,7 +40,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
{
AVStream *st;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -85,12 +85,11 @@ retry:
}
AVInputFormat ff_iv8_demuxer = {
- "iv8",
- NULL_IF_CONFIG_SMALL("A format generated by IndigoVision 8000 video server"),
- 0,
- probe,
- read_header,
- read_packet,
+ .name = "iv8",
+ .long_name = NULL_IF_CONFIG_SMALL("A format generated by IndigoVision 8000 video server"),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
.flags= AVFMT_GENERIC_INDEX,
.value = CODEC_ID_MPEG4,
};
diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c
index 390173105a..cc7687e4da 100644
--- a/libavformat/ivfdec.c
+++ b/libavformat/ivfdec.c
@@ -1,20 +1,20 @@
/*
* Copyright (c) 2010 David Conrad
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -40,7 +40,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
avio_rl16(s->pb); // version
avio_rl16(s->pb); // header size
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -80,12 +80,11 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_ivf_demuxer = {
- "ivf",
- NULL_IF_CONFIG_SMALL("On2 IVF"),
- 0,
- probe,
- read_header,
- read_packet,
+ .name = "ivf",
+ .long_name = NULL_IF_CONFIG_SMALL("On2 IVF"),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
.flags= AVFMT_GENERIC_INDEX,
.codec_tag = (const AVCodecTag*[]){ff_codec_bmp_tags, 0},
};
diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c
index 55ce58615b..5fffaf7959 100644
--- a/libavformat/ivfenc.c
+++ b/libavformat/ivfenc.c
@@ -1,20 +1,20 @@
/*
* Copyright (c) 2010 Reimar Döffinger
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
diff --git a/libavformat/jvdec.c b/libavformat/jvdec.c
index d4008f7148..7e1a6ce7b4 100644
--- a/libavformat/jvdec.c
+++ b/libavformat/jvdec.c
@@ -2,20 +2,20 @@
* Bitmap Brothers JV demuxer
* Copyright (c) 2005, 2011 Peter Ross <pross@xvid.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -69,8 +69,8 @@ static int read_header(AVFormatContext *s,
avio_skip(pb, 80);
- ast = av_new_stream(s, 0);
- vst = av_new_stream(s, 1);
+ ast = avformat_new_stream(s, NULL);
+ vst = avformat_new_stream(s, NULL);
if (!ast || !vst)
return AVERROR(ENOMEM);
@@ -139,7 +139,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
AVIOContext *pb = s->pb;
AVStream *ast = s->streams[0];
- while (!s->pb->eof_reached && jv->pts < ast->nb_index_entries) {
+ while (!url_feof(s->pb) && jv->pts < ast->nb_index_entries) {
const AVIndexEntry *e = ast->index_entries + jv->pts;
const JVFrame *jvf = jv->frames + jv->pts;
@@ -207,10 +207,11 @@ static int read_seek(AVFormatContext *s, int stream_index,
if (i < 0 || i >= ast->nb_index_entries)
return 0;
+ if (avio_seek(s->pb, ast->index_entries[i].pos, SEEK_SET) < 0)
+ return -1;
jv->state = JV_AUDIO;
jv->pts = i;
- avio_seek(s->pb, ast->index_entries[i].pos, SEEK_SET);
return 0;
}
diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c
new file mode 100644
index 0000000000..56522106d6
--- /dev/null
+++ b/libavformat/latmenc.c
@@ -0,0 +1,198 @@
+/*
+ * LATM/LOAS muxer
+ * Copyright (c) 2011 Kieran Kunhya <kieran@kunhya.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavcodec/get_bits.h"
+#include "libavcodec/put_bits.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/mpeg4audio.h"
+#include "libavutil/opt.h"
+#include "avformat.h"
+#include "rawenc.h"
+
+typedef struct {
+ AVClass *av_class;
+ int off;
+ int channel_conf;
+ int object_type;
+ int counter;
+ int mod;
+} LATMContext;
+
+static const AVOption options[] = {
+ {"smc-interval", "StreamMuxConfig interval.",
+ offsetof(LATMContext, mod), AV_OPT_TYPE_INT, {.dbl = 0x0014}, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
+ {NULL},
+};
+
+static const AVClass latm_muxer_class = {
+ .class_name = "LATM/LOAS muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static int latm_decode_extradata(LATMContext *ctx, uint8_t *buf, int size)
+{
+ GetBitContext gb;
+ MPEG4AudioConfig m4ac;
+
+ init_get_bits(&gb, buf, size * 8);
+ ctx->off = avpriv_mpeg4audio_get_config(&m4ac, buf, size);
+ if (ctx->off < 0)
+ return ctx->off;
+ skip_bits_long(&gb, ctx->off);
+
+ /* FIXME: are any formats not allowed in LATM? */
+
+ if (m4ac.object_type > AOT_SBR && m4ac.object_type != AOT_ALS) {
+ av_log(ctx, AV_LOG_ERROR, "Muxing MPEG-4 AOT %d in LATM is not supported\n", m4ac.object_type);
+ return AVERROR_INVALIDDATA;
+ }
+ ctx->channel_conf = m4ac.chan_config;
+ ctx->object_type = m4ac.object_type;
+
+ return 0;
+}
+
+static int latm_write_header(AVFormatContext *s)
+{
+ LATMContext *ctx = s->priv_data;
+ AVCodecContext *avctx = s->streams[0]->codec;
+
+ if (avctx->codec_id == CODEC_ID_AAC_LATM)
+ return 0;
+
+ if (avctx->extradata_size > 0 &&
+ latm_decode_extradata(ctx, avctx->extradata, avctx->extradata_size) < 0)
+ return AVERROR_INVALIDDATA;
+
+ return 0;
+}
+
+static int latm_write_frame_header(AVFormatContext *s, PutBitContext *bs)
+{
+ LATMContext *ctx = s->priv_data;
+ AVCodecContext *avctx = s->streams[0]->codec;
+ GetBitContext gb;
+ int header_size;
+
+ /* AudioMuxElement */
+ put_bits(bs, 1, !!ctx->counter);
+
+ if (!ctx->counter) {
+ init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8);
+
+ /* StreamMuxConfig */
+ put_bits(bs, 1, 0); /* audioMuxVersion */
+ put_bits(bs, 1, 1); /* allStreamsSameTimeFraming */
+ put_bits(bs, 6, 0); /* numSubFrames */
+ put_bits(bs, 4, 0); /* numProgram */
+ put_bits(bs, 3, 0); /* numLayer */
+
+ /* AudioSpecificConfig */
+ if (ctx->object_type == AOT_ALS) {
+ header_size = avctx->extradata_size-(ctx->off + 7) >> 3;
+ avpriv_copy_bits(bs, &avctx->extradata[ctx->off], header_size);
+ } else {
+ avpriv_copy_bits(bs, avctx->extradata, ctx->off + 3);
+
+ if (!ctx->channel_conf) {
+ avpriv_copy_pce_data(bs, &gb);
+ }
+ }
+
+ put_bits(bs, 3, 0); /* frameLengthType */
+ put_bits(bs, 8, 0xff); /* latmBufferFullness */
+
+ put_bits(bs, 1, 0); /* otherDataPresent */
+ put_bits(bs, 1, 0); /* crcCheckPresent */
+ }
+
+ ctx->counter++;
+ ctx->counter %= ctx->mod;
+
+ return 0;
+}
+
+static int latm_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ AVIOContext *pb = s->pb;
+ PutBitContext bs;
+ int i, len;
+ uint8_t loas_header[] = "\x56\xe0\x00";
+ uint8_t *buf;
+
+ if (s->streams[0]->codec->codec_id == CODEC_ID_AAC_LATM)
+ return ff_raw_write_packet(s, pkt);
+
+ if (pkt->size > 2 && pkt->data[0] == 0xff && (pkt->data[1] >> 4) == 0xf) {
+ av_log(s, AV_LOG_ERROR, "ADTS header detected - ADTS will not be incorrectly muxed into LATM\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ buf = av_malloc(pkt->size+1024);
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ init_put_bits(&bs, buf, pkt->size+1024);
+
+ latm_write_frame_header(s, &bs);
+
+ /* PayloadLengthInfo() */
+ for (i = 0; i <= pkt->size-255; i+=255)
+ put_bits(&bs, 8, 255);
+
+ put_bits(&bs, 8, pkt->size-i);
+
+ /* The LATM payload is written unaligned */
+
+ /* PayloadMux() */
+ for (i = 0; i < pkt->size; i++)
+ put_bits(&bs, 8, pkt->data[i]);
+
+ avpriv_align_put_bits(&bs);
+ flush_put_bits(&bs);
+
+ len = put_bits_count(&bs) >> 3;
+
+ loas_header[1] |= (len >> 8) & 0x1f;
+ loas_header[2] |= len & 0xff;
+
+ avio_write(pb, loas_header, 3);
+ avio_write(pb, buf, len);
+
+ av_free(buf);
+
+ return 0;
+}
+
+AVOutputFormat ff_latm_muxer = {
+ .name = "latm",
+ .long_name = NULL_IF_CONFIG_SMALL("LOAS/LATM"),
+ .mime_type = "audio/MP4A-LATM",
+ .extensions = "latm,loas",
+ .priv_data_size = sizeof(LATMContext),
+ .audio_codec = CODEC_ID_AAC,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = latm_write_header,
+ .write_packet = latm_write_packet,
+ .priv_class = &latm_muxer_class,
+};
diff --git a/libavformat/libavformat.v b/libavformat/libavformat.v
index 0ec1c3c4de..7ed2d76647 100644
--- a/libavformat/libavformat.v
+++ b/libavformat/libavformat.v
@@ -1,7 +1,27 @@
LIBAVFORMAT_$MAJOR {
- global: *;
- local:
- ff_*_demuxer;
- ff_*_muxer;
- ff_*_protocol;
+ global: av*;
+ #FIXME those are for avserver
+ ff_inet_aton;
+ ff_socket_nonblock;
+ ffm_set_write_index;
+ ffm_read_write_index;
+ ffm_write_write_index;
+ ff_rtsp_parse_line;
+ ff_rtp_get_local_rtp_port;
+ ff_rtp_get_local_rtcp_port;
+ ffio_open_dyn_packet_buf;
+ url_open;
+ url_close;
+ url_write;
+ url_get_max_packet_size;
+ #those are deprecated, remove on next bump
+ find_info_tag;
+ parse_date;
+ dump_format;
+ url_*;
+ ff_timefilter_destroy;
+ ff_timefilter_new;
+ ff_timefilter_update;
+ ff_timefilter_reset;
+ local: *;
};
diff --git a/libavformat/libmodplug.c b/libavformat/libmodplug.c
new file mode 100644
index 0000000000..8b4e4f3bcd
--- /dev/null
+++ b/libavformat/libmodplug.c
@@ -0,0 +1,367 @@
+/*
+ * 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
+* ModPlug demuxer
+* @todo better probing than extensions matching
+*/
+
+#include <libmodplug/modplug.h>
+#include "libavutil/avstring.h"
+#include "libavutil/eval.h"
+#include "libavutil/opt.h"
+#include "avformat.h"
+
+typedef struct ModPlugContext {
+ const AVClass *class;
+ ModPlugFile *f;
+ uint8_t *buf; ///< input file content
+
+ /* options */
+ int noise_reduction;
+ int reverb_depth;
+ int reverb_delay;
+ int bass_amount;
+ int bass_range;
+ int surround_depth;
+ int surround_delay;
+
+ int max_size; ///< max file size to allocate
+
+ /* optional video stream */
+ double ts_per_packet; ///< used to define the pts/dts using packet_count;
+ int packet_count; ///< total number of audio packets
+ int print_textinfo; ///< bool flag for printing speed, tempo, order, ...
+ int video_stream; ///< 1 if the user want a video stream, otherwise 0
+ int w; ///< video stream width in char (one char = 8x8px)
+ int h; ///< video stream height in char (one char = 8x8px)
+ int video_switch; ///< 1 if current packet is video, otherwise 0
+ int fsize; ///< constant frame size
+ int linesize; ///< line size in bytes
+ char *color_eval; ///< color eval user input expression
+ AVExpr *expr; ///< parsed color eval expression
+} ModPlugContext;
+
+static const char *var_names[] = {
+ "x", "y",
+ "w", "h",
+ "t",
+ "speed", "tempo", "order", "pattern", "row",
+ NULL
+};
+
+enum var_name {
+ VAR_X, VAR_Y,
+ VAR_W, VAR_H,
+ VAR_TIME,
+ VAR_SPEED, VAR_TEMPO, VAR_ORDER, VAR_PATTERN, VAR_ROW,
+ VAR_VARS_NB
+};
+
+#define FF_MODPLUG_MAX_FILE_SIZE (100 * 1<<20) // 100M
+#define FF_MODPLUG_DEF_FILE_SIZE ( 5 * 1<<20) // 5M
+
+#define OFFSET(x) offsetof(ModPlugContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ {"noise_reduction", "Enable noise reduction 0(off)-1(on)", OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, D},
+ {"reverb_depth", "Reverb level 0(quiet)-100(loud)", OFFSET(reverb_depth), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 100, D},
+ {"reverb_delay", "Reverb delay in ms, usually 40-200ms", OFFSET(reverb_delay), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, D},
+ {"bass_amount", "XBass level 0(quiet)-100(loud)", OFFSET(bass_amount), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 100, D},
+ {"bass_range", "XBass cutoff in Hz 10-100", OFFSET(bass_range), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 100, D},
+ {"surround_depth", "Surround level 0(quiet)-100(heavy)", OFFSET(surround_depth), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 100, D},
+ {"surround_delay", "Surround delay in ms, usually 5-40ms", OFFSET(surround_delay), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, D},
+ {"max_size", "Max file size supported (in bytes). Default is 5MB. Set to 0 for no limit (not recommended)",
+ OFFSET(max_size), AV_OPT_TYPE_INT, {.dbl = FF_MODPLUG_DEF_FILE_SIZE}, 0, FF_MODPLUG_MAX_FILE_SIZE, D},
+ {"video_stream_expr", "Color formula", OFFSET(color_eval), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D},
+ {"video_stream", "Make demuxer output a video stream", OFFSET(video_stream), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, D},
+ {"video_stream_w", "Video stream width in char (one char = 8x8px)", OFFSET(w), AV_OPT_TYPE_INT, {.dbl = 30}, 20, 512, D},
+ {"video_stream_h", "Video stream height in char (one char = 8x8px)", OFFSET(h), AV_OPT_TYPE_INT, {.dbl = 30}, 20, 512, D},
+ {"video_stream_ptxt", "Print speed, tempo, order, ... in video stream", OFFSET(print_textinfo), AV_OPT_TYPE_INT, {.dbl = 1}, 0, 1, D},
+ {NULL},
+};
+
+#define SET_OPT_IF_REQUESTED(libopt, opt, flag) do { \
+ if (modplug->opt) { \
+ settings.libopt = modplug->opt; \
+ settings.mFlags |= flag; \
+ } \
+} while (0)
+
+#define ADD_META_MULTIPLE_ENTRIES(entry_name, fname) do { \
+ if (n_## entry_name ##s) { \
+ unsigned i, n = 0; \
+ \
+ for (i = 0; i < n_## entry_name ##s; i++) { \
+ char item_name[64] = {0}; \
+ fname(f, i, item_name); \
+ if (!*item_name) \
+ continue; \
+ if (n) \
+ av_dict_set(&s->metadata, #entry_name, "\n", AV_DICT_APPEND); \
+ av_dict_set(&s->metadata, #entry_name, item_name, AV_DICT_APPEND); \
+ n++; \
+ } \
+ \
+ extra = av_asprintf(", %u/%u " #entry_name "%s", \
+ n, n_## entry_name ##s, n > 1 ? "s" : ""); \
+ if (!extra) \
+ return AVERROR(ENOMEM); \
+ av_dict_set(&s->metadata, "extra info", extra, AV_DICT_APPEND); \
+ av_free(extra); \
+ } \
+} while (0)
+
+static int modplug_load_metadata(AVFormatContext *s)
+{
+ ModPlugContext *modplug = s->priv_data;
+ ModPlugFile *f = modplug->f;
+ char *extra;
+ const char *name = ModPlug_GetName(f);
+ const char *msg = ModPlug_GetMessage(f);
+
+ unsigned n_instruments = ModPlug_NumInstruments(f);
+ unsigned n_samples = ModPlug_NumSamples(f);
+ unsigned n_patterns = ModPlug_NumPatterns(f);
+ unsigned n_channels = ModPlug_NumChannels(f);
+
+ if (name && *name) av_dict_set(&s->metadata, "name", name, 0);
+ if (msg && *msg) av_dict_set(&s->metadata, "message", msg, 0);
+
+ extra = av_asprintf("%u pattern%s, %u channel%s",
+ n_patterns, n_patterns > 1 ? "s" : "",
+ n_channels, n_channels > 1 ? "s" : "");
+ if (!extra)
+ return AVERROR(ENOMEM);
+ av_dict_set(&s->metadata, "extra info", extra, AV_DICT_DONT_STRDUP_VAL);
+
+ ADD_META_MULTIPLE_ENTRIES(instrument, ModPlug_InstrumentName);
+ ADD_META_MULTIPLE_ENTRIES(sample, ModPlug_SampleName);
+
+ return 0;
+}
+
+#define AUDIO_PKT_SIZE 512
+
+static int modplug_read_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+ AVStream *st;
+ AVIOContext *pb = s->pb;
+ ModPlug_Settings settings;
+ ModPlugContext *modplug = s->priv_data;
+ int sz = avio_size(pb);
+
+ if (sz < 0) {
+ av_log(s, AV_LOG_WARNING, "Could not determine file size\n");
+ sz = modplug->max_size;
+ } else if (modplug->max_size && sz > modplug->max_size) {
+ sz = modplug->max_size;
+ av_log(s, AV_LOG_WARNING, "Max file size reach%s, allocating %dB "
+ "but demuxing is likely to fail due to incomplete buffer\n",
+ sz == FF_MODPLUG_DEF_FILE_SIZE ? " (see -max_size)" : "", sz);
+ }
+
+ if (modplug->color_eval) {
+ int r = av_expr_parse(&modplug->expr, modplug->color_eval, var_names,
+ NULL, NULL, NULL, NULL, 0, s);
+ if (r < 0)
+ return r;
+ }
+
+ modplug->buf = av_malloc(modplug->max_size);
+ if (!modplug->buf)
+ return AVERROR(ENOMEM);
+ sz = avio_read(pb, modplug->buf, sz);
+
+ ModPlug_GetSettings(&settings);
+ settings.mChannels = 2;
+ settings.mBits = 16;
+ settings.mFrequency = 44100;
+ settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; // best quality
+ settings.mLoopCount = 0; // prevents looping forever
+
+ if (modplug->noise_reduction) settings.mFlags |= MODPLUG_ENABLE_NOISE_REDUCTION;
+ SET_OPT_IF_REQUESTED(mReverbDepth, reverb_depth, MODPLUG_ENABLE_REVERB);
+ SET_OPT_IF_REQUESTED(mReverbDelay, reverb_delay, MODPLUG_ENABLE_REVERB);
+ SET_OPT_IF_REQUESTED(mBassAmount, bass_amount, MODPLUG_ENABLE_MEGABASS);
+ SET_OPT_IF_REQUESTED(mBassRange, bass_range, MODPLUG_ENABLE_MEGABASS);
+ SET_OPT_IF_REQUESTED(mSurroundDepth, surround_depth, MODPLUG_ENABLE_SURROUND);
+ SET_OPT_IF_REQUESTED(mSurroundDelay, surround_delay, MODPLUG_ENABLE_SURROUND);
+
+ if (modplug->reverb_depth) settings.mReverbDepth = modplug->reverb_depth;
+ if (modplug->reverb_delay) settings.mReverbDelay = modplug->reverb_delay;
+ if (modplug->bass_amount) settings.mBassAmount = modplug->bass_amount;
+ if (modplug->bass_range) settings.mBassRange = modplug->bass_range;
+ if (modplug->surround_depth) settings.mSurroundDepth = modplug->surround_depth;
+ if (modplug->surround_delay) settings.mSurroundDelay = modplug->surround_delay;
+
+ ModPlug_SetSettings(&settings);
+
+ modplug->f = ModPlug_Load(modplug->buf, sz);
+ if (!modplug->f)
+ return AVERROR_INVALIDDATA;
+
+ st = av_new_stream(s, 0);
+ if (!st)
+ return AVERROR(ENOMEM);
+ av_set_pts_info(st, 64, 1, 1000);
+ st->duration = ModPlug_GetLength(modplug->f);
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = CODEC_ID_PCM_S16LE;
+ st->codec->channels = settings.mChannels;
+ st->codec->sample_rate = settings.mFrequency;
+
+ // timebase = 1/1000, 2ch 16bits 44.1kHz-> 2*2*44100
+ modplug->ts_per_packet = 1000*AUDIO_PKT_SIZE / (4*44100.);
+
+ if (modplug->video_stream) {
+ AVStream *vst = av_new_stream(s, 1);
+ if (!vst)
+ return AVERROR(ENOMEM);
+ av_set_pts_info(vst, 64, 1, 1000);
+ vst->duration = st->duration;
+ vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ vst->codec->codec_id = CODEC_ID_XBIN;
+ vst->codec->width = modplug->w << 3;
+ vst->codec->height = modplug->h << 3;
+ modplug->linesize = modplug->w * 3;
+ modplug->fsize = modplug->linesize * modplug->h;
+ }
+
+ return modplug_load_metadata(s);
+}
+
+static void write_text(uint8_t *dst, const char *s, int linesize, int x, int y)
+{
+ int i;
+ dst += y*linesize + x*3;
+ for (i = 0; s[i]; i++, dst += 3) {
+ dst[0] = 0x0; // count - 1
+ dst[1] = s[i]; // char
+ dst[2] = 0x0f; // background / foreground
+ }
+}
+
+#define PRINT_INFO(line, name, idvalue) do { \
+ snprintf(intbuf, sizeof(intbuf), "%.0f", var_values[idvalue]); \
+ write_text(pkt->data, name ":", modplug->linesize, 0+1, line+1); \
+ write_text(pkt->data, intbuf, modplug->linesize, 10+1, line+1); \
+} while (0)
+
+static int modplug_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ ModPlugContext *modplug = s->priv_data;
+
+ if (modplug->video_stream) {
+ modplug->video_switch ^= 1; // one video packet for one audio packet
+ if (modplug->video_switch) {
+ double var_values[VAR_VARS_NB];
+
+ var_values[VAR_W ] = modplug->w;
+ var_values[VAR_H ] = modplug->h;
+ var_values[VAR_TIME ] = modplug->packet_count * modplug->ts_per_packet;
+ var_values[VAR_SPEED ] = ModPlug_GetCurrentSpeed (modplug->f);
+ var_values[VAR_TEMPO ] = ModPlug_GetCurrentTempo (modplug->f);
+ var_values[VAR_ORDER ] = ModPlug_GetCurrentOrder (modplug->f);
+ var_values[VAR_PATTERN] = ModPlug_GetCurrentPattern(modplug->f);
+ var_values[VAR_ROW ] = ModPlug_GetCurrentRow (modplug->f);
+
+ if (av_new_packet(pkt, modplug->fsize) < 0)
+ return AVERROR(ENOMEM);
+ pkt->stream_index = 1;
+ memset(pkt->data, 0, modplug->fsize);
+
+ if (modplug->print_textinfo) {
+ char intbuf[32];
+ PRINT_INFO(0, "speed", VAR_SPEED);
+ PRINT_INFO(1, "tempo", VAR_TEMPO);
+ PRINT_INFO(2, "order", VAR_ORDER);
+ PRINT_INFO(3, "pattern", VAR_PATTERN);
+ PRINT_INFO(4, "row", VAR_ROW);
+ PRINT_INFO(5, "ts", VAR_TIME);
+ }
+
+ if (modplug->expr) {
+ int x, y;
+ for (y = 0; y < modplug->h; y++) {
+ for (x = 0; x < modplug->w; x++) {
+ double color;
+ var_values[VAR_X] = x;
+ var_values[VAR_Y] = y;
+ color = av_expr_eval(modplug->expr, var_values, NULL);
+ pkt->data[y*modplug->linesize + x*3 + 2] |= av_clip((int)color, 0, 0xf)<<4;
+ }
+ }
+ }
+ pkt->pts = pkt->dts = var_values[VAR_TIME];
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ return 0;
+ }
+ }
+
+ if (av_new_packet(pkt, AUDIO_PKT_SIZE) < 0)
+ return AVERROR(ENOMEM);
+
+ if (modplug->video_stream)
+ pkt->pts = pkt->dts = modplug->packet_count++ * modplug->ts_per_packet;
+
+ pkt->size = ModPlug_Read(modplug->f, pkt->data, AUDIO_PKT_SIZE);
+ if (pkt->size <= 0) {
+ av_free_packet(pkt);
+ return pkt->size == 0 ? AVERROR_EOF : AVERROR(EIO);
+ }
+ return 0;
+}
+
+static int modplug_read_close(AVFormatContext *s)
+{
+ ModPlugContext *modplug = s->priv_data;
+ ModPlug_Unload(modplug->f);
+ av_freep(&modplug->buf);
+ return 0;
+}
+
+static int modplug_read_seek(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
+{
+ ModPlugContext *modplug = s->priv_data;
+ ModPlug_Seek(modplug->f, (int)ts);
+ if (modplug->video_stream)
+ modplug->packet_count = ts / modplug->ts_per_packet;
+ return 0;
+}
+
+static const AVClass modplug_class = {
+ .class_name = "ModPlug demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_libmodplug_demuxer = {
+ .name = "libmodplug",
+ .long_name = NULL_IF_CONFIG_SMALL("ModPlug demuxer"),
+ .priv_data_size = sizeof(ModPlugContext),
+ .read_header = modplug_read_header,
+ .read_packet = modplug_read_packet,
+ .read_close = modplug_read_close,
+ .read_seek = modplug_read_seek,
+ .extensions = "669,abc,amf,ams,dbm,dmf,dsm,far,it,mdl,med,mid,mod,mt2,mtm,okt,psm,ptm,s3m,stm,ult,umx,xm"
+ ",itgz,itr,itz,mdgz,mdr,mdz,s3gz,s3r,s3z,xmgz,xmr,xmz", // compressed mods
+ .priv_class = &modplug_class,
+};
diff --git a/libavformat/libnut.c b/libavformat/libnut.c
index 76a621a2d7..7628abdfb8 100644
--- a/libavformat/libnut.c
+++ b/libavformat/libnut.c
@@ -2,20 +2,20 @@
* NUT (de)muxing via libnut
* copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -151,16 +151,16 @@ static int nut_write_trailer(AVFormatContext * avf) {
}
AVOutputFormat ff_libnut_muxer = {
- "libnut",
- "nut format",
- "video/x-nut",
- "nut",
- sizeof(NUTContext),
- CODEC_ID_VORBIS,
- CODEC_ID_MPEG4,
- nut_write_header,
- nut_write_packet,
- nut_write_trailer,
+ .name = "libnut",
+ .long_name = "nut format",
+ .mime_type = "video/x-nut",
+ .extensions = "nut",
+ .priv_data_size = sizeof(NUTContext),
+ .audio_codec = CODEC_ID_VORBIS,
+ .video_codec = CODEC_ID_MPEG4,
+ .write_header = nut_write_header,
+ .write_packet = nut_write_packet,
+ .write_trailer = nut_write_trailer,
.flags = AVFMT_GLOBALHEADER,
};
#endif /* CONFIG_LIBNUT_MUXER */
@@ -213,7 +213,7 @@ static int nut_read_header(AVFormatContext * avf, AVFormatParameters * ap) {
priv->s = s;
for (i = 0; s[i].type != -1 && i < 2; i++) {
- AVStream * st = av_new_stream(avf, i);
+ AVStream * st = avformat_new_stream(avf, NULL);
int j;
for (j = 0; j < s[i].fourcc_len && j < 8; j++) st->codec->codec_tag |= s[i].fourcc[j]<<(j*8);
@@ -298,13 +298,13 @@ static int nut_read_close(AVFormatContext *s) {
}
AVInputFormat ff_libnut_demuxer = {
- "libnut",
- NULL_IF_CONFIG_SMALL("NUT format"),
- sizeof(NUTContext),
- nut_probe,
- nut_read_header,
- nut_read_packet,
- nut_read_close,
- nut_read_seek,
+ .name = "libnut",
+ .long_name = NULL_IF_CONFIG_SMALL("NUT format"),
+ .priv_data_size = sizeof(NUTContext),
+ .read_probe = nut_probe,
+ .read_header = nut_read_header,
+ .read_packet = nut_read_packet,
+ .read_close = nut_read_close,
+ .read_seek = nut_read_seek,
.extensions = "nut",
};
diff --git a/libavformat/librtmp.c b/libavformat/librtmp.c
index 30fe8a196b..01b6c3deb0 100644
--- a/libavformat/librtmp.c
+++ b/libavformat/librtmp.c
@@ -2,20 +2,20 @@
* RTMP network protocol
* Copyright (c) 2010 Howard Chu
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -24,6 +24,7 @@
* RTMP protocol based on http://rtmpdump.mplayerhq.hu/ librtmp
*/
+#include "libavutil/mathematics.h"
#include "avformat.h"
#include "url.h"
diff --git a/libavformat/lmlm4.c b/libavformat/lmlm4.c
index eafc1b60bd..96007aa472 100644
--- a/libavformat/lmlm4.c
+++ b/libavformat/lmlm4.c
@@ -5,20 +5,20 @@
* Due to a lack of sample files, only files with one channel are supported.
* u-law and ADPCM audio are unsupported for the same reason.
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -60,14 +60,14 @@ static int lmlm4_probe(AVProbeData * pd) {
static int lmlm4_read_header(AVFormatContext *s, AVFormatParameters *ap) {
AVStream *st;
- if (!(st = av_new_stream(s, 0)))
+ if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_MPEG4;
st->need_parsing = AVSTREAM_PARSE_HEADERS;
av_set_pts_info(st, 64, 1001, 30000);
- if (!(st = av_new_stream(s, 1)))
+ if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_MP2;
@@ -118,10 +118,9 @@ static int lmlm4_read_packet(AVFormatContext *s, AVPacket *pkt) {
}
AVInputFormat ff_lmlm4_demuxer = {
- "lmlm4",
- NULL_IF_CONFIG_SMALL("lmlm4 raw format"),
- 0,
- lmlm4_probe,
- lmlm4_read_header,
- lmlm4_read_packet,
+ .name = "lmlm4",
+ .long_name = NULL_IF_CONFIG_SMALL("lmlm4 raw format"),
+ .read_probe = lmlm4_probe,
+ .read_header = lmlm4_read_header,
+ .read_packet = lmlm4_read_packet,
};
diff --git a/libavformat/loasdec.c b/libavformat/loasdec.c
new file mode 100644
index 0000000000..dd74b304fb
--- /dev/null
+++ b/libavformat/loasdec.c
@@ -0,0 +1,88 @@
+/*
+ * LOAS AudioSyncStream demuxer
+ * Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * 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 "libavutil/intreadwrite.h"
+#include "libavutil/internal.h"
+#include "avformat.h"
+#include "rawdec.h"
+
+static int loas_probe(AVProbeData *p)
+{
+ int max_frames = 0, first_frames = 0;
+ int fsize, frames;
+ uint8_t *buf0 = p->buf;
+ uint8_t *buf2;
+ uint8_t *buf;
+ uint8_t *end = buf0 + p->buf_size - 3;
+ buf = buf0;
+
+ for(; buf < end; buf= buf2+1) {
+ buf2 = buf;
+
+ for(frames = 0; buf2 < end; frames++) {
+ uint32_t header = AV_RB24(buf2);
+ if((header >> 13) != 0x2B7)
+ break;
+ fsize = (header & 0x1FFF) + 3;
+ if(fsize < 7)
+ break;
+ fsize = FFMIN(fsize, end - buf2);
+ buf2 += fsize;
+ }
+ max_frames = FFMAX(max_frames, frames);
+ if(buf == buf0)
+ first_frames= frames;
+ }
+ if (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;
+ else if(max_frames>100)return AVPROBE_SCORE_MAX/2;
+ else if(max_frames>=3) return AVPROBE_SCORE_MAX/4;
+ else if(max_frames>=1) return 1;
+ else return 0;
+}
+
+static int loas_read_header(AVFormatContext *s,
+ AVFormatParameters *ap)
+{
+ AVStream *st;
+
+ st = av_new_stream(s, 0);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = s->iformat->value;
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+
+ //LCM of all possible AAC sample rates
+ av_set_pts_info(st, 64, 1, 28224000);
+
+ return 0;
+}
+
+AVInputFormat ff_loas_demuxer = {
+ .name = "loas",
+ .long_name = NULL_IF_CONFIG_SMALL("LOAS AudioSyncStream"),
+ .read_probe = loas_probe,
+ .read_header = loas_read_header,
+ .read_packet = ff_raw_read_partial_packet,
+ .flags= AVFMT_GENERIC_INDEX,
+ .value = CODEC_ID_AAC_LATM,
+};
diff --git a/libavformat/lxfdec.c b/libavformat/lxfdec.c
index 0f7e4268d2..855e625284 100644
--- a/libavformat/lxfdec.c
+++ b/libavformat/lxfdec.c
@@ -2,20 +2,20 @@
* LXF demuxer
* Copyright (c) 2010 Tomas Härdin
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -90,7 +90,7 @@ static int sync(AVFormatContext *s, uint8_t *header)
return ret < 0 ? ret : AVERROR_EOF;
while (memcmp(buf, LXF_IDENT, LXF_IDENT_LENGTH)) {
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR_EOF;
memmove(buf, &buf[1], LXF_IDENT_LENGTH-1);
@@ -217,7 +217,7 @@ static int lxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
if ((ret = avio_read(pb, header_data, LXF_HEADER_DATA_SIZE)) != LXF_HEADER_DATA_SIZE)
return ret < 0 ? ret : AVERROR_EOF;
- if (!(st = av_new_stream(s, 0)))
+ if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
st->duration = AV_RL32(&header_data[32]);
@@ -243,7 +243,7 @@ static int lxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
av_log(s, AV_LOG_WARNING, "VBI data not yet supported\n");
if ((lxf->channels = (disk_params >> 2) & 0xF)) {
- if (!(st = av_new_stream(s, 1)))
+ if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
diff --git a/libavformat/m4vdec.c b/libavformat/m4vdec.c
index e856aadc10..88f838022e 100644
--- a/libavformat/m4vdec.c
+++ b/libavformat/m4vdec.c
@@ -2,20 +2,20 @@
* RAW MPEG-4 video demuxer
* Copyright (c) 2006 Thijs Vermeir <thijs.vermeir@barco.com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -45,7 +45,7 @@ static int mpeg4video_probe(AVProbeData *probe_packet)
}
if (VOP >= VISO && VOP >= VOL && VO >= VOL && VOL > 0 && res==0)
- return AVPROBE_SCORE_MAX/2;
+ return VOP+VO > 3 ? AVPROBE_SCORE_MAX/2 : AVPROBE_SCORE_MAX/4;
return 0;
}
diff --git a/libavformat/matroska.c b/libavformat/matroska.c
index b448af21aa..52481d7556 100644
--- a/libavformat/matroska.c
+++ b/libavformat/matroska.c
@@ -2,20 +2,20 @@
* Matroska common data
* Copyright (c) 2003-2004 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -99,3 +99,27 @@ const AVMetadataConv ff_mkv_metadata_conv[] = {
{ "PART_NUMBER" , "track" },
{ 0 }
};
+
+const char * const matroska_video_stereo_mode[MATROSKA_VIDEO_STEREO_MODE_COUNT] = {
+ "mono",
+ "left_right",
+ "bottom_top",
+ "top_bottom",
+ "checkerboard_rl",
+ "checkerboard_lr"
+ "row_interleaved_rl",
+ "row_interleaved_lr",
+ "col_interleaved_rl",
+ "col_interleaved_lr",
+ "anaglyph_cyan_red",
+ "right_left",
+ "anaglyph_green_magenta",
+ "block_lr",
+ "block_rl",
+};
+
+const char * const matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_PLANE_COUNT] = {
+ "left",
+ "right",
+ "background",
+};
diff --git a/libavformat/matroska.h b/libavformat/matroska.h
index 8e747e6a9c..ab7e3269fa 100644
--- a/libavformat/matroska.h
+++ b/libavformat/matroska.h
@@ -2,20 +2,20 @@
* Matroska constants
* Copyright (c) 2003-2004 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -77,8 +77,13 @@
#define MATROSKA_ID_TRACKNUMBER 0xD7
#define MATROSKA_ID_TRACKUID 0x73C5
#define MATROSKA_ID_TRACKTYPE 0x83
-#define MATROSKA_ID_TRACKAUDIO 0xE1
-#define MATROSKA_ID_TRACKVIDEO 0xE0
+#define MATROSKA_ID_TRACKVIDEO 0xE0
+#define MATROSKA_ID_TRACKAUDIO 0xE1
+#define MATROSKA_ID_TRACKOPERATION 0xE2
+#define MATROSKA_ID_TRACKCOMBINEPLANES 0xE3
+#define MATROSKA_ID_TRACKPLANE 0xE4
+#define MATROSKA_ID_TRACKPLANEUID 0xE5
+#define MATROSKA_ID_TRACKPLANETYPE 0xE6
#define MATROSKA_ID_CODECID 0x86
#define MATROSKA_ID_CODECPRIVATE 0x63A2
#define MATROSKA_ID_CODECNAME 0x258688
@@ -253,8 +258,13 @@ typedef struct CodecMime{
/* max. depth in the EBML tree structure */
#define EBML_MAX_DEPTH 16
+#define MATROSKA_VIDEO_STEREO_MODE_COUNT 15
+#define MATROSKA_VIDEO_STEREO_PLANE_COUNT 3
+
extern const CodecTags ff_mkv_codec_tags[];
extern const CodecMime ff_mkv_mime_tags[];
extern const AVMetadataConv ff_mkv_metadata_conv[];
+extern const char * const matroska_video_stereo_mode[MATROSKA_VIDEO_STEREO_MODE_COUNT];
+extern const char * const matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_PLANE_COUNT];
#endif /* AVFORMAT_MATROSKA_H */
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index a1e827f093..78e337bfab 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1,21 +1,21 @@
/*
* Matroska file demuxer
- * Copyright (c) 2003-2008 The Libav Project
+ * Copyright (c) 2003-2008 The FFmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -112,7 +112,8 @@ typedef struct {
uint64_t display_height;
uint64_t pixel_width;
uint64_t pixel_height;
- uint64_t fourcc;
+ EbmlBin color_space;
+ uint64_t stereo_mode;
} MatroskaTrackVideo;
typedef struct {
@@ -133,6 +134,15 @@ typedef struct {
} MatroskaTrackAudio;
typedef struct {
+ uint64_t uid;
+ uint64_t type;
+} MatroskaTrackPlane;
+
+typedef struct {
+ EbmlList combine_planes;
+} MatroskaTrackOperation;
+
+typedef struct {
uint64_t num;
uint64_t uid;
uint64_t type;
@@ -146,6 +156,7 @@ typedef struct {
uint64_t flag_forced;
MatroskaTrackVideo video;
MatroskaTrackAudio audio;
+ MatroskaTrackOperation operation;
EbmlList encodings;
AVStream *stream;
@@ -244,6 +255,9 @@ typedef struct {
/* What to skip before effectively reading a packet. */
int skip_to_keyframe;
uint64_t skip_to_timecode;
+
+ /* File has a CUES element, but we defer parsing until it is needed. */
+ int cues_parsing_deferred;
} MatroskaDemuxContext;
typedef struct {
@@ -291,14 +305,14 @@ static EbmlSyntax matroska_track_video[] = {
{ MATROSKA_ID_VIDEODISPLAYHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,display_height) },
{ MATROSKA_ID_VIDEOPIXELWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_width) },
{ MATROSKA_ID_VIDEOPIXELHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_height) },
- { MATROSKA_ID_VIDEOCOLORSPACE, EBML_UINT, 0, offsetof(MatroskaTrackVideo,fourcc) },
+ { MATROSKA_ID_VIDEOCOLORSPACE, EBML_BIN, 0, offsetof(MatroskaTrackVideo,color_space) },
+ { MATROSKA_ID_VIDEOSTEREOMODE, EBML_UINT, 0, offsetof(MatroskaTrackVideo,stereo_mode) },
{ MATROSKA_ID_VIDEOPIXELCROPB, EBML_NONE },
{ MATROSKA_ID_VIDEOPIXELCROPT, EBML_NONE },
{ MATROSKA_ID_VIDEOPIXELCROPL, EBML_NONE },
{ MATROSKA_ID_VIDEOPIXELCROPR, EBML_NONE },
{ MATROSKA_ID_VIDEODISPLAYUNIT, EBML_NONE },
{ MATROSKA_ID_VIDEOFLAGINTERLACED,EBML_NONE },
- { MATROSKA_ID_VIDEOSTEREOMODE, EBML_NONE },
{ MATROSKA_ID_VIDEOASPECTRATIO, EBML_NONE },
{ 0 }
};
@@ -330,6 +344,22 @@ static EbmlSyntax matroska_track_encodings[] = {
{ 0 }
};
+static EbmlSyntax matroska_track_plane[] = {
+ { MATROSKA_ID_TRACKPLANEUID, EBML_UINT, 0, offsetof(MatroskaTrackPlane,uid) },
+ { MATROSKA_ID_TRACKPLANETYPE, EBML_UINT, 0, offsetof(MatroskaTrackPlane,type) },
+ { 0 }
+};
+
+static EbmlSyntax matroska_track_combine_planes[] = {
+ { MATROSKA_ID_TRACKPLANE, EBML_NEST, sizeof(MatroskaTrackPlane), offsetof(MatroskaTrackOperation,combine_planes), {.n=matroska_track_plane} },
+ { 0 }
+};
+
+static EbmlSyntax matroska_track_operation[] = {
+ { MATROSKA_ID_TRACKCOMBINEPLANES, EBML_NEST, 0, 0, {.n=matroska_track_combine_planes} },
+ { 0 }
+};
+
static EbmlSyntax matroska_track[] = {
{ MATROSKA_ID_TRACKNUMBER, EBML_UINT, 0, offsetof(MatroskaTrack,num) },
{ MATROSKA_ID_TRACKNAME, EBML_UTF8, 0, offsetof(MatroskaTrack,name) },
@@ -344,6 +374,7 @@ static EbmlSyntax matroska_track[] = {
{ MATROSKA_ID_TRACKFLAGFORCED, EBML_UINT, 0, offsetof(MatroskaTrack,flag_forced), {.u=0} },
{ MATROSKA_ID_TRACKVIDEO, EBML_NEST, 0, offsetof(MatroskaTrack,video), {.n=matroska_track_video} },
{ MATROSKA_ID_TRACKAUDIO, EBML_NEST, 0, offsetof(MatroskaTrack,audio), {.n=matroska_track_audio} },
+ { MATROSKA_ID_TRACKOPERATION, EBML_NEST, 0, offsetof(MatroskaTrack,operation), {.n=matroska_track_operation} },
{ MATROSKA_ID_TRACKCONTENTENCODINGS,EBML_NEST, 0, 0, {.n=matroska_track_encodings} },
{ MATROSKA_ID_TRACKFLAGENABLED, EBML_NONE },
{ MATROSKA_ID_TRACKFLAGLACING, EBML_NONE },
@@ -487,7 +518,7 @@ static EbmlSyntax matroska_segments[] = {
static EbmlSyntax matroska_blockgroup[] = {
{ MATROSKA_ID_BLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) },
{ MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) },
- { MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock,duration), {.u=AV_NOPTS_VALUE} },
+ { MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock,duration) },
{ MATROSKA_ID_BLOCKREFERENCE, EBML_UINT, 0, offsetof(MatroskaBlock,reference) },
{ 1, EBML_UINT, 0, offsetof(MatroskaBlock,non_simple), {.u=1} },
{ 0 }
@@ -550,7 +581,7 @@ static int ebml_read_num(MatroskaDemuxContext *matroska, AVIOContext *pb,
* use it safely here to catch EOS. */
if (!(total = avio_r8(pb))) {
/* we might encounter EOS here */
- if (!pb->eof_reached) {
+ if (!url_feof(pb)) {
int64_t pos = avio_tell(pb);
av_log(matroska->ctx, AV_LOG_ERROR,
"Read error at pos. %"PRIu64" (0x%"PRIx64")\n",
@@ -798,11 +829,15 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska,
uint32_t id = syntax->id;
uint64_t length;
int res;
+ void *newelem;
data = (char *)data + syntax->data_offset;
if (syntax->list_elem_size) {
EbmlList *list = data;
- list->elem = av_realloc(list->elem, (list->nb_elem+1)*syntax->list_elem_size);
+ newelem = av_realloc(list->elem, (list->nb_elem+1)*syntax->list_elem_size);
+ if (!newelem)
+ return AVERROR(ENOMEM);
+ list->elem = newelem;
data = (char*)list->elem + list->nb_elem*syntax->list_elem_size;
memset(data, 0, syntax->list_elem_size);
list->nb_elem++;
@@ -900,6 +935,8 @@ static int matroska_probe(AVProbeData *p)
* Not fully fool-proof, but good enough. */
for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) {
int probelen = strlen(matroska_doctypes[i]);
+ if (total < probelen)
+ continue;
for (n = 4+size; n <= 4+size+total-probelen; n++)
if (!memcmp(p->buf+n, matroska_doctypes[i], probelen))
return AVPROBE_SCORE_MAX;
@@ -930,6 +967,7 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size,
uint8_t* data = *buf;
int isize = *buf_size;
uint8_t* pkt_data = NULL;
+ uint8_t* newpktdata;
int pkt_size = isize;
int result = 0;
int olen;
@@ -959,10 +997,18 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size,
zstream.avail_in = isize;
do {
pkt_size *= 3;
- pkt_data = av_realloc(pkt_data, pkt_size);
+ newpktdata = av_realloc(pkt_data, pkt_size);
+ if (!newpktdata) {
+ inflateEnd(&zstream);
+ goto failed;
+ }
+ pkt_data = newpktdata;
zstream.avail_out = pkt_size - zstream.total_out;
zstream.next_out = pkt_data + zstream.total_out;
- result = inflate(&zstream, Z_NO_FLUSH);
+ if (pkt_data) {
+ result = inflate(&zstream, Z_NO_FLUSH);
+ } else
+ result = Z_MEM_ERROR;
} while (result==Z_OK && pkt_size<10000000);
pkt_size = zstream.total_out;
inflateEnd(&zstream);
@@ -980,10 +1026,18 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size,
bzstream.avail_in = isize;
do {
pkt_size *= 3;
- pkt_data = av_realloc(pkt_data, pkt_size);
+ newpktdata = av_realloc(pkt_data, pkt_size);
+ if (!newpktdata) {
+ BZ2_bzDecompressEnd(&bzstream);
+ goto failed;
+ }
+ pkt_data = newpktdata;
bzstream.avail_out = pkt_size - bzstream.total_out_lo32;
bzstream.next_out = pkt_data + bzstream.total_out_lo32;
- result = BZ2_bzDecompress(&bzstream);
+ if (pkt_data) {
+ result = BZ2_bzDecompress(&bzstream);
+ } else
+ result = BZ_MEM_ERROR;
} while (result==BZ_OK && pkt_size<10000000);
pkt_size = bzstream.total_out_lo32;
BZ2_bzDecompressEnd(&bzstream);
@@ -1010,7 +1064,8 @@ static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska,
char *line, *layer, *ptr = pkt->data, *end = ptr+pkt->size;
for (; *ptr!=',' && ptr<end-1; ptr++);
if (*ptr == ',')
- layer = ++ptr;
+ ptr++;
+ layer = ptr;
for (; *ptr!=',' && ptr<end-1; ptr++);
if (*ptr == ',') {
int64_t end_pts = pkt->pts + display_duration;
@@ -1035,13 +1090,17 @@ static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska,
}
}
-static void matroska_merge_packets(AVPacket *out, AVPacket *in)
+static int matroska_merge_packets(AVPacket *out, AVPacket *in)
{
- out->data = av_realloc(out->data, out->size+in->size);
+ void *newdata = av_realloc(out->data, out->size+in->size);
+ if (!newdata)
+ return AVERROR(ENOMEM);
+ out->data = newdata;
memcpy(out->data+out->size, in->data, in->size);
out->size += in->size;
av_destruct_packet(in);
av_free(in);
+ return 0;
}
static void matroska_convert_tag(AVFormatContext *s, EbmlList *list,
@@ -1110,7 +1169,7 @@ static void matroska_convert_tags(AVFormatContext *s)
}
}
-static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
+static int matroska_parse_seekhead_entry(MatroskaDemuxContext *matroska, int idx)
{
EbmlList *seekhead_list = &matroska->seekhead;
MatroskaSeekhead *seekhead = seekhead_list->elem;
@@ -1118,6 +1177,54 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
int64_t before_pos = avio_tell(matroska->ctx->pb);
uint32_t saved_id = matroska->current_id;
MatroskaLevel level;
+ int64_t offset;
+ int ret = 0;
+
+ if (idx >= seekhead_list->nb_elem
+ || seekhead[idx].id == MATROSKA_ID_SEEKHEAD
+ || seekhead[idx].id == MATROSKA_ID_CLUSTER)
+ return 0;
+
+ /* seek */
+ offset = seekhead[idx].pos + matroska->segment_start;
+ if (avio_seek(matroska->ctx->pb, offset, SEEK_SET) == offset) {
+ /* We don't want to lose our seekhead level, so we add
+ * a dummy. This is a crude hack. */
+ if (matroska->num_levels == EBML_MAX_DEPTH) {
+ av_log(matroska->ctx, AV_LOG_INFO,
+ "Max EBML element depth (%d) reached, "
+ "cannot parse further.\n", EBML_MAX_DEPTH);
+ ret = AVERROR_INVALIDDATA;
+ } else {
+ level.start = 0;
+ level.length = (uint64_t)-1;
+ matroska->levels[matroska->num_levels] = level;
+ matroska->num_levels++;
+ matroska->current_id = 0;
+
+ ret = ebml_parse(matroska, matroska_segment, matroska);
+
+ /* remove dummy level */
+ while (matroska->num_levels) {
+ uint64_t length = matroska->levels[--matroska->num_levels].length;
+ if (length == (uint64_t)-1)
+ break;
+ }
+ }
+ }
+ /* seek back */
+ avio_seek(matroska->ctx->pb, before_pos, SEEK_SET);
+ matroska->level_up = level_up;
+ matroska->current_id = saved_id;
+
+ return ret;
+}
+
+static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
+{
+ EbmlList *seekhead_list = &matroska->seekhead;
+ MatroskaSeekhead *seekhead = seekhead_list->elem;
+ int64_t before_pos = avio_tell(matroska->ctx->pb);
int i;
// we should not do any seeking in the streaming case
@@ -1125,47 +1232,60 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
(matroska->ctx->flags & AVFMT_FLAG_IGNIDX))
return;
- for (i=0; i<seekhead_list->nb_elem; i++) {
- int64_t offset = seekhead[i].pos + matroska->segment_start;
-
- if (seekhead[i].pos <= before_pos
- || seekhead[i].id == MATROSKA_ID_SEEKHEAD
- || seekhead[i].id == MATROSKA_ID_CLUSTER)
+ for (i = 0; i < seekhead_list->nb_elem; i++) {
+ if (seekhead[i].pos <= before_pos)
continue;
- /* seek */
- if (avio_seek(matroska->ctx->pb, offset, SEEK_SET) != offset)
+ // defer cues parsing until we actually need cue data.
+ if (seekhead[i].id == MATROSKA_ID_CUES) {
+ matroska->cues_parsing_deferred = 1;
continue;
-
- /* We don't want to lose our seekhead level, so we add
- * a dummy. This is a crude hack. */
- if (matroska->num_levels == EBML_MAX_DEPTH) {
- av_log(matroska->ctx, AV_LOG_INFO,
- "Max EBML element depth (%d) reached, "
- "cannot parse further.\n", EBML_MAX_DEPTH);
- break;
}
- level.start = 0;
- level.length = (uint64_t)-1;
- matroska->levels[matroska->num_levels] = level;
- matroska->num_levels++;
- matroska->current_id = 0;
+ if (matroska_parse_seekhead_entry(matroska, i) < 0)
+ break;
+ }
+}
- ebml_parse(matroska, matroska_segment, matroska);
+static void matroska_add_index_entries(MatroskaDemuxContext *matroska) {
+ EbmlList *index_list;
+ MatroskaIndex *index;
+ int index_scale = 1;
+ int i, j;
- /* remove dummy level */
- while (matroska->num_levels) {
- uint64_t length = matroska->levels[--matroska->num_levels].length;
- if (length == (uint64_t)-1)
- break;
+ index_list = &matroska->index;
+ index = index_list->elem;
+ if (index_list->nb_elem
+ && index[0].time > 1E14/matroska->time_scale) {
+ av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n");
+ index_scale = matroska->time_scale;
+ }
+ for (i = 0; i < index_list->nb_elem; i++) {
+ EbmlList *pos_list = &index[i].pos;
+ MatroskaIndexPos *pos = pos_list->elem;
+ for (j = 0; j < pos_list->nb_elem; j++) {
+ MatroskaTrack *track = matroska_find_track_by_num(matroska, pos[j].track);
+ if (track && track->stream)
+ av_add_index_entry(track->stream,
+ pos[j].pos + matroska->segment_start,
+ index[i].time/index_scale, 0, 0,
+ AVINDEX_KEYFRAME);
}
}
+}
- /* seek back */
- avio_seek(matroska->ctx->pb, before_pos, SEEK_SET);
- matroska->level_up = level_up;
- matroska->current_id = saved_id;
+static void matroska_parse_cues(MatroskaDemuxContext *matroska) {
+ EbmlList *seekhead_list = &matroska->seekhead;
+ MatroskaSeekhead *seekhead = seekhead_list->elem;
+ int i;
+
+ for (i = 0; i < seekhead_list->nb_elem; i++)
+ if (seekhead[i].id == MATROSKA_ID_CUES)
+ break;
+ assert(i <= seekhead_list->nb_elem);
+
+ matroska_parse_seekhead_entry(matroska, i);
+ matroska_add_index_entries(matroska);
}
static int matroska_aac_profile(char *codec_id)
@@ -1183,8 +1303,8 @@ static int matroska_aac_sri(int samplerate)
{
int sri;
- for (sri=0; sri<FF_ARRAY_ELEMS(ff_mpeg4audio_sample_rates); sri++)
- if (ff_mpeg4audio_sample_rates[sri] == samplerate)
+ for (sri=0; sri<FF_ARRAY_ELEMS(avpriv_mpeg4audio_sample_rates); sri++)
+ if (avpriv_mpeg4audio_sample_rates[sri] == samplerate)
break;
return sri;
}
@@ -1197,26 +1317,28 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
EbmlList *chapters_list = &matroska->chapters;
MatroskaChapter *chapters;
MatroskaTrack *tracks;
- EbmlList *index_list;
- MatroskaIndex *index;
- int index_scale = 1;
uint64_t max_start = 0;
Ebml ebml = { 0 };
AVStream *st;
- int i, j, res;
+ int i, j, k, res;
matroska->ctx = s;
/* 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) || ebml.doctype_version > 2) {
+ || ebml.id_length > sizeof(uint32_t) || ebml.doctype_version > 3) {
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;
+ } else if (ebml.doctype_version == 3) {
+ av_log(matroska->ctx, AV_LOG_WARNING,
+ "EBML header using unsupported features\n"
+ "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
+ ebml.version, ebml.doctype, ebml.doctype_version);
}
for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++)
if (!strcmp(ebml.doctype, matroska_doctypes[i]))
@@ -1242,11 +1364,12 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
for (i=0; i < matroska->tracks.nb_elem; i++) {
MatroskaTrack *track = &tracks[i];
enum CodecID codec_id = CODEC_ID_NONE;
- EbmlList *encodings_list = &tracks->encodings;
+ EbmlList *encodings_list = &track->encodings;
MatroskaTrackEncoding *encodings = encodings_list->elem;
uint8_t *extradata = NULL;
int extradata_size = 0;
int extradata_offset = 0;
+ uint32_t fourcc = 0;
AVIOContext b;
/* Apply some sanity checks. */
@@ -1268,13 +1391,15 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
track->video.display_width = track->video.pixel_width;
if (!track->video.display_height)
track->video.display_height = track->video.pixel_height;
+ if (track->video.color_space.size == 4)
+ fourcc = AV_RL32(track->video.color_space.data);
} else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
if (!track->audio.out_samplerate)
track->audio.out_samplerate = track->audio.samplerate;
}
if (encodings_list->nb_elem > 1) {
av_log(matroska->ctx, AV_LOG_ERROR,
- "Multiple combined encodings no supported");
+ "Multiple combined encodings not supported");
} else if (encodings_list->nb_elem == 1) {
if (encodings[0].type ||
(encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP &&
@@ -1319,7 +1444,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
}
- st = track->stream = av_new_stream(s, 0);
+ st = track->stream = avformat_new_stream(s, NULL);
if (st == NULL)
return AVERROR(ENOMEM);
@@ -1327,8 +1452,8 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
&& track->codec_priv.size >= 40
&& track->codec_priv.data != NULL) {
track->ms_compat = 1;
- track->video.fourcc = AV_RL32(track->codec_priv.data + 16);
- codec_id = ff_codec_get_id(ff_codec_bmp_tags, track->video.fourcc);
+ fourcc = AV_RL32(track->codec_priv.data + 16);
+ codec_id = ff_codec_get_id(ff_codec_bmp_tags, fourcc);
extradata_offset = 40;
} else if (!strcmp(track->codec_id, "A_MS/ACM")
&& track->codec_priv.size >= 14
@@ -1344,8 +1469,8 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
} else if (!strcmp(track->codec_id, "V_QUICKTIME")
&& (track->codec_priv.size >= 86)
&& (track->codec_priv.data != NULL)) {
- track->video.fourcc = AV_RL32(track->codec_priv.data);
- codec_id=ff_codec_get_id(codec_movvideo_tags, track->video.fourcc);
+ fourcc = AV_RL32(track->codec_priv.data);
+ codec_id = ff_codec_get_id(codec_movvideo_tags, fourcc);
} else if (codec_id == CODEC_ID_PCM_S16BE) {
switch (track->audio.bitdepth) {
case 8: codec_id = CODEC_ID_PCM_U8; break;
@@ -1463,8 +1588,10 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
if (track->type == MATROSKA_TRACK_TYPE_VIDEO) {
+ MatroskaTrackPlane *planes = track->operation.combine_planes.elem;
+
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_tag = track->video.fourcc;
+ st->codec->codec_tag = fourcc;
st->codec->width = track->video.pixel_width;
st->codec->height = track->video.pixel_height;
av_reduce(&st->sample_aspect_ratio.num,
@@ -1476,6 +1603,25 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->need_parsing = AVSTREAM_PARSE_HEADERS;
if (track->default_duration)
st->avg_frame_rate = av_d2q(1000000000.0/track->default_duration, INT_MAX);
+
+ /* export stereo mode flag as metadata tag */
+ if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREO_MODE_COUNT)
+ av_dict_set(&st->metadata, "stereo_mode", matroska_video_stereo_mode[track->video.stereo_mode], 0);
+
+ /* if we have virtual track, mark the real tracks */
+ for (j=0; j < track->operation.combine_planes.nb_elem; j++) {
+ char buf[32];
+ if (planes[j].type >= MATROSKA_VIDEO_STEREO_PLANE_COUNT)
+ continue;
+ snprintf(buf, sizeof(buf), "%s_%d",
+ matroska_video_stereo_plane[planes[j].type], i);
+ for (k=0; k < matroska->tracks.nb_elem; k++)
+ if (planes[j].uid == tracks[k].uid) {
+ av_dict_set(&s->streams[k]->metadata,
+ "stereo_mode", buf, 0);
+ break;
+ }
+ }
} else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->sample_rate = track->audio.out_samplerate;
@@ -1493,10 +1639,11 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
attachements[j].bin.data && attachements[j].bin.size > 0)) {
av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n");
} else {
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (st == NULL)
break;
av_dict_set(&st->metadata, "filename",attachements[j].filename, 0);
+ av_dict_set(&st->metadata, "mimetype", attachements[j].mime, 0);
st->codec->codec_id = CODEC_ID_NONE;
st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
st->codec->extradata = av_malloc(attachements[j].bin.size);
@@ -1521,7 +1668,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (chapters[i].start != AV_NOPTS_VALUE && chapters[i].uid
&& (max_start==0 || chapters[i].start > max_start)) {
chapters[i].chapter =
- ff_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000},
+ avpriv_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000},
chapters[i].start, chapters[i].end,
chapters[i].title);
av_dict_set(&chapters[i].chapter->metadata,
@@ -1529,26 +1676,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
max_start = chapters[i].start;
}
- index_list = &matroska->index;
- index = index_list->elem;
- if (index_list->nb_elem
- && index[0].time > 100000000000000/matroska->time_scale) {
- av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n");
- index_scale = matroska->time_scale;
- }
- for (i=0; i<index_list->nb_elem; i++) {
- EbmlList *pos_list = &index[i].pos;
- MatroskaIndexPos *pos = pos_list->elem;
- for (j=0; j<pos_list->nb_elem; j++) {
- MatroskaTrack *track = matroska_find_track_by_num(matroska,
- pos[j].track);
- if (track && track->stream)
- av_add_index_entry(track->stream,
- pos[j].pos + matroska->segment_start,
- index[i].time/index_scale, 0, 0,
- AVINDEX_KEYFRAME);
- }
- }
+ matroska_add_index_entries(matroska);
matroska_convert_tags(s);
@@ -1566,11 +1694,13 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
memcpy(pkt, matroska->packets[0], sizeof(AVPacket));
av_free(matroska->packets[0]);
if (matroska->num_packets > 1) {
+ void *newpackets;
memmove(&matroska->packets[0], &matroska->packets[1],
(matroska->num_packets - 1) * sizeof(AVPacket *));
- matroska->packets =
- av_realloc(matroska->packets, (matroska->num_packets - 1) *
- sizeof(AVPacket *));
+ newpackets = av_realloc(matroska->packets,
+ (matroska->num_packets - 1) * sizeof(AVPacket *));
+ if (newpackets)
+ matroska->packets = newpackets;
} else {
av_freep(&matroska->packets);
}
@@ -1628,7 +1758,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
st = track->stream;
if (st->discard >= AVDISCARD_ALL)
return res;
- if (duration == AV_NOPTS_VALUE)
+ if (!duration)
duration = track->default_duration / matroska->time_scale;
block_time = AV_RB16(data);
@@ -1724,7 +1854,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
lace_size[n] = lace_size[n - 1] + snum;
total += lace_size[n];
}
- lace_size[n] = size - total;
+ lace_size[laces - 1] = size - total;
break;
}
}
@@ -1863,8 +1993,6 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
for (i=0; i<blocks_list->nb_elem && !res; i++)
if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
- if (!blocks[i].non_simple)
- blocks[i].duration = AV_NOPTS_VALUE;
res=matroska_parse_block(matroska,
blocks[i].bin.data, blocks[i].bin.size,
blocks[i].bin.pos, cluster.timecode,
@@ -1898,6 +2026,12 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index,
AVStream *st = s->streams[stream_index];
int i, index, index_sub, index_min;
+ /* Parse the CUES now since we need the index data to seek. */
+ if (matroska->cues_parsing_deferred) {
+ matroska_parse_cues(matroska);
+ matroska->cues_parsing_deferred = 0;
+ }
+
if (!st->nb_index_entries)
return 0;
timestamp = FFMAX(timestamp, st->index_entries[0].timestamp);
@@ -1958,12 +2092,12 @@ static int matroska_read_close(AVFormatContext *s)
}
AVInputFormat ff_matroska_demuxer = {
- "matroska,webm",
- NULL_IF_CONFIG_SMALL("Matroska/WebM file format"),
- sizeof(MatroskaDemuxContext),
- matroska_probe,
- matroska_read_header,
- matroska_read_packet,
- matroska_read_close,
- matroska_read_seek,
+ .name = "matroska,webm",
+ .long_name = NULL_IF_CONFIG_SMALL("Matroska/WebM file format"),
+ .priv_data_size = sizeof(MatroskaDemuxContext),
+ .read_probe = matroska_probe,
+ .read_header = matroska_read_header,
+ .read_packet = matroska_read_packet,
+ .read_close = matroska_read_close,
+ .read_seek = matroska_read_seek,
};
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index d132b65f5b..6cf4156cb8 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -2,20 +2,20 @@
* Matroska muxer
* Copyright (c) 2007 David Conrad
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -91,6 +91,8 @@ typedef struct MatroskaMuxContext {
unsigned int audio_buffer_size;
AVPacket cur_audio_pkt;
+
+ int have_attachments;
} MatroskaMuxContext;
@@ -421,7 +423,7 @@ static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, AVCodecContex
else
first_header_size = 42;
- if (ff_split_xiph_headers(codec->extradata, codec->extradata_size,
+ if (avpriv_split_xiph_headers(codec->extradata, codec->extradata_size,
first_header_size, header_start, header_len) < 0) {
av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n");
return -1;
@@ -441,7 +443,7 @@ static void get_aac_sample_rates(AVFormatContext *s, AVCodecContext *codec, int
{
MPEG4AudioConfig mp4ac;
- if (ff_mpeg4audio_get_config(&mp4ac, codec->extradata, codec->extradata_size) < 0) {
+ if (avpriv_mpeg4audio_get_config(&mp4ac, codec->extradata, codec->extradata_size) < 0) {
av_log(s, AV_LOG_WARNING, "Error parsing AAC extradata, unable to determine samplerate.\n");
return;
}
@@ -528,6 +530,11 @@ static int mkv_write_tracks(AVFormatContext *s)
int output_sample_rate = 0;
AVDictionaryEntry *tag;
+ if (codec->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
+ mkv->have_attachments = 1;
+ continue;
+ }
+
if (!bit_depth)
bit_depth = av_get_bytes_per_sample(codec->sample_fmt) << 3;
@@ -589,31 +596,38 @@ static int mkv_write_tracks(AVFormatContext *s)
// XXX: interlace flag?
put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width);
put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height);
- if ((tag = av_dict_get(s->metadata, "stereo_mode", NULL, 0))) {
- uint8_t stereo_fmt = atoi(tag->value);
- int valid_fmt = 0;
-
- switch (mkv->mode) {
- case MODE_WEBM:
- if (stereo_fmt <= MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM
- || stereo_fmt == MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT)
- valid_fmt = 1;
- break;
- case MODE_MATROSKAv2:
- if (stereo_fmt <= MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_RL)
- valid_fmt = 1;
- break;
- }
-
- if (valid_fmt)
- put_ebml_uint (pb, MATROSKA_ID_VIDEOSTEREOMODE, stereo_fmt);
+
+ if ((tag = av_dict_get(st->metadata, "stereo_mode", NULL, 0)) ||
+ (tag = av_dict_get( s->metadata, "stereo_mode", NULL, 0))) {
+ // save stereo mode flag
+ uint64_t st_mode = MATROSKA_VIDEO_STEREO_MODE_COUNT;
+
+ for (j=0; j<MATROSKA_VIDEO_STEREO_MODE_COUNT; j++)
+ if (!strcmp(tag->value, matroska_video_stereo_mode[j])){
+ st_mode = j;
+ break;
+ }
+
+ if ((mkv->mode == MODE_WEBM && st_mode > 3 && st_mode != 11)
+ || st_mode >= MATROSKA_VIDEO_STEREO_MODE_COUNT) {
+ av_log(s, AV_LOG_ERROR,
+ "The specified stereo mode is not valid.\n");
+ return AVERROR(EINVAL);
+ } else
+ put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, st_mode);
}
+
if (st->sample_aspect_ratio.num) {
int d_width = codec->width*av_q2d(st->sample_aspect_ratio);
put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width);
put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->height);
put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYUNIT, 3);
}
+
+ if (codec->codec_id == CODEC_ID_RAWVIDEO) {
+ uint32_t color_space = av_le2ne32(codec->codec_tag);
+ put_ebml_binary(pb, MATROSKA_ID_VIDEOCOLORSPACE, &color_space, sizeof(color_space));
+ }
end_ebml_master(pb, subinfo);
break;
@@ -753,7 +767,7 @@ static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int eleme
end_ebml_master(s->pb, targets);
while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX)))
- if (strcasecmp(t->key, "title"))
+ if (strcasecmp(t->key, "title") && strcasecmp(t->key, "stereo_mode"))
mkv_write_simpletag(s->pb, t);
end_ebml_master(s->pb, tag);
@@ -797,6 +811,68 @@ static int mkv_write_tags(AVFormatContext *s)
return 0;
}
+static int mkv_write_attachments(AVFormatContext *s)
+{
+ MatroskaMuxContext *mkv = s->priv_data;
+ AVIOContext *pb = s->pb;
+ ebml_master attachments;
+ AVLFG c;
+ int i, ret;
+
+ if (!mkv->have_attachments)
+ return 0;
+
+ av_lfg_init(&c, av_get_random_seed());
+
+ ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_ATTACHMENTS, avio_tell(pb));
+ if (ret < 0) return ret;
+
+ attachments = start_ebml_master(pb, MATROSKA_ID_ATTACHMENTS, 0);
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ ebml_master attached_file;
+ AVDictionaryEntry *t;
+ const char *mimetype = NULL;
+
+ if (st->codec->codec_type != AVMEDIA_TYPE_ATTACHMENT)
+ continue;
+
+ attached_file = start_ebml_master(pb, MATROSKA_ID_ATTACHEDFILE, 0);
+
+ if (t = av_dict_get(st->metadata, "title", NULL, 0))
+ put_ebml_string(pb, MATROSKA_ID_FILEDESC, t->value);
+ if (!(t = av_dict_get(st->metadata, "filename", NULL, 0))) {
+ av_log(s, AV_LOG_ERROR, "Attachment stream %d has no filename tag.\n", i);
+ return AVERROR(EINVAL);
+ }
+ put_ebml_string(pb, MATROSKA_ID_FILENAME, t->value);
+ if (t = av_dict_get(st->metadata, "mimetype", NULL, 0))
+ mimetype = t->value;
+ else if (st->codec->codec_id != CODEC_ID_NONE ) {
+ int i;
+ for (i = 0; ff_mkv_mime_tags[i].id != CODEC_ID_NONE; i++)
+ if (ff_mkv_mime_tags[i].id == st->codec->codec_id) {
+ mimetype = ff_mkv_mime_tags[i].str;
+ break;
+ }
+ }
+ if (!mimetype) {
+ av_log(s, AV_LOG_ERROR, "Attachment stream %d has no mimetype tag and "
+ "it cannot be deduced from the codec id.\n", i);
+ return AVERROR(EINVAL);
+ }
+
+ put_ebml_string(pb, MATROSKA_ID_FILEMIMETYPE, mimetype);
+ put_ebml_binary(pb, MATROSKA_ID_FILEDATA, st->codec->extradata, st->codec->extradata_size);
+ put_ebml_uint(pb, MATROSKA_ID_FILEUID, av_lfg_get(&c));
+ end_ebml_master(pb, attached_file);
+ }
+ end_ebml_master(pb, attachments);
+
+ return 0;
+}
+
static int mkv_write_header(AVFormatContext *s)
{
MatroskaMuxContext *mkv = s->priv_data;
@@ -870,6 +946,9 @@ static int mkv_write_header(AVFormatContext *s)
ret = mkv_write_tags(s);
if (ret < 0) return ret;
+
+ ret = mkv_write_attachments(s);
+ if (ret < 0) return ret;
}
if (!s->pb->seekable)
@@ -932,7 +1011,7 @@ static int mkv_write_ass_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *p
size -= start - data;
sscanf(data, "Dialogue: %d,", &layer);
i = snprintf(buffer, sizeof(buffer), "%"PRId64",%d,",
- s->streams[pkt->stream_index]->nb_frames++, layer);
+ s->streams[pkt->stream_index]->nb_frames, layer);
size = FFMIN(i+size, sizeof(buffer));
memcpy(buffer+i, start, size-i);
@@ -1191,53 +1270,80 @@ static int mkv_write_trailer(AVFormatContext *s)
return 0;
}
+static int mkv_query_codec(enum CodecID codec_id, int std_compliance)
+{
+ int i;
+ for (i = 0; ff_mkv_codec_tags[i].id != CODEC_ID_NONE; i++)
+ if (ff_mkv_codec_tags[i].id == codec_id)
+ return 1;
+
+ if (std_compliance < FF_COMPLIANCE_NORMAL) { // mkv theoretically supports any
+ enum AVMediaType type = avcodec_get_type(codec_id); // video/audio through VFW/ACM
+ if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)
+ return 1;
+ }
+
+ return 0;
+}
+
#if CONFIG_MATROSKA_MUXER
AVOutputFormat ff_matroska_muxer = {
- "matroska",
- NULL_IF_CONFIG_SMALL("Matroska file format"),
- "video/x-matroska",
- "mkv",
- sizeof(MatroskaMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG4,
- mkv_write_header,
- mkv_write_packet,
- mkv_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
- .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
- .subtitle_codec = CODEC_ID_TEXT,
+ .name = "matroska",
+ .long_name = NULL_IF_CONFIG_SMALL("Matroska file format"),
+ .mime_type = "video/x-matroska",
+ .extensions = "mkv",
+ .priv_data_size = sizeof(MatroskaMuxContext),
+#if CONFIG_LIBVORBIS_ENCODER
+ .audio_codec = CODEC_ID_VORBIS,
+#else
+ .audio_codec = CODEC_ID_AC3,
+#endif
+#if CONFIG_LIBX264_ENCODER
+ .video_codec = CODEC_ID_H264,
+#else
+ .video_codec = CODEC_ID_MPEG4,
+#endif
+ .write_header = mkv_write_header,
+ .write_packet = mkv_write_packet,
+ .write_trailer = mkv_write_trailer,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
+ .subtitle_codec = CODEC_ID_SSA,
+ .query_codec = mkv_query_codec,
};
#endif
#if CONFIG_WEBM_MUXER
AVOutputFormat ff_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,
+ .name = "webm",
+ .long_name = NULL_IF_CONFIG_SMALL("WebM file format"),
+ .mime_type = "video/webm",
+ .extensions = "webm",
+ .priv_data_size = sizeof(MatroskaMuxContext),
+ .audio_codec = CODEC_ID_VORBIS,
+ .video_codec = CODEC_ID_VP8,
+ .write_header = mkv_write_header,
+ .write_packet = mkv_write_packet,
+ .write_trailer = mkv_write_trailer,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
};
#endif
#if CONFIG_MATROSKA_AUDIO_MUXER
AVOutputFormat ff_matroska_audio_muxer = {
- "matroska",
- NULL_IF_CONFIG_SMALL("Matroska file format"),
- "audio/x-matroska",
- "mka",
- sizeof(MatroskaMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_NONE,
- mkv_write_header,
- mkv_write_packet,
- mkv_write_trailer,
+ .name = "matroska",
+ .long_name = NULL_IF_CONFIG_SMALL("Matroska file format"),
+ .mime_type = "audio/x-matroska",
+ .extensions = "mka",
+ .priv_data_size = sizeof(MatroskaMuxContext),
+#if CONFIG_LIBVORBIS_ENCODER
+ .audio_codec = CODEC_ID_VORBIS,
+#else
+ .audio_codec = CODEC_ID_AC3,
+#endif
+ .video_codec = CODEC_ID_NONE,
+ .write_header = mkv_write_header,
+ .write_packet = mkv_write_packet,
+ .write_trailer = mkv_write_trailer,
.flags = AVFMT_GLOBALHEADER,
- .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0},
};
#endif
diff --git a/libavformat/md5enc.c b/libavformat/md5enc.c
index 3b7d0ea8d8..512e082778 100644
--- a/libavformat/md5enc.c
+++ b/libavformat/md5enc.c
@@ -2,20 +2,20 @@
* MD5 encoder (for codec/format testing)
* Copyright (c) 2009 Reimar Döffinger, based on crcenc (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -66,16 +66,15 @@ static int write_trailer(struct AVFormatContext *s)
}
AVOutputFormat ff_md5_muxer = {
- "md5",
- NULL_IF_CONFIG_SMALL("MD5 testing format"),
- NULL,
- "",
- PRIVSIZE,
- CODEC_ID_PCM_S16LE,
- CODEC_ID_RAWVIDEO,
- write_header,
- write_packet,
- write_trailer,
+ .name = "md5",
+ .long_name = NULL_IF_CONFIG_SMALL("MD5 testing format"),
+ .extensions = "",
+ .priv_data_size = PRIVSIZE,
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_header = write_header,
+ .write_packet = write_packet,
+ .write_trailer = write_trailer,
};
#endif
@@ -96,15 +95,12 @@ static int framemd5_write_packet(struct AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_framemd5_muxer = {
- "framemd5",
- NULL_IF_CONFIG_SMALL("Per-frame MD5 testing format"),
- NULL,
- "",
- PRIVSIZE,
- CODEC_ID_PCM_S16LE,
- CODEC_ID_RAWVIDEO,
- NULL,
- framemd5_write_packet,
- NULL,
+ .name = "framemd5",
+ .long_name = NULL_IF_CONFIG_SMALL("Per-frame MD5 testing format"),
+ .extensions = "",
+ .priv_data_size = PRIVSIZE,
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_packet = framemd5_write_packet,
};
#endif
diff --git a/libavformat/md5proto.c b/libavformat/md5proto.c
index 4630c49f5c..3f099da440 100644
--- a/libavformat/md5proto.c
+++ b/libavformat/md5proto.c
@@ -1,20 +1,20 @@
/*
* Copyright (c) 2010 Mans Rullgard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/metadata-example.c b/libavformat/metadata-example.c
deleted file mode 100644
index 7bf77e7378..0000000000
--- a/libavformat/metadata-example.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2011 Reinhard Tartler
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/**
- * @file
- * @example libavformat/metadata-example.c
- * Shows how the metadata API can be used in application programs.
- */
-
-#include <stdio.h>
-
-#include <libavformat/avformat.h>
-#include <libavutil/dict.h>
-
-int main (int argc, char **argv)
-{
- AVFormatContext *fmt_ctx = NULL;
- AVDictionaryEntry *tag = NULL;
- int ret;
-
- if (argc != 2) {
- printf("usage: %s <input_file>\n"
- "example program to demonstrate the use of the libavformat metadata API.\n"
- "\n", argv[0]);
- return 1;
- }
-
- av_register_all();
- if ((ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL)))
- return ret;
-
- while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
- printf("%s=%s\n", tag->key, tag->value);
-
- avformat_free_context(fmt_ctx);
- return 0;
-}
diff --git a/libavformat/metadata.c b/libavformat/metadata.c
index d8957dfa95..e6fbe30da9 100644
--- a/libavformat/metadata.c
+++ b/libavformat/metadata.c
@@ -1,20 +1,20 @@
/*
* copyright (c) 2009 Michael Niedermayer
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/metadata.h b/libavformat/metadata.h
index 33e0d1ff6c..d826c6f144 100644
--- a/libavformat/metadata.h
+++ b/libavformat/metadata.h
@@ -1,20 +1,20 @@
/*
* copyright (c) 2009 Michael Niedermayer
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/microdvddec.c b/libavformat/microdvddec.c
new file mode 100644
index 0000000000..95c76afc8d
--- /dev/null
+++ b/libavformat/microdvddec.c
@@ -0,0 +1,129 @@
+/*
+ * MicroDVD subtitle demuxer
+ * Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org>
+ *
+ * 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 "avformat.h"
+#include "internal.h"
+#include "libavutil/intreadwrite.h"
+
+#define MAX_LINESIZE 2048
+
+
+typedef struct {
+ uint8_t lines[3][MAX_LINESIZE];
+ int64_t pos[3];
+} MicroDVDContext;
+
+
+static int microdvd_probe(AVProbeData *p)
+{
+ unsigned char c, *ptr = p->buf;
+ int i;
+
+ if (AV_RB24(ptr) == 0xEFBBBF)
+ ptr += 3; /* skip UTF-8 BOM */
+
+ for (i=0; i<3; i++) {
+ if (sscanf(ptr, "{%*d}{}%c", &c) != 1 &&
+ sscanf(ptr, "{%*d}{%*d}%c", &c) != 1 &&
+ sscanf(ptr, "{DEFAULT}{}%c", &c) != 1)
+ return 0;
+ ptr += strcspn(ptr, "\n") + 1;
+ }
+ return AVPROBE_SCORE_MAX;
+}
+
+static int microdvd_read_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+ AVRational pts_info = (AVRational){ 2997, 125 }; /* default: 23.976 fps */
+ MicroDVDContext *microdvd = s->priv_data;
+ AVStream *st = av_new_stream(s, 0);
+ int i, frame;
+ double fps;
+ char c;
+
+ if (!st)
+ return -1;
+ for (i=0; i<FF_ARRAY_ELEMS(microdvd->lines); i++) {
+ microdvd->pos[i] = avio_tell(s->pb);
+ ff_get_line(s->pb, microdvd->lines[i], sizeof(microdvd->lines[i]));
+ if ((sscanf(microdvd->lines[i], "{%d}{}%6lf", &frame, &fps) == 2 ||
+ sscanf(microdvd->lines[i], "{%d}{%*d}%6lf", &frame, &fps) == 2)
+ && frame <= 1 && fps > 3 && fps < 100)
+ pts_info = av_d2q(fps, 100000);
+ if (sscanf(microdvd->lines[i], "{DEFAULT}{}%c", &c) == 1) {
+ st->codec->extradata = av_strdup(microdvd->lines[i] + 11);
+ st->codec->extradata_size = strlen(st->codec->extradata);
+ i--;
+ }
+ }
+ av_set_pts_info(st, 64, pts_info.den, pts_info.num);
+ st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+ st->codec->codec_id = CODEC_ID_MICRODVD;
+ return 0;
+}
+
+static int64_t get_pts(const char *buf)
+{
+ int frame;
+ char c;
+
+ if (sscanf(buf, "{%d}{%c", &frame, &c) == 2)
+ return frame;
+ return AV_NOPTS_VALUE;
+}
+
+static int microdvd_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ MicroDVDContext *microdvd = s->priv_data;
+ char buffer[MAX_LINESIZE];
+ int64_t pos = avio_tell(s->pb);
+ int i, len = 0, res = AVERROR_EOF;
+
+ for (i=0; i<FF_ARRAY_ELEMS(microdvd->lines); i++) {
+ if (microdvd->lines[i][0]) {
+ strcpy(buffer, microdvd->lines[i]);
+ pos = microdvd->pos[i];
+ len = strlen(buffer);
+ microdvd->lines[i][0] = 0;
+ break;
+ }
+ }
+ if (!len)
+ len = ff_get_line(s->pb, buffer, sizeof(buffer));
+
+ if (buffer[0] && !(res = av_new_packet(pkt, len))) {
+ memcpy(pkt->data, buffer, len);
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ pkt->pos = pos;
+ pkt->pts = pkt->dts = get_pts(buffer);
+ }
+ return res;
+}
+
+AVInputFormat ff_microdvd_demuxer = {
+ .name = "microdvd",
+ .long_name = NULL_IF_CONFIG_SMALL("MicroDVD subtitle format"),
+ .priv_data_size = sizeof(MicroDVDContext),
+ .read_probe = microdvd_probe,
+ .read_header = microdvd_read_header,
+ .read_packet = microdvd_read_packet,
+ .flags = AVFMT_GENERIC_INDEX,
+};
diff --git a/libavformat/microdvdenc.c b/libavformat/microdvdenc.c
new file mode 100644
index 0000000000..b2abc547e6
--- /dev/null
+++ b/libavformat/microdvdenc.c
@@ -0,0 +1,51 @@
+/*
+ * MicroDVD subtitle muxer
+ * Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org>
+ *
+ * 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 "avformat.h"
+#include "rawenc.h"
+
+static int microdvd_write_header(struct AVFormatContext *s)
+{
+ AVCodecContext *avctx = s->streams[0]->codec;
+
+ if (s->nb_streams != 1 || avctx->codec_id != CODEC_ID_MICRODVD) {
+ av_log(s, AV_LOG_ERROR, "Exactly one MicroDVD stream is needed.\n");
+ return -1;
+ }
+
+ if (avctx->extradata && avctx->extradata_size > 0) {
+ avio_write(s->pb, "{DEFAULT}{}", 11);
+ avio_write(s->pb, avctx->extradata, avctx->extradata_size);
+ avio_flush(s->pb);
+ }
+ return 0;
+}
+
+AVOutputFormat ff_microdvd_muxer = {
+ .name = "microdvd",
+ .long_name = NULL_IF_CONFIG_SMALL("MicroDVD subtitle format"),
+ .mime_type = "text/x-microdvd",
+ .extensions = "sub",
+ .write_header = microdvd_write_header,
+ .write_packet = ff_raw_write_packet,
+ .flags = AVFMT_NOTIMESTAMPS,
+ .subtitle_codec = CODEC_ID_MICRODVD,
+};
diff --git a/libavformat/mm.c b/libavformat/mm.c
index dae659f3c6..3ad47418fc 100644
--- a/libavformat/mm.c
+++ b/libavformat/mm.c
@@ -2,20 +2,20 @@
* American Laser Games MM Format Demuxer
* Copyright (c) 2006 Peter Ross
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -105,7 +105,7 @@ static int read_header(AVFormatContext *s,
avio_skip(pb, length - 10); /* unknown data */
/* video stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -117,7 +117,7 @@ static int read_header(AVFormatContext *s,
/* audio stream */
if (length == MM_HEADER_LEN_AV) {
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -187,10 +187,10 @@ static int read_packet(AVFormatContext *s,
}
AVInputFormat ff_mm_demuxer = {
- "mm",
- NULL_IF_CONFIG_SMALL("American Laser Games MM format"),
- sizeof(MmDemuxContext),
- probe,
- read_header,
- read_packet,
+ .name = "mm",
+ .long_name = NULL_IF_CONFIG_SMALL("American Laser Games MM format"),
+ .priv_data_size = sizeof(MmDemuxContext),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
};
diff --git a/libavformat/mmf.c b/libavformat/mmf.c
index 3848d5cf56..956f567203 100644
--- a/libavformat/mmf.c
+++ b/libavformat/mmf.c
@@ -2,20 +2,20 @@
* Yamaha SMAF format
* Copyright (c) 2005 Vidar Madsen
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
@@ -241,7 +241,7 @@ static int mmf_read_header(AVFormatContext *s,
}
mmf->data_size = size;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -265,7 +265,7 @@ static int mmf_read_packet(AVFormatContext *s,
MMFContext *mmf = s->priv_data;
int ret, size;
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR(EIO);
size = MAX_SIZE;
@@ -291,27 +291,26 @@ static int mmf_read_packet(AVFormatContext *s,
#if CONFIG_MMF_DEMUXER
AVInputFormat ff_mmf_demuxer = {
- "mmf",
- NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
- sizeof(MMFContext),
- mmf_probe,
- mmf_read_header,
- mmf_read_packet,
- NULL,
- pcm_read_seek,
+ .name = "mmf",
+ .long_name = NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
+ .priv_data_size = sizeof(MMFContext),
+ .read_probe = mmf_probe,
+ .read_header = mmf_read_header,
+ .read_packet = mmf_read_packet,
+ .read_seek = pcm_read_seek,
};
#endif
#if CONFIG_MMF_MUXER
AVOutputFormat ff_mmf_muxer = {
- "mmf",
- NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
- "application/vnd.smaf",
- "mmf",
- sizeof(MMFContext),
- CODEC_ID_ADPCM_YAMAHA,
- CODEC_ID_NONE,
- mmf_write_header,
- mmf_write_packet,
- mmf_write_trailer,
+ .name = "mmf",
+ .long_name = NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
+ .mime_type = "application/vnd.smaf",
+ .extensions = "mmf",
+ .priv_data_size = sizeof(MMFContext),
+ .audio_codec = CODEC_ID_ADPCM_YAMAHA,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = mmf_write_header,
+ .write_packet = mmf_write_packet,
+ .write_trailer = mmf_write_trailer,
};
#endif
diff --git a/libavformat/mms.c b/libavformat/mms.c
index 192e7039af..46fbede90c 100644
--- a/libavformat/mms.c
+++ b/libavformat/mms.c
@@ -4,20 +4,20 @@
* Copyright (c) 2007 Björn Axelsson
* Copyright (c) 2010 Zhentan Feng <spyfeng at gmail dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mms.h"
diff --git a/libavformat/mms.h b/libavformat/mms.h
index 36e772c7f9..0117089d24 100644
--- a/libavformat/mms.h
+++ b/libavformat/mms.h
@@ -2,20 +2,20 @@
* MMS protocol common definitions.
* Copyright (c) 2010 Zhentan Feng <spyfeng at gmail dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * 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_MMS_H
diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c
index 0ce282c906..029baed211 100644
--- a/libavformat/mmsh.c
+++ b/libavformat/mmsh.c
@@ -2,20 +2,20 @@
* MMS protocol over HTTP
* Copyright (c) 2010 Zhentan Feng <spyfeng at gmail dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -243,7 +243,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags)
"Pragma: no-cache,rate=1.000000,stream-time=0,"
"stream-offset=0:0,request-context=%u,max-duration=0\r\n"
CLIENTGUID
- "Connection: Close\r\n\r\n",
+ "Connection: Close\r\n",
host, port, mmsh->request_seq++);
ff_http_set_headers(mms->mms_hd, headers);
@@ -283,7 +283,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags)
CLIENTGUID
"Pragma: stream-switch-count=%d\r\n"
"Pragma: stream-switch-entry=%s\r\n"
- "Connection: Close\r\n\r\n",
+ "Connection: Close\r\n",
host, port, mmsh->request_seq++, mms->stream_num, stream_selection);
av_freep(&stream_selection);
if (err < 0) {
diff --git a/libavformat/mmst.c b/libavformat/mmst.c
index e1904de1e2..a3db288b35 100644
--- a/libavformat/mmst.c
+++ b/libavformat/mmst.c
@@ -4,20 +4,20 @@
* Copyright (c) 2007 Björn Axelsson
* Copyright (c) 2010 Zhentan Feng <spyfeng at gmail dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -152,7 +152,7 @@ static int send_command_packet(MMSTContext *mmst)
return 0;
}
-static void mms_put_utf16(MMSContext *mms, uint8_t *src)
+static void mms_put_utf16(MMSContext *mms, const uint8_t *src)
{
AVIOContext bic;
int size = mms->write_out_ptr - mms->out_buffer;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index acde35d97e..198f3cd938 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -3,20 +3,20 @@
* Copyright (c) 2001 Fabrice Bellard
* Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -35,6 +35,7 @@
#include "riff.h"
#include "isom.h"
#include "libavcodec/get_bits.h"
+#include "id3v1.h"
#if CONFIG_ZLIB
#include <zlib.h>
@@ -81,15 +82,64 @@ typedef struct MOVParseTableEntry {
static const MOVParseTableEntry mov_default_parse_table[];
-static int mov_metadata_trkn(MOVContext *c, AVIOContext *pb, unsigned len)
+static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
+ unsigned len, const char *key)
{
char buf[16];
+ short current, total;
avio_rb16(pb); // unknown
- snprintf(buf, sizeof(buf), "%d", avio_rb16(pb));
- av_dict_set(&c->fc->metadata, "track", buf, 0);
+ current = avio_rb16(pb);
+ total = avio_rb16(pb);
+ if (!total)
+ snprintf(buf, sizeof(buf), "%d", current);
+ else
+ snprintf(buf, sizeof(buf), "%d/%d", current, total);
+ av_dict_set(&c->fc->metadata, key, buf, 0);
+
+ return 0;
+}
+
+static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
+ unsigned len, const char *key)
+{
+ char buf[16];
+
+ /* bypass padding bytes */
+ avio_r8(pb);
+ avio_r8(pb);
+ avio_r8(pb);
+
+ snprintf(buf, sizeof(buf), "%hu", avio_r8(pb));
+ av_dict_set(&c->fc->metadata, key, buf, 0);
+
+ return 0;
+}
+
+static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
+ unsigned len, const char *key)
+{
+ char buf[16];
+
+ snprintf(buf, sizeof(buf), "%hu", avio_r8(pb));
+ av_dict_set(&c->fc->metadata, key, buf, 0);
+
+ return 0;
+}
+
+static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
+ unsigned len, const char *key)
+{
+ short genre;
+ char buf[20];
- avio_rb16(pb); // total tracks
+ avio_r8(pb); // unknown
+
+ genre = avio_r8(pb);
+ if (genre < 1 || genre > ID3v1_GENRE_MAX)
+ return 0;
+ snprintf(buf, sizeof(buf), "%s", ff_id3v1_genre_str[genre-1]);
+ av_dict_set(&c->fc->metadata, key, buf, 0);
return 0;
}
@@ -140,20 +190,25 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
const char *key = NULL;
uint16_t str_size, langcode = 0;
uint32_t data_type = 0;
- int (*parse)(MOVContext*, AVIOContext*, unsigned) = NULL;
+ int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
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 = "artist"; break;
+ case MKTAG( 'a','A','R','T'): key = "album_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;
+ case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
+ case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
case MKTAG(0xa9,'c','m','t'):
case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
case MKTAG(0xa9,'a','l','b'): key = "album"; break;
case MKTAG(0xa9,'d','a','y'): key = "date"; break;
case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
+ case MKTAG( 'g','n','r','e'): key = "genre";
+ parse = mov_metadata_gnre; break;
case MKTAG(0xa9,'t','o','o'):
case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
@@ -163,7 +218,19 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
case MKTAG( 't','v','e','n'): key = "episode_id";break;
case MKTAG( 't','v','n','n'): key = "network"; break;
case MKTAG( 't','r','k','n'): key = "track";
- parse = mov_metadata_trkn; break;
+ parse = mov_metadata_track_or_disc_number; break;
+ case MKTAG( 'd','i','s','k'): key = "disc";
+ parse = mov_metadata_track_or_disc_number; break;
+ case MKTAG( 't','v','e','s'): key = "episode_sort";
+ parse = mov_metadata_int8_bypass_padding; break;
+ case MKTAG( 't','v','s','n'): key = "season_number";
+ parse = mov_metadata_int8_bypass_padding; break;
+ case MKTAG( 's','t','i','k'): key = "media_type";
+ parse = mov_metadata_int8_no_padding; break;
+ case MKTAG( 'h','d','v','d'): key = "hd_video";
+ parse = mov_metadata_int8_no_padding; break;
+ case MKTAG( 'p','g','a','p'): key = "gapless_playback";
+ parse = mov_metadata_int8_no_padding; break;
}
if (c->itunes_metadata && atom.size > 8) {
@@ -198,7 +265,7 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
str_size = FFMIN3(sizeof(str)-1, str_size, atom.size);
if (parse)
- parse(c, pb, str_size);
+ parse(c, pb, str_size, key);
else {
if (data_type == 3 || (data_type == 0 && langcode < 0x800)) { // MAC Encoded
mov_read_mac_string(c, pb, str_size, str, sizeof(str));
@@ -246,7 +313,7 @@ static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_read(pb, str, str_len);
str[str_len] = 0;
- ff_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
+ avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
}
return 0;
}
@@ -259,11 +326,11 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (atom.size < 0)
atom.size = INT64_MAX;
- while (total_size + 8 < atom.size && !pb->eof_reached) {
+ while (total_size + 8 < atom.size && !url_feof(pb)) {
int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
a.size = atom.size;
a.type=0;
- if(atom.size >= 8) {
+ if (atom.size >= 8) {
a.size = avio_rb32(pb);
a.type = avio_rl32(pb);
}
@@ -280,7 +347,7 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
break;
}
a.size -= 8;
- if(a.size < 0)
+ if (a.size < 0)
break;
a.size = FFMIN(a.size, atom.size - total_size);
@@ -447,11 +514,11 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (type == MKTAG('v','i','d','e'))
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- else if(type == MKTAG('s','o','u','n'))
+ else if (type == MKTAG('s','o','u','n'))
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- else if(type == MKTAG('m','1','a',' '))
+ else if (type == MKTAG('m','1','a',' '))
st->codec->codec_id = CODEC_ID_MP2;
- else if(type == MKTAG('s','u','b','p'))
+ else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
avio_rb32(pb); /* component manufacture */
@@ -473,8 +540,7 @@ int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom)
avio_rb32(pb); /* version + flags */
ff_mp4_read_descr(fc, pb, &tag);
if (tag == MP4ESDescrTag) {
- avio_rb16(pb); /* ID */
- avio_r8(pb); /* priority */
+ ff_mp4_parse_es_descr(pb, NULL);
} else
avio_rb16(pb); /* ID */
@@ -549,7 +615,7 @@ static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
/* this atom contains actual media data */
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
- if(atom.size == 0) /* wrong one (MP4) */
+ if (atom.size == 0) /* wrong one (MP4) */
return 0;
c->found_mdat=1;
return 0; /* now go for moov */
@@ -703,7 +769,7 @@ static int mov_read_smi(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- if((uint64_t)atom.size > (1<<30))
+ if ((uint64_t)atom.size > (1<<30))
return -1;
// currently SVQ3 decoder expect full STSD header - so let's fake it
@@ -728,7 +794,7 @@ static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- little_endian = avio_rb16(pb);
+ little_endian = avio_rb16(pb) & 0xFF;
av_dlog(c->fc, "enda %d\n", little_endian);
if (little_endian == 1) {
switch (st->codec->codec_id) {
@@ -752,7 +818,8 @@ static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
}
/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
-static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
+ enum CodecID codec_id)
{
AVStream *st;
uint64_t size;
@@ -761,11 +828,15 @@ static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1) // will happen with jp2 files
return 0;
st= c->fc->streams[c->fc->nb_streams-1];
+
+ if (st->codec->codec_id != codec_id)
+ return 0; /* unexpected codec_id - don't mess with extradata */
+
size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE;
- if(size > INT_MAX || (uint64_t)atom.size > INT_MAX)
+ if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
return -1;
buf= av_realloc(st->codec->extradata, size);
- if(!buf)
+ if (!buf)
return -1;
st->codec->extradata= buf;
buf+= st->codec->extradata_size;
@@ -776,6 +847,27 @@ static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
+/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
+static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ return mov_read_extradata(c, pb, atom, CODEC_ID_ALAC);
+}
+
+static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ return mov_read_extradata(c, pb, atom, CODEC_ID_AVS);
+}
+
+static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ return mov_read_extradata(c, pb, atom, CODEC_ID_MJPEG);
+}
+
+static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ return mov_read_extradata(c, pb, atom, CODEC_ID_JPEG2000);
+}
+
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
@@ -784,7 +876,7 @@ static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- if((uint64_t)atom.size > (1<<30))
+ if ((uint64_t)atom.size > (1<<30))
return -1;
if (st->codec->codec_id == CODEC_ID_QDM2 || st->codec->codec_id == CODEC_ID_QDMC) {
@@ -815,7 +907,7 @@ static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- if((uint64_t)atom.size > (1<<30))
+ if ((uint64_t)atom.size > (1<<30))
return -1;
av_free(st->codec->extradata);
@@ -842,7 +934,7 @@ static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- if((uint64_t)atom.size > (1<<30))
+ if ((uint64_t)atom.size > (1<<30))
return -1;
av_free(st->codec->extradata);
@@ -871,7 +963,7 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
entries = avio_rb32(pb);
- if(entries >= UINT_MAX/sizeof(int64_t))
+ if (entries >= UINT_MAX/sizeof(int64_t))
return -1;
sc->chunk_offsets = av_malloc(entries * sizeof(int64_t));
@@ -880,10 +972,10 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sc->chunk_count = entries;
if (atom.type == MKTAG('s','t','c','o'))
- for(i=0; i<entries; i++)
+ for (i=0; i<entries; i++)
sc->chunk_offsets[i] = avio_rb32(pb);
else if (atom.type == MKTAG('c','o','6','4'))
- for(i=0; i<entries; i++)
+ for (i=0; i<entries; i++)
sc->chunk_offsets[i] = avio_rb64(pb);
else
return -1;
@@ -937,7 +1029,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
st = c->fc->streams[c->fc->nb_streams-1];
sc = st->priv_data;
- for(pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) {
+ for (pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) {
//Parsing Sample description table
enum CodecID id;
int dref_id = 1;
@@ -985,9 +1077,9 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
id = ff_codec_get_id(ff_codec_bmp_tags, format);
if (id > 0)
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- else if(st->codec->codec_type == AVMEDIA_TYPE_DATA){
+ else if (st->codec->codec_type == AVMEDIA_TYPE_DATA){
id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
- if(id > 0)
+ if (id > 0)
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
}
}
@@ -996,7 +1088,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
(format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff,
(format >> 24) & 0xff, st->codec->codec_type);
- if(st->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
+ if (st->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
unsigned int color_depth, len;
int color_greyscale;
@@ -1048,6 +1140,9 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
color_index = 255;
color_dec = 256 / (color_count - 1);
for (j = 0; j < color_count; j++) {
+ if (id == CODEC_ID_CINEPAK){
+ r = g = b = color_count - 1 - color_index;
+ }else
r = g = b = color_index;
sc->palette[j] =
(r << 16) | (g << 8) | (b);
@@ -1099,7 +1194,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
}
sc->has_palette = 1;
}
- } else if(st->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
+ } else if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
int bits_per_sample, flags;
uint16_t version = avio_rb16(pb);
@@ -1118,13 +1213,13 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
//Read QT version 1 fields. In version 0 these do not exist.
av_dlog(c->fc, "version =%d, isom =%d\n",version,c->isom);
- if(!c->isom) {
- if(version==1) {
+ if (!c->isom) {
+ if (version==1) {
sc->samples_per_frame = avio_rb32(pb);
avio_rb32(pb); /* bytes per packet */
sc->bytes_per_frame = avio_rb32(pb);
avio_rb32(pb); /* bytes per sample */
- } else if(version==2) {
+ } else if (version==2) {
avio_rb32(pb); /* sizeof struct only */
st->codec->sample_rate = av_int2dbl(avio_rb64(pb)); /* float 64 */
st->codec->channels = avio_rb32(pb);
@@ -1179,7 +1274,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
st->codec->bits_per_coded_sample = bits_per_sample;
sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
}
- } else if(st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){
+ } else if (st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){
// ttxt stsd contains display flags, justification, background
// color, fonts, and default styles, so fake an atom to read it
MOVAtom fake_atom = { .size = size - (avio_tell(pb) - start_pos) };
@@ -1189,7 +1284,18 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
st->codec->width = sc->width;
st->codec->height = sc->height;
} else {
- /* other codec type, just skip (rtp, mp4s, tmcd ...) */
+ if (st->codec->codec_tag == MKTAG('t','m','c','d')) {
+ int val;
+ avio_rb32(pb); /* reserved */
+ val = avio_rb32(pb); /* flags */
+ if (val & 1)
+ st->codec->flags2 |= CODEC_FLAG2_DROP_FRAME_TIMECODE;
+ avio_rb32(pb);
+ avio_rb32(pb);
+ st->codec->time_base.den = get_byte(pb);
+ st->codec->time_base.num = 1;
+ }
+ /* other codec type, just skip (rtp, mp4s, ...) */
avio_skip(pb, size - (avio_tell(pb) - start_pos));
}
/* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
@@ -1201,7 +1307,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
avio_skip(pb, a.size);
}
- if(st->codec->codec_type==AVMEDIA_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1)
+ if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1)
st->codec->sample_rate= sc->time_scale;
/* special codec parameters handling */
@@ -1209,7 +1315,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
#if CONFIG_DV_DEMUXER
case CODEC_ID_DVAUDIO:
c->dv_fctx = avformat_alloc_context();
- c->dv_demux = dv_init_demux(c->dv_fctx);
+ c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
if (!c->dv_demux) {
av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
return -1;
@@ -1254,6 +1360,9 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
st->codec->sample_rate = AV_RB32(st->codec->extradata+32);
}
break;
+ case CODEC_ID_AC3:
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+ break;
default:
break;
}
@@ -1290,14 +1399,14 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_dlog(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
- if(entries >= UINT_MAX / sizeof(*sc->stsc_data))
+ if (entries >= UINT_MAX / sizeof(*sc->stsc_data))
return -1;
sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));
if (!sc->stsc_data)
return AVERROR(ENOMEM);
sc->stsc_count = entries;
- for(i=0; i<entries; i++) {
+ for (i=0; i<entries; i++) {
sc->stsc_data[i].first = avio_rb32(pb);
sc->stsc_data[i].count = avio_rb32(pb);
sc->stsc_data[i].id = avio_rb32(pb);
@@ -1352,14 +1461,14 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_dlog(c->fc, "keyframe_count = %d\n", entries);
- if(entries >= UINT_MAX / sizeof(int))
+ if (entries >= UINT_MAX / sizeof(int))
return -1;
sc->keyframes = av_malloc(entries * sizeof(int));
if (!sc->keyframes)
return AVERROR(ENOMEM);
sc->keyframe_count = entries;
- for(i=0; i<entries; i++) {
+ for (i=0; i<entries; i++) {
sc->keyframes[i] = avio_rb32(pb);
//av_dlog(c->fc, "keyframes[]=%d\n", sc->keyframes[i]);
}
@@ -1427,7 +1536,7 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
init_get_bits(&gb, buf, 8*num_bytes);
- for(i=0; i<entries; i++)
+ for (i=0; i<entries; i++)
sc->sample_sizes[i] = get_bits_long(&gb, field_size);
av_free(buf);
@@ -1451,32 +1560,41 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_rb24(pb); /* flags */
entries = avio_rb32(pb);
- av_dlog(c->fc, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
+ av_dlog(c->fc, "track[%i].stts.entries = %i\n",
+ c->fc->nb_streams-1, entries);
+
+ if (!entries || entries >= UINT_MAX / sizeof(*sc->stts_data))
+ return AVERROR(EINVAL);
- if(entries >= UINT_MAX / sizeof(*sc->stts_data))
- return -1;
sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data));
if (!sc->stts_data)
return AVERROR(ENOMEM);
+
sc->stts_count = entries;
- for(i=0; i<entries; i++) {
+ for (i=0; i<entries; i++) {
int sample_duration;
int sample_count;
sample_count=avio_rb32(pb);
sample_duration = avio_rb32(pb);
+ /* sample_duration < 0 is invalid based on the spec */
+ if (sample_duration < 0) {
+ av_log(c->fc, AV_LOG_ERROR, "Invalid SampleDelta in STTS %d", sample_duration);
+ sample_duration = 1;
+ }
sc->stts_data[i].count= sample_count;
sc->stts_data[i].duration= sample_duration;
- av_dlog(c->fc, "sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
+ av_dlog(c->fc, "sample_count=%d, sample_duration=%d\n",
+ sample_count, sample_duration);
duration+=(int64_t)sample_duration*sample_count;
total_sample_count+=sample_count;
}
st->nb_frames= total_sample_count;
- if(duration)
+ if (duration)
st->duration= duration;
return 0;
}
@@ -1498,20 +1616,20 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_dlog(c->fc, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);
- if(entries >= UINT_MAX / sizeof(*sc->ctts_data))
+ if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
return -1;
sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data));
if (!sc->ctts_data)
return AVERROR(ENOMEM);
sc->ctts_count = entries;
- for(i=0; i<entries; i++) {
+ for (i=0; i<entries; i++) {
int count =avio_rb32(pb);
int duration =avio_rb32(pb);
sc->ctts_data[i].count = count;
sc->ctts_data[i].duration= duration;
- if (duration < 0)
+ if (duration < 0 && i+2<entries)
sc->dts_shift = FFMAX(sc->dts_shift, -duration);
}
@@ -1538,7 +1656,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale);
current_dts = -sc->time_offset;
if (sc->ctts_data && sc->stts_data &&
- sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) {
+ sc->ctts_data[0].duration / FFMAX(sc->stts_data[0].duration, 1) > 16) {
/* more than 16 frames delay, dts are likely wrong
this happens with files created by iMovie */
sc->wrong_dts = 1;
@@ -1588,7 +1706,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
if (keyframe)
distance = 0;
sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
- if(sc->pseudo_stream_id == -1 ||
+ if (sc->pseudo_stream_id == -1 ||
sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
AVIndexEntry *e = &st->index_entries[st->nb_index_entries++];
e->pos = current_offset;
@@ -1700,13 +1818,13 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
}
}
-static int mov_open_dref(AVIOContext **pb, char *src, MOVDref *ref)
+static int mov_open_dref(AVIOContext **pb, const char *src, MOVDref *ref)
{
/* try relative path, we do not try the absolute because it can leak information about our
system to an attacker */
if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
char filename[1024];
- char *src_path;
+ const char *src_path;
int i, l;
/* find a source dir */
@@ -1749,8 +1867,9 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
MOVStreamContext *sc;
int ret;
- st = av_new_stream(c->fc, c->fc->nb_streams);
+ st = avformat_new_stream(c->fc, NULL);
if (!st) return AVERROR(ENOMEM);
+ st->id = c->fc->nb_streams;
sc = av_mallocz(sizeof(MOVStreamContext));
if (!sc) return AVERROR(ENOMEM);
@@ -1924,6 +2043,10 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sc->width = width >> 16;
sc->height = height >> 16;
+ if (display_matrix[0][0] == -65536 && display_matrix[1][1] == -65536) {
+ av_dict_set(&st->metadata, "rotate", "180", 0);
+ }
+
// transform the display width/height according to the matrix
// skip this if the display matrix is the default identity matrix
// or if it is rotating the picture, ex iPhone 3GS
@@ -2153,9 +2276,9 @@ static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return AVERROR(ENOMEM);
}
avio_read(pb, cmov_data, cmov_len);
- if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
+ if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
goto free_and_return;
- if(ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
+ if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
goto free_and_return;
atom.type = MKTAG('m','o','o','v');
atom.size = moov_len;
@@ -2184,10 +2307,10 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_rb24(pb); /* flags */
edit_count = avio_rb32(pb); /* entries */
- if((uint64_t)edit_count*12+8 > atom.size)
+ if ((uint64_t)edit_count*12+8 > atom.size)
return -1;
- for(i=0; i<edit_count; i++){
+ for (i=0; i<edit_count; i++){
int64_t time;
int64_t duration;
if (version == 1) {
@@ -2203,7 +2326,7 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
}
}
- if(edit_count > 1)
+ if (edit_count > 1)
av_log(c->fc, AV_LOG_WARNING, "multiple edit list entries, "
"a/v desync might occur, patch welcome\n");
@@ -2211,8 +2334,17 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
+static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ if (atom.size < 16)
+ return AVERROR_INVALIDDATA;
+ avio_skip(pb, 4);
+ ff_mov_read_chan(c->fc, atom.size - 4, c->fc->streams[0]->codec);
+ return 0;
+}
+
static const MOVParseTableEntry mov_default_parse_table[] = {
-{ MKTAG('a','v','s','s'), mov_read_extradata },
+{ MKTAG('a','v','s','s'), mov_read_avss },
{ MKTAG('c','h','p','l'), mov_read_chpl },
{ MKTAG('c','o','6','4'), mov_read_stco },
{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
@@ -2221,12 +2353,12 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('e','d','t','s'), mov_read_default },
{ MKTAG('e','l','s','t'), mov_read_elst },
{ MKTAG('e','n','d','a'), mov_read_enda },
-{ MKTAG('f','i','e','l'), mov_read_extradata },
+{ MKTAG('f','i','e','l'), mov_read_fiel },
{ MKTAG('f','t','y','p'), mov_read_ftyp },
{ MKTAG('g','l','b','l'), mov_read_glbl },
{ MKTAG('h','d','l','r'), mov_read_hdlr },
{ MKTAG('i','l','s','t'), mov_read_ilst },
-{ MKTAG('j','p','2','h'), mov_read_extradata },
+{ MKTAG('j','p','2','h'), mov_read_jp2h },
{ MKTAG('m','d','a','t'), mov_read_mdat },
{ MKTAG('m','d','h','d'), mov_read_mdhd },
{ MKTAG('m','d','i','a'), mov_read_default },
@@ -2237,7 +2369,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('m','v','e','x'), mov_read_default },
{ MKTAG('m','v','h','d'), mov_read_mvhd },
{ MKTAG('S','M','I',' '), mov_read_smi }, /* Sorenson extension ??? */
-{ MKTAG('a','l','a','c'), mov_read_extradata }, /* alac specific atom */
+{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
{ MKTAG('a','v','c','C'), mov_read_glbl },
{ MKTAG('p','a','s','p'), mov_read_pasp },
{ MKTAG('s','t','b','l'), mov_read_default },
@@ -2265,6 +2397,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
{ MKTAG('w','f','e','x'), mov_read_wfex },
{ MKTAG('c','m','o','v'), mov_read_cmov },
+{ MKTAG('c','h','a','n'), mov_read_chan },
{ 0, NULL }
};
@@ -2276,7 +2409,7 @@ static int mov_probe(AVProbeData *p)
/* check file header */
offset = 0;
- for(;;) {
+ for (;;) {
/* ignore invalid offset */
if ((offset + 8) > (unsigned int)p->buf_size)
return score;
@@ -2358,17 +2491,24 @@ static void mov_read_chapters(AVFormatContext *s)
// The samples could theoretically be in any encoding if there's an encd
// atom following, but in practice are only utf-8 or utf-16, distinguished
// instead by the presence of a BOM
- ch = avio_rb16(sc->pb);
- if (ch == 0xfeff)
- avio_get_str16be(sc->pb, len, title, title_len);
- else if (ch == 0xfffe)
- avio_get_str16le(sc->pb, len, title, title_len);
- else {
- AV_WB16(title, ch);
- avio_get_str(sc->pb, len - 2, title + 2, title_len - 2);
+ if (!len) {
+ title[0] = 0;
+ } else {
+ ch = avio_rb16(sc->pb);
+ if (ch == 0xfeff)
+ avio_get_str16be(sc->pb, len, title, title_len);
+ else if (ch == 0xfffe)
+ avio_get_str16le(sc->pb, len, title, title_len);
+ else {
+ AV_WB16(title, ch);
+ if (len == 1 || len == 2)
+ title[len] = 0;
+ else
+ get_strz(sc->pb, title + 2, len - 1);
+ }
}
- ff_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
+ avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
av_freep(&title);
}
finish:
@@ -2384,7 +2524,7 @@ static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
mov->fc = s;
/* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
- if(pb->seekable)
+ if (pb->seekable)
atom.size = avio_size(pb);
else
atom.size = INT64_MAX;
@@ -2445,7 +2585,7 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
mov->found_mdat = 0;
if (s->pb->seekable||
mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 ||
- s->pb->eof_reached)
+ url_feof(s->pb))
return AVERROR_EOF;
av_dlog(s, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
goto retry;
@@ -2476,10 +2616,10 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
}
#if CONFIG_DV_DEMUXER
if (mov->dv_demux && sc->dv_audio_container) {
- dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size);
+ avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
av_free(pkt->data);
pkt->size = 0;
- ret = dv_get_packet(mov->dv_demux, pkt);
+ ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
if (ret < 0)
return ret;
}
@@ -2592,12 +2732,10 @@ static int mov_read_close(AVFormatContext *s)
av_freep(&sc->drefs);
if (sc->pb && sc->pb != s->pb)
avio_close(sc->pb);
-
- av_freep(&st->codec->palctrl);
}
if (mov->dv_demux) {
- for(i = 0; i < mov->dv_fctx->nb_streams; i++) {
+ for (i = 0; i < mov->dv_fctx->nb_streams; i++) {
av_freep(&mov->dv_fctx->streams[i]->codec);
av_freep(&mov->dv_fctx->streams[i]);
}
@@ -2611,12 +2749,12 @@ static int mov_read_close(AVFormatContext *s)
}
AVInputFormat ff_mov_demuxer = {
- "mov,mp4,m4a,3gp,3g2,mj2",
- NULL_IF_CONFIG_SMALL("QuickTime/MPEG-4/Motion JPEG 2000 format"),
- sizeof(MOVContext),
- mov_probe,
- mov_read_header,
- mov_read_packet,
- mov_read_close,
- mov_read_seek,
+ .name = "mov,mp4,m4a,3gp,3g2,mj2",
+ .long_name = NULL_IF_CONFIG_SMALL("QuickTime/MPEG-4/Motion JPEG 2000 format"),
+ .priv_data_size = sizeof(MOVContext),
+ .read_probe = mov_probe,
+ .read_header = mov_read_header,
+ .read_packet = mov_read_packet,
+ .read_close = mov_read_close,
+ .read_seek = mov_read_seek,
};
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 0de7c4d44d..1d5a96e51a 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -4,20 +4,20 @@
* 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 Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -42,17 +42,18 @@
#include <assert.h>
static const AVOption options[] = {
- { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), FF_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
- { "rtphint", "Add RTP hint tracks", 0, FF_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+ { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+ { "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
{ NULL },
};
-static const AVClass mov_muxer_class = {
- .class_name = "MOV/3GP/MP4/3G2 muxer",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
+#define MOV_CLASS(flavor)\
+static const AVClass flavor ## _muxer_class = {\
+ .class_name = #flavor " muxer",\
+ .item_name = av_default_item_name,\
+ .option = options,\
+ .version = LIBAVUTIL_VERSION_INT,\
};
//FIXME support 64 bit variant with wide placeholders
@@ -208,7 +209,7 @@ static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track)
avio_wb32(pb, 11);
ffio_wfourcc(pb, "dac3");
- init_get_bits(&gbc, track->vosData+4, track->vosLen-4);
+ init_get_bits(&gbc, track->vosData+4, (track->vosLen-4) * 8);
fscod = get_bits(&gbc, 2);
frmsizecod = get_bits(&gbc, 6);
bsid = get_bits(&gbc, 5);
@@ -266,10 +267,20 @@ static void putDescr(AVIOContext *pb, int tag, unsigned int size)
avio_w8(pb, size & 0x7F);
}
+static unsigned compute_avg_bitrate(MOVTrack *track)
+{
+ uint64_t size = 0;
+ int i;
+ for (i = 0; i < track->entry; i++)
+ size += track->cluster[i].size;
+ return size * 8 * track->timescale / track->trackDuration;
+}
+
static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
{
int64_t pos = avio_tell(pb);
int decoderSpecificInfoLen = track->vosLen ? 5+track->vosLen : 0;
+ unsigned avg_bitrate;
avio_wb32(pb, 0); // size
ffio_wfourcc(pb, "esds");
@@ -301,11 +312,10 @@ static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
avio_w8(pb, track->enc->rc_buffer_size>>(3+16)); // Buffersize DB (24 bits)
avio_wb16(pb, (track->enc->rc_buffer_size>>3)&0xFFFF); // Buffersize DB
- avio_wb32(pb, FFMAX(track->enc->bit_rate, track->enc->rc_max_rate)); // maxbitrate (FIXME should be max rate in any 1 sec window)
- if(track->enc->rc_max_rate != track->enc->rc_min_rate || track->enc->rc_min_rate==0)
- avio_wb32(pb, 0); // vbr
- else
- avio_wb32(pb, track->enc->rc_max_rate); // avg bitrate
+ avg_bitrate = compute_avg_bitrate(track);
+ // maxbitrate (FIXME should be max rate in any 1 sec window)
+ avio_wb32(pb, FFMAX3(track->enc->bit_rate, track->enc->rc_max_rate, avg_bitrate));
+ avio_wb32(pb, avg_bitrate);
if (track->vosLen) {
// DecoderSpecific info descriptor
@@ -711,7 +721,7 @@ static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
if (!tag) { // if no mac fcc found, try with Microsoft tags
tag = ff_codec_get_tag(ff_codec_bmp_tags, track->enc->codec_id);
if (tag)
- av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, "
+ av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
"the file may be unplayable!\n");
}
} else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -720,7 +730,7 @@ static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->enc->codec_id);
if (ms_tag) {
tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
- av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, "
+ av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
"the file may be unplayable!\n");
}
}
@@ -1216,7 +1226,8 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
avio_wb32(pb, 0); /* reserved */
avio_wb32(pb, 0); /* reserved */
- avio_wb32(pb, 0x0); /* reserved (Layer & Alternate group) */
+ avio_wb16(pb, 0); /* layer */
+ avio_wb16(pb, st ? st->codec->codec_type : 0); /* alternate group) */
/* Volume, only for audio */
if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
avio_wb16(pb, 0x0100);
@@ -2002,7 +2013,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
if (enc->codec_id == CODEC_ID_AMR_NB) {
/* We must find out how many AMR blocks there are in one packet */
static uint16_t packed_size[16] =
- {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 0};
+ {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
int len = 0;
while (len < size && samplesInChunk < 100) {
@@ -2032,6 +2043,10 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
/* from x264 or from bytestream h264 */
/* nal reformating needed */
size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size);
+ } else if (enc->codec_id == CODEC_ID_AAC && pkt->size > 2 &&
+ (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
+ av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n");
+ return -1;
} else {
avio_write(pb, pkt->data, size);
}
@@ -2047,7 +2062,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
}
if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) {
- trk->cluster = av_realloc(trk->cluster, (trk->entry + MOV_INDEX_CLUSTER_SIZE) * sizeof(*trk->cluster));
+ trk->cluster = av_realloc_f(trk->cluster, sizeof(*trk->cluster), (trk->entry + MOV_INDEX_CLUSTER_SIZE));
if (!trk->cluster)
return -1;
}
@@ -2102,7 +2117,7 @@ static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
track->mode = mov->mode;
track->tag = MKTAG('t','e','x','t');
track->timescale = MOV_TIMESCALE;
- track->enc = avcodec_alloc_context();
+ track->enc = avcodec_alloc_context3(NULL);
track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
for (i = 0; i < s->nb_chapters; i++) {
@@ -2129,6 +2144,7 @@ static int mov_write_header(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
MOVMuxContext *mov = s->priv_data;
+ AVDictionaryEntry *t;
int i, hint_track = 0;
if (!s->pb->seekable) {
@@ -2259,7 +2275,15 @@ static int mov_write_header(AVFormatContext *s)
}
mov_write_mdat_tag(pb, mov);
- mov->time = s->timestamp + 0x7C25B080; //1970 based -> 1904 based
+
+#if FF_API_TIMESTAMP
+ if (s->timestamp)
+ mov->time = s->timestamp;
+ else
+#endif
+ if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+ mov->time = ff_iso8601_to_unix_time(t->value);
+ mov->time += 0x7C25B080; //1970 based -> 1904 based
if (mov->chapter_track)
mov_create_chapter_track(s, mov->chapter_track);
@@ -2328,104 +2352,118 @@ static int mov_write_trailer(AVFormatContext *s)
}
#if CONFIG_MOV_MUXER
+MOV_CLASS(mov)
AVOutputFormat ff_mov_muxer = {
- "mov",
- NULL_IF_CONFIG_SMALL("MOV format"),
- NULL,
- "mov",
- sizeof(MOVMuxContext),
- CODEC_ID_AAC,
- CODEC_ID_MPEG4,
- mov_write_header,
- ff_mov_write_packet,
- mov_write_trailer,
+ .name = "mov",
+ .long_name = NULL_IF_CONFIG_SMALL("MOV format"),
+ .extensions = "mov",
+ .priv_data_size = sizeof(MOVMuxContext),
+ .audio_codec = CODEC_ID_AAC,
+#if CONFIG_LIBX264_ENCODER
+ .video_codec = CODEC_ID_H264,
+#else
+ .video_codec = CODEC_ID_MPEG4,
+#endif
+ .write_header = mov_write_header,
+ .write_packet = ff_mov_write_packet,
+ .write_trailer = mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){codec_movvideo_tags, codec_movaudio_tags, 0},
.priv_class = &mov_muxer_class,
};
#endif
#if CONFIG_TGP_MUXER
+MOV_CLASS(tgp)
AVOutputFormat ff_tgp_muxer = {
- "3gp",
- NULL_IF_CONFIG_SMALL("3GP format"),
- NULL,
- "3gp",
- sizeof(MOVMuxContext),
- CODEC_ID_AMR_NB,
- CODEC_ID_H263,
- mov_write_header,
- ff_mov_write_packet,
- mov_write_trailer,
+ .name = "3gp",
+ .long_name = NULL_IF_CONFIG_SMALL("3GP format"),
+ .extensions = "3gp",
+ .priv_data_size = sizeof(MOVMuxContext),
+ .audio_codec = CODEC_ID_AMR_NB,
+ .video_codec = CODEC_ID_H263,
+ .write_header = mov_write_header,
+ .write_packet = ff_mov_write_packet,
+ .write_trailer = mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
- .priv_class = &mov_muxer_class,
+ .priv_class = &tgp_muxer_class,
};
#endif
#if CONFIG_MP4_MUXER
+MOV_CLASS(mp4)
AVOutputFormat ff_mp4_muxer = {
- "mp4",
- NULL_IF_CONFIG_SMALL("MP4 format"),
- "application/mp4",
- "mp4",
- sizeof(MOVMuxContext),
- CODEC_ID_AAC,
- CODEC_ID_MPEG4,
- mov_write_header,
- ff_mov_write_packet,
- mov_write_trailer,
+ .name = "mp4",
+ .long_name = NULL_IF_CONFIG_SMALL("MP4 format"),
+ .mime_type = "application/mp4",
+ .extensions = "mp4",
+ .priv_data_size = sizeof(MOVMuxContext),
+ .audio_codec = CODEC_ID_AAC,
+#if CONFIG_LIBX264_ENCODER
+ .video_codec = CODEC_ID_H264,
+#else
+ .video_codec = CODEC_ID_MPEG4,
+#endif
+ .write_header = mov_write_header,
+ .write_packet = ff_mov_write_packet,
+ .write_trailer = mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
- .priv_class = &mov_muxer_class,
+ .priv_class = &mp4_muxer_class,
};
#endif
#if CONFIG_PSP_MUXER
+MOV_CLASS(psp)
AVOutputFormat ff_psp_muxer = {
- "psp",
- NULL_IF_CONFIG_SMALL("PSP MP4 format"),
- NULL,
- "mp4,psp",
- sizeof(MOVMuxContext),
- CODEC_ID_AAC,
- CODEC_ID_MPEG4,
- mov_write_header,
- ff_mov_write_packet,
- mov_write_trailer,
+ .name = "psp",
+ .long_name = NULL_IF_CONFIG_SMALL("PSP MP4 format"),
+ .extensions = "mp4,psp",
+ .priv_data_size = sizeof(MOVMuxContext),
+ .audio_codec = CODEC_ID_AAC,
+#if CONFIG_LIBX264_ENCODER
+ .video_codec = CODEC_ID_H264,
+#else
+ .video_codec = CODEC_ID_MPEG4,
+#endif
+ .write_header = mov_write_header,
+ .write_packet = ff_mov_write_packet,
+ .write_trailer = mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
- .priv_class = &mov_muxer_class,
+ .priv_class = &psp_muxer_class,
};
#endif
#if CONFIG_TG2_MUXER
+MOV_CLASS(tg2)
AVOutputFormat ff_tg2_muxer = {
- "3g2",
- NULL_IF_CONFIG_SMALL("3GP2 format"),
- NULL,
- "3g2",
- sizeof(MOVMuxContext),
- CODEC_ID_AMR_NB,
- CODEC_ID_H263,
- mov_write_header,
- ff_mov_write_packet,
- mov_write_trailer,
+ .name = "3g2",
+ .long_name = NULL_IF_CONFIG_SMALL("3GP2 format"),
+ .extensions = "3g2",
+ .priv_data_size = sizeof(MOVMuxContext),
+ .audio_codec = CODEC_ID_AMR_NB,
+ .video_codec = CODEC_ID_H263,
+ .write_header = mov_write_header,
+ .write_packet = ff_mov_write_packet,
+ .write_trailer = mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
- .priv_class = &mov_muxer_class,
+ .priv_class = &tg2_muxer_class,
};
#endif
#if CONFIG_IPOD_MUXER
+MOV_CLASS(ipod)
AVOutputFormat ff_ipod_muxer = {
- "ipod",
- NULL_IF_CONFIG_SMALL("iPod H.264 MP4 format"),
- "application/mp4",
- "m4v,m4a",
- sizeof(MOVMuxContext),
- CODEC_ID_AAC,
- CODEC_ID_H264,
- mov_write_header,
- ff_mov_write_packet,
- mov_write_trailer,
+ .name = "ipod",
+ .long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 format"),
+ .mime_type = "application/mp4",
+ .extensions = "m4v,m4a",
+ .priv_data_size = sizeof(MOVMuxContext),
+ .audio_codec = CODEC_ID_AAC,
+ .video_codec = CODEC_ID_H264,
+ .write_header = mov_write_header,
+ .write_packet = ff_mov_write_packet,
+ .write_trailer = mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){codec_ipod_tags, 0},
- .priv_class = &mov_muxer_class,
+ .priv_class = &ipod_muxer_class,
};
#endif
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 39cdb39284..610683fa6a 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -4,20 +4,20 @@
* 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 Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c
index 615714627c..8e96355abc 100644
--- a/libavformat/movenchint.c
+++ b/libavformat/movenchint.c
@@ -2,20 +2,20 @@
* MOV, 3GP, MP4 muxer RTP hinting
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -36,7 +36,7 @@ int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
track->tag = MKTAG('r','t','p',' ');
track->src_track = src_index;
- track->enc = avcodec_alloc_context();
+ track->enc = avcodec_alloc_context3(NULL);
if (!track->enc)
goto fail;
track->enc->codec_type = AVMEDIA_TYPE_DATA;
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index 70ced02218..3101bae99d 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -2,20 +2,20 @@
* MP3 demuxer
* Copyright (c) 2003 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -51,7 +51,7 @@ static int mp3_read_probe(AVProbeData *p)
for(frames = 0; buf2 < end; frames++) {
header = AV_RB32(buf2);
- fsize = ff_mpa_decode_header(&avctx, header, &sample_rate, &sample_rate, &sample_rate, &sample_rate);
+ fsize = avpriv_mpa_decode_header(&avctx, header, &sample_rate, &sample_rate, &sample_rate, &sample_rate);
if(fsize < 0)
break;
buf2 += fsize;
@@ -86,7 +86,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
if(ff_mpa_check_header(v) < 0)
return -1;
- if (ff_mpegaudio_decode_header(&c, v) == 0)
+ if (avpriv_mpegaudio_decode_header(&c, v) == 0)
vbrtag_size = c.frame_size;
if(c.layer != 3)
return -1;
@@ -110,8 +110,8 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
if(avio_rb16(s->pb) == 1) {
/* skip delay and quality */
avio_skip(s->pb, 4);
- frames = avio_rb32(s->pb);
size = avio_rb32(s->pb);
+ frames = avio_rb32(s->pb);
}
}
@@ -137,7 +137,7 @@ static int mp3_read_header(AVFormatContext *s,
AVStream *st;
int64_t off;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -174,7 +174,9 @@ static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->stream_index = 0;
if (ret <= 0) {
- return AVERROR(EIO);
+ if(ret<0)
+ return ret;
+ return AVERROR_EOF;
}
if (ret > ID3v1_TAG_SIZE &&
@@ -188,12 +190,11 @@ static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_mp3_demuxer = {
- "mp3",
- NULL_IF_CONFIG_SMALL("MPEG audio layer 2/3"),
- 0,
- mp3_read_probe,
- mp3_read_header,
- mp3_read_packet,
+ .name = "mp3",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG audio layer 2/3"),
+ .read_probe = mp3_read_probe,
+ .read_header = mp3_read_header,
+ .read_packet = mp3_read_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "mp2,mp3,m2a", /* XXX: use probe */
};
diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
index 092d16ecc1..b847350232 100644
--- a/libavformat/mp3enc.c
+++ b/libavformat/mp3enc.c
@@ -2,31 +2,39 @@
* MP3 muxer
* Copyright (c) 2003 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <strings.h>
#include "avformat.h"
+#include "avio_internal.h"
#include "id3v1.h"
#include "id3v2.h"
#include "rawenc.h"
#include "libavutil/avstring.h"
+#include "libavcodec/mpegaudio.h"
+#include "libavcodec/mpegaudiodata.h"
+#include "libavcodec/mpegaudiodecheader.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/opt.h"
+#include "libavcodec/mpegaudio.h"
+#include "libavcodec/mpegaudiodata.h"
+#include "libavcodec/mpegaudiodecheader.h"
+#include "libavformat/avio_internal.h"
#include "libavutil/dict.h"
static int id3v1_set_string(AVFormatContext *s, const char *key,
@@ -128,42 +136,64 @@ static int id3v2_put_ttag(AVFormatContext *s, const char *str1, const char *str2
return len + ID3v2_HEADER_SIZE;
}
-static int mp3_write_trailer(struct AVFormatContext *s)
+#define VBR_NUM_BAGS 400
+#define VBR_TOC_SIZE 100
+typedef struct MP3Context {
+ const AVClass *class;
+ int id3v2_version;
+ int write_id3v1;
+ int64_t frames_offset;
+ int32_t frames;
+ int32_t size;
+ uint32_t want;
+ uint32_t seen;
+ uint32_t pos;
+ uint64_t bag[VBR_NUM_BAGS];
+} MP3Context;
+
+static int mp2_write_trailer(struct AVFormatContext *s)
{
uint8_t buf[ID3v1_TAG_SIZE];
+ MP3Context *mp3 = s->priv_data;
/* write the id3v1 tag */
- if (id3v1_create_tag(s, buf) > 0) {
+ if (mp3 && mp3->write_id3v1 && id3v1_create_tag(s, buf) > 0) {
avio_write(s->pb, buf, ID3v1_TAG_SIZE);
- avio_flush(s->pb);
}
+
+ /* write number of frames */
+ if (mp3 && mp3->frames_offset) {
+ avio_seek(s->pb, mp3->frames_offset, SEEK_SET);
+ avio_wb32(s->pb, s->streams[0]->nb_frames);
+ avio_seek(s->pb, 0, SEEK_END);
+ }
+
+ avio_flush(s->pb);
+
return 0;
}
#if CONFIG_MP2_MUXER
AVOutputFormat ff_mp2_muxer = {
- "mp2",
- NULL_IF_CONFIG_SMALL("MPEG audio layer 2"),
- "audio/x-mpeg",
- "mp2,m2a",
- 0,
- CODEC_ID_MP2,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
- mp3_write_trailer,
+ .name = "mp2",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG audio layer 2"),
+ .mime_type = "audio/x-mpeg",
+ .extensions = "mp2,m2a",
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
+ .write_trailer = mp2_write_trailer,
+ .flags = AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_MP3_MUXER
-typedef struct MP3Context {
- const AVClass *class;
- int id3v2_version;
-} MP3Context;
static const AVOption options[] = {
{ "id3v2_version", "Select ID3v2 version to write. Currently 3 and 4 are supported.",
- offsetof(MP3Context, id3v2_version), FF_OPT_TYPE_INT, {.dbl = 4}, 3, 4, AV_OPT_FLAG_ENCODING_PARAM},
+ offsetof(MP3Context, id3v2_version), AV_OPT_TYPE_INT, {.dbl = 4}, 3, 4, AV_OPT_FLAG_ENCODING_PARAM},
+ { "write_id3v1", "Enable ID3v1 writing. ID3v1 tags are written in UTF-8 which may not be supported by most software.",
+ offsetof(MP3Context, write_id3v1), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
{ NULL },
};
@@ -189,6 +219,143 @@ static int id3v2_check_write_tag(AVFormatContext *s, AVDictionaryEntry *t, const
return -1;
}
+static const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
+
+/*
+ * Write an empty XING header and initialize respective data.
+ */
+static int mp3_write_xing(AVFormatContext *s)
+{
+ AVCodecContext *codec = s->streams[0]->codec;
+ MP3Context *mp3 = s->priv_data;
+ int bitrate_idx = 3;
+ int64_t xing_offset;
+ int32_t mask, header;
+ MPADecodeHeader c;
+ int srate_idx, i, channels;
+ int needed;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++)
+ if (avpriv_mpa_freq_tab[i] == codec->sample_rate) {
+ srate_idx = i;
+ break;
+ }
+ if (i == FF_ARRAY_ELEMS(avpriv_mpa_freq_tab)) {
+ av_log(s, AV_LOG_ERROR, "Unsupported sample rate.\n");
+ return -1;
+ }
+
+ switch (codec->channels) {
+ case 1: channels = MPA_MONO; break;
+ case 2: channels = MPA_STEREO; break;
+ default: av_log(s, AV_LOG_ERROR, "Unsupported number of channels.\n"); return -1;
+ }
+
+ /* dummy MPEG audio header */
+ header = 0xff << 24; // sync
+ header |= (0x7 << 5 | 0x3 << 3 | 0x1 << 1 | 0x1) << 16; // sync/mpeg-1/layer 3/no crc*/
+ header |= (srate_idx << 2) << 8;
+ header |= channels << 6;
+
+ for (;;) {
+ if (15 == bitrate_idx)
+ return -1;
+
+ mask = (bitrate_idx << 4) << 8;
+ header |= mask;
+ avpriv_mpegaudio_decode_header(&c, header);
+ xing_offset=xing_offtbl[c.lsf == 1][c.nb_channels == 1];
+ needed = 4 // header
+ + xing_offset
+ + 4 // xing tag
+ + 4 // frames/size/toc flags
+ + 4 // frames
+ + 4 // size
+ + VBR_TOC_SIZE; // toc
+
+ if (needed <= c.frame_size)
+ break;
+
+ header &= ~mask;
+ ++bitrate_idx;
+ }
+
+ avio_wb32(s->pb, header);
+ ffio_fill(s->pb, 0, xing_offset);
+ avio_wb32(s->pb, MKBETAG('X', 'i', 'n', 'g'));
+ avio_wb32(s->pb, 0x01 | 0x02 | 0x04); // frames/size/toc
+
+ mp3->frames_offset = avio_tell(s->pb);
+ mp3->size = c.frame_size;
+ mp3->want=1;
+ mp3->seen=0;
+ mp3->pos=0;
+
+ avio_wb32(s->pb, 0); // frames
+ avio_wb32(s->pb, 0); // size
+
+ // toc
+ for (i = 0; i < VBR_TOC_SIZE; ++i)
+ avio_w8(s->pb, (uint8_t)(255 * i / VBR_TOC_SIZE));
+
+ ffio_fill(s->pb, 0, c.frame_size - needed);
+ avio_flush(s->pb);
+
+ return 0;
+}
+
+/*
+ * Add a frame to XING data.
+ * Following lame's "VbrTag.c".
+ */
+static void mp3_xing_add_frame(AVFormatContext *s, AVPacket *pkt)
+{
+ MP3Context *mp3 = s->priv_data;
+ int i;
+
+ ++mp3->frames;
+ mp3->size += pkt->size;
+
+ if (mp3->want == ++mp3->seen) {
+ mp3->bag[mp3->pos] = mp3->size;
+
+ if (VBR_NUM_BAGS == ++mp3->pos) {
+ /* shrink table to half size by throwing away each second bag. */
+ for (i = 1; i < VBR_NUM_BAGS; i += 2)
+ mp3->bag[i >> 1] = mp3->bag[i];
+
+ /* double wanted amount per bag. */
+ mp3->want <<= 1;
+ /* adjust current position to half of table size. */
+ mp3->pos >>= 1;
+ }
+
+ mp3->seen = 0;
+ }
+}
+
+static void mp3_fix_xing(AVFormatContext *s)
+{
+ MP3Context *mp3 = s->priv_data;
+ int i;
+
+ avio_flush(s->pb);
+ avio_seek(s->pb, mp3->frames_offset, SEEK_SET);
+ avio_wb32(s->pb, mp3->frames);
+ avio_wb32(s->pb, mp3->size);
+
+ avio_w8(s->pb, 0); // first toc entry has to be zero.
+
+ for (i = 1; i < VBR_TOC_SIZE; ++i) {
+ int j = i * mp3->pos / VBR_TOC_SIZE;
+ int seek_point = 256LL * mp3->bag[j] / mp3->size;
+ avio_w8(s->pb, FFMIN(seek_point, 255));
+ }
+
+ avio_flush(s->pb);
+ avio_seek(s->pb, 0, SEEK_END);
+}
+
/**
* Write an ID3v2 header at beginning of stream
*/
@@ -237,21 +404,74 @@ static int mp3_write_header(struct AVFormatContext *s)
id3v2_put_size(s, totlen);
avio_seek(s->pb, cur_pos, SEEK_SET);
+ if (s->pb->seekable)
+ mp3_write_xing(s);
+
+ return 0;
+}
+
+static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ if (! pkt || ! pkt->data || pkt->size < 4)
+ return ff_raw_write_packet(s, pkt);
+ else {
+ MP3Context *mp3 = s->priv_data;
+#ifdef FILTER_VBR_HEADERS
+ MPADecodeHeader c;
+ int base;
+
+ ff_mpegaudio_decode_header(&c, AV_RB32(pkt->data));
+
+ /* filter out XING and INFO headers. */
+ base = 4 + xing_offtbl[c.lsf == 1][c.nb_channels == 1];
+
+ if (base + 4 <= pkt->size) {
+ uint32_t v = AV_RB32(pkt->data + base);
+
+ if (MKBETAG('X','i','n','g') == v || MKBETAG('I','n','f','o') == v)
+ return 0;
+ }
+
+ /* filter out VBRI headers. */
+ base = 4 + 32;
+
+ if (base + 4 <= pkt->size && MKBETAG('V','B','R','I') == AV_RB32(pkt->data + base))
+ return 0;
+#endif
+
+ if (mp3->frames_offset)
+ mp3_xing_add_frame(s, pkt);
+
+ return ff_raw_write_packet(s, pkt);
+ }
+}
+
+static int mp3_write_trailer(AVFormatContext *s)
+{
+ MP3Context *mp3 = s->priv_data;
+ int ret=mp2_write_trailer(s);
+
+ if (ret < 0)
+ return ret;
+
+ if (mp3->frames_offset)
+ mp3_fix_xing(s);
+
return 0;
}
AVOutputFormat ff_mp3_muxer = {
- "mp3",
- NULL_IF_CONFIG_SMALL("MPEG audio layer 3"),
- "audio/x-mpeg",
- "mp3",
- sizeof(MP3Context),
- CODEC_ID_MP3,
- CODEC_ID_NONE,
- mp3_write_header,
- ff_raw_write_packet,
- mp3_write_trailer,
- AVFMT_NOTIMESTAMPS,
+ .name = "mp3",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG audio layer 3"),
+ .mime_type = "audio/x-mpeg",
+ .extensions = "mp3",
+ .priv_data_size = sizeof(MP3Context),
+ .audio_codec = CODEC_ID_MP3,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = mp3_write_header,
+ .write_packet = mp3_write_packet,
+ .write_trailer = mp3_write_trailer,
+ .flags = AVFMT_NOTIMESTAMPS,
.priv_class = &mp3_muxer_class,
};
#endif
diff --git a/libavformat/mpc.c b/libavformat/mpc.c
index 0aec1e81d3..f377e1f990 100644
--- a/libavformat/mpc.c
+++ b/libavformat/mpc.c
@@ -2,20 +2,20 @@
* Musepack demuxer
* Copyright (c) 2006 Konstantin Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -70,13 +70,21 @@ static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap)
av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n");
return -1;
}
- c->frames = av_malloc(c->fcount * sizeof(MPCFrame));
+ if(c->fcount){
+ c->frames = av_malloc(c->fcount * sizeof(MPCFrame));
+ if(!c->frames){
+ av_log(s, AV_LOG_ERROR, "Cannot allocate seektable\n");
+ return AVERROR(ENOMEM);
+ }
+ }else{
+ av_log(s, AV_LOG_WARNING, "Container reports no frames\n");
+ }
c->curframe = 0;
c->lastframe = -1;
c->curbits = 8;
c->frames_noted = 0;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -111,7 +119,7 @@ static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt)
int ret, size, size2, curbits, cur = c->curframe;
int64_t tmp, pos;
- if (c->curframe >= c->fcount)
+ if (c->curframe >= c->fcount && c->fcount)
return -1;
if(c->curframe != c->lastframe + 1){
@@ -133,7 +141,7 @@ static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt)
avio_seek(s->pb, pos, SEEK_SET);
size = ((size2 + curbits + 31) & ~31) >> 3;
- if(cur == c->frames_noted){
+ if(cur == c->frames_noted && c->fcount){
c->frames[cur].pos = pos;
c->frames[cur].size = size;
c->frames[cur].skip = curbits - 20;
@@ -146,7 +154,7 @@ static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR(EIO);
pkt->data[0] = curbits;
- pkt->data[1] = (c->curframe > c->fcount);
+ pkt->data[1] = (c->curframe > c->fcount) && c->fcount;
pkt->data[2] = 0;
pkt->data[3] = 0;
@@ -214,13 +222,13 @@ static int mpc_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
AVInputFormat ff_mpc_demuxer = {
- "mpc",
- NULL_IF_CONFIG_SMALL("Musepack"),
- sizeof(MPCContext),
- mpc_probe,
- mpc_read_header,
- mpc_read_packet,
- mpc_read_close,
- mpc_read_seek,
+ .name = "mpc",
+ .long_name = NULL_IF_CONFIG_SMALL("Musepack"),
+ .priv_data_size = sizeof(MPCContext),
+ .read_probe = mpc_probe,
+ .read_header = mpc_read_header,
+ .read_packet = mpc_read_packet,
+ .read_close = mpc_read_close,
+ .read_seek = mpc_read_seek,
.extensions = "mpc",
};
diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c
index c4810f6eaf..22e2adcb1c 100644
--- a/libavformat/mpc8.c
+++ b/libavformat/mpc8.c
@@ -2,20 +2,20 @@
* Musepack SV8 demuxer
* Copyright (c) 2007 Konstantin Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -201,7 +201,7 @@ static int mpc8_read_header(AVFormatContext *s, AVFormatParameters *ap)
return -1;
}
- while(!pb->eof_reached){
+ while(!url_feof(pb)){
pos = avio_tell(pb);
mpc8_get_chunk_header(pb, &tag, &size);
if(tag == TAG_STREAMHDR)
@@ -222,7 +222,7 @@ static int mpc8_read_header(AVFormatContext *s, AVFormatParameters *ap)
c->samples = ffio_read_varlen(pb);
ffio_read_varlen(pb); //silence samples at the beginning
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -248,7 +248,7 @@ static int mpc8_read_packet(AVFormatContext *s, AVPacket *pkt)
int tag;
int64_t pos, size;
- while(!s->pb->eof_reached){
+ while(!url_feof(s->pb)){
pos = avio_tell(s->pb);
mpc8_get_chunk_header(s->pb, &tag, &size);
if (size < 0)
@@ -264,7 +264,7 @@ static int mpc8_read_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR(EIO);
mpc8_handle_chunk(s, tag, pos, size);
}
- return 0;
+ return AVERROR_EOF;
}
static int mpc8_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
@@ -274,19 +274,19 @@ static int mpc8_read_seek(AVFormatContext *s, int stream_index, int64_t timestam
int index = av_index_search_timestamp(st, timestamp, flags);
if(index < 0) return -1;
- avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
+ if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0)
+ return -1;
c->frame = st->index_entries[index].timestamp;
return 0;
}
AVInputFormat ff_mpc8_demuxer = {
- "mpc8",
- NULL_IF_CONFIG_SMALL("Musepack SV8"),
- sizeof(MPCContext),
- mpc8_probe,
- mpc8_read_header,
- mpc8_read_packet,
- NULL,
- mpc8_read_seek,
+ .name = "mpc8",
+ .long_name = NULL_IF_CONFIG_SMALL("Musepack SV8"),
+ .priv_data_size = sizeof(MPCContext),
+ .read_probe = mpc8_probe,
+ .read_header = mpc8_read_header,
+ .read_packet = mpc8_read_packet,
+ .read_seek = mpc8_read_seek,
};
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 496b9d45f5..5b72c93c2c 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -2,20 +2,20 @@
* MPEG1/2 demuxer
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -49,6 +49,10 @@ static int check_pes(uint8_t *p, uint8_t *end){
return pes1||pes2;
}
+static int check_pack_header(const uint8_t *buf) {
+ return (buf[1] & 0xC0) == 0x40 || (buf[1] & 0xF0) == 0x20;
+}
+
static int mpegps_probe(AVProbeData *p)
{
uint32_t code= -1;
@@ -61,14 +65,16 @@ static int mpegps_probe(AVProbeData *p)
if ((code & 0xffffff00) == 0x100) {
int len= p->buf[i+1] << 8 | p->buf[i+2];
int pes= check_pes(p->buf+i, p->buf+p->buf_size);
+ int pack = check_pack_header(p->buf+i);
if(code == SYSTEM_HEADER_START_CODE) sys++;
- else if(code == PACK_START_CODE) pspack++;
+ else if(code == PACK_START_CODE && pack) pspack++;
else if((code & 0xf0) == VIDEO_ID && pes) vid++;
// skip pes payload to avoid start code emulation for private
// and audio streams
else if((code & 0xe0) == AUDIO_ID && pes) {audio++; i+=len;}
else if(code == PRIVATE_STREAM_1 && pes) {priv1++; i+=len;}
+ else if(code == 0x1fd && pes) vid++; //VC1
else if((code & 0xf0) == VIDEO_ID && !pes) invalid++;
else if((code & 0xe0) == AUDIO_ID && !pes) invalid++;
@@ -76,7 +82,7 @@ static int mpegps_probe(AVProbeData *p)
}
}
- if(vid+audio > invalid) /* invalid VDR files nd short PES streams */
+ if(vid+audio > invalid+1) /* invalid VDR files nd short PES streams */
score= AVPROBE_SCORE_MAX/4;
//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d %d len:%d\n", sys, priv1, pspack,vid, audio, invalid, p->buf_size);
@@ -105,6 +111,7 @@ static int mpegps_read_header(AVFormatContext *s,
MpegDemuxContext *m = s->priv_data;
const char *sofdec = "Sofdec";
int v, i = 0;
+ int64_t last_pos = avio_tell(s->pb);
m->header_state = 0xff;
s->ctx_flags |= AVFMTCTX_NOHEADER;
@@ -112,12 +119,14 @@ static int mpegps_read_header(AVFormatContext *s,
m->sofdec = -1;
do {
v = avio_r8(s->pb);
- m->header_state = m->header_state << 8 | v;
m->sofdec++;
} while (v == sofdec[i] && i++ < 6);
m->sofdec = (m->sofdec == 6) ? 1 : 0;
+ if (!m->sofdec)
+ avio_seek(s->pb, last_pos, SEEK_SET);
+
/* no need to do more */
return 0;
}
@@ -141,7 +150,7 @@ static int find_next_start_code(AVIOContext *pb, int *size_ptr,
state = *header_state;
n = *size_ptr;
while (n > 0) {
- if (pb->eof_reached)
+ if (url_feof(pb))
break;
v = avio_r8(pb);
n--;
@@ -251,7 +260,7 @@ static int mpegps_read_pes_header(AVFormatContext *s,
last_sync = avio_tell(s->pb);
//printf("startcode=%x pos=0x%"PRIx64"\n", startcode, avio_tell(s->pb));
if (startcode < 0){
- if(s->pb->eof_reached)
+ if(url_feof(s->pb))
return AVERROR_EOF;
//FIXME we should remember header_state
return AVERROR(EAGAIN);
@@ -418,7 +427,8 @@ static int mpegps_read_packet(AVFormatContext *s,
{
MpegDemuxContext *m = s->priv_data;
AVStream *st;
- int len, startcode, i, es_type;
+ int len, startcode, i, es_type, ret;
+ int request_probe= 0;
enum CodecID codec_id = CODEC_ID_NONE;
enum AVMediaType type;
int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work
@@ -477,7 +487,7 @@ static int mpegps_read_packet(AVFormatContext *s,
if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
codec_id = CODEC_ID_CAVS;
else
- codec_id = CODEC_ID_PROBE;
+ request_probe= 1;
type = AVMEDIA_TYPE_VIDEO;
} else if (startcode >= 0x1c0 && startcode <= 0x1df) {
type = AVMEDIA_TYPE_AUDIO;
@@ -527,11 +537,13 @@ static int mpegps_read_packet(AVFormatContext *s,
goto redo;
}
/* no stream found: add a new stream */
- st = av_new_stream(s, startcode);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto skip;
+ st->id = startcode;
st->codec->codec_type = type;
st->codec->codec_id = codec_id;
+ st->request_probe = request_probe;
if (codec_id != CODEC_ID_PCM_S16BE)
st->need_parsing = AVSTREAM_PARSE_FULL;
found:
@@ -561,8 +573,7 @@ static int mpegps_read_packet(AVFormatContext *s,
else if (st->codec->bits_per_coded_sample == 28)
return AVERROR(EINVAL);
}
- av_new_packet(pkt, len);
- avio_read(s->pb, pkt->data, pkt->size);
+ ret = av_get_packet(s->pb, pkt, len);
pkt->pts = pts;
pkt->dts = dts;
pkt->pos = dummy_pos;
@@ -571,7 +582,7 @@ static int mpegps_read_packet(AVFormatContext *s,
pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0,
pkt->size);
- return 0;
+ return (ret < 0) ? ret : 0;
}
static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
@@ -603,14 +614,13 @@ static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
}
AVInputFormat ff_mpegps_demuxer = {
- "mpeg",
- NULL_IF_CONFIG_SMALL("MPEG-PS format"),
- sizeof(MpegDemuxContext),
- mpegps_probe,
- mpegps_read_header,
- mpegps_read_packet,
- NULL,
- NULL, //mpegps_read_seek,
- mpegps_read_dts,
+ .name = "mpeg",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-PS format"),
+ .priv_data_size = sizeof(MpegDemuxContext),
+ .read_probe = mpegps_probe,
+ .read_header = mpegps_read_header,
+ .read_packet = mpegps_read_packet,
+ .read_seek = NULL, //mpegps_read_seek,
+ .read_timestamp = mpegps_read_dts,
.flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
};
diff --git a/libavformat/mpeg.h b/libavformat/mpeg.h
index 75dddf346b..ca019c9eb2 100644
--- a/libavformat/mpeg.h
+++ b/libavformat/mpeg.h
@@ -2,20 +2,20 @@
* MPEG1/2 muxer and demuxer common defines
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
index 5859254492..817f541805 100644
--- a/libavformat/mpegenc.c
+++ b/libavformat/mpegenc.c
@@ -2,25 +2,27 @@
* MPEG1/2 muxer
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/fifo.h"
+#include "libavutil/log.h"
#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
#include "libavcodec/put_bits.h"
#include "avformat.h"
#include "mpeg.h"
@@ -56,6 +58,7 @@ typedef struct {
} StreamInfo;
typedef struct {
+ const AVClass *class;
int packet_size; /* required packet size */
int packet_number;
int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */
@@ -416,9 +419,12 @@ static int mpeg_mux_init(AVFormatContext *ctx)
video_bitrate += codec_rate;
}
+#if FF_API_MUXRATE
if(ctx->mux_rate){
s->mux_rate= (ctx->mux_rate + (8 * 50) - 1) / (8 * 50);
- } else {
+ } else
+#endif
+ if (!s->mux_rate) {
/* we increase slightly the bitrate to take into account the
headers. XXX: compute it exactly */
bitrate += bitrate*5/100;
@@ -920,7 +926,7 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
/* output data */
assert(payload_size - stuffing_size <= av_fifo_size(stream->fifo));
- av_fifo_generic_read(stream->fifo, ctx->pb, payload_size - stuffing_size, &avio_write);
+ av_fifo_generic_read(stream->fifo, ctx->pb, payload_size - stuffing_size, (void*)avio_write);
stream->bytes_to_iframe -= payload_size - stuffing_size;
}else{
payload_size=
@@ -1227,77 +1233,101 @@ static int mpeg_mux_end(AVFormatContext *ctx)
return 0;
}
+#define OFFSET(x) offsetof(MpegMuxContext, x)
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "muxrate", NULL, OFFSET(mux_rate), AV_OPT_TYPE_INT, {0}, 0, INT_MAX, E },
+ { NULL },
+};
+
+#define MPEGENC_CLASS(flavor)\
+static const AVClass flavor ## _class = {\
+ .class_name = #flavor " muxer",\
+ .item_name = av_default_item_name,\
+ .version = LIBAVUTIL_VERSION_INT,\
+ .option = options,\
+};
+
#if CONFIG_MPEG1SYSTEM_MUXER
+MPEGENC_CLASS(mpeg)
AVOutputFormat ff_mpeg1system_muxer = {
- "mpeg",
- NULL_IF_CONFIG_SMALL("MPEG-1 System format"),
- "video/mpeg",
- "mpg,mpeg",
- sizeof(MpegMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG1VIDEO,
- mpeg_mux_init,
- mpeg_mux_write_packet,
- mpeg_mux_end,
+ .name = "mpeg",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 System format"),
+ .mime_type = "video/mpeg",
+ .extensions = "mpg,mpeg",
+ .priv_data_size = sizeof(MpegMuxContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG1VIDEO,
+ .write_header = mpeg_mux_init,
+ .write_packet = mpeg_mux_write_packet,
+ .write_trailer = mpeg_mux_end,
+ .priv_class = &mpeg_class,
};
#endif
#if CONFIG_MPEG1VCD_MUXER
+MPEGENC_CLASS(vcd)
AVOutputFormat ff_mpeg1vcd_muxer = {
- "vcd",
- NULL_IF_CONFIG_SMALL("MPEG-1 System format (VCD)"),
- "video/mpeg",
- NULL,
- sizeof(MpegMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG1VIDEO,
- mpeg_mux_init,
- mpeg_mux_write_packet,
- mpeg_mux_end,
+ .name = "vcd",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 System format (VCD)"),
+ .mime_type = "video/mpeg",
+ .priv_data_size = sizeof(MpegMuxContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG1VIDEO,
+ .write_header = mpeg_mux_init,
+ .write_packet = mpeg_mux_write_packet,
+ .write_trailer = mpeg_mux_end,
+ .priv_class = &vcd_class,
};
#endif
#if CONFIG_MPEG2VOB_MUXER
+MPEGENC_CLASS(vob)
AVOutputFormat ff_mpeg2vob_muxer = {
- "vob",
- NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"),
- "video/mpeg",
- "vob",
- sizeof(MpegMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG2VIDEO,
- mpeg_mux_init,
- mpeg_mux_write_packet,
- mpeg_mux_end,
+ .name = "vob",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"),
+ .mime_type = "video/mpeg",
+ .extensions = "vob",
+ .priv_data_size = sizeof(MpegMuxContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = mpeg_mux_init,
+ .write_packet = mpeg_mux_write_packet,
+ .write_trailer = mpeg_mux_end,
+ .priv_class = &vob_class,
};
#endif
/* Same as mpeg2vob_mux except that the pack size is 2324 */
#if CONFIG_MPEG2SVCD_MUXER
+MPEGENC_CLASS(svcd)
AVOutputFormat ff_mpeg2svcd_muxer = {
- "svcd",
- NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"),
- "video/mpeg",
- "vob",
- sizeof(MpegMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG2VIDEO,
- mpeg_mux_init,
- mpeg_mux_write_packet,
- mpeg_mux_end,
+ .name = "svcd",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"),
+ .mime_type = "video/mpeg",
+ .extensions = "vob",
+ .priv_data_size = sizeof(MpegMuxContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = mpeg_mux_init,
+ .write_packet = mpeg_mux_write_packet,
+ .write_trailer = mpeg_mux_end,
+ .priv_class = &svcd_class,
};
#endif
/* Same as mpeg2vob_mux except the 'is_dvd' flag is set to produce NAV pkts */
#if CONFIG_MPEG2DVD_MUXER
+MPEGENC_CLASS(dvd)
AVOutputFormat ff_mpeg2dvd_muxer = {
- "dvd",
- NULL_IF_CONFIG_SMALL("MPEG-2 PS format (DVD VOB)"),
- "video/mpeg",
- "dvd",
- sizeof(MpegMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG2VIDEO,
- mpeg_mux_init,
- mpeg_mux_write_packet,
- mpeg_mux_end,
+ .name = "dvd",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (DVD VOB)"),
+ .mime_type = "video/mpeg",
+ .extensions = "dvd",
+ .priv_data_size = sizeof(MpegMuxContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = mpeg_mux_init,
+ .write_packet = mpeg_mux_write_packet,
+ .write_trailer = mpeg_mux_end,
+ .priv_class = &dvd_class,
};
#endif
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index f2ae567789..5000134a25 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -2,20 +2,20 @@
* MPEG2 transport stream (aka DVB) demuxer
* Copyright (c) 2002-2003 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -25,7 +25,9 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
+#include "libavutil/avassert.h"
#include "libavcodec/bytestream.h"
#include "avformat.h"
#include "mpegts.h"
@@ -125,7 +127,7 @@ struct MpegTSContext {
};
static const AVOption options[] = {
- {"compute_pcr", "Compute exact PCR for each transport stream packet.", offsetof(MpegTSContext, mpeg2ts_compute_pcr), FF_OPT_TYPE_INT,
+ {"compute_pcr", "Compute exact PCR for each transport stream packet.", offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_INT,
{.dbl = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
{ NULL },
};
@@ -163,6 +165,7 @@ typedef struct PESContext {
enum MpegTSState state;
/* used to get the format */
int data_index;
+ int flags; /**< copied to the AVPacket flags */
int total_size;
int pes_header_size;
int extended_stream_id;
@@ -220,6 +223,17 @@ static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, unsigned i
p->pids[p->nb_pids++] = pid;
}
+static void set_pcr_pid(AVFormatContext *s, unsigned int programid, unsigned int pid)
+{
+ int i;
+ for(i=0; i<s->nb_programs; i++) {
+ if(s->programs[i]->id == programid) {
+ s->programs[i]->pcr_pid = pid;
+ break;
+ }
+ }
+}
+
/**
* @brief discard_pid() decides if the pid is to be discarded according
* to caller's programs selection
@@ -512,7 +526,9 @@ static const StreamType ISO_types[] = {
{ 0x04, AVMEDIA_TYPE_AUDIO, CODEC_ID_MP3 },
{ 0x0f, AVMEDIA_TYPE_AUDIO, CODEC_ID_AAC },
{ 0x10, AVMEDIA_TYPE_VIDEO, CODEC_ID_MPEG4 },
- { 0x11, AVMEDIA_TYPE_AUDIO, CODEC_ID_AAC_LATM }, /* LATM syntax */
+ /* Makito encoder sets stream type 0x11 for AAC,
+ * so auto-detect LOAS/LATM instead of hardcoding it. */
+// { 0x11, AVMEDIA_TYPE_AUDIO, CODEC_ID_AAC_LATM }, /* LATM syntax */
{ 0x1b, AVMEDIA_TYPE_VIDEO, CODEC_ID_H264 },
{ 0xd1, AVMEDIA_TYPE_VIDEO, CODEC_ID_DIRAC },
{ 0xea, AVMEDIA_TYPE_VIDEO, CODEC_ID_VC1 },
@@ -525,6 +541,8 @@ static const StreamType HDMV_types[] = {
{ 0x82, AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS },
{ 0x83, AVMEDIA_TYPE_AUDIO, CODEC_ID_TRUEHD },
{ 0x84, AVMEDIA_TYPE_AUDIO, CODEC_ID_EAC3 },
+ { 0x85, AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS }, /* DTS HD */
+ { 0x86, AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS }, /* DTS HD MASTER*/
{ 0x90, AVMEDIA_TYPE_SUBTITLE, CODEC_ID_HDMV_PGS_SUBTITLE },
{ 0 },
};
@@ -540,6 +558,10 @@ static const StreamType REGD_types[] = {
{ MKTAG('d','r','a','c'), AVMEDIA_TYPE_VIDEO, CODEC_ID_DIRAC },
{ MKTAG('A','C','-','3'), AVMEDIA_TYPE_AUDIO, CODEC_ID_AC3 },
{ MKTAG('B','S','S','D'), AVMEDIA_TYPE_AUDIO, CODEC_ID_S302M },
+ { MKTAG('D','T','S','1'), AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS },
+ { MKTAG('D','T','S','2'), AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS },
+ { MKTAG('D','T','S','3'), AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS },
+ { MKTAG('V','C','-','1'), AVMEDIA_TYPE_VIDEO, CODEC_ID_VC1 },
{ 0 },
};
@@ -560,6 +582,7 @@ static void mpegts_find_stream_type(AVStream *st,
if (stream_type == types->stream_type) {
st->codec->codec_type = types->codec_type;
st->codec->codec_id = types->codec_id;
+ st->request_probe = 0;
return;
}
}
@@ -568,6 +591,8 @@ static void mpegts_find_stream_type(AVStream *st,
static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
uint32_t stream_type, uint32_t prog_reg_desc)
{
+ int old_codec_type= st->codec->codec_type;
+ int old_codec_id = st->codec->codec_id;
av_set_pts_info(st, 33, 1, 90000);
st->priv_data = pes;
st->codec->codec_type = AVMEDIA_TYPE_DATA;
@@ -596,12 +621,13 @@ static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
return AVERROR(ENOMEM);
memcpy(sub_pes, pes, sizeof(*sub_pes));
- sub_st = av_new_stream(pes->stream, pes->pid);
+ sub_st = avformat_new_stream(pes->stream, NULL);
if (!sub_st) {
av_free(sub_pes);
return AVERROR(ENOMEM);
}
+ sub_st->id = pes->pid;
av_set_pts_info(sub_st, 33, 1, 90000);
sub_st->priv_data = sub_pes;
sub_st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -612,6 +638,10 @@ static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
}
if (st->codec->codec_id == CODEC_ID_NONE)
mpegts_find_stream_type(st, pes->stream_type, MISC_types);
+ if (st->codec->codec_id == CODEC_ID_NONE){
+ st->codec->codec_id = old_codec_id;
+ st->codec->codec_type= old_codec_type;
+ }
return 0;
}
@@ -623,6 +653,12 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
pkt->destruct = av_destruct_packet;
pkt->data = pes->buffer;
pkt->size = pes->data_index;
+
+ if(pes->total_size != MAX_PES_PAYLOAD &&
+ pes->pes_header_size + pes->data_index != pes->total_size + 6) {
+ av_log(pes->stream, AV_LOG_WARNING, "PES packet size mismatch\n");
+ pes->flags |= AV_PKT_FLAG_CORRUPT;
+ }
memset(pkt->data+pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
// Separate out the AC3 substream from an HDMV combined TrueHD/AC3 PID
@@ -634,12 +670,14 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
pkt->dts = pes->dts;
/* store position of first TS packet of this PES packet */
pkt->pos = pes->ts_packet_pos;
+ pkt->flags = pes->flags;
/* reset pts values */
pes->pts = AV_NOPTS_VALUE;
pes->dts = AV_NOPTS_VALUE;
pes->buffer = NULL;
pes->data_index = 0;
+ pes->flags = 0;
}
/* return non zero if a packet could be constructed */
@@ -690,9 +728,10 @@ static int mpegts_push_data(MpegTSFilter *filter,
/* stream not present in PMT */
if (!pes->st) {
- pes->st = av_new_stream(ts->stream, pes->pid);
+ pes->st = avformat_new_stream(ts->stream, NULL);
if (!pes->st)
return AVERROR(ENOMEM);
+ pes->st->id = pes->pid;
mpegts_set_stream_info(pes->st, pes, 0, 0);
}
@@ -712,10 +751,10 @@ static int mpegts_push_data(MpegTSFilter *filter,
code != 0x1ff && code != 0x1f2 && /* program_stream_directory, DSMCC_stream */
code != 0x1f8) { /* ITU-T Rec. H.222.1 type E stream */
pes->state = MPEGTS_PESHEADER;
- if (pes->st->codec->codec_id == CODEC_ID_NONE) {
+ if (pes->st->codec->codec_id == CODEC_ID_NONE && !pes->st->request_probe) {
av_dlog(pes->stream, "pid=%x stream_type=%x probing\n",
pes->pid, pes->stream_type);
- pes->st->codec->codec_id = CODEC_ID_PROBE;
+ pes->st->request_probe= 1;
}
} else {
pes->state = MPEGTS_PAYLOAD;
@@ -876,9 +915,8 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size,
avio_r8(&pb);
len = ff_mp4_read_descr(s, &pb, &tag);
if (tag == MP4ESDescrTag) {
- *es_id = avio_rb16(&pb); /* ES_ID */
+ ff_mp4_parse_es_descr(&pb, es_id);
av_dlog(s, "ES_ID %#x\n", *es_id);
- avio_r8(&pb); /* priority */
len = ff_mp4_read_descr(s, &pb, &tag);
if (tag == MP4DecConfigDescrTag) {
*dec_config_descr = av_malloc(len);
@@ -992,6 +1030,9 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
stream_type == STREAM_TYPE_PRIVATE_DATA)
mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types);
break;
+ case 0x52: /* stream identifier descriptor */
+ st->stream_identifier = 1 + get8(pp, desc_end);
+ break;
default:
break;
}
@@ -1032,6 +1073,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
if (pcr_pid < 0)
return;
add_pid_to_pmt(ts, h->id, pcr_pid);
+ set_pcr_pid(ts->stream, h->id, pcr_pid);
av_dlog(ts->stream, "pcr_pid=0x%x\n", pcr_pid);
@@ -1067,7 +1109,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
// stop parsing after pmt, we found header
if (!ts->stream->nb_streams)
- ts->stop_parse = 1;
+ ts->stop_parse = 2;
for(;;) {
st = 0;
@@ -1081,14 +1123,18 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
/* now create ffmpeg stream */
if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) {
pes = ts->pids[pid]->u.pes_filter.opaque;
- if (!pes->st)
- pes->st = av_new_stream(pes->stream, pes->pid);
+ if (!pes->st) {
+ pes->st = avformat_new_stream(pes->stream, NULL);
+ st->id = pes->pid;
+ }
st = pes->st;
} else {
if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably
pes = add_pes_stream(ts, pid, pcr_pid);
- if (pes)
- st = av_new_stream(pes->stream, pes->pid);
+ if (pes) {
+ st = avformat_new_stream(pes->stream, NULL);
+ st->id = pes->pid;
+ }
}
if (!st)
@@ -1130,6 +1176,7 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
SectionHeader h1, *h = &h1;
const uint8_t *p, *p_end;
int sid, pmt_pid;
+ AVProgram *program;
av_dlog(ts->stream, "PAT:\n");
hex_dump_debug(ts->stream, (uint8_t *)section, section_len);
@@ -1141,6 +1188,8 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
if (h->tid != PAT_TID)
return;
+ ts->stream->ts_id = h->id;
+
clear_programs(ts);
for(;;) {
sid = get16(&p, p_end);
@@ -1155,7 +1204,9 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
if (sid == 0x0000) {
/* NIT info */
} else {
- av_new_program(ts->stream, sid);
+ program = av_new_program(ts->stream, sid);
+ program->program_num = sid;
+ program->pmt_pid = pmt_pid;
if (ts->pids[pmt_pid])
mpegts_close_filter(ts, ts->pids[pmt_pid]);
mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
@@ -1247,7 +1298,8 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
{
AVFormatContext *s = ts->stream;
MpegTSFilter *tss;
- int len, pid, cc, cc_ok, afc, is_start;
+ int len, pid, cc, expected_cc, cc_ok, afc, is_start, is_discontinuity,
+ has_adaptation, has_payload;
const uint8_t *p, *p_end;
int64_t pos;
@@ -1263,19 +1315,38 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
if (!tss)
return 0;
+ afc = (packet[3] >> 4) & 3;
+ if (afc == 0) /* reserved value */
+ return 0;
+ has_adaptation = afc & 2;
+ has_payload = afc & 1;
+ is_discontinuity = has_adaptation
+ && packet[4] != 0 /* with length > 0 */
+ && (packet[5] & 0x80); /* and discontinuity indicated */
+
/* continuity check (currently not used) */
cc = (packet[3] & 0xf);
- cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc));
+ expected_cc = has_payload ? (tss->last_cc + 1) & 0x0f : tss->last_cc;
+ cc_ok = pid == 0x1FFF // null packet PID
+ || is_discontinuity
+ || tss->last_cc < 0
+ || expected_cc == cc;
+
tss->last_cc = cc;
+ if (!cc_ok) {
+ av_log(ts->stream, AV_LOG_DEBUG,
+ "Continuity check failed for pid %d expected %d got %d\n",
+ pid, expected_cc, cc);
+ if(tss->type == MPEGTS_PES) {
+ PESContext *pc = tss->u.pes_filter.opaque;
+ pc->flags |= AV_PKT_FLAG_CORRUPT;
+ }
+ }
- /* skip adaptation field */
- afc = (packet[3] >> 4) & 3;
- p = packet + 4;
- if (afc == 0) /* reserved value */
- return 0;
- if (afc == 2) /* adaptation field only */
+ if (!has_payload)
return 0;
- if (afc == 3) {
+ p = packet + 4;
+ if (has_adaptation) {
/* skip adapation field */
p += p[0] + 1;
}
@@ -1332,7 +1403,7 @@ static int mpegts_resync(AVFormatContext *s)
for(i = 0;i < MAX_RESYNC_SIZE; i++) {
c = avio_r8(pb);
- if (pb->eof_reached)
+ if (url_feof(pb))
return -1;
if (c == 0x47) {
avio_seek(pb, -1, SEEK_CUR);
@@ -1376,24 +1447,46 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
{
AVFormatContext *s = ts->stream;
uint8_t packet[TS_PACKET_SIZE];
- int packet_num, ret;
+ int packet_num, ret = 0;
+
+ if (avio_tell(s->pb) != ts->last_pos) {
+ int i;
+ av_dlog(ts->stream, "Skipping after seek\n");
+ /* seek detected, flush pes buffer */
+ for (i = 0; i < NB_PID_MAX; i++) {
+ if (ts->pids[i]) {
+ if (ts->pids[i]->type == MPEGTS_PES) {
+ PESContext *pes = ts->pids[i]->u.pes_filter.opaque;
+ av_freep(&pes->buffer);
+ pes->data_index = 0;
+ pes->state = MPEGTS_SKIP; /* skip until pes header */
+ }
+ ts->pids[i]->last_cc = -1;
+ }
+ }
+ }
ts->stop_parse = 0;
packet_num = 0;
for(;;) {
- if (ts->stop_parse>0)
- break;
packet_num++;
- if (nb_packets != 0 && packet_num >= nb_packets)
+ if (nb_packets != 0 && packet_num >= nb_packets ||
+ ts->stop_parse > 1) {
+ ret = AVERROR(EAGAIN);
break;
+ }
+ if (ts->stop_parse > 0)
+ break;
+
ret = read_packet(s, packet, ts->raw_packet_size);
if (ret != 0)
- return ret;
+ break;
ret = handle_packet(ts, packet);
if (ret != 0)
- return ret;
+ break;
}
- return 0;
+ ts->last_pos = avio_tell(s->pb);
+ return ret;
}
static int mpegts_probe(AVProbeData *p)
@@ -1460,29 +1553,20 @@ static int mpegts_read_header(AVFormatContext *s,
{
MpegTSContext *ts = s->priv_data;
AVIOContext *pb = s->pb;
- uint8_t buf[5*1024];
+ uint8_t buf[8*1024];
int len;
int64_t pos;
-#if FF_API_FORMAT_PARAMETERS
- if (ap) {
- if (ap->mpeg2ts_compute_pcr)
- ts->mpeg2ts_compute_pcr = ap->mpeg2ts_compute_pcr;
- if(ap->mpeg2ts_raw){
- av_log(s, AV_LOG_ERROR, "use mpegtsraw_demuxer!\n");
- return -1;
- }
- }
-#endif
-
- /* read the first 1024 bytes to get packet size */
+ /* read the first 8192 bytes to get packet size */
pos = avio_tell(pb);
len = avio_read(pb, buf, sizeof(buf));
if (len != sizeof(buf))
goto fail;
ts->raw_packet_size = get_packet_size(buf, sizeof(buf));
- if (ts->raw_packet_size <= 0)
- goto fail;
+ if (ts->raw_packet_size <= 0) {
+ av_log(s, AV_LOG_WARNING, "Could not detect TS packet size, defaulting to non-FEC/DVHS\n");
+ ts->raw_packet_size = TS_PACKET_SIZE;
+ }
ts->stream = s;
ts->auto_guess = 0;
@@ -1490,8 +1574,11 @@ static int mpegts_read_header(AVFormatContext *s,
/* normal demux */
/* first do a scaning to get all the services */
+ /* NOTE: We attempt to seek on non-seekable files as well, as the
+ * probe buffer usually is big enough. Only warn if the seek failed
+ * on files where the seek should work. */
if (avio_seek(pb, pos, SEEK_SET) < 0)
- av_log(s, AV_LOG_ERROR, "Unable to seek back to the start\n");
+ av_log(s, pb->seekable ? AV_LOG_ERROR : AV_LOG_INFO, "Unable to seek back to the start\n");
mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);
@@ -1514,7 +1601,7 @@ static int mpegts_read_header(AVFormatContext *s,
/* only read packets */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto fail;
av_set_pts_info(st, 60, 1, 27000000);
@@ -1611,18 +1698,6 @@ static int mpegts_read_packet(AVFormatContext *s,
MpegTSContext *ts = s->priv_data;
int ret, i;
- if (avio_tell(s->pb) != ts->last_pos) {
- /* seek detected, flush pes buffer */
- for (i = 0; i < NB_PID_MAX; i++) {
- if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) {
- PESContext *pes = ts->pids[i]->u.pes_filter.opaque;
- av_freep(&pes->buffer);
- pes->data_index = 0;
- pes->state = MPEGTS_SKIP; /* skip until pes header */
- }
- }
- }
-
ts->pkt = pkt;
ret = handle_packets(ts, 0);
if (ret < 0) {
@@ -1640,8 +1715,6 @@ static int mpegts_read_packet(AVFormatContext *s,
}
}
- ts->last_pos = avio_tell(s->pb);
-
return ret;
}
@@ -1665,36 +1738,58 @@ static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index,
int64_t pos, timestamp;
uint8_t buf[TS_PACKET_SIZE];
int pcr_l, pcr_pid = ((PESContext*)s->streams[stream_index]->priv_data)->pcr_pid;
- const int find_next= 1;
pos = ((*ppos + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47;
- if (find_next) {
- for(;;) {
- avio_seek(s->pb, pos, SEEK_SET);
- if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
+ while(pos < pos_limit) {
+ if (avio_seek(s->pb, pos, SEEK_SET) < 0)
+ return AV_NOPTS_VALUE;
+ if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
+ return AV_NOPTS_VALUE;
+ if (buf[0] != 0x47) {
+ if (mpegts_resync(s) < 0)
return AV_NOPTS_VALUE;
- if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) &&
- parse_pcr(&timestamp, &pcr_l, buf) == 0) {
- break;
- }
- pos += ts->raw_packet_size;
+ pos = url_ftell(s->pb);
+ continue;
}
- } else {
- for(;;) {
- pos -= ts->raw_packet_size;
- if (pos < 0)
- return AV_NOPTS_VALUE;
- avio_seek(s->pb, pos, SEEK_SET);
- if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
- return AV_NOPTS_VALUE;
- if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) &&
- parse_pcr(&timestamp, &pcr_l, buf) == 0) {
- break;
+ if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) &&
+ parse_pcr(&timestamp, &pcr_l, buf) == 0) {
+ *ppos = pos;
+ return timestamp;
+ }
+ pos += ts->raw_packet_size;
+ }
+
+ return AV_NOPTS_VALUE;
+}
+
+static int64_t mpegts_get_dts(AVFormatContext *s, int stream_index,
+ int64_t *ppos, int64_t pos_limit)
+{
+ MpegTSContext *ts = s->priv_data;
+ int64_t pos, timestamp;
+ pos = ((*ppos + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47;
+ ff_read_frame_flush(s);
+ if (avio_seek(s->pb, pos, SEEK_SET) < 0)
+ return AV_NOPTS_VALUE;
+ while(pos < pos_limit) {
+ int ret;
+ AVPacket pkt;
+ av_init_packet(&pkt);
+ ret= av_read_frame(s, &pkt);
+ if(ret < 0)
+ return AV_NOPTS_VALUE;
+ av_free_packet(&pkt);
+ if(pkt.dts != AV_NOPTS_VALUE && pkt.pos >= 0){
+ ff_reduce_index(s, pkt.stream_index);
+ av_add_index_entry(s->streams[pkt.stream_index], pkt.pos, pkt.dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */);
+ if(pkt.stream_index == stream_index){
+ *ppos= pkt.pos;
+ return pkt.dts;
}
}
+ pos = pkt.pos;
}
- *ppos = pos;
- return timestamp;
+ return AV_NOPTS_VALUE;
}
#ifdef USE_SYNCPOINT_SEARCH
@@ -1781,31 +1876,6 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, in
return ret;
}
-#else
-
-static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
- MpegTSContext *ts = s->priv_data;
- uint8_t buf[TS_PACKET_SIZE];
- int64_t pos;
-
- if(av_seek_frame_binary(s, stream_index, target_ts, flags) < 0)
- return -1;
-
- pos= avio_tell(s->pb);
-
- for(;;) {
- avio_seek(s->pb, pos, SEEK_SET);
- if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
- return -1;
-// pid = AV_RB16(buf + 1) & 0x1fff;
- if(buf[1] & 0x40) break;
- pos += ts->raw_packet_size;
- }
- avio_seek(s->pb, pos, SEEK_SET);
-
- return 0;
-}
-
#endif
/**************************************************************/
@@ -1822,6 +1892,9 @@ MpegTSContext *ff_mpegts_parse_open(AVFormatContext *s)
ts->raw_packet_size = TS_PACKET_SIZE;
ts->stream = s;
ts->auto_guess = 1;
+ mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);
+ mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1);
+
return ts;
}
@@ -1834,10 +1907,8 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
len1 = len;
ts->pkt = pkt;
- ts->stop_parse = 0;
for(;;) {
- if (ts->stop_parse>0)
- break;
+ ts->stop_parse = 0;
if (len < TS_PACKET_SIZE)
return -1;
if (buf[0] != 0x47) {
@@ -1847,6 +1918,8 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
handle_packet(ts, buf);
buf += TS_PACKET_SIZE;
len -= TS_PACKET_SIZE;
+ if (ts->stop_parse == 1)
+ break;
}
}
return len1 - len;
@@ -1862,15 +1935,14 @@ void ff_mpegts_parse_close(MpegTSContext *ts)
}
AVInputFormat ff_mpegts_demuxer = {
- "mpegts",
- NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
- sizeof(MpegTSContext),
- mpegts_probe,
- mpegts_read_header,
- mpegts_read_packet,
- mpegts_read_close,
- read_seek,
- mpegts_get_pcr,
+ .name = "mpegts",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
+ .priv_data_size = sizeof(MpegTSContext),
+ .read_probe = mpegts_probe,
+ .read_header = mpegts_read_header,
+ .read_packet = mpegts_read_packet,
+ .read_close = mpegts_read_close,
+ .read_timestamp = mpegts_get_dts,
.flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
#ifdef USE_SYNCPOINT_SEARCH
.read_seek2 = read_seek2,
@@ -1878,15 +1950,13 @@ AVInputFormat ff_mpegts_demuxer = {
};
AVInputFormat ff_mpegtsraw_demuxer = {
- "mpegtsraw",
- NULL_IF_CONFIG_SMALL("MPEG-2 raw transport stream format"),
- sizeof(MpegTSContext),
- NULL,
- mpegts_read_header,
- mpegts_raw_read_packet,
- mpegts_read_close,
- read_seek,
- mpegts_get_pcr,
+ .name = "mpegtsraw",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 raw transport stream format"),
+ .priv_data_size = sizeof(MpegTSContext),
+ .read_header = mpegts_read_header,
+ .read_packet = mpegts_raw_read_packet,
+ .read_close = mpegts_read_close,
+ .read_timestamp = mpegts_get_dts,
.flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
#ifdef USE_SYNCPOINT_SEARCH
.read_seek2 = read_seek2,
diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h
index 73ef2ed10a..e60329711b 100644
--- a/libavformat/mpegts.h
+++ b/libavformat/mpegts.h
@@ -2,20 +2,20 @@
* MPEG2 transport stream defines
* Copyright (c) 2003 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 83ede1d79b..fa773ebbee 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -2,20 +2,20 @@
* MPEG2 transport stream (aka DVB) muxer
* Copyright (c) 2003 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -24,6 +24,7 @@
#include "libavutil/dict.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
+#include "libavutil/avassert.h"
#include "libavcodec/mpegvideo.h"
#include "avformat.h"
#include "internal.h"
@@ -75,19 +76,24 @@ typedef struct MpegTSWrite {
int pmt_start_pid;
int start_pid;
+ int m2ts_mode;
} MpegTSWrite;
static const AVOption options[] = {
{ "mpegts_transport_stream_id", "Set transport_stream_id field.",
- offsetof(MpegTSWrite, transport_stream_id), FF_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
+ offsetof(MpegTSWrite, transport_stream_id), AV_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
{ "mpegts_original_network_id", "Set original_network_id field.",
- offsetof(MpegTSWrite, original_network_id), FF_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
+ offsetof(MpegTSWrite, original_network_id), AV_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
{ "mpegts_service_id", "Set service_id field.",
- offsetof(MpegTSWrite, service_id), FF_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
+ offsetof(MpegTSWrite, service_id), AV_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
{ "mpegts_pmt_start_pid", "Set the first pid of the PMT.",
- offsetof(MpegTSWrite, pmt_start_pid), FF_OPT_TYPE_INT, {.dbl = 0x1000 }, 0x1000, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM},
+ offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT, {.dbl = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM},
{ "mpegts_start_pid", "Set the first pid.",
- offsetof(MpegTSWrite, start_pid), FF_OPT_TYPE_INT, {.dbl = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM},
+ offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT, {.dbl = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM},
+ {"mpegts_m2ts_mode", "Enable m2ts mode.",
+ offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_INT, {.dbl = -1 },
+ -1,1, AV_OPT_FLAG_ENCODING_PARAM},
+ { "muxrate", NULL, offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT, {1}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ NULL },
};
@@ -184,7 +190,7 @@ static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
/*********************************************/
/* mpegts writer */
-#define DEFAULT_PROVIDER_NAME "Libav"
+#define DEFAULT_PROVIDER_NAME "FFmpeg"
#define DEFAULT_SERVICE_NAME "Service01"
/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
@@ -204,6 +210,7 @@ typedef struct MpegTSWriteStream {
int first_pts_check; ///< first pts check needed
int64_t payload_pts;
int64_t payload_dts;
+ int payload_flags;
uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE];
ADTSContext *adts;
} MpegTSWriteStream;
@@ -433,9 +440,28 @@ static MpegTSService *mpegts_add_service(MpegTSWrite *ts,
return service;
}
+static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
+{
+ return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) +
+ ts->first_pcr;
+}
+
+static void mpegts_prefix_m2ts_header(AVFormatContext *s)
+{
+ MpegTSWrite *ts = s->priv_data;
+ if (ts->m2ts_mode) {
+ int64_t pcr = get_pcr(s->priv_data, s->pb);
+ uint32_t tp_extra_header = pcr % 0x3fffffff;
+ tp_extra_header = AV_RB32(&tp_extra_header);
+ avio_write(s->pb, (unsigned char *) &tp_extra_header,
+ sizeof(tp_extra_header));
+ }
+}
+
static void section_write_packet(MpegTSSection *s, const uint8_t *packet)
{
AVFormatContext *ctx = s->opaque;
+ mpegts_prefix_m2ts_header(ctx);
avio_write(ctx->pb, packet, TS_PACKET_SIZE);
}
@@ -538,7 +564,10 @@ static int mpegts_write_header(AVFormatContext *s)
service->pcr_pid = ts_st->pid;
}
- ts->mux_rate = s->mux_rate ? s->mux_rate : 1;
+#if FF_API_MUXRATE
+ if (s->mux_rate)
+ ts->mux_rate = s->mux_rate;
+#endif
if (ts->mux_rate > 1) {
service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) /
@@ -583,6 +612,14 @@ static int mpegts_write_header(AVFormatContext *s)
service->pcr_packet_period,
ts->sdt_packet_period, ts->pat_packet_period);
+ if (ts->m2ts_mode == -1) {
+ if (av_match_ext(s->filename, "m2ts")) {
+ ts->m2ts_mode = 1;
+ } else {
+ ts->m2ts_mode = 0;
+ }
+ }
+
avio_flush(s->pb);
return 0;
@@ -615,13 +652,7 @@ static void retransmit_si_info(AVFormatContext *s)
}
}
-static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
-{
- return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) +
- ts->first_pcr;
-}
-
-static uint8_t* write_pcr_bits(uint8_t *buf, int64_t pcr)
+static int write_pcr_bits(uint8_t *buf, int64_t pcr)
{
int64_t pcr_low = pcr % 300, pcr_high = pcr / 300;
@@ -632,7 +663,7 @@ static uint8_t* write_pcr_bits(uint8_t *buf, int64_t pcr)
*buf++ = pcr_high << 7 | pcr_low >> 8 | 0x7e;
*buf++ = pcr_low;
- return buf;
+ return 6;
}
/* Write a single null transport stream packet */
@@ -647,6 +678,7 @@ static void mpegts_insert_null_packet(AVFormatContext *s)
*q++ = 0xff;
*q++ = 0x10;
memset(q, 0x0FF, TS_PACKET_SIZE - (q - buf));
+ mpegts_prefix_m2ts_header(s);
avio_write(s->pb, buf, TS_PACKET_SIZE);
}
@@ -668,10 +700,11 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
*q++ = 0x10; /* Adaptation flags: PCR present */
/* PCR coded into 6 bytes */
- q = write_pcr_bits(q, get_pcr(ts, s->pb));
+ q += write_pcr_bits(q, get_pcr(ts, s->pb));
/* stuffing bytes */
memset(q, 0xFF, TS_PACKET_SIZE - (q - buf));
+ mpegts_prefix_m2ts_header(s);
avio_write(s->pb, buf, TS_PACKET_SIZE);
}
@@ -689,6 +722,39 @@ static void write_pts(uint8_t *q, int fourbits, int64_t pts)
*q++ = val;
}
+/* Set an adaptation field flag in an MPEG-TS packet*/
+static void set_af_flag(uint8_t *pkt, int flag)
+{
+ // expect at least one flag to set
+ assert(flag);
+
+ if ((pkt[3] & 0x20) == 0) {
+ // no AF yet, set adaptation field flag
+ pkt[3] |= 0x20;
+ // 1 byte length, no flags
+ pkt[4] = 1;
+ pkt[5] = 0;
+ }
+ pkt[5] |= flag;
+}
+
+/* Extend the adaptation field by size bytes */
+static void extend_af(uint8_t *pkt, int size)
+{
+ // expect already existing adaptation field
+ assert(pkt[3] & 0x20);
+ pkt[4] += size;
+}
+
+/* Get a pointer to MPEG-TS payload (right after TS packet header) */
+static uint8_t *get_ts_payload_start(uint8_t *pkt)
+{
+ if (pkt[3] & 0x20)
+ return pkt + 5 + pkt[4];
+ else
+ return pkt + 4;
+}
+
/* Add a pes header to the front of payload, and segment into an integer number of
* ts packets. The final ts packet is padded using an over-sized adaptation header
* to exactly fill the last ts packet.
@@ -696,7 +762,7 @@ static void write_pts(uint8_t *q, int fourbits, int64_t pts)
*/
static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
const uint8_t *payload, int payload_size,
- int64_t pts, int64_t dts)
+ int64_t pts, int64_t dts, int key)
{
MpegTSWriteStream *ts_st = st->priv_data;
MpegTSWrite *ts = s->priv_data;
@@ -741,8 +807,17 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
*q++ = val;
*q++ = ts_st->pid;
ts_st->cc = (ts_st->cc + 1) & 0xf;
- *q++ = 0x10 | ts_st->cc | (write_pcr ? 0x20 : 0);
+ *q++ = 0x10 | ts_st->cc; // payload indicator + CC
+ if (key && is_start && pts != AV_NOPTS_VALUE) {
+ // set Random Access for key frames
+ if (ts_st->pid == ts_st->service->pcr_pid)
+ write_pcr = 1;
+ set_af_flag(buf, 0x40);
+ q = get_ts_payload_start(buf);
+ }
if (write_pcr) {
+ set_af_flag(buf, 0x10);
+ q = get_ts_payload_start(buf);
// add 11, pcr references the last byte of program clock reference base
if (ts->mux_rate > 1)
pcr = get_pcr(ts, s->pb);
@@ -750,9 +825,8 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
pcr = (dts - delay)*300;
if (dts != AV_NOPTS_VALUE && dts < pcr / 300)
av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n");
- *q++ = 7; /* AFC length */
- *q++ = 0x10; /* flags: PCR present */
- q = write_pcr_bits(q, pcr);
+ extend_af(buf, write_pcr_bits(q, pcr));
+ q = get_ts_payload_start(buf);
}
if (is_start) {
int pes_extension = 0;
@@ -867,6 +941,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
memcpy(buf + TS_PACKET_SIZE - len, payload, len);
payload += len;
payload_size -= len;
+ mpegts_prefix_m2ts_header(s);
avio_write(s->pb, buf, TS_PACKET_SIZE);
}
avio_flush(s->pb);
@@ -904,7 +979,7 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
}
do {
- p = ff_find_start_code(p, buf_end, &state);
+ p = avpriv_mpv_find_start_code(p, buf_end, &state);
//av_log(s, AV_LOG_INFO, "nal %d\n", state & 0x1f);
} while (p < buf_end && (state & 0x1f) != 9 &&
(state & 0x1f) != 5 && (state & 0x1f) != 1);
@@ -948,22 +1023,25 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
}
}
- if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
+ if (ts_st->payload_index && ts_st->payload_index + size > DEFAULT_PES_PAYLOAD_SIZE) {
+ mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
+ ts_st->payload_pts, ts_st->payload_dts,
+ ts_st->payload_flags & AV_PKT_FLAG_KEY);
+ ts_st->payload_index = 0;
+ }
+
+ if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO || size > DEFAULT_PES_PAYLOAD_SIZE) {
+ av_assert0(!ts_st->payload_index);
// for video and subtitle, write a single pes packet
- mpegts_write_pes(s, st, buf, size, pts, dts);
+ mpegts_write_pes(s, st, buf, size, pts, dts, pkt->flags & AV_PKT_FLAG_KEY);
av_free(data);
return 0;
}
- if (ts_st->payload_index + size > DEFAULT_PES_PAYLOAD_SIZE) {
- mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
- ts_st->payload_pts, ts_st->payload_dts);
- ts_st->payload_index = 0;
- }
-
if (!ts_st->payload_index) {
ts_st->payload_pts = pts;
ts_st->payload_dts = dts;
+ ts_st->payload_flags = pkt->flags;
}
memcpy(ts_st->payload + ts_st->payload_index, buf, size);
@@ -988,7 +1066,8 @@ static int mpegts_write_end(AVFormatContext *s)
ts_st = st->priv_data;
if (ts_st->payload_index > 0) {
mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
- ts_st->payload_pts, ts_st->payload_dts);
+ ts_st->payload_pts, ts_st->payload_dts,
+ ts_st->payload_flags & AV_PKT_FLAG_KEY);
}
av_freep(&ts_st->adts);
}
@@ -1006,15 +1085,15 @@ static int mpegts_write_end(AVFormatContext *s)
}
AVOutputFormat ff_mpegts_muxer = {
- "mpegts",
- NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
- "video/x-mpegts",
- "ts,m2t",
- sizeof(MpegTSWrite),
- CODEC_ID_MP2,
- CODEC_ID_MPEG2VIDEO,
- mpegts_write_header,
- mpegts_write_packet,
- mpegts_write_end,
+ .name = "mpegts",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
+ .mime_type = "video/x-mpegts",
+ .extensions = "ts,m2t,m2ts",
+ .priv_data_size = sizeof(MpegTSWrite),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = mpegts_write_header,
+ .write_packet = mpegts_write_packet,
+ .write_trailer = mpegts_write_end,
.priv_class = &mpegts_muxer_class,
};
diff --git a/libavformat/mpegvideodec.c b/libavformat/mpegvideodec.c
index 9fea117632..d38d6955e4 100644
--- a/libavformat/mpegvideodec.c
+++ b/libavformat/mpegvideodec.c
@@ -3,20 +3,20 @@
* Copyright (c) 2002-2003 Fabrice Bellard
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/mpjpeg.c b/libavformat/mpjpeg.c
index ebb57bf87c..46a98b3d44 100644
--- a/libavformat/mpjpeg.c
+++ b/libavformat/mpjpeg.c
@@ -2,20 +2,20 @@
* Multipart JPEG format
* Copyright (c) 2000, 2001, 2002, 2003 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
@@ -54,14 +54,13 @@ static int mpjpeg_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_mpjpeg_muxer = {
- "mpjpeg",
- NULL_IF_CONFIG_SMALL("MIME multipart JPEG format"),
- "multipart/x-mixed-replace;boundary=" BOUNDARY_TAG,
- "mjpg",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_MJPEG,
- mpjpeg_write_header,
- mpjpeg_write_packet,
- mpjpeg_write_trailer,
+ .name = "mpjpeg",
+ .long_name = NULL_IF_CONFIG_SMALL("MIME multipart JPEG format"),
+ .mime_type = "multipart/x-mixed-replace;boundary=" BOUNDARY_TAG,
+ .extensions = "mjpg",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_MJPEG,
+ .write_header = mpjpeg_write_header,
+ .write_packet = mpjpeg_write_packet,
+ .write_trailer = mpjpeg_write_trailer,
};
diff --git a/libavformat/msnwc_tcp.c b/libavformat/msnwc_tcp.c
index d9d8000e8b..b394b8779b 100644
--- a/libavformat/msnwc_tcp.c
+++ b/libavformat/msnwc_tcp.c
@@ -1,20 +1,20 @@
/*
* Copyright (C) 2008 Ramiro Polla
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -75,7 +75,7 @@ static int msnwc_tcp_read_header(AVFormatContext *ctx, AVFormatParameters *ap)
AVCodecContext *codec;
AVStream *st;
- st = av_new_stream(ctx, 0);
+ st = avformat_new_stream(ctx, NULL);
if(!st)
return AVERROR(ENOMEM);
@@ -88,9 +88,9 @@ static int msnwc_tcp_read_header(AVFormatContext *ctx, AVFormatParameters *ap)
/* Some files start with "connected\r\n\r\n".
* So skip until we find the first byte of struct size */
- while(avio_r8(pb) != HEADER_SIZE && !pb->eof_reached);
+ while(avio_r8(pb) != HEADER_SIZE && !url_feof(pb));
- if(pb->eof_reached) {
+ if(url_feof(pb)) {
av_log(ctx, AV_LOG_ERROR, "Could not find valid start.");
return -1;
}
@@ -131,10 +131,9 @@ static int msnwc_tcp_read_packet(AVFormatContext *ctx, AVPacket *pkt)
}
AVInputFormat ff_msnwc_tcp_demuxer = {
- "msnwctcp",
- NULL_IF_CONFIG_SMALL("MSN TCP Webcam stream"),
- 0,
- msnwc_tcp_probe,
- msnwc_tcp_read_header,
- msnwc_tcp_read_packet,
+ .name = "msnwctcp",
+ .long_name = NULL_IF_CONFIG_SMALL("MSN TCP Webcam stream"),
+ .read_probe = msnwc_tcp_probe,
+ .read_header = msnwc_tcp_read_header,
+ .read_packet = msnwc_tcp_read_packet,
};
diff --git a/libavformat/mtv.c b/libavformat/mtv.c
index 92d38e13cd..966e9bb8b0 100644
--- a/libavformat/mtv.c
+++ b/libavformat/mtv.c
@@ -2,20 +2,20 @@
* mtv demuxer
* Copyright (c) 2006 Reynaldo H. Verdejo Pinochet
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -32,8 +32,6 @@
#define MTV_HEADER_SIZE 512
#define MTV_AUDIO_PADDING_SIZE 12
#define AUDIO_SAMPLING_RATE 44100
-#define VIDEO_SID 0
-#define AUDIO_SID 1
typedef struct MTVDemuxContext {
@@ -118,7 +116,7 @@ static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap)
// video - raw rgb565
- st = av_new_stream(s, VIDEO_SID);
+ st = avformat_new_stream(s, NULL);
if(!st)
return AVERROR(ENOMEM);
@@ -134,7 +132,7 @@ static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap)
// audio - mp3
- st = av_new_stream(s, AUDIO_SID);
+ st = avformat_new_stream(s, NULL);
if(!st)
return AVERROR(ENOMEM);
@@ -171,7 +169,7 @@ static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt)
return ret;
pkt->pos -= MTV_AUDIO_PADDING_SIZE;
- pkt->stream_index = AUDIO_SID;
+ pkt->stream_index = 1;
}else
{
@@ -190,17 +188,17 @@ static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt)
for(i=0;i<mtv->img_segment_size/2;i++)
*((uint16_t *)pkt->data+i) = av_bswap16(*((uint16_t *)pkt->data+i));
#endif
- pkt->stream_index = VIDEO_SID;
+ pkt->stream_index = 0;
}
return ret;
}
AVInputFormat ff_mtv_demuxer = {
- "MTV",
- NULL_IF_CONFIG_SMALL("MTV format"),
- sizeof(MTVDemuxContext),
- mtv_probe,
- mtv_read_header,
- mtv_read_packet,
+ .name = "MTV",
+ .long_name = NULL_IF_CONFIG_SMALL("MTV format"),
+ .priv_data_size = sizeof(MTVDemuxContext),
+ .read_probe = mtv_probe,
+ .read_header = mtv_read_header,
+ .read_packet = mtv_read_packet,
};
diff --git a/libavformat/mvi.c b/libavformat/mvi.c
index 809cdf5a3b..8586d10e07 100644
--- a/libavformat/mvi.c
+++ b/libavformat/mvi.c
@@ -2,20 +2,20 @@
* Motion Pixels MVI Demuxer
* Copyright (c) 2008 Gregory Montoir (cyx@users.sourceforge.net)
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -42,11 +42,11 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
AVStream *ast, *vst;
unsigned int version, frames_count, msecs_per_frame, player_version;
- ast = av_new_stream(s, 0);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
- vst = av_new_stream(s, 0);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
@@ -124,11 +124,10 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_mvi_demuxer = {
- "mvi",
- NULL_IF_CONFIG_SMALL("Motion Pixels MVI format"),
- sizeof(MviDemuxContext),
- NULL,
- read_header,
- read_packet,
+ .name = "mvi",
+ .long_name = NULL_IF_CONFIG_SMALL("Motion Pixels MVI format"),
+ .priv_data_size = sizeof(MviDemuxContext),
+ .read_header = read_header,
+ .read_packet = read_packet,
.extensions = "mvi"
};
diff --git a/libavformat/mxf.c b/libavformat/mxf.c
index 6192368da0..b39a9b64cc 100644
--- a/libavformat/mxf.c
+++ b/libavformat/mxf.c
@@ -2,23 +2,24 @@
* MXF
* Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/common.h"
#include "mxf.h"
/**
@@ -41,6 +42,8 @@ const MXFCodecUL ff_mxf_codec_uls[] = {
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14, CODEC_ID_JPEG2000 }, /* JPEG2000 Codestream */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, CODEC_ID_RAWVIDEO }, /* Uncompressed */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x03,0x02,0x00,0x00 }, 14, CODEC_ID_DNXHD }, /* SMPTE VC-3/DNxHD */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x00,0x00 }, 14, CODEC_ID_H264 }, /* H.264/MPEG-4 AVC Intra */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x02,0x00 }, 15, CODEC_ID_V210 }, /* V210 */
/* SoundEssenceCompression */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16LE }, /* Uncompressed */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16LE },
@@ -80,7 +83,7 @@ static const struct {
{PIX_FMT_PAL8, {'P', 8 }},
};
-static const int num_pixel_layouts = sizeof(ff_mxf_pixel_layouts) / sizeof(*ff_mxf_pixel_layouts);
+static const int num_pixel_layouts = FF_ARRAY_ELEMS(ff_mxf_pixel_layouts);
int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum PixelFormat *pix_fmt)
{
diff --git a/libavformat/mxf.h b/libavformat/mxf.h
index beb66281ab..4f5d4c0d95 100644
--- a/libavformat/mxf.h
+++ b/libavformat/mxf.h
@@ -2,20 +2,20 @@
* MXF
* Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * 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_MXF_H
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index cf2bb6cc65..e1fec3dbbb 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -2,20 +2,20 @@
* MXF demuxer.
* Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -51,6 +51,34 @@
#include "avformat.h"
#include "mxf.h"
+typedef enum {
+ Header,
+ BodyPartition,
+ Footer
+} MXFPartitionType;
+
+typedef enum {
+ OP1a,
+ OP1b,
+ OP1c,
+ OP2a,
+ OP2b,
+ OP2c,
+ OP3a,
+ OP3b,
+ OP3c,
+ OPAtom,
+} MXFOP;
+
+typedef struct {
+ int closed;
+ int complete;
+ MXFPartitionType type;
+ uint64_t previous_partition;
+ int index_sid;
+ int body_sid;
+} MXFPartition;
+
typedef struct {
UID uid;
enum MXFMetadataSetType type;
@@ -126,6 +154,9 @@ typedef struct {
} MXFMetadataSet;
typedef struct {
+ MXFPartition *partitions;
+ unsigned partitions_count;
+ MXFOP op;
UID *packages_refs;
int packages_count;
MXFMetadataSet **metadata_sets;
@@ -134,6 +165,7 @@ typedef struct {
struct AVAES *aesc;
uint8_t *local_tags;
int local_tags_count;
+ uint64_t footer_partition;
} MXFContext;
enum MXFWrappingScheme {
@@ -180,7 +212,7 @@ static int64_t klv_decode_ber_length(AVIOContext *pb)
static int mxf_read_sync(AVIOContext *pb, const uint8_t *key, unsigned size)
{
int i, b;
- for (i = 0; i < size && !pb->eof_reached; i++) {
+ for (i = 0; i < size && !url_feof(pb); i++) {
b = avio_r8(pb);
if (b == key[0])
i = 0;
@@ -224,12 +256,13 @@ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt,
if (length > 61444) /* worst case PAL 1920 samples 8 channels */
return -1;
- av_new_packet(pkt, length);
- avio_read(pb, pkt->data, length);
+ length = av_get_packet(pb, pkt, length);
+ if (length < 0)
+ return length;
data_ptr = pkt->data;
end_ptr = pkt->data + length;
buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */
- for (; buf_ptr < end_ptr; ) {
+ for (; buf_ptr + st->codec->channels*4 < end_ptr; ) {
for (i = 0; i < st->codec->channels; i++) {
uint32_t sample = bytestream_get_le32(&buf_ptr);
if (st->codec->bits_per_coded_sample == 24)
@@ -239,7 +272,7 @@ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt,
}
buf_ptr += 32 - st->codec->channels*4; // always 8 channels stored SMPTE 331M
}
- pkt->size = data_ptr - pkt->data;
+ av_shrink_packet(pkt, data_ptr - pkt->data);
return 0;
}
@@ -291,12 +324,16 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv
if (memcmp(tmpbuf, checkv, 16))
av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n");
size -= 32;
- av_get_packet(pb, pkt, size);
+ size = av_get_packet(pb, pkt, size);
+ if (size < 0)
+ return size;
+ else if (size < plaintext_size)
+ return AVERROR_INVALIDDATA;
size -= plaintext_size;
if (mxf->aesc)
av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size],
&pkt->data[plaintext_size], size >> 4, ivec, 1);
- pkt->size = orig_size;
+ av_shrink_packet(pkt, orig_size);
pkt->stream_index = index;
avio_skip(pb, end - avio_tell(pb));
return 0;
@@ -306,7 +343,7 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
{
KLVPacket klv;
- while (!s->pb->eof_reached) {
+ while (!url_feof(s->pb)) {
if (klv_read_packet(&klv, s->pb) < 0)
return -1;
PRINT_KEY(s, "read packet", klv.key);
@@ -333,8 +370,11 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
return -1;
}
- } else
- av_get_packet(s->pb, pkt, klv.length);
+ } else {
+ int ret = av_get_packet(s->pb, pkt, klv.length);
+ if (ret < 0)
+ return ret;
+ }
pkt->stream_index = index;
pkt->pos = klv.offset;
return 0;
@@ -365,6 +405,80 @@ static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, U
return 0;
}
+static int mxf_read_partition_pack(void *arg, ByteIOContext *pb, int tag, int size, UID uid)
+{
+ MXFContext *mxf = arg;
+ MXFPartition *partition;
+ UID op;
+ uint64_t footer_partition;
+
+ if (mxf->partitions_count+1 >= UINT_MAX / sizeof(*mxf->partitions))
+ return AVERROR(ENOMEM);
+
+ mxf->partitions = av_realloc(mxf->partitions, (mxf->partitions_count + 1) * sizeof(*mxf->partitions));
+ if (!mxf->partitions)
+ return AVERROR(ENOMEM);
+
+ partition = &mxf->partitions[mxf->partitions_count++];
+
+ switch(uid[13]) {
+ case 2:
+ partition->type = Header;
+ break;
+ case 3:
+ partition->type = BodyPartition;
+ break;
+ case 4:
+ partition->type = Footer;
+ break;
+ default:
+ av_log(mxf->fc, AV_LOG_ERROR, "unknown partition type %i\n", uid[13]);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* consider both footers to be closed (there is only Footer and CompleteFooter) */
+ partition->closed = partition->type == Footer || !(uid[14] & 1);
+ partition->complete = uid[14] > 2;
+ avio_skip(pb, 16);
+ partition->previous_partition = avio_rb64(pb);
+ footer_partition = avio_rb64(pb);
+ avio_skip(pb, 16);
+ partition->index_sid = avio_rb32(pb);
+ avio_skip(pb, 8);
+ partition->body_sid = avio_rb32(pb);
+ avio_read(pb, op, sizeof(UID));
+
+ /* some files don'thave FooterPartition set in every partition */
+ if (footer_partition) {
+ if (mxf->footer_partition && mxf->footer_partition != footer_partition) {
+ av_log(mxf->fc, AV_LOG_ERROR, "inconsistent FooterPartition value: %li != %li\n",
+ mxf->footer_partition, footer_partition);
+ } else {
+ mxf->footer_partition = footer_partition;
+ }
+ }
+
+ av_dlog(mxf->fc, "PartitionPack: PreviousPartition = 0x%lx, "
+ "FooterPartition = 0x%lx, IndexSID = %i, BodySID = %i\n",
+ partition->previous_partition, footer_partition,
+ partition->index_sid, partition->body_sid);
+
+ if (op[12] == 1 && op[13] == 1) mxf->op = OP1a;
+ else if (op[12] == 1 && op[13] == 2) mxf->op = OP1b;
+ else if (op[12] == 1 && op[13] == 3) mxf->op = OP1c;
+ else if (op[12] == 2 && op[13] == 1) mxf->op = OP2a;
+ else if (op[12] == 2 && op[13] == 2) mxf->op = OP2b;
+ else if (op[12] == 2 && op[13] == 3) mxf->op = OP2c;
+ else if (op[12] == 3 && op[13] == 1) mxf->op = OP3a;
+ else if (op[12] == 3 && op[13] == 2) mxf->op = OP3b;
+ else if (op[12] == 3 && op[13] == 3) mxf->op = OP3c;
+ else if (op[12] == 0x10) mxf->op = OPAtom;
+ else
+ av_log(mxf->fc, AV_LOG_ERROR, "unknown operational pattern: %02xh %02xh\n", op[12], op[13]);
+
+ return 0;
+}
+
static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
{
if (mxf->metadata_sets_count+1 >= UINT_MAX / sizeof(*mxf->metadata_sets))
@@ -600,7 +714,7 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
default:
/* Private uid used by SONY C0023S01.mxf */
if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) {
- descriptor->extradata = av_malloc(size);
+ descriptor->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!descriptor->extradata)
return -1;
descriptor->extradata_size = size;
@@ -738,11 +852,12 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
if (!source_track)
continue;
- st = av_new_stream(mxf->fc, source_track->track_id);
+ st = avformat_new_stream(mxf->fc, NULL);
if (!st) {
av_log(mxf->fc, AV_LOG_ERROR, "could not allocate stream\n");
return -1;
}
+ st->id = source_track->track_id;
st->priv_data = source_track;
st->duration = component->duration;
if (st->duration == -1)
@@ -821,12 +936,12 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
/* TODO: implement CODEC_ID_RAWAUDIO */
if (st->codec->codec_id == CODEC_ID_PCM_S16LE) {
- if (descriptor->bits_per_sample == 24)
+ if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)
st->codec->codec_id = CODEC_ID_PCM_S24LE;
else if (descriptor->bits_per_sample == 32)
st->codec->codec_id = CODEC_ID_PCM_S32LE;
} else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {
- if (descriptor->bits_per_sample == 24)
+ if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)
st->codec->codec_id = CODEC_ID_PCM_S24BE;
else if (descriptor->bits_per_sample == 32)
st->codec->codec_id = CODEC_ID_PCM_S32BE;
@@ -844,6 +959,16 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
{ { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }, mxf_read_primer_pack },
+ { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }, mxf_read_partition_pack },
+ { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x02,0x00 }, mxf_read_partition_pack },
+ { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x03,0x00 }, mxf_read_partition_pack },
+ { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }, mxf_read_partition_pack },
+ { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x01,0x00 }, mxf_read_partition_pack },
+ { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x02,0x00 }, mxf_read_partition_pack },
+ { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x03,0x00 }, mxf_read_partition_pack },
+ { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }, mxf_read_partition_pack },
+ { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x02,0x00 }, mxf_read_partition_pack },
+ { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }, mxf_read_partition_pack },
{ { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_content_storage, 0, AnyType },
{ { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_source_package, sizeof(MXFPackage), SourcePackage },
{ { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_material_package, sizeof(MXFPackage), MaterialPackage },
@@ -915,7 +1040,7 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
avio_seek(s->pb, -14, SEEK_CUR);
mxf->fc = s;
- while (!s->pb->eof_reached) {
+ while (!url_feof(s->pb)) {
const MXFMetadataReadTableEntry *metadata;
if (klv_read_packet(&klv, s->pb) < 0)
@@ -934,8 +1059,11 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
int res;
if (klv.key[5] == 0x53) {
res = mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type);
- } else
- res = metadata->read(mxf, s->pb, 0, 0, NULL);
+ } else {
+ uint64_t next = avio_tell(s->pb) + klv.length;
+ res = metadata->read(mxf, s->pb, 0, 0, klv.key);
+ avio_seek(s->pb, next, SEEK_SET);
+ }
if (res < 0) {
av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
return -1;
@@ -976,6 +1104,7 @@ static int mxf_read_close(AVFormatContext *s)
}
av_freep(&mxf->metadata_sets[i]);
}
+ av_freep(&mxf->partitions);
av_freep(&mxf->metadata_sets);
av_freep(&mxf->aesc);
av_freep(&mxf->local_tags);
@@ -1010,18 +1139,19 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
if (sample_time < 0)
sample_time = 0;
seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den);
- avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET);
+ if (avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET) < 0)
+ return -1;
av_update_cur_dts(s, st, sample_time);
return 0;
}
AVInputFormat ff_mxf_demuxer = {
- "mxf",
- NULL_IF_CONFIG_SMALL("Material eXchange Format"),
- sizeof(MXFContext),
- mxf_probe,
- mxf_read_header,
- mxf_read_packet,
- mxf_read_close,
- mxf_read_seek,
+ .name = "mxf",
+ .long_name = NULL_IF_CONFIG_SMALL("Material eXchange Format"),
+ .priv_data_size = sizeof(MXFContext),
+ .read_probe = mxf_probe,
+ .read_header = mxf_read_header,
+ .read_packet = mxf_read_packet,
+ .read_close = mxf_read_close,
+ .read_seek = mxf_read_seek,
};
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 16fa0dadd1..ce71ed2e51 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -3,20 +3,20 @@
* Copyright (c) 2008 GUCAS, Zhentan Feng <spyfeng at gmail dot com>
* Copyright (c) 2008 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -35,10 +35,13 @@
#include <math.h>
#include <time.h>
+#include "libavutil/opt.h"
#include "libavutil/random_seed.h"
#include "libavcodec/bytestream.h"
+#include "libavcodec/timecode.h"
#include "audiointerleave.h"
#include "avformat.h"
+#include "internal.h"
#include "mxf.h"
static const int NTSC_samples_per_frame[] = { 1602, 1601, 1602, 1601, 1602, 0 };
@@ -170,6 +173,7 @@ static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
};
typedef struct MXFContext {
+ AVClass *av_class;
int64_t footer_partition_offset;
int essence_container_count;
AVRational time_base;
@@ -183,10 +187,9 @@ typedef struct MXFContext {
unsigned body_partitions_count;
int last_key_index; ///< index of last key frame
uint64_t duration;
+ struct ff_timecode tc;
AVStream *timecode_track;
int timecode_base; ///< rounded time code base (25 or 30)
- int timecode_start; ///< frame number computed from mpeg-2 gop header timecode
- int timecode_drop_frame; ///< time code use drop frame method frop mpeg-2 essence gop header
int edit_unit_byte_count; ///< fixed edit unit byte count
uint64_t body_offset;
uint32_t instance_number;
@@ -499,7 +502,7 @@ static void mxf_write_identification(AVFormatContext *s)
{
MXFContext *mxf = s->priv_data;
AVIOContext *pb = s->pb;
- const char *company = "Libav";
+ const char *company = "FFmpeg";
const char *product = "OP1a Muxer";
const char *version;
int length;
@@ -664,7 +667,7 @@ static void mxf_write_timecode_component(AVFormatContext *s, AVStream *st, enum
// Start Time Code
mxf_write_local_tag(pb, 8, 0x1501);
- avio_wb64(pb, mxf->timecode_start);
+ avio_wb64(pb, mxf->tc.start);
// Rounded Time Code Base
mxf_write_local_tag(pb, 2, 0x1502);
@@ -672,7 +675,7 @@ static void mxf_write_timecode_component(AVFormatContext *s, AVStream *st, enum
// Drop Frame
mxf_write_local_tag(pb, 1, 0x1503);
- avio_w8(pb, mxf->timecode_drop_frame);
+ avio_w8(pb, mxf->tc.drop);
}
static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
@@ -1284,6 +1287,8 @@ static const UID mxf_mpeg2_codec_uls[] = {
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, // MP-HL Long GOP
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, // 422P-HL I-Frame
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 }, // 422P-HL Long GOP
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x02,0x00 }, // MP@H-14 I-Frame
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x03,0x00 }, // MP@H-14 Long GOP
};
static const UID *mxf_get_mpeg2_codec_ul(AVCodecContext *avctx)
@@ -1295,6 +1300,8 @@ static const UID *mxf_get_mpeg2_codec_ul(AVCodecContext *avctx)
return &mxf_mpeg2_codec_uls[0+long_gop];
else if (avctx->level == 4) // High
return &mxf_mpeg2_codec_uls[4+long_gop];
+ else if (avctx->level == 6) // High 14
+ return &mxf_mpeg2_codec_uls[8+long_gop];
} else if (avctx->profile == 0) { // 422
if (avctx->level == 5) // Main
return &mxf_mpeg2_codec_uls[2+long_gop];
@@ -1308,7 +1315,6 @@ static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st,
AVPacket *pkt, MXFIndexEntry *e)
{
MXFStreamContext *sc = st->priv_data;
- MXFContext *mxf = s->priv_data;
uint32_t c = -1;
int i;
@@ -1328,21 +1334,6 @@ static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st,
if (e->flags & 0x40) // sequence header present
e->flags |= 0x80; // random access
}
- if (!mxf->header_written) {
- unsigned hours = (pkt->data[i+1]>>2) & 0x1f;
- unsigned minutes = ((pkt->data[i+1] & 0x03) << 4) | (pkt->data[i+2]>>4);
- unsigned seconds = ((pkt->data[i+2] & 0x07) << 3) | (pkt->data[i+3]>>5);
- unsigned frames = ((pkt->data[i+3] & 0x1f) << 1) | (pkt->data[i+4]>>7);
- mxf->timecode_drop_frame = !!(pkt->data[i+1] & 0x80);
- mxf->timecode_start = (hours*3600 + minutes*60 + seconds) *
- mxf->timecode_base + frames;
- if (mxf->timecode_drop_frame) {
- unsigned tminutes = 60 * hours + minutes;
- mxf->timecode_start -= 2 * (tminutes - tminutes / 10);
- }
- av_log(s, AV_LOG_DEBUG, "frame %d %d:%d:%d%c%d\n", mxf->timecode_start,
- hours, minutes, seconds, mxf->timecode_drop_frame ? ';':':', frames);
- }
} else if (c == 0x1b3) { // seq
e->flags |= 0x40;
switch ((pkt->data[i+4]>>4) & 0xf) {
@@ -1407,6 +1398,8 @@ static int mxf_write_header(AVFormatContext *s)
int i;
uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};
const int *samples_per_frame = NULL;
+ AVDictionaryEntry *t;
+ int64_t timestamp = 0;
if (!s->nb_streams)
return -1;
@@ -1436,6 +1429,12 @@ static int mxf_write_header(AVFormatContext *s)
return -1;
}
av_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);
+ if (mxf->tc.str) {
+ mxf->tc.rate.num = mxf->time_base.den;
+ mxf->tc.rate.den = mxf->time_base.num;
+ if (ff_init_smtpe_timecode(s, &mxf->tc) < 0)
+ return -1;
+ }
if (s->oformat == &ff_mxf_d10_muxer) {
if (st->codec->bit_rate == 50000000)
if (mxf->time_base.den == 25) sc->index = 3;
@@ -1512,8 +1511,15 @@ static int mxf_write_header(AVFormatContext *s)
sc->order = AV_RB32(sc->track_essence_element_key+12);
}
+#if FF_API_TIMESTAMP
if (s->timestamp)
- mxf->timestamp = mxf_parse_timestamp(s->timestamp);
+ timestamp = s->timestamp;
+ else
+#endif
+ if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+ timestamp = ff_iso8601_to_unix_time(t->value);
+ if (timestamp)
+ mxf->timestamp = mxf_parse_timestamp(timestamp);
mxf->duration = -1;
mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track));
@@ -1536,24 +1542,6 @@ static int mxf_write_header(AVFormatContext *s)
static const uint8_t system_metadata_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x01,0x00 };
static const uint8_t system_metadata_package_set_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x43,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x02,0x01 };
-static uint32_t ff_framenum_to_12m_time_code(unsigned frame, int drop, int fps)
-{
- return (0 << 31) | // color frame flag
- (drop << 30) | // drop frame flag
- ( ((frame % fps) / 10) << 28) | // tens of frames
- ( ((frame % fps) % 10) << 24) | // units of frames
- (0 << 23) | // field phase (NTSC), b0 (PAL)
- ((((frame / fps) % 60) / 10) << 20) | // tens of seconds
- ((((frame / fps) % 60) % 10) << 16) | // units of seconds
- (0 << 15) | // b0 (NTSC), b2 (PAL)
- ((((frame / (fps * 60)) % 60) / 10) << 12) | // tens of minutes
- ((((frame / (fps * 60)) % 60) % 10) << 8) | // units of minutes
- (0 << 7) | // b1
- (0 << 6) | // b2 (NTSC), field phase (PAL)
- ((((frame / (fps * 3600) % 24)) / 10) << 4) | // tens of hours
- ( (frame / (fps * 3600) % 24)) % 10; // units of hours
-}
-
static void mxf_write_system_item(AVFormatContext *s)
{
MXFContext *mxf = s->priv_data;
@@ -1561,7 +1549,7 @@ static void mxf_write_system_item(AVFormatContext *s)
unsigned frame;
uint32_t time_code;
- frame = mxf->timecode_start + mxf->last_indexed_edit_unit + mxf->edit_units_count;
+ frame = mxf->tc.start + mxf->last_indexed_edit_unit + mxf->edit_units_count;
// write system metadata pack
avio_write(pb, system_metadata_pack_key, 16);
@@ -1582,7 +1570,11 @@ static void mxf_write_system_item(AVFormatContext *s)
avio_wb64(pb, 0); // creation date/time stamp
avio_w8(pb, 0x81); // SMPTE 12M time code
- time_code = ff_framenum_to_12m_time_code(frame, mxf->timecode_drop_frame, mxf->timecode_base);
+ time_code = frame;
+ if (mxf->tc.drop)
+ time_code = ff_framenum_to_drop_timecode(time_code);
+ time_code = ff_framenum_to_smtpe_timecode(time_code, mxf->timecode_base,
+ mxf->tc.drop);
avio_wb32(pb, time_code);
avio_wb32(pb, 0); // binary group data
avio_wb64(pb, 0);
@@ -1879,34 +1871,53 @@ static int mxf_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int
mxf_interleave_get_packet, mxf_compare_timestamps);
}
+static const AVClass mxf_class = {
+ .class_name = "mxf",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+ .option = (const AVOption[]){
+ {TIMECODE_OPT(MXFContext, AV_OPT_FLAG_ENCODING_PARAM)},
+ {NULL}
+ },
+};
+
+static const AVClass mxf_d10_class = {
+ .class_name = "mxf_d10",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+ .option = (const AVOption[]){
+ {TIMECODE_OPT(MXFContext, AV_OPT_FLAG_ENCODING_PARAM)},
+ {NULL}
+ },
+};
+
AVOutputFormat ff_mxf_muxer = {
- "mxf",
- NULL_IF_CONFIG_SMALL("Material eXchange Format"),
- "application/mxf",
- "mxf",
- sizeof(MXFContext),
- CODEC_ID_PCM_S16LE,
- CODEC_ID_MPEG2VIDEO,
- mxf_write_header,
- mxf_write_packet,
- mxf_write_footer,
- AVFMT_NOTIMESTAMPS,
- NULL,
- mxf_interleave,
+ .name = "mxf",
+ .long_name = NULL_IF_CONFIG_SMALL("Material eXchange Format"),
+ .mime_type = "application/mxf",
+ .extensions = "mxf",
+ .priv_data_size = sizeof(MXFContext),
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = mxf_write_header,
+ .write_packet = mxf_write_packet,
+ .write_trailer = mxf_write_footer,
+ .flags = AVFMT_NOTIMESTAMPS,
+ .interleave_packet = mxf_interleave,
+ .priv_class = &mxf_class,
};
AVOutputFormat ff_mxf_d10_muxer = {
- "mxf_d10",
- NULL_IF_CONFIG_SMALL("Material eXchange Format, D-10 Mapping"),
- "application/mxf",
- NULL,
- sizeof(MXFContext),
- CODEC_ID_PCM_S16LE,
- CODEC_ID_MPEG2VIDEO,
- mxf_write_header,
- mxf_write_packet,
- mxf_write_footer,
- AVFMT_NOTIMESTAMPS,
- NULL,
- mxf_interleave,
+ .name = "mxf_d10",
+ .long_name = NULL_IF_CONFIG_SMALL("Material eXchange Format, D-10 Mapping"),
+ .mime_type = "application/mxf",
+ .priv_data_size = sizeof(MXFContext),
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = mxf_write_header,
+ .write_packet = mxf_write_packet,
+ .write_trailer = mxf_write_footer,
+ .flags = AVFMT_NOTIMESTAMPS,
+ .interleave_packet = mxf_interleave,
+ .priv_class = &mxf_d10_class,
};
diff --git a/libavformat/mxg.c b/libavformat/mxg.c
index 5caa68a667..04991b3530 100644
--- a/libavformat/mxg.c
+++ b/libavformat/mxg.c
@@ -2,20 +2,20 @@
* MxPEG clip file demuxer
* Copyright (c) 2010 Anatoly Nenashev
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -24,8 +24,6 @@
#include "avformat.h"
#include "avio.h"
-#define VIDEO_STREAM_INDEX 0
-#define AUDIO_STREAM_INDEX 1
#define DEFAULT_PACKET_SIZE 1024
#define OVERREAD_SIZE 3
@@ -44,14 +42,14 @@ static int mxg_read_header(AVFormatContext *s, AVFormatParameters *ap)
MXGContext *mxg = s->priv_data;
/* video parameters will be extracted from the compressed bitstream */
- video_st = av_new_stream(s, VIDEO_STREAM_INDEX);
+ video_st = avformat_new_stream(s, NULL);
if (!video_st)
return AVERROR(ENOMEM);
video_st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
video_st->codec->codec_id = CODEC_ID_MXPEG;
av_set_pts_info(video_st, 64, 1, 1000000);
- audio_st = av_new_stream(s, AUDIO_STREAM_INDEX);
+ audio_st = avformat_new_stream(s, NULL);
if (!audio_st)
return AVERROR(ENOMEM);
audio_st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -132,7 +130,7 @@ static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt)
uint8_t *startmarker_ptr, *end, *search_end, marker;
MXGContext *mxg = s->priv_data;
- while (!s->pb->eof_reached && !s->pb->error){
+ while (!url_feof(s->pb) && !s->pb->error){
if (mxg->cache_size <= OVERREAD_SIZE) {
/* update internal buffer */
ret = mxg_update_cache(s, DEFAULT_PACKET_SIZE + OVERREAD_SIZE);
@@ -166,7 +164,7 @@ static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt)
}
pkt->pts = pkt->dts = mxg->dts;
- pkt->stream_index = VIDEO_STREAM_INDEX;
+ pkt->stream_index = 0;
pkt->destruct = NULL;
pkt->size = mxg->buffer_ptr - mxg->soi_ptr;
pkt->data = mxg->soi_ptr;
@@ -204,7 +202,7 @@ static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt)
if (marker == APP13 && size >= 16) { /* audio data */
/* time (GMT) of first sample in usec since 1970, little-endian */
pkt->pts = pkt->dts = AV_RL64(startmarker_ptr + 8);
- pkt->stream_index = AUDIO_STREAM_INDEX;
+ pkt->stream_index = 1;
pkt->destruct = NULL;
pkt->size = size - 14;
pkt->data = startmarker_ptr + 16;
diff --git a/libavformat/ncdec.c b/libavformat/ncdec.c
index 7e43adcd1e..3430035f3f 100644
--- a/libavformat/ncdec.c
+++ b/libavformat/ncdec.c
@@ -3,20 +3,20 @@
* Copyright (c) 2009 Nicolas Martin (martinic at iro dot umontreal dot ca)
* Edouard Auvinet
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -45,7 +45,7 @@ static int nc_probe(AVProbeData *probe_packet)
static int nc_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -66,7 +66,7 @@ static int nc_read_packet(AVFormatContext *s, AVPacket *pkt)
uint32_t state=-1;
while (state != NC_VIDEO_FLAG) {
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR(EIO);
state = (state<<8) + avio_r8(s->pb);
}
@@ -91,11 +91,10 @@ static int nc_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_nc_demuxer = {
- "nc",
- NULL_IF_CONFIG_SMALL("NC camera feed format"),
- 0,
- nc_probe,
- nc_read_header,
- nc_read_packet,
+ .name = "nc",
+ .long_name = NULL_IF_CONFIG_SMALL("NC camera feed format"),
+ .read_probe = nc_probe,
+ .read_header = nc_read_header,
+ .read_packet = nc_read_packet,
.extensions = "v",
};
diff --git a/libavformat/network.h b/libavformat/network.h
index 80d094a0de..f7e19b196e 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -1,20 +1,20 @@
/*
- * Copyright (c) 2007 The Libav Project
+ * Copyright (c) 2007 The FFmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c
index 4787331def..5de7512f99 100644
--- a/libavformat/nsvdec.c
+++ b/libavformat/nsvdec.c
@@ -1,21 +1,21 @@
/*
* NSV demuxer
- * Copyright (c) 2004 The Libav Project
+ * Copyright (c) 2004 The FFmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -23,6 +23,7 @@
#include "avformat.h"
#include "riff.h"
#include "libavutil/dict.h"
+#include "libavutil/intreadwrite.h"
//#define DEBUG_DUMP_INDEX // XXX dumbdriving-271.nsv breaks with it commented!!
#define CHECK_SUBSEQUENT_NSVS
@@ -231,7 +232,7 @@ static int nsv_resync(AVFormatContext *s)
//nsv->state = NSV_UNSYNC;
for (i = 0; i < NSV_MAX_RESYNC; i++) {
- if (pb->eof_reached) {
+ if (url_feof(pb)) {
av_dlog(s, "NSV EOF\n");
nsv->state = NSV_UNSYNC;
return -1;
@@ -298,7 +299,7 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap)
table_entries_used = avio_rl32(pb);
av_dlog(s, "NSV NSVf info-strings size: %d, table entries: %d, bis %d\n",
strings_size, table_entries, table_entries_used);
- if (pb->eof_reached)
+ if (url_feof(pb))
return -1;
av_dlog(s, "NSV got header; filepos %"PRId64"\n", avio_tell(pb));
@@ -333,7 +334,7 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap)
}
av_free(strings);
}
- if (pb->eof_reached)
+ if (url_feof(pb))
return -1;
av_dlog(s, "NSV got infos; filepos %"PRId64"\n", avio_tell(pb));
@@ -380,7 +381,7 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap)
avio_seek(pb, nsv->base_offset + size, SEEK_SET); /* required for dumbdriving-271.nsv (2 extra bytes) */
- if (pb->eof_reached)
+ if (url_feof(pb))
return -1;
nsv->state = NSV_HAS_READ_NSVF;
return 0;
@@ -437,10 +438,11 @@ static int nsv_parse_NSVs_header(AVFormatContext *s, AVFormatParameters *ap)
nsv->vheight = vwidth;
if (vtag != T_NONE) {
int i;
- st = av_new_stream(s, NSV_ST_VIDEO);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto fail;
+ st->id = NSV_ST_VIDEO;
nst = av_mallocz(sizeof(NSVStream));
if (!nst)
goto fail;
@@ -468,10 +470,11 @@ static int nsv_parse_NSVs_header(AVFormatContext *s, AVFormatParameters *ap)
}
if (atag != T_NONE) {
#ifndef DISABLE_AUDIO
- st = av_new_stream(s, NSV_ST_AUDIO);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto fail;
+ st->id = NSV_ST_AUDIO;
nst = av_mallocz(sizeof(NSVStream));
if (!nst)
goto fail;
@@ -556,7 +559,7 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header)
return 0; //-1; /* hey! eat what you've in your plate first! */
null_chunk_retry:
- if (pb->eof_reached)
+ if (url_feof(pb))
return -1;
for (i = 0; i < NSV_MAX_RESYNC_TRIES && nsv->state < NSV_FOUND_NSVS && !err; i++)
@@ -590,7 +593,7 @@ null_chunk_retry:
vsize -= auxsize + sizeof(uint16_t) + sizeof(uint32_t); /* that's becoming braindead */
}
- if (pb->eof_reached)
+ if (url_feof(pb))
return -1;
if (!vsize && !asize) {
nsv->state = NSV_UNSYNC;
@@ -702,7 +705,9 @@ static int nsv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
if(index < 0)
return -1;
- avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
+ if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0)
+ return -1;
+
nst->frame_offset = st->index_entries[index].timestamp;
nsv->state = NSV_UNSYNC;
return 0;
@@ -738,10 +743,8 @@ static int nsv_read_close(AVFormatContext *s)
static int nsv_probe(AVProbeData *p)
{
- int i;
- int score;
- int vsize, asize, auxcount;
- score = 0;
+ int i, score = 0;
+
av_dlog(NULL, "nsv_probe(), buf_size %d\n", p->buf_size);
/* check file header */
/* streamed files might not have any header */
@@ -753,19 +756,14 @@ static int nsv_probe(AVProbeData *p)
/* seems the servers don't bother starting clean chunks... */
/* sometimes even the first header is at 9KB or something :^) */
for (i = 1; i < p->buf_size - 3; i++) {
- if (p->buf[i+0] == 'N' && p->buf[i+1] == 'S' &&
- p->buf[i+2] == 'V' && p->buf[i+3] == 's') {
- score = AVPROBE_SCORE_MAX/5;
+ if (AV_RL32(p->buf + i) == AV_RL32("NSVs")) {
/* Get the chunk size and check if at the end we are getting 0xBEEF */
- auxcount = p->buf[i+19];
- vsize = p->buf[i+20] | p->buf[i+21] << 8;
- asize = p->buf[i+22] | p->buf[i+23] << 8;
- vsize = (vsize << 4) | (auxcount >> 4);
- if ((asize + vsize + i + 23) < p->buf_size - 2) {
- if (p->buf[i+23+asize+vsize+1] == 0xEF &&
- p->buf[i+23+asize+vsize+2] == 0xBE)
- return AVPROBE_SCORE_MAX-20;
- }
+ int vsize = AV_RL24(p->buf+i+19) >> 4;
+ int asize = AV_RL16(p->buf+i+22);
+ int offset = i + 23 + asize + vsize + 1;
+ if (offset <= p->buf_size - 2 && AV_RL16(p->buf + offset) == 0xBEEF)
+ return 4*AVPROBE_SCORE_MAX/5;
+ score = AVPROBE_SCORE_MAX/5;
}
}
/* so we'll have more luck on extension... */
@@ -776,12 +774,12 @@ static int nsv_probe(AVProbeData *p)
}
AVInputFormat ff_nsv_demuxer = {
- "nsv",
- NULL_IF_CONFIG_SMALL("Nullsoft Streaming Video"),
- sizeof(NSVContext),
- nsv_probe,
- nsv_read_header,
- nsv_read_packet,
- nsv_read_close,
- nsv_read_seek,
+ .name = "nsv",
+ .long_name = NULL_IF_CONFIG_SMALL("Nullsoft Streaming Video"),
+ .priv_data_size = sizeof(NSVContext),
+ .read_probe = nsv_probe,
+ .read_header = nsv_read_header,
+ .read_packet = nsv_read_packet,
+ .read_close = nsv_read_close,
+ .read_seek = nsv_read_seek,
};
diff --git a/libavformat/nullenc.c b/libavformat/nullenc.c
index 8e38b278b1..2ab92dff75 100644
--- a/libavformat/nullenc.c
+++ b/libavformat/nullenc.c
@@ -2,20 +2,20 @@
* RAW null muxer
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -27,14 +27,10 @@ static int null_write_packet(struct AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_null_muxer = {
- "null",
- NULL_IF_CONFIG_SMALL("raw null video format"),
- NULL,
- NULL,
- 0,
- AV_NE(CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE),
- CODEC_ID_RAWVIDEO,
- NULL,
- null_write_packet,
+ .name = "null",
+ .long_name = NULL_IF_CONFIG_SMALL("raw null video format"),
+ .audio_codec = AV_NE(CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE),
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_packet = null_write_packet,
.flags = AVFMT_NOFILE | AVFMT_RAWPICTURE | AVFMT_NOTIMESTAMPS,
};
diff --git a/libavformat/nut.c b/libavformat/nut.c
index 1ce048d645..2a5e6fe567 100644
--- a/libavformat/nut.c
+++ b/libavformat/nut.c
@@ -2,20 +2,20 @@
* nut
* Copyright (c) 2004-2007 Michael Niedermayer
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/nut.h b/libavformat/nut.h
index 419b123bee..033bc0898e 100644
--- a/libavformat/nut.h
+++ b/libavformat/nut.h
@@ -2,20 +2,20 @@
* "NUT" Container Format (de)muxer
* Copyright (c) 2006 Michael Niedermayer
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index 93888a2bd6..6015bf6900 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -3,20 +3,20 @@
* Copyright (c) 2004-2006 Michael Niedermayer
* Copyright (c) 2003 Alex Beregszaszi
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -120,7 +120,7 @@ static uint64_t find_any_startcode(AVIOContext *bc, int64_t pos){
if(pos >= 0)
avio_seek(bc, pos, SEEK_SET); //note, this may fail if the stream is not seekable, but that should not matter, as in this case we simply start where we currently are
- while(!bc->eof_reached){
+ while(!url_feof(bc)){
state= (state<<8) | avio_r8(bc);
if((state>>56) != 'N')
continue;
@@ -288,7 +288,7 @@ static int decode_main_header(NUTContext *nut){
nut->stream = av_mallocz(sizeof(StreamContext)*stream_count);
for(i=0; i<stream_count; i++){
- av_new_stream(s, i);
+ avformat_new_stream(s, NULL);
}
return 0;
@@ -416,7 +416,7 @@ static int decode_info_header(NUTContext *nut){
if(chapter_id && !stream_id_plus1){
int64_t start= chapter_start / nut->time_base_count;
- chapter= ff_new_chapter(s, chapter_id,
+ chapter= avpriv_new_chapter(s, chapter_id,
nut->time_base[chapter_start % nut->time_base_count],
start, start + chapter_len, NULL);
metadata = &chapter->metadata;
@@ -787,7 +787,7 @@ static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)
pos-=8;
}else{
frame_code = avio_r8(bc);
- if(bc->eof_reached)
+ if(url_feof(bc))
return -1;
if(frame_code == 'N'){
tmp= frame_code;
@@ -924,14 +924,14 @@ static int nut_read_close(AVFormatContext *s)
#if CONFIG_NUT_DEMUXER
AVInputFormat ff_nut_demuxer = {
- "nut",
- NULL_IF_CONFIG_SMALL("NUT format"),
- sizeof(NUTContext),
- nut_probe,
- nut_read_header,
- nut_read_packet,
- nut_read_close,
- read_seek,
+ .name = "nut",
+ .long_name = NULL_IF_CONFIG_SMALL("NUT format"),
+ .priv_data_size = sizeof(NUTContext),
+ .read_probe = nut_probe,
+ .read_header = nut_read_header,
+ .read_packet = nut_read_packet,
+ .read_close = nut_read_close,
+ .read_seek = read_seek,
.extensions = "nut",
.codec_tag = (const AVCodecTag * const []) { ff_codec_bmp_tags, ff_nut_video_tags, ff_codec_wav_tags, ff_nut_subtitle_tags, 0 },
};
diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c
index 412c670387..3c963debd6 100644
--- a/libavformat/nutenc.c
+++ b/libavformat/nutenc.c
@@ -2,20 +2,20 @@
* nut muxer
* Copyright (c) 2004-2007 Michael Niedermayer
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -59,10 +59,10 @@ static int find_expected_header(AVCodecContext *c, int size, int key_frame, uint
else if(sample_rate < (44100 + 48000)/2) sample_rate_index=0;
else sample_rate_index=1;
- sample_rate= ff_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25);
+ sample_rate= avpriv_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25);
for(bitrate_index=2; bitrate_index<30; bitrate_index++){
- frame_size = ff_mpa_bitrate_tab[lsf][layer-1][bitrate_index>>1];
+ frame_size = avpriv_mpa_bitrate_tab[lsf][layer-1][bitrate_index>>1];
frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1);
if(frame_size == size)
@@ -177,6 +177,7 @@ static void build_frame_code(AVFormatContext *s){
}
key_frame= intra_only;
+#if 1
if(is_audio){
int frame_bytes= codec->frame_size*(int64_t)codec->bit_rate / (8*codec->sample_rate);
int pts;
@@ -200,6 +201,7 @@ static void build_frame_code(AVFormatContext *s){
ft->pts_delta=1;
start2++;
}
+#endif
if(codec->has_b_frames){
pred_count=5;
@@ -578,7 +580,7 @@ static int write_headers(AVFormatContext *avctx, AVIOContext *bc){
return 0;
}
-static int write_header(AVFormatContext *s){
+static int nut_write_header(AVFormatContext *s){
NUTContext *nut = s->priv_data;
AVIOContext *bc = s->pb;
int i, j, ret;
@@ -586,11 +588,10 @@ static int write_header(AVFormatContext *s){
nut->avf= s;
nut->stream = av_mallocz(sizeof(StreamContext)*s->nb_streams);
- if (s->nb_chapters)
- nut->chapter = av_mallocz(sizeof(ChapterContext)*s->nb_chapters);
+ nut->chapter = av_mallocz(sizeof(ChapterContext)*s->nb_chapters);
nut->time_base= av_mallocz(sizeof(AVRational )*(s->nb_streams +
s->nb_chapters));
- if (!nut->stream || (s->nb_chapters && !nut->chapter) || !nut->time_base) {
+ if (!nut->stream || !nut->chapter || !nut->time_base) {
av_freep(&nut->stream);
av_freep(&nut->chapter);
av_freep(&nut->time_base);
@@ -691,7 +692,7 @@ static int find_best_header_idx(NUTContext *nut, AVPacket *pkt){
return best_i;
}
-static int write_packet(AVFormatContext *s, AVPacket *pkt){
+static int nut_write_packet(AVFormatContext *s, AVPacket *pkt){
NUTContext *nut = s->priv_data;
StreamContext *nus= &nut->stream[pkt->stream_index];
AVIOContext *bc = s->pb, *dyn_bc;
@@ -845,7 +846,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt){
return 0;
}
-static int write_trailer(AVFormatContext *s){
+static int nut_write_trailer(AVFormatContext *s){
NUTContext *nut= s->priv_data;
AVIOContext *bc= s->pb;
@@ -861,22 +862,22 @@ static int write_trailer(AVFormatContext *s){
}
AVOutputFormat ff_nut_muxer = {
- "nut",
- NULL_IF_CONFIG_SMALL("NUT format"),
- "video/x-nut",
- "nut",
- sizeof(NUTContext),
+ .name = "nut",
+ .long_name = NULL_IF_CONFIG_SMALL("NUT format"),
+ .mime_type = "video/x-nut",
+ .extensions = "nut",
+ .priv_data_size = sizeof(NUTContext),
#if CONFIG_LIBVORBIS
- CODEC_ID_VORBIS,
+ .audio_codec = CODEC_ID_VORBIS,
#elif CONFIG_LIBMP3LAME
- CODEC_ID_MP3,
+ .audio_codec = CODEC_ID_MP3,
#else
- CODEC_ID_MP2,
+ .audio_codec = CODEC_ID_MP2,
#endif
- CODEC_ID_MPEG4,
- write_header,
- write_packet,
- write_trailer,
+ .video_codec = CODEC_ID_MPEG4,
+ .write_header = nut_write_header,
+ .write_packet = nut_write_packet,
+ .write_trailer = nut_write_trailer,
.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
.codec_tag = (const AVCodecTag * const []){ ff_codec_bmp_tags, ff_nut_video_tags, ff_codec_wav_tags, ff_nut_subtitle_tags, 0 },
};
diff --git a/libavformat/nuv.c b/libavformat/nuv.c
index 854aadd990..caf85b0ef8 100644
--- a/libavformat/nuv.c
+++ b/libavformat/nuv.c
@@ -2,20 +2,20 @@
* NuppelVideo demuxer.
* Copyright (c) 2006 Reimar Doeffinger
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -61,7 +61,7 @@ static int get_codec_data(AVIOContext *pb, AVStream *vst,
nuv_frametype frametype;
if (!vst && !myth)
return 1; // no codec data needed
- while (!pb->eof_reached) {
+ while (!url_feof(pb)) {
int size, subtype;
frametype = avio_r8(pb);
switch (frametype) {
@@ -153,7 +153,7 @@ static int nuv_header(AVFormatContext *s, AVFormatParameters *ap) {
if (v_packs) {
ctx->v_id = stream_nr++;
- vst = av_new_stream(s, ctx->v_id);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -169,7 +169,7 @@ static int nuv_header(AVFormatContext *s, AVFormatParameters *ap) {
if (a_packs) {
ctx->a_id = stream_nr++;
- ast = av_new_stream(s, ctx->a_id);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -196,7 +196,7 @@ static int nuv_packet(AVFormatContext *s, AVPacket *pkt) {
uint8_t hdr[HDRSIZE];
nuv_frametype frametype;
int ret, size;
- while (!pb->eof_reached) {
+ while (!url_feof(pb)) {
int copyhdrsize = ctx->rtjpg_video ? HDRSIZE : 0;
uint64_t pos = avio_tell(pb);
ret = avio_read(pb, hdr, HDRSIZE);
@@ -219,10 +219,9 @@ static int nuv_packet(AVFormatContext *s, AVPacket *pkt) {
ret = av_new_packet(pkt, copyhdrsize + size);
if (ret < 0)
return ret;
- // HACK: we have no idea if it is a keyframe,
- // but if we mark none seeking will not work at all.
- pkt->flags |= AV_PKT_FLAG_KEY;
+
pkt->pos = pos;
+ pkt->flags |= hdr[2] == 0 ? AV_PKT_FLAG_KEY : 0;
pkt->pts = AV_RL32(&hdr[4]);
pkt->stream_index = ctx->v_id;
memcpy(pkt->data, hdr, copyhdrsize);
@@ -258,14 +257,88 @@ static int nuv_packet(AVFormatContext *s, AVPacket *pkt) {
return AVERROR(EIO);
}
+/**
+ * \brief looks for the string RTjjjjjjjjjj in the stream too resync reading
+ * \return 1 if the syncword is found 0 otherwise.
+ */
+static int nuv_resync(AVFormatContext *s, int64_t pos_limit) {
+ AVIOContext *pb = s->pb;
+ uint32_t tag = 0;
+ while(!url_feof(pb) && avio_tell(pb) < pos_limit) {
+ tag = (tag << 8) | avio_r8(pb);
+ if (tag == MKBETAG('R','T','j','j') &&
+ (tag = avio_rb32(pb)) == MKBETAG('j','j','j','j') &&
+ (tag = avio_rb32(pb)) == MKBETAG('j','j','j','j'))
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * \brief attempts to read a timestamp from stream at the given stream position
+ * \return timestamp if successfull and AV_NOPTS_VALUE if failure
+ */
+static int64_t nuv_read_dts(AVFormatContext *s, int stream_index,
+ int64_t *ppos, int64_t pos_limit)
+{
+ NUVContext *ctx = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint8_t hdr[HDRSIZE];
+ nuv_frametype frametype;
+ int size, key, idx;
+ int64_t pos, dts;
+
+ if (avio_seek(pb, *ppos, SEEK_SET) < 0)
+ return AV_NOPTS_VALUE;
+
+ if (!nuv_resync(s, pos_limit))
+ return AV_NOPTS_VALUE;
+
+ while (!url_feof(pb) && avio_tell(pb) < pos_limit) {
+ if (avio_read(pb, hdr, HDRSIZE) < HDRSIZE)
+ return AV_NOPTS_VALUE;
+ frametype = hdr[0];
+ size = PKTSIZE(AV_RL32(&hdr[8]));
+ switch (frametype) {
+ case NUV_SEEKP:
+ break;
+ case NUV_AUDIO:
+ case NUV_VIDEO:
+ if (frametype == NUV_VIDEO) {
+ idx = ctx->v_id;
+ key = hdr[2] == 0;
+ } else {
+ idx = ctx->a_id;
+ key = 1;
+ }
+ if (stream_index == idx) {
+
+ pos = avio_tell(s->pb) - HDRSIZE;
+ dts = AV_RL32(&hdr[4]);
+
+ // TODO - add general support in av_gen_search, so it adds positions after reading timestamps
+ av_add_index_entry(s->streams[stream_index], pos, dts, size + HDRSIZE, 0,
+ key ? AVINDEX_KEYFRAME : 0);
+
+ *ppos = pos;
+ return dts;
+ }
+ default:
+ avio_skip(pb, size);
+ break;
+ }
+ }
+ return AV_NOPTS_VALUE;
+}
+
+
AVInputFormat ff_nuv_demuxer = {
- "nuv",
- NULL_IF_CONFIG_SMALL("NuppelVideo format"),
- sizeof(NUVContext),
- nuv_probe,
- nuv_header,
- nuv_packet,
- NULL,
- NULL,
+ .name = "nuv",
+ .long_name = NULL_IF_CONFIG_SMALL("NuppelVideo format"),
+ .priv_data_size = sizeof(NUVContext),
+ .read_probe = nuv_probe,
+ .read_header = nuv_header,
+ .read_packet = nuv_packet,
+ .read_timestamp = nuv_read_dts,
.flags = AVFMT_GENERIC_INDEX,
};
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index e33de7d978..8e7653c6b8 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -29,7 +29,6 @@
DEALINGS IN THE SOFTWARE.
**/
-
#include <stdio.h>
#include "oggdec.h"
#include "avformat.h"
@@ -45,6 +44,7 @@ static const struct ogg_codec * const ogg_codecs[] = {
&ff_vorbis_codec,
&ff_theora_codec,
&ff_flac_codec,
+ &ff_celt_codec,
&ff_old_dirac_codec,
&ff_old_flac_codec,
&ff_ogm_video_codec,
@@ -92,14 +92,24 @@ static int ogg_restore(AVFormatContext *s, int discard)
ogg->state = ost->next;
if (!discard){
+ struct ogg_stream *old_streams = ogg->streams;
+
for (i = 0; i < ogg->nstreams; i++)
av_free (ogg->streams[i].buf);
avio_seek (bc, ost->pos, SEEK_SET);
ogg->curidx = ost->curidx;
ogg->nstreams = ost->nstreams;
- memcpy(ogg->streams, ost->streams,
- ost->nstreams * sizeof(*ogg->streams));
+ ogg->streams = av_realloc (ogg->streams,
+ ogg->nstreams * sizeof (*ogg->streams));
+
+ if (ogg->streams) {
+ memcpy(ogg->streams, ost->streams,
+ ost->nstreams * sizeof(*ogg->streams));
+ } else {
+ av_free(old_streams);
+ ogg->nstreams = 0;
+ }
}
av_free (ost);
@@ -161,10 +171,11 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
os->header = -1;
if (new_avstream) {
- st = av_new_stream(s, idx);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
+ st->id = idx;
av_set_pts_info(st, 64, 1, 1000000);
}
@@ -213,7 +224,7 @@ static int ogg_read_page(AVFormatContext *s, int *str)
break;
c = avio_r8(bc);
- if (bc->eof_reached)
+ if (url_feof(bc))
return AVERROR_EOF;
sync[sp++ & 3] = c;
}while (i++ < MAX_PAGE_SIZE);
@@ -361,8 +372,6 @@ static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
}
}while (!complete);
- av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
- idx, os->psize, os->pstart);
if (os->granule == -1)
av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
@@ -412,6 +421,8 @@ static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
*fpos = os->sync_pos;
os->pstart += os->psize;
os->psize = 0;
+ if(os->pstart == os->bufpos)
+ os->bufpos = os->pstart = 0;
os->sync_pos = os->page_pos;
}
@@ -451,6 +462,7 @@ static int ogg_get_length(AVFormatContext *s)
struct ogg *ogg = s->priv_data;
int i;
int64_t size, end;
+ int streams_left=0;
if(!s->pb->seekable)
return 0;
@@ -472,13 +484,37 @@ static int ogg_get_length(AVFormatContext *s)
ogg->streams[i].codec) {
s->streams[i]->duration =
ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
- if (s->streams[i]->start_time != AV_NOPTS_VALUE)
+ if (s->streams[i]->start_time != AV_NOPTS_VALUE){
s->streams[i]->duration -= s->streams[i]->start_time;
+ streams_left-= (ogg->streams[i].got_start==-1);
+ ogg->streams[i].got_start= 1;
+ }else if(!ogg->streams[i].got_start){
+ ogg->streams[i].got_start= -1;
+ streams_left++;
+ }
}
}
ogg_restore (s, 0);
+ ogg_save (s);
+ avio_seek (s->pb, 0, SEEK_SET);
+ while (!ogg_read_page (s, &i)){
+ if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
+ ogg->streams[i].codec) {
+ if(s->streams[i]->duration && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
+ int64_t start= ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
+ if(av_rescale_q(start, s->streams[i]->time_base, AV_TIME_BASE_Q) > AV_TIME_BASE)
+ s->streams[i]->duration -= start;
+ ogg->streams[i].got_start= 1;
+ streams_left--;
+ }
+ if(streams_left<=0)
+ break;
+ }
+ }
+ ogg_restore (s, 0);
+
return 0;
}
@@ -592,15 +628,15 @@ static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
int64_t *pos_arg, int64_t pos_limit)
{
struct ogg *ogg = s->priv_data;
- struct ogg_stream *os = ogg->streams + stream_index;
AVIOContext *bc = s->pb;
int64_t pts = AV_NOPTS_VALUE;
- int i;
+ int i = -1;
avio_seek(bc, *pos_arg, SEEK_SET);
ogg_reset(ogg);
while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
if (i == stream_index) {
+ struct ogg_stream *os = ogg->streams + stream_index;
pts = ogg_calc_pts(s, i, NULL);
if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
pts = AV_NOPTS_VALUE;
@@ -626,6 +662,7 @@ static int ogg_read_seek(AVFormatContext *s, int stream_index,
os->keyframe_seek = 1;
ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
+ os = ogg->streams + stream_index;
if (ret < 0)
os->keyframe_seek = 0;
return ret;
diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h
index e7d1022734..7f5452f2b0 100644
--- a/libavformat/oggdec.h
+++ b/libavformat/oggdec.h
@@ -75,6 +75,7 @@ struct ogg_stream {
int incomplete; ///< whether we're expecting a continuation in the next page
int page_end; ///< current packet is the last one completed in the page
int keyframe_seek;
+ int got_start;
void *private;
};
@@ -98,6 +99,7 @@ struct ogg {
#define OGG_FLAG_BOS 2
#define OGG_FLAG_EOS 4
+extern const struct ogg_codec ff_celt_codec;
extern const struct ogg_codec ff_dirac_codec;
extern const struct ogg_codec ff_flac_codec;
extern const struct ogg_codec ff_ogm_audio_codec;
diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c
index 2b2189c10e..53350719fa 100644
--- a/libavformat/oggenc.c
+++ b/libavformat/oggenc.c
@@ -2,24 +2,25 @@
* Ogg muxer
* Copyright (c) 2007 Baptiste Coudurier <baptiste dot coudurier at free dot fr>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/crc.h"
+#include "libavutil/opt.h"
#include "libavutil/mathematics.h"
#include "libavutil/random_seed.h"
#include "libavcodec/xiph.h"
@@ -63,9 +64,26 @@ typedef struct OGGPageList {
} OGGPageList;
typedef struct {
+ const AVClass *class;
OGGPageList *page_list;
+ int pref_size; ///< preferred page size (0 => fill all segments)
} OGGContext;
+
+static const AVOption options[] = {
+ { "oggpagesize", "Set preferred Ogg page size.",
+ offsetof(OGGContext, pref_size), AV_OPT_TYPE_INT, {.dbl = 0}, 0, MAX_PAGE_SIZE, AV_OPT_FLAG_ENCODING_PARAM},
+ { NULL },
+};
+
+static const AVClass ogg_muxer_class = {
+ "Ogg muxer",
+ av_default_item_name,
+ options,
+ LIBAVUTIL_VERSION_INT,
+};
+
+
static void ogg_update_checksum(AVFormatContext *s, AVIOContext *pb, int64_t crc_offset)
{
int64_t pos = avio_tell(pb);
@@ -175,6 +193,7 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st,
uint8_t *data, unsigned size, int64_t granule)
{
OGGStreamContext *oggstream = st->priv_data;
+ OGGContext *ogg = s->priv_data;
int total_segments = size / 255 + 1;
uint8_t *p = data;
int i, segments, len, flush = 0;
@@ -210,8 +229,9 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st,
if (i == total_segments)
page->granule = granule;
- if (page->segments_count == 255) {
- ogg_buffer_page(s, oggstream);
+ if(page->segments_count == 255 ||
+ (ogg->pref_size > 0 && page->size >= ogg->pref_size)) {
+ ogg_buffer_page(s, oggstream);
}
}
@@ -254,7 +274,7 @@ static int ogg_build_flac_headers(AVCodecContext *avctx,
uint8_t *streaminfo;
uint8_t *p;
- if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))
+ if (!avpriv_flac_is_extradata_valid(avctx, &format, &streaminfo))
return -1;
// first packet: STREAMINFO
@@ -377,7 +397,7 @@ static int ogg_write_header(AVFormatContext *s)
int header_type = st->codec->codec_id == CODEC_ID_VORBIS ? 3 : 0x81;
int framing_bit = st->codec->codec_id == CODEC_ID_VORBIS ? 1 : 0;
- if (ff_split_xiph_headers(st->codec->extradata, st->codec->extradata_size,
+ if (avpriv_split_xiph_headers(st->codec->extradata, st->codec->extradata_size,
st->codec->codec_id == CODEC_ID_VORBIS ? 30 : 42,
oggstream->header, oggstream->header_len) < 0) {
av_log(s, AV_LOG_ERROR, "Extradata corrupted\n");
@@ -496,23 +516,26 @@ static int ogg_write_trailer(AVFormatContext *s)
OGGStreamContext *oggstream = st->priv_data;
if (st->codec->codec_id == CODEC_ID_FLAC ||
st->codec->codec_id == CODEC_ID_SPEEX) {
- av_free(oggstream->header[0]);
- av_free(oggstream->header[1]);
+ av_freep(&oggstream->header[0]);
+ av_freep(&oggstream->header[1]);
}
+ else
+ av_freep(&oggstream->header[1]);
av_freep(&st->priv_data);
}
return 0;
}
AVOutputFormat ff_ogg_muxer = {
- "ogg",
- NULL_IF_CONFIG_SMALL("Ogg"),
- "application/ogg",
- "ogg,ogv,spx",
- sizeof(OGGContext),
- CODEC_ID_FLAC,
- CODEC_ID_THEORA,
- ogg_write_header,
- ogg_write_packet,
- ogg_write_trailer,
+ .name = "ogg",
+ .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
+ .mime_type = "application/ogg",
+ .extensions = "ogg,ogv,spx",
+ .priv_data_size = sizeof(OGGContext),
+ .audio_codec = CODEC_ID_FLAC,
+ .video_codec = CODEC_ID_THEORA,
+ .write_header = ogg_write_header,
+ .write_packet = ogg_write_packet,
+ .write_trailer = ogg_write_trailer,
+ .priv_class = &ogg_muxer_class,
};
diff --git a/libavformat/oggparsecelt.c b/libavformat/oggparsecelt.c
new file mode 100644
index 0000000000..0af6fccfa2
--- /dev/null
+++ b/libavformat/oggparsecelt.c
@@ -0,0 +1,95 @@
+/*
+ * Xiph CELT / Opus parser for Ogg
+ * Copyright (c) 2011 Nicolas George
+ *
+ * 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 <string.h>
+
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "oggdec.h"
+
+struct oggcelt_private {
+ int extra_headers_left;
+};
+
+static int celt_header(AVFormatContext *s, int idx)
+{
+ struct ogg *ogg = s->priv_data;
+ struct ogg_stream *os = ogg->streams + idx;
+ AVStream *st = s->streams[idx];
+ struct oggcelt_private *priv = os->private;
+ uint8_t *p = os->buf + os->pstart;
+
+ if (os->psize == 60 &&
+ !memcmp(p, ff_celt_codec.magic, ff_celt_codec.magicsize)) {
+ /* Main header */
+
+ uint32_t version, sample_rate, nb_channels, frame_size;
+ uint32_t overlap, extra_headers;
+ uint8_t *extradata;
+
+ extradata = av_malloc(2 * sizeof(uint32_t) +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ priv = av_malloc(sizeof(struct oggcelt_private));
+ if (!extradata || !priv) {
+ av_free(extradata);
+ av_free(priv);
+ return AVERROR(ENOMEM);
+ }
+ version = AV_RL32(p + 28);
+ /* unused header size field skipped */
+ sample_rate = AV_RL32(p + 36);
+ nb_channels = AV_RL32(p + 40);
+ frame_size = AV_RL32(p + 44);
+ overlap = AV_RL32(p + 48);
+ /* unused bytes per packet field skipped */
+ extra_headers = AV_RL32(p + 56);
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = CODEC_ID_CELT;
+ st->codec->sample_rate = sample_rate;
+ st->codec->channels = nb_channels;
+ st->codec->frame_size = frame_size;
+ av_free(st->codec->extradata);
+ st->codec->extradata = extradata;
+ st->codec->extradata_size = 2 * sizeof(uint32_t);
+ if (sample_rate)
+ av_set_pts_info(st, 64, 1, sample_rate);
+ priv->extra_headers_left = 1 + extra_headers;
+ av_free(os->private);
+ os->private = priv;
+ AV_WL32(extradata + 0, overlap);
+ AV_WL32(extradata + 4, version);
+ return 1;
+ } else if (priv && priv->extra_headers_left) {
+ /* Extra headers (vorbiscomment) */
+
+ ff_vorbis_comment(s, &st->metadata, p, os->psize);
+ priv->extra_headers_left--;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+const struct ogg_codec ff_celt_codec = {
+ .magic = "CELT ",
+ .magicsize = 8,
+ .header = celt_header,
+};
diff --git a/libavformat/oggparsedirac.c b/libavformat/oggparsedirac.c
index f6afafd0e4..524736a416 100644
--- a/libavformat/oggparsedirac.c
+++ b/libavformat/oggparsedirac.c
@@ -1,20 +1,20 @@
/*
* Copyright (C) 2008 David Conrad
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -36,7 +36,7 @@ static int dirac_header(AVFormatContext *s, int idx)
return 0;
init_get_bits(&gb, os->buf + os->pstart + 13, (os->psize - 13) * 8);
- if (ff_dirac_parse_sequence_header(st->codec, &gb, &source) < 0)
+ if (avpriv_dirac_parse_sequence_header(st->codec, &gb, &source) < 0)
return -1;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
diff --git a/libavformat/oggparseflac.c b/libavformat/oggparseflac.c
index 53cd0fa582..87239c6a53 100644
--- a/libavformat/oggparseflac.c
+++ b/libavformat/oggparseflac.c
@@ -1,20 +1,20 @@
/*
* Copyright (C) 2005 Matthieu CASTET
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -55,7 +55,7 @@ flac_header (AVFormatContext * s, int idx)
if (get_bits_long(&gb, 32) != FLAC_STREAMINFO_SIZE)
return -1;
- ff_flac_parse_streaminfo(st->codec, &si, streaminfo_start);
+ avpriv_flac_parse_streaminfo(st->codec, &si, streaminfo_start);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_FLAC;
diff --git a/libavformat/oggparseskeleton.c b/libavformat/oggparseskeleton.c
index ceb7c6991e..e318e9e718 100644
--- a/libavformat/oggparseskeleton.c
+++ b/libavformat/oggparseskeleton.c
@@ -1,20 +1,20 @@
/*
* Copyright (C) 2010 David Conrad
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/oggparsespeex.c b/libavformat/oggparsespeex.c
index 2f4aec7f07..bbeeb20d60 100644
--- a/libavformat/oggparsespeex.c
+++ b/libavformat/oggparsespeex.c
@@ -31,6 +31,7 @@
#include "oggdec.h"
struct speex_params {
+ int packet_size;
int final_packet_duration;
int seq;
};
@@ -58,14 +59,10 @@ static int speex_header(AVFormatContext *s, int idx) {
st->codec->sample_rate = AV_RL32(p + 36);
st->codec->channels = AV_RL32(p + 48);
- /* We treat the whole Speex packet as a single frame everywhere Speex
- is handled in Libav. This avoids the complexities of splitting
- and joining individual Speex frames, which are not always
- byte-aligned. */
- st->codec->frame_size = AV_RL32(p + 56);
- frames_per_packet = AV_RL32(p + 64);
+ spxp->packet_size = AV_RL32(p + 56);
+ frames_per_packet = AV_RL32(p + 64);
if (frames_per_packet)
- st->codec->frame_size *= frames_per_packet;
+ spxp->packet_size *= frames_per_packet;
st->codec->extradata_size = os->psize;
st->codec->extradata = av_malloc(st->codec->extradata_size
@@ -95,7 +92,7 @@ static int speex_packet(AVFormatContext *s, int idx)
struct ogg *ogg = s->priv_data;
struct ogg_stream *os = ogg->streams + idx;
struct speex_params *spxp = os->private;
- int packet_size = s->streams[idx]->codec->frame_size;
+ int packet_size = spxp->packet_size;
if (os->flags & OGG_FLAG_EOS && os->lastpts != AV_NOPTS_VALUE &&
os->granule > 0) {
@@ -108,9 +105,10 @@ static int speex_packet(AVFormatContext *s, int idx)
if (!os->lastpts && os->granule > 0)
/* first packet */
- os->pduration = os->granule - packet_size * (ogg_page_packets(os) - 1);
- else if (os->flags & OGG_FLAG_EOS && os->segp == os->nsegs &&
- spxp->final_packet_duration)
+ os->lastpts = os->lastdts = os->granule - packet_size *
+ ogg_page_packets(os);
+ if (os->flags & OGG_FLAG_EOS && os->segp == os->nsegs &&
+ spxp->final_packet_duration)
/* final packet */
os->pduration = spxp->final_packet_duration;
else
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index 86951f3e2f..8a406976b5 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -45,7 +45,7 @@ static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
return 0;
- ff_new_chapter(as, cnum, (AVRational){1,1000},
+ avpriv_new_chapter(as, cnum, (AVRational){1,1000},
ms + 1000*(s + 60*(m + 60*h)),
AV_NOPTS_VALUE, NULL);
av_free(val);
diff --git a/libavformat/oma.c b/libavformat/oma.c
index 0ec81ebefb..eeb920553a 100644
--- a/libavformat/oma.c
+++ b/libavformat/oma.c
@@ -3,21 +3,22 @@
*
* Copyright (c) 2008 Maxim Poliakovski
* 2008 Benjamin Larsson
+ * 2011 David Goldwich
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -36,20 +37,19 @@
* - Sound data organized in packets follow the EA3 header
* (can be encrypted using the Sony DRM!).
*
- * LIMITATIONS: This version supports only plain (unencrypted) OMA files.
- * If any DRM-protected (encrypted) file is encountered you will get the
- * corresponding error message. Try to remove the encryption using any
- * Sony software (for example SonicStage).
* CODEC SUPPORT: Only ATRAC3 codec is currently supported!
*/
#include "avformat.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/des.h"
#include "pcm.h"
#include "riff.h"
#include "id3v2.h"
#define EA3_HEADER_SIZE 96
+#define ID3v2_EA3_MAGIC "ea3"
+#define OMA_ENC_HEADER_SIZE 16
enum {
OMA_CODECID_ATRAC3 = 0,
@@ -65,7 +65,211 @@ static const AVCodecTag codec_oma_tags[] = {
{ CODEC_ID_MP3, OMA_CODECID_MP3 },
};
-#define ID3v2_EA3_MAGIC "ea3"
+static const uint64_t leaf_table[] = {
+ 0xd79e8283acea4620, 0x7a9762f445afd0d8,
+ 0x354d60a60b8c79f1, 0x584e1cde00b07aee,
+ 0x1573cd93da7df623, 0x47f98d79620dd535
+};
+
+typedef struct OMAContext {
+ uint64_t content_start;
+ int encrypted;
+ uint16_t k_size;
+ uint16_t e_size;
+ uint16_t i_size;
+ uint16_t s_size;
+ uint32_t rid;
+ uint8_t r_val[24];
+ uint8_t n_val[24];
+ uint8_t m_val[8];
+ uint8_t s_val[8];
+ uint8_t sm_val[8];
+ uint8_t e_val[8];
+ uint8_t iv[8];
+ struct AVDES av_des;
+} OMAContext;
+
+static void hex_log(AVFormatContext *s, int level, const char *name, const uint8_t *value, int len)
+{
+ char buf[33];
+ len = FFMIN(len, 16);
+ if (av_log_get_level() < level)
+ return;
+ ff_data_to_hex(buf, value, len, 1);
+ buf[len<<1] = '\0';
+ av_log(s, level, "%s: %s\n", name, buf);
+}
+
+static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val, int len)
+{
+ OMAContext *oc = s->priv_data;
+
+ if (!r_val && !n_val)
+ return -1;
+
+ len = FFMIN(len, 16);
+
+ /* use first 64 bits in the third round again */
+ if (r_val) {
+ if (r_val != oc->r_val) {
+ memset(oc->r_val, 0, 24);
+ memcpy(oc->r_val, r_val, len);
+ }
+ memcpy(&oc->r_val[16], r_val, 8);
+ }
+ if (n_val) {
+ if (n_val != oc->n_val) {
+ memset(oc->n_val, 0, 24);
+ memcpy(oc->n_val, n_val, len);
+ }
+ memcpy(&oc->n_val[16], n_val, 8);
+ }
+
+ return 0;
+}
+
+static int rprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *r_val)
+{
+ OMAContext *oc = s->priv_data;
+ unsigned int pos;
+ struct AVDES av_des;
+
+ if (!enc_header || !r_val)
+ return -1;
+
+ /* m_val */
+ av_des_init(&av_des, r_val, 192, 1);
+ av_des_crypt(&av_des, oc->m_val, &enc_header[48], 1, NULL, 1);
+
+ /* s_val */
+ av_des_init(&av_des, oc->m_val, 64, 0);
+ av_des_crypt(&av_des, oc->s_val, NULL, 1, NULL, 0);
+
+ /* sm_val */
+ pos = OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size;
+ av_des_init(&av_des, oc->s_val, 64, 0);
+ av_des_mac(&av_des, oc->sm_val, &enc_header[pos], (oc->i_size >> 3));
+
+ pos += oc->i_size;
+
+ return memcmp(&enc_header[pos], oc->sm_val, 8) ? -1 : 0;
+}
+
+static int nprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *n_val)
+{
+ OMAContext *oc = s->priv_data;
+ uint32_t pos, taglen, datalen;
+ struct AVDES av_des;
+
+ if (!enc_header || !n_val)
+ return -1;
+
+ pos = OMA_ENC_HEADER_SIZE + oc->k_size;
+ if (!memcmp(&enc_header[pos], "EKB ", 4))
+ pos += 32;
+
+ if (AV_RB32(&enc_header[pos]) != oc->rid)
+ av_log(s, AV_LOG_DEBUG, "Mismatching RID\n");
+
+ taglen = AV_RB32(&enc_header[pos+32]);
+ datalen = AV_RB32(&enc_header[pos+36]) >> 4;
+
+ pos += 44 + taglen;
+
+ av_des_init(&av_des, n_val, 192, 1);
+ while (datalen-- > 0) {
+ av_des_crypt(&av_des, oc->r_val, &enc_header[pos], 2, NULL, 1);
+ kset(s, oc->r_val, NULL, 16);
+ if (!rprobe(s, enc_header, oc->r_val))
+ return 0;
+ pos += 16;
+ }
+
+ return -1;
+}
+
+static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
+{
+ OMAContext *oc = s->priv_data;
+ ID3v2ExtraMetaGEOB *geob = NULL;
+ uint8_t *gdata;
+
+ oc->encrypted = 1;
+ av_log(s, AV_LOG_INFO, "File is encrypted\n");
+
+ /* find GEOB metadata */
+ while (em) {
+ if (!strcmp(em->tag, "GEOB") &&
+ (geob = em->data) &&
+ !strcmp(geob->description, "OMG_LSI") ||
+ !strcmp(geob->description, "OMG_BKLSI")) {
+ break;
+ }
+ em = em->next;
+ }
+ if (!em) {
+ av_log(s, AV_LOG_ERROR, "No encryption header found\n");
+ return -1;
+ }
+
+ if (geob->datasize < 64) {
+ av_log(s, AV_LOG_ERROR, "Invalid GEOB data size: %u\n", geob->datasize);
+ return -1;
+ }
+
+ gdata = geob->data;
+
+ if (AV_RB16(gdata) != 1)
+ av_log(s, AV_LOG_WARNING, "Unknown version in encryption header\n");
+
+ oc->k_size = AV_RB16(&gdata[2]);
+ oc->e_size = AV_RB16(&gdata[4]);
+ oc->i_size = AV_RB16(&gdata[6]);
+ oc->s_size = AV_RB16(&gdata[8]);
+
+ if (memcmp(&gdata[OMA_ENC_HEADER_SIZE], "KEYRING ", 12)) {
+ av_log(s, AV_LOG_ERROR, "Invalid encryption header\n");
+ return -1;
+ }
+ oc->rid = AV_RB32(&gdata[OMA_ENC_HEADER_SIZE + 28]);
+ av_log(s, AV_LOG_DEBUG, "RID: %.8x\n", oc->rid);
+
+ memcpy(oc->iv, &header[0x58], 8);
+ hex_log(s, AV_LOG_DEBUG, "IV", oc->iv, 8);
+
+ hex_log(s, AV_LOG_DEBUG, "CBC-MAC", &gdata[OMA_ENC_HEADER_SIZE+oc->k_size+oc->e_size+oc->i_size], 8);
+
+ if (s->keylen > 0) {
+ kset(s, s->key, s->key, s->keylen);
+ }
+ if (!memcmp(oc->r_val, (const uint8_t[8]){0}, 8) ||
+ rprobe(s, gdata, oc->r_val) < 0 &&
+ nprobe(s, gdata, oc->n_val) < 0) {
+ int i;
+ for (i = 0; i < sizeof(leaf_table); i += 2) {
+ uint8_t buf[16];
+ AV_WL64(buf, leaf_table[i]);
+ AV_WL64(&buf[8], leaf_table[i+1]);
+ kset(s, buf, buf, 16);
+ if (!rprobe(s, gdata, oc->r_val) || !nprobe(s, gdata, oc->n_val))
+ break;
+ }
+ if (i >= sizeof(leaf_table)) {
+ av_log(s, AV_LOG_ERROR, "Invalid key\n");
+ return -1;
+ }
+ }
+
+ /* e_val */
+ av_des_init(&oc->av_des, oc->m_val, 64, 0);
+ av_des_crypt(&oc->av_des, oc->e_val, &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0);
+ hex_log(s, AV_LOG_DEBUG, "EK", oc->e_val, 8);
+
+ /* init e_val */
+ av_des_init(&oc->av_des, oc->e_val, 64, 1);
+
+ return 0;
+}
static int oma_read_header(AVFormatContext *s,
AVFormatParameters *ap)
@@ -77,8 +281,10 @@ static int oma_read_header(AVFormatContext *s,
uint8_t buf[EA3_HEADER_SIZE];
uint8_t *edata;
AVStream *st;
+ ID3v2ExtraMeta *extra_meta = NULL;
+ OMAContext *oc = s->priv_data;
- ff_id3v2_read(s, ID3v2_EA3_MAGIC);
+ ff_id3v2_read_all(s, ID3v2_EA3_MAGIC, &extra_meta);
ret = avio_read(s->pb, buf, EA3_HEADER_SIZE);
if (ret < EA3_HEADER_SIZE)
return -1;
@@ -88,15 +294,20 @@ static int oma_read_header(AVFormatContext *s,
return -1;
}
+ oc->content_start = avio_tell(s->pb);
+
+ /* encrypted file */
eid = AV_RB16(&buf[6]);
- if (eid != -1 && eid != -128) {
- av_log(s, AV_LOG_ERROR, "Encrypted file! Eid: %d\n", eid);
+ if (eid != -1 && eid != -128 && decrypt_init(s, extra_meta, buf) < 0) {
+ ff_id3v2_free_extra_meta(&extra_meta);
return -1;
}
+ ff_id3v2_free_extra_meta(&extra_meta);
+
codec_params = AV_RB24(&buf[33]);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -159,12 +370,20 @@ static int oma_read_header(AVFormatContext *s,
static int oma_read_packet(AVFormatContext *s, AVPacket *pkt)
{
- int ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align);
+ OMAContext *oc = s->priv_data;
+ int packet_size = s->streams[0]->codec->block_align;
+ int ret = av_get_packet(s->pb, pkt, packet_size);
- pkt->stream_index = 0;
if (ret <= 0)
return AVERROR(EIO);
+ pkt->stream_index = 0;
+
+ if (oc->encrypted) {
+ /* previous unencrypted block saved in IV for the next packet (CBC mode) */
+ av_des_crypt(&oc->av_des, pkt->data, pkt->data, (packet_size >> 3), oc->iv, 1);
+ }
+
return ret;
}
@@ -190,18 +409,38 @@ static int oma_read_probe(AVProbeData *p)
return 0;
}
+static int oma_read_seek(struct AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
+{
+ OMAContext *oc = s->priv_data;
+
+ pcm_read_seek(s, stream_index, timestamp, flags);
+
+ if (oc->encrypted) {
+ /* readjust IV for CBC */
+ int64_t pos = avio_tell(s->pb);
+ if (pos < oc->content_start)
+ memset(oc->iv, 0, 8);
+ else {
+ if (avio_seek(s->pb, -8, SEEK_CUR) < 0 || avio_read(s->pb, oc->iv, 8) < 8) {
+ memset(oc->iv, 0, 8);
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
AVInputFormat ff_oma_demuxer = {
- "oma",
- NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
- 0,
- oma_read_probe,
- oma_read_header,
- oma_read_packet,
- 0,
- pcm_read_seek,
- .flags= AVFMT_GENERIC_INDEX,
- .extensions = "oma,aa3",
- .codec_tag= (const AVCodecTag* const []){codec_oma_tags, 0},
+ .name = "oma",
+ .long_name = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
+ .priv_data_size = sizeof(OMAContext),
+ .read_probe = oma_read_probe,
+ .read_header = oma_read_header,
+ .read_packet = oma_read_packet,
+ .read_seek = oma_read_seek,
+ .flags = AVFMT_GENERIC_INDEX,
+ .extensions = "oma,omg,aa3",
+ .codec_tag = (const AVCodecTag* const []){codec_oma_tags, 0},
};
diff --git a/libavformat/options.c b/libavformat/options.c
index c2729b75d9..64bc7a8996 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -1,20 +1,20 @@
/*
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
@@ -33,30 +33,36 @@ static const char* format_to_name(void* ptr)
else return "NULL";
}
-static const AVOption *opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags)
+static void *format_child_next(void *obj, void *prev)
+{
+ AVFormatContext *s = obj;
+ if (!prev && s->priv_data &&
+ ((s->iformat && s->iformat->priv_class) ||
+ s->oformat && s->oformat->priv_class))
+ return s->priv_data;
+ return NULL;
+}
+
+static const AVClass *format_child_class_next(const AVClass *prev)
{
- AVFormatContext *s = obj;
AVInputFormat *ifmt = NULL;
AVOutputFormat *ofmt = NULL;
- if (s->priv_data) {
- if ((s->iformat && !s->iformat->priv_class) ||
- (s->oformat && !s->oformat->priv_class))
- return NULL;
- return av_opt_find(s->priv_data, name, unit, opt_flags, search_flags);
- }
-
- while ((ifmt = av_iformat_next(ifmt))) {
- const AVOption *o;
-
- if (ifmt->priv_class && (o = av_opt_find(&ifmt->priv_class, name, unit, opt_flags, search_flags)))
- return o;
- }
- while ((ofmt = av_oformat_next(ofmt))) {
- const AVOption *o;
-
- if (ofmt->priv_class && (o = av_opt_find(&ofmt->priv_class, name, unit, opt_flags, search_flags)))
- return o;
- }
+
+ while (prev && (ifmt = av_iformat_next(ifmt)))
+ if (ifmt->priv_class == prev)
+ break;
+ if ((prev && ifmt) || (!prev))
+ while (ifmt = av_iformat_next(ifmt))
+ if (ifmt->priv_class)
+ return ifmt->priv_class;
+
+ while (prev && (ofmt = av_oformat_next(ofmt)))
+ if (ofmt->priv_class == prev)
+ break;
+ while (ofmt = av_oformat_next(ofmt))
+ if (ofmt->priv_class)
+ return ofmt->priv_class;
+
return NULL;
}
@@ -67,26 +73,35 @@ static const AVOption *opt_find(void *obj, const char *name, const char *unit, i
#define D AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[]={
-{"probesize", "set probing size", OFFSET(probesize), FF_OPT_TYPE_INT, {.dbl = 5000000 }, 32, INT_MAX, D},
-{"muxrate", "set mux rate", OFFSET(mux_rate), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E},
-{"packetsize", "set packet size", OFFSET(packet_size), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E},
-{"fflags", NULL, OFFSET(flags), FF_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, D|E, "fflags"},
-{"ignidx", "ignore index", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_IGNIDX }, INT_MIN, INT_MAX, D, "fflags"},
-{"genpts", "generate pts", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_GENPTS }, INT_MIN, INT_MAX, D, "fflags"},
-{"nofillin", "do not fill in missing values that can be exactly calculated", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_NOFILLIN }, INT_MIN, INT_MAX, D, "fflags"},
-{"noparse", "disable AVParsers, this needs nofillin too", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_NOPARSE }, INT_MIN, INT_MAX, D, "fflags"},
-{"igndts", "ignore dts", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_IGNDTS }, INT_MIN, INT_MAX, D, "fflags"},
+{"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT, {.dbl = 5000000 }, 32, INT_MAX, D},
+#if FF_API_MUXRATE
+{"muxrate", "set mux rate", OFFSET(mux_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E},
+#endif
+{"packetsize", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E},
+{"fflags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, D|E, "fflags"},
+{"ignidx", "ignore index", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_IGNIDX }, INT_MIN, INT_MAX, D, "fflags"},
+{"genpts", "generate pts", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_GENPTS }, INT_MIN, INT_MAX, D, "fflags"},
+{"nofillin", "do not fill in missing values that can be exactly calculated", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_NOFILLIN }, INT_MIN, INT_MAX, D, "fflags"},
+{"noparse", "disable AVParsers, this needs nofillin too", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_NOPARSE }, INT_MIN, INT_MAX, D, "fflags"},
+{"igndts", "ignore dts", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_IGNDTS }, INT_MIN, INT_MAX, D, "fflags"},
#if FF_API_FLAG_RTP_HINT
-{"rtphint", "add rtp hinting (deprecated, use the -movflags rtphint option instead)", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_RTP_HINT }, INT_MIN, INT_MAX, E, "fflags"},
+{"rtphint", "add rtp hinting (deprecated, use the -movflags rtphint option instead)", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_RTP_HINT }, INT_MIN, INT_MAX, E, "fflags"},
#endif
-{"analyzeduration", "how many microseconds are analyzed to estimate duration", OFFSET(max_analyze_duration), FF_OPT_TYPE_INT, {.dbl = 5*AV_TIME_BASE }, 0, INT_MAX, D},
-{"cryptokey", "decryption key", OFFSET(key), FF_OPT_TYPE_BINARY, {.dbl = 0}, 0, 0, D},
-{"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), FF_OPT_TYPE_INT, {.dbl = 1<<20 }, 0, INT_MAX, D},
-{"rtbufsize", "max memory used for buffering real-time frames", OFFSET(max_picture_buffer), FF_OPT_TYPE_INT, {.dbl = 3041280 }, 0, INT_MAX, D}, /* defaults to 1s of 15fps 352x288 YUYV422 video */
-{"fdebug", "print specific debug info", OFFSET(debug), FF_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, 0, INT_MAX, E|D, "fdebug"},
-{"ts", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_FDEBUG_TS }, INT_MIN, INT_MAX, E|D, "fdebug"},
-{"max_delay", "maximum muxing or demuxing delay in microseconds", OFFSET(max_delay), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E|D},
-{"fpsprobesize", "number of frames used to probe fps", OFFSET(fps_probe_size), FF_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX-1, D},
+{"discardcorrupt", "discard corrupted frames", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_DISCARD_CORRUPT }, INT_MIN, INT_MAX, D, "fflags"},
+{"sortdts", "try to interleave outputted packets by dts", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_SORT_DTS }, INT_MIN, INT_MAX, D, "fflags"},
+{"keepside", "dont merge side data", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_KEEP_SIDE_DATA }, INT_MIN, INT_MAX, D, "fflags"},
+{"latm", "enable RTP MP4A-LATM payload", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_MP4A_LATM }, INT_MIN, INT_MAX, E, "fflags"},
+{"analyzeduration", "how many microseconds are analyzed to estimate duration", OFFSET(max_analyze_duration), AV_OPT_TYPE_INT, {.dbl = 5*AV_TIME_BASE }, 0, INT_MAX, D},
+{"cryptokey", "decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, {.dbl = 0}, 0, 0, D},
+{"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), AV_OPT_TYPE_INT, {.dbl = 1<<20 }, 0, INT_MAX, D},
+{"rtbufsize", "max memory used for buffering real-time frames", OFFSET(max_picture_buffer), AV_OPT_TYPE_INT, {.dbl = 3041280 }, 0, INT_MAX, D}, /* defaults to 1s of 15fps 352x288 YUYV422 video */
+{"fdebug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, 0, INT_MAX, E|D, "fdebug"},
+{"ts", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_FDEBUG_TS }, INT_MIN, INT_MAX, E|D, "fdebug"},
+{"max_delay", "maximum muxing or demuxing delay in microseconds", OFFSET(max_delay), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E|D},
+{"fer", "set error detection aggressivity", OFFSET(error_recognition), AV_OPT_TYPE_INT, {.dbl = FF_ER_CAREFUL }, INT_MIN, INT_MAX, D, "fer"},
+{"careful", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_ER_CAREFUL }, INT_MIN, INT_MAX, D, "fer"},
+{"explode", "abort decoding on error recognition", 0, AV_OPT_TYPE_CONST, {.dbl = FF_ER_EXPLODE }, INT_MIN, INT_MAX, D, "fer"},
+{"fpsprobesize", "number of frames used to probe fps", OFFSET(fps_probe_size), AV_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX-1, D},
{NULL},
};
@@ -99,7 +114,8 @@ static const AVClass av_format_context_class = {
.item_name = format_to_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
- .opt_find = opt_find,
+ .child_next = format_child_next,
+ .child_class_next = format_child_class_next,
};
static void avformat_get_context_defaults(AVFormatContext *s)
@@ -119,3 +135,8 @@ AVFormatContext *avformat_alloc_context(void)
avformat_get_context_defaults(ic);
return ic;
}
+
+const AVClass *avformat_get_class(void)
+{
+ return &av_format_context_class;
+}
diff --git a/libavformat/os_support.c b/libavformat/os_support.c
index a0fcd6c9ba..ac9086c3c3 100644
--- a/libavformat/os_support.c
+++ b/libavformat/os_support.c
@@ -3,20 +3,20 @@
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
* copyright (c) 2002 Francois Revol
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/os_support.h b/libavformat/os_support.h
index 521e9978a2..f770528365 100644
--- a/libavformat/os_support.h
+++ b/libavformat/os_support.h
@@ -2,20 +2,20 @@
* various utilities for ffmpeg system
* copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/output-example.c b/libavformat/output-example.c
deleted file mode 100644
index 3b28b7c7c6..0000000000
--- a/libavformat/output-example.c
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/**
- * @file
- * libavformat API example.
- *
- * @example libavformat/output-example.c
- * Output a media file in any supported libavformat format.
- * The default codecs are used.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-
-#include "libavutil/mathematics.h"
-#include "libavformat/avformat.h"
-#include "libswscale/swscale.h"
-
-#undef exit
-
-/* 5 seconds stream duration */
-#define STREAM_DURATION 5.0
-#define STREAM_FRAME_RATE 25 /* 25 images/s */
-#define STREAM_NB_FRAMES ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
-#define STREAM_PIX_FMT PIX_FMT_YUV420P /* default pix_fmt */
-
-static int sws_flags = SWS_BICUBIC;
-
-/**************************************************************/
-/* audio output */
-
-float t, tincr, tincr2;
-int16_t *samples;
-uint8_t *audio_outbuf;
-int audio_outbuf_size;
-int audio_input_frame_size;
-
-/*
- * add an audio output stream
- */
-static AVStream *add_audio_stream(AVFormatContext *oc, enum CodecID codec_id)
-{
- AVCodecContext *c;
- AVStream *st;
-
- st = av_new_stream(oc, 1);
- if (!st) {
- fprintf(stderr, "Could not alloc stream\n");
- exit(1);
- }
-
- c = st->codec;
- c->codec_id = codec_id;
- c->codec_type = AVMEDIA_TYPE_AUDIO;
-
- /* put sample parameters */
- c->sample_fmt = AV_SAMPLE_FMT_S16;
- c->bit_rate = 64000;
- c->sample_rate = 44100;
- c->channels = 2;
-
- // some formats want stream headers to be separate
- if(oc->oformat->flags & AVFMT_GLOBALHEADER)
- c->flags |= CODEC_FLAG_GLOBAL_HEADER;
-
- return st;
-}
-
-static void open_audio(AVFormatContext *oc, AVStream *st)
-{
- AVCodecContext *c;
- AVCodec *codec;
-
- c = st->codec;
-
- /* find the audio encoder */
- codec = avcodec_find_encoder(c->codec_id);
- if (!codec) {
- fprintf(stderr, "codec not found\n");
- exit(1);
- }
-
- /* open it */
- if (avcodec_open(c, codec) < 0) {
- fprintf(stderr, "could not open codec\n");
- exit(1);
- }
-
- /* init signal generator */
- t = 0;
- tincr = 2 * M_PI * 110.0 / c->sample_rate;
- /* increment frequency by 110 Hz per second */
- tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
-
- audio_outbuf_size = 10000;
- audio_outbuf = av_malloc(audio_outbuf_size);
-
- /* ugly hack for PCM codecs (will be removed ASAP with new PCM
- support to compute the input frame size in samples */
- if (c->frame_size <= 1) {
- audio_input_frame_size = audio_outbuf_size / c->channels;
- switch(st->codec->codec_id) {
- case CODEC_ID_PCM_S16LE:
- case CODEC_ID_PCM_S16BE:
- case CODEC_ID_PCM_U16LE:
- case CODEC_ID_PCM_U16BE:
- audio_input_frame_size >>= 1;
- break;
- default:
- break;
- }
- } else {
- audio_input_frame_size = c->frame_size;
- }
- samples = av_malloc(audio_input_frame_size * 2 * c->channels);
-}
-
-/* prepare a 16 bit dummy audio frame of 'frame_size' samples and
- 'nb_channels' channels */
-static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
-{
- int j, i, v;
- int16_t *q;
-
- q = samples;
- for(j=0;j<frame_size;j++) {
- v = (int)(sin(t) * 10000);
- for(i = 0; i < nb_channels; i++)
- *q++ = v;
- t += tincr;
- tincr += tincr2;
- }
-}
-
-static void write_audio_frame(AVFormatContext *oc, AVStream *st)
-{
- AVCodecContext *c;
- AVPacket pkt;
- av_init_packet(&pkt);
-
- c = st->codec;
-
- get_audio_frame(samples, audio_input_frame_size, c->channels);
-
- pkt.size= avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size, samples);
-
- if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
- pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
- pkt.flags |= AV_PKT_FLAG_KEY;
- pkt.stream_index= st->index;
- pkt.data= audio_outbuf;
-
- /* write the compressed frame in the media file */
- if (av_interleaved_write_frame(oc, &pkt) != 0) {
- fprintf(stderr, "Error while writing audio frame\n");
- exit(1);
- }
-}
-
-static void close_audio(AVFormatContext *oc, AVStream *st)
-{
- avcodec_close(st->codec);
-
- av_free(samples);
- av_free(audio_outbuf);
-}
-
-/**************************************************************/
-/* video output */
-
-AVFrame *picture, *tmp_picture;
-uint8_t *video_outbuf;
-int frame_count, video_outbuf_size;
-
-/* add a video output stream */
-static AVStream *add_video_stream(AVFormatContext *oc, enum CodecID codec_id)
-{
- AVCodecContext *c;
- AVStream *st;
-
- st = av_new_stream(oc, 0);
- if (!st) {
- fprintf(stderr, "Could not alloc stream\n");
- exit(1);
- }
-
- c = st->codec;
- c->codec_id = codec_id;
- c->codec_type = AVMEDIA_TYPE_VIDEO;
-
- /* put sample parameters */
- c->bit_rate = 400000;
- /* resolution must be a multiple of two */
- c->width = 352;
- c->height = 288;
- /* time base: this is the fundamental unit of time (in seconds) in terms
- of which frame timestamps are represented. for fixed-fps content,
- timebase should be 1/framerate and timestamp increments should be
- identically 1. */
- c->time_base.den = STREAM_FRAME_RATE;
- c->time_base.num = 1;
- c->gop_size = 12; /* emit one intra frame every twelve frames at most */
- c->pix_fmt = STREAM_PIX_FMT;
- if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
- /* just for testing, we also add B frames */
- c->max_b_frames = 2;
- }
- if (c->codec_id == CODEC_ID_MPEG1VIDEO){
- /* Needed to avoid using macroblocks in which some coeffs overflow.
- This does not happen with normal video, it just happens here as
- the motion of the chroma plane does not match the luma plane. */
- c->mb_decision=2;
- }
- // some formats want stream headers to be separate
- if(oc->oformat->flags & AVFMT_GLOBALHEADER)
- c->flags |= CODEC_FLAG_GLOBAL_HEADER;
-
- return st;
-}
-
-static AVFrame *alloc_picture(enum PixelFormat pix_fmt, int width, int height)
-{
- AVFrame *picture;
- uint8_t *picture_buf;
- int size;
-
- picture = avcodec_alloc_frame();
- if (!picture)
- return NULL;
- size = avpicture_get_size(pix_fmt, width, height);
- picture_buf = av_malloc(size);
- if (!picture_buf) {
- av_free(picture);
- return NULL;
- }
- avpicture_fill((AVPicture *)picture, picture_buf,
- pix_fmt, width, height);
- return picture;
-}
-
-static void open_video(AVFormatContext *oc, AVStream *st)
-{
- AVCodec *codec;
- AVCodecContext *c;
-
- c = st->codec;
-
- /* find the video encoder */
- codec = avcodec_find_encoder(c->codec_id);
- if (!codec) {
- fprintf(stderr, "codec not found\n");
- exit(1);
- }
-
- /* open the codec */
- if (avcodec_open(c, codec) < 0) {
- fprintf(stderr, "could not open codec\n");
- exit(1);
- }
-
- video_outbuf = NULL;
- if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
- /* allocate output buffer */
- /* XXX: API change will be done */
- /* buffers passed into lav* can be allocated any way you prefer,
- as long as they're aligned enough for the architecture, and
- they're freed appropriately (such as using av_free for buffers
- allocated with av_malloc) */
- video_outbuf_size = 200000;
- video_outbuf = av_malloc(video_outbuf_size);
- }
-
- /* allocate the encoded raw picture */
- picture = alloc_picture(c->pix_fmt, c->width, c->height);
- if (!picture) {
- fprintf(stderr, "Could not allocate picture\n");
- exit(1);
- }
-
- /* if the output format is not YUV420P, then a temporary YUV420P
- picture is needed too. It is then converted to the required
- output format */
- tmp_picture = NULL;
- if (c->pix_fmt != PIX_FMT_YUV420P) {
- tmp_picture = alloc_picture(PIX_FMT_YUV420P, c->width, c->height);
- if (!tmp_picture) {
- fprintf(stderr, "Could not allocate temporary picture\n");
- exit(1);
- }
- }
-}
-
-/* prepare a dummy image */
-static void fill_yuv_image(AVFrame *pict, int frame_index, int width, int height)
-{
- int x, y, i;
-
- i = frame_index;
-
- /* Y */
- for(y=0;y<height;y++) {
- for(x=0;x<width;x++) {
- pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
- }
- }
-
- /* Cb and Cr */
- for(y=0;y<height/2;y++) {
- for(x=0;x<width/2;x++) {
- pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
- pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
- }
- }
-}
-
-static void write_video_frame(AVFormatContext *oc, AVStream *st)
-{
- int out_size, ret;
- AVCodecContext *c;
- static struct SwsContext *img_convert_ctx;
-
- c = st->codec;
-
- if (frame_count >= STREAM_NB_FRAMES) {
- /* no more frame to compress. The codec has a latency of a few
- frames if using B frames, so we get the last frames by
- passing the same picture again */
- } else {
- if (c->pix_fmt != PIX_FMT_YUV420P) {
- /* as we only generate a YUV420P picture, we must convert it
- to the codec pixel format if needed */
- if (img_convert_ctx == NULL) {
- img_convert_ctx = sws_getContext(c->width, c->height,
- PIX_FMT_YUV420P,
- c->width, c->height,
- c->pix_fmt,
- sws_flags, NULL, NULL, NULL);
- if (img_convert_ctx == NULL) {
- fprintf(stderr, "Cannot initialize the conversion context\n");
- exit(1);
- }
- }
- fill_yuv_image(tmp_picture, frame_count, c->width, c->height);
- sws_scale(img_convert_ctx, tmp_picture->data, tmp_picture->linesize,
- 0, c->height, picture->data, picture->linesize);
- } else {
- fill_yuv_image(picture, frame_count, c->width, c->height);
- }
- }
-
-
- if (oc->oformat->flags & AVFMT_RAWPICTURE) {
- /* raw video case. The API will change slightly in the near
- futur for that */
- AVPacket pkt;
- av_init_packet(&pkt);
-
- pkt.flags |= AV_PKT_FLAG_KEY;
- pkt.stream_index= st->index;
- pkt.data= (uint8_t *)picture;
- pkt.size= sizeof(AVPicture);
-
- ret = av_interleaved_write_frame(oc, &pkt);
- } else {
- /* encode the image */
- out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);
- /* if zero size, it means the image was buffered */
- if (out_size > 0) {
- AVPacket pkt;
- av_init_packet(&pkt);
-
- if (c->coded_frame->pts != AV_NOPTS_VALUE)
- pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
- if(c->coded_frame->key_frame)
- pkt.flags |= AV_PKT_FLAG_KEY;
- pkt.stream_index= st->index;
- pkt.data= video_outbuf;
- pkt.size= out_size;
-
- /* write the compressed frame in the media file */
- ret = av_interleaved_write_frame(oc, &pkt);
- } else {
- ret = 0;
- }
- }
- if (ret != 0) {
- fprintf(stderr, "Error while writing video frame\n");
- exit(1);
- }
- frame_count++;
-}
-
-static void close_video(AVFormatContext *oc, AVStream *st)
-{
- avcodec_close(st->codec);
- av_free(picture->data[0]);
- av_free(picture);
- if (tmp_picture) {
- av_free(tmp_picture->data[0]);
- av_free(tmp_picture);
- }
- av_free(video_outbuf);
-}
-
-/**************************************************************/
-/* media file output */
-
-int main(int argc, char **argv)
-{
- const char *filename;
- AVOutputFormat *fmt;
- AVFormatContext *oc;
- AVStream *audio_st, *video_st;
- double audio_pts, video_pts;
- int i;
-
- /* initialize libavcodec, and register all codecs and formats */
- av_register_all();
-
- if (argc != 2) {
- printf("usage: %s output_file\n"
- "API example program to output a media file with libavformat.\n"
- "The output format is automatically guessed according to the file extension.\n"
- "Raw images can also be output by using '%%d' in the filename\n"
- "\n", argv[0]);
- exit(1);
- }
-
- filename = argv[1];
-
- /* auto detect the output format from the name. default is
- mpeg. */
- fmt = av_guess_format(NULL, filename, NULL);
- if (!fmt) {
- printf("Could not deduce output format from file extension: using MPEG.\n");
- fmt = av_guess_format("mpeg", NULL, NULL);
- }
- if (!fmt) {
- fprintf(stderr, "Could not find suitable output format\n");
- exit(1);
- }
-
- /* allocate the output media context */
- oc = avformat_alloc_context();
- if (!oc) {
- fprintf(stderr, "Memory error\n");
- exit(1);
- }
- oc->oformat = fmt;
- snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
-
- /* add the audio and video streams using the default format codecs
- and initialize the codecs */
- video_st = NULL;
- audio_st = NULL;
- if (fmt->video_codec != CODEC_ID_NONE) {
- video_st = add_video_stream(oc, fmt->video_codec);
- }
- if (fmt->audio_codec != CODEC_ID_NONE) {
- audio_st = add_audio_stream(oc, fmt->audio_codec);
- }
-
- /* set the output parameters (must be done even if no
- parameters). */
- if (av_set_parameters(oc, NULL) < 0) {
- fprintf(stderr, "Invalid output format parameters\n");
- exit(1);
- }
-
- av_dump_format(oc, 0, filename, 1);
-
- /* now that all the parameters are set, we can open the audio and
- video codecs and allocate the necessary encode buffers */
- if (video_st)
- open_video(oc, video_st);
- if (audio_st)
- open_audio(oc, audio_st);
-
- /* open the output file, if needed */
- if (!(fmt->flags & AVFMT_NOFILE)) {
- if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) {
- fprintf(stderr, "Could not open '%s'\n", filename);
- exit(1);
- }
- }
-
- /* write the stream header, if any */
- av_write_header(oc);
-
- for(;;) {
- /* compute current audio and video time */
- if (audio_st)
- audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
- else
- audio_pts = 0.0;
-
- if (video_st)
- video_pts = (double)video_st->pts.val * video_st->time_base.num / video_st->time_base.den;
- else
- video_pts = 0.0;
-
- if ((!audio_st || audio_pts >= STREAM_DURATION) &&
- (!video_st || video_pts >= STREAM_DURATION))
- break;
-
- /* write interleaved audio and video frames */
- if (!video_st || (video_st && audio_st && audio_pts < video_pts)) {
- write_audio_frame(oc, audio_st);
- } else {
- write_video_frame(oc, video_st);
- }
- }
-
- /* write the trailer, if any. the trailer must be written
- * before you close the CodecContexts open when you wrote the
- * header; otherwise write_trailer may try to use memory that
- * was freed on av_codec_close() */
- av_write_trailer(oc);
-
- /* close each codec */
- if (video_st)
- close_video(oc, video_st);
- if (audio_st)
- close_audio(oc, audio_st);
-
- /* free the streams */
- for(i = 0; i < oc->nb_streams; i++) {
- av_freep(&oc->streams[i]->codec);
- av_freep(&oc->streams[i]);
- }
-
- if (!(fmt->flags & AVFMT_NOFILE)) {
- /* close the output file */
- avio_close(oc->pb);
- }
-
- /* free the stream */
- av_free(oc);
-
- return 0;
-}
diff --git a/libavformat/pcm.c b/libavformat/pcm.c
index 7d5fed5601..d66be59ccb 100644
--- a/libavformat/pcm.c
+++ b/libavformat/pcm.c
@@ -2,20 +2,20 @@
* PCM common functions
* Copyright (c) 2003 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/pcm.h b/libavformat/pcm.h
index 228df1394b..7c0b7d70aa 100644
--- a/libavformat/pcm.h
+++ b/libavformat/pcm.h
@@ -2,20 +2,20 @@
* PCM common functions
* Copyright (C) 2007 Aurelien Jacobs <aurel@gnuage.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/pcmdec.c b/libavformat/pcmdec.c
index 343bbf0ae2..542ee17749 100644
--- a/libavformat/pcmdec.c
+++ b/libavformat/pcmdec.c
@@ -2,26 +2,28 @@
* RAW PCM demuxers
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
#include "rawdec.h"
#include "pcm.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
#define RAW_SAMPLES 1024
@@ -46,20 +48,30 @@ static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
return ret;
}
-#define PCMDEF(name, long_name, ext, codec) \
-AVInputFormat ff_pcm_ ## name ## _demuxer = {\
- #name,\
- NULL_IF_CONFIG_SMALL(long_name),\
- sizeof(RawAudioDemuxerContext),\
- NULL,\
- ff_raw_read_header,\
- raw_read_packet,\
- NULL,\
- pcm_read_seek,\
- .flags= AVFMT_GENERIC_INDEX,\
- .extensions = ext,\
- .value = codec,\
- .priv_class = &ff_rawaudio_demuxer_class,\
+static const AVOption pcm_options[] = {
+ { "sample_rate", "", offsetof(RawAudioDemuxerContext, sample_rate), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "channels", "", offsetof(RawAudioDemuxerContext, channels), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { NULL },
+};
+
+#define PCMDEF(name_, long_name_, ext, codec) \
+static const AVClass name_ ## _demuxer_class = { \
+ .class_name = #name_ " demuxer", \
+ .item_name = av_default_item_name, \
+ .option = pcm_options, \
+ .version = LIBAVUTIL_VERSION_INT, \
+}; \
+AVInputFormat ff_pcm_ ## name_ ## _demuxer = { \
+ .name = #name_, \
+ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
+ .priv_data_size = sizeof(RawAudioDemuxerContext), \
+ .read_header = ff_raw_read_header, \
+ .read_packet = raw_read_packet, \
+ .read_seek = pcm_read_seek, \
+ .flags = AVFMT_GENERIC_INDEX, \
+ .extensions = ext, \
+ .value = codec, \
+ .priv_class = &name_ ## _demuxer_class, \
};
PCMDEF(f64be, "PCM 64 bit floating-point big-endian format",
diff --git a/libavformat/pcmenc.c b/libavformat/pcmenc.c
index 928124e9b0..12e64b0fb8 100644
--- a/libavformat/pcmenc.c
+++ b/libavformat/pcmenc.c
@@ -2,38 +2,35 @@
* RAW PCM muxers
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
#include "rawenc.h"
-#define PCMDEF(name, long_name, ext, codec) \
-AVOutputFormat ff_pcm_ ## name ## _muxer = {\
- #name,\
- NULL_IF_CONFIG_SMALL(long_name),\
- NULL,\
- ext,\
- 0,\
- codec,\
- CODEC_ID_NONE,\
- NULL,\
- ff_raw_write_packet,\
- .flags= AVFMT_NOTIMESTAMPS,\
+#define PCMDEF(name_, long_name_, ext, codec) \
+AVOutputFormat ff_pcm_ ## name_ ## _muxer = { \
+ .name = #name_, \
+ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
+ .extensions = ext, \
+ .audio_codec = codec, \
+ .video_codec = CODEC_ID_NONE, \
+ .write_packet = ff_raw_write_packet, \
+ .flags = AVFMT_NOTIMESTAMPS, \
};
PCMDEF(f64be, "PCM 64 bit floating-point big-endian format",
diff --git a/libavformat/pmpdec.c b/libavformat/pmpdec.c
new file mode 100644
index 0000000000..ba40003359
--- /dev/null
+++ b/libavformat/pmpdec.c
@@ -0,0 +1,172 @@
+/*
+ * PMP demuxer.
+ * Copyright (c) 2011 Reimar Döffinger
+ *
+ * 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 "libavutil/intreadwrite.h"
+#include "avformat.h"
+
+typedef struct {
+ int cur_stream;
+ int num_streams;
+ int audio_packets;
+ int current_packet;
+ uint32_t *packet_sizes;
+ int packet_sizes_alloc;
+} PMPContext;
+
+static int pmp_probe(AVProbeData *p) {
+ if (AV_RN32(p->buf) == AV_RN32("pmpm") &&
+ AV_RL32(p->buf + 4) == 1)
+ return AVPROBE_SCORE_MAX;
+ return 0;
+}
+
+static int pmp_header(AVFormatContext *s, AVFormatParameters *ap) {
+ PMPContext *pmp = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int tb_num, tb_den;
+ int index_cnt;
+ int audio_codec_id = CODEC_ID_NONE;
+ int srate, channels;
+ int i;
+ uint64_t pos;
+ AVStream *vst = av_new_stream(s, 0);
+ if (!vst)
+ return AVERROR(ENOMEM);
+ vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ avio_skip(pb, 8);
+ switch (avio_rl32(pb)) {
+ case 0:
+ vst->codec->codec_id = CODEC_ID_MPEG4;
+ break;
+ case 1:
+ vst->codec->codec_id = CODEC_ID_H264;
+ break;
+ default:
+ av_log(s, AV_LOG_ERROR, "Unsupported video format\n");
+ break;
+ }
+ index_cnt = avio_rl32(pb);
+ vst->codec->width = avio_rl32(pb);
+ vst->codec->height = avio_rl32(pb);
+
+ tb_num = avio_rl32(pb);
+ tb_den = avio_rl32(pb);
+ av_set_pts_info(vst, 32, tb_num, tb_den);
+ vst->nb_frames = index_cnt;
+ vst->duration = index_cnt;
+
+ switch (avio_rl32(pb)) {
+ case 0:
+ audio_codec_id = CODEC_ID_MP3;
+ break;
+ case 1:
+ av_log(s, AV_LOG_ERROR, "AAC not yet correctly supported\n");
+ audio_codec_id = CODEC_ID_AAC;
+ break;
+ default:
+ av_log(s, AV_LOG_ERROR, "Unsupported audio format\n");
+ break;
+ }
+ pmp->num_streams = avio_rl16(pb) + 1;
+ avio_skip(pb, 10);
+ srate = avio_rl32(pb);
+ channels = avio_rl32(pb) + 1;
+ for (i = 1; i < pmp->num_streams; i++) {
+ AVStream *ast = av_new_stream(s, i);
+ if (!ast)
+ return AVERROR(ENOMEM);
+ ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ ast->codec->codec_id = audio_codec_id;
+ ast->codec->channels = channels;
+ ast->codec->sample_rate = srate;
+ av_set_pts_info(ast, 32, 1, srate);
+ }
+ pos = avio_tell(pb) + 4*index_cnt;
+ for (i = 0; i < index_cnt; i++) {
+ int size = avio_rl32(pb);
+ int flags = size & 1 ? AVINDEX_KEYFRAME : 0;
+ size >>= 1;
+ av_add_index_entry(vst, pos, i, size, 0, flags);
+ pos += size;
+ }
+ return 0;
+}
+
+static int pmp_packet(AVFormatContext *s, AVPacket *pkt) {
+ PMPContext *pmp = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int ret = 0;
+ int i;
+
+ if (url_feof(pb))
+ return AVERROR_EOF;
+ if (pmp->cur_stream == 0) {
+ int num_packets;
+ pmp->audio_packets = avio_r8(pb);
+ num_packets = (pmp->num_streams - 1) * pmp->audio_packets + 1;
+ avio_skip(pb, 8);
+ pmp->current_packet = 0;
+ av_fast_malloc(&pmp->packet_sizes,
+ &pmp->packet_sizes_alloc,
+ num_packets * sizeof(*pmp->packet_sizes));
+ for (i = 0; i < num_packets; i++)
+ pmp->packet_sizes[i] = avio_rl32(pb);
+ }
+ ret = av_get_packet(pb, pkt, pmp->packet_sizes[pmp->current_packet]);
+ if (ret >= 0) {
+ ret = 0;
+ // FIXME: this is a hack that should be remove once
+ // compute_pkt_fields can handle
+ if (pmp->cur_stream == 0)
+ pkt->dts = s->streams[0]->cur_dts++;
+ pkt->stream_index = pmp->cur_stream;
+ }
+ if (pmp->current_packet % pmp->audio_packets == 0)
+ pmp->cur_stream = (pmp->cur_stream + 1) % pmp->num_streams;
+ pmp->current_packet++;
+ return ret;
+}
+
+static int pmp_seek(AVFormatContext *s, int stream_index,
+ int64_t ts, int flags) {
+ PMPContext *pmp = s->priv_data;
+ pmp->cur_stream = 0;
+ // fallback to default seek now
+ return -1;
+}
+
+static int pmp_close(AVFormatContext *s)
+{
+ PMPContext *pmp = s->priv_data;
+ av_freep(&pmp->packet_sizes);
+ return 0;
+}
+
+AVInputFormat ff_pmp_demuxer = {
+ .name = "pmp",
+ .long_name = NULL_IF_CONFIG_SMALL("Playstation Portable PMP format"),
+ .priv_data_size = sizeof(PMPContext),
+ .read_probe = pmp_probe,
+ .read_header = pmp_header,
+ .read_packet = pmp_packet,
+ .read_seek = pmp_seek,
+ .read_close = pmp_close,
+};
diff --git a/libavformat/psxstr.c b/libavformat/psxstr.c
index 646244238c..675a4b11df 100644
--- a/libavformat/psxstr.c
+++ b/libavformat/psxstr.c
@@ -2,20 +2,20 @@
* Sony Playstation (PSX) STR File Demuxer
* Copyright (c) 2003 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -68,6 +68,8 @@ static const char sync_header[12] = {0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf
static int str_probe(AVProbeData *p)
{
uint8_t *sector= p->buf;
+ uint8_t *end= sector + p->buf_size;
+ int aud=0, vid=0;
if (p->buf_size < RAW_CD_SECTOR_SIZE)
return 0;
@@ -79,20 +81,52 @@ static int str_probe(AVProbeData *p)
sector += RIFF_HEADER_SIZE;
}
- /* look for CD sync header (00, 0xFF x 10, 00) */
- if (memcmp(sector,sync_header,sizeof(sync_header)))
- return 0;
+ while (end - sector >= RAW_CD_SECTOR_SIZE) {
+ /* look for CD sync header (00, 0xFF x 10, 00) */
+ if (memcmp(sector,sync_header,sizeof(sync_header)))
+ return 0;
- if(sector[0x11] >= 32)
- return 0;
- if( (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_VIDEO
- && (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_AUDIO
- && (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_DATA)
- return 0;
+ if (sector[0x11] >= 32)
+ return 0;
+
+ switch (sector[0x12] & CDXA_TYPE_MASK) {
+ case CDXA_TYPE_DATA:
+ case CDXA_TYPE_VIDEO: {
+ int current_sector = AV_RL16(&sector[0x1C]);
+ int sector_count = AV_RL16(&sector[0x1E]);
+ int frame_size = AV_RL32(&sector[0x24]);
+
+ if(!( frame_size>=0
+ && current_sector < sector_count
+ && sector_count*VIDEO_DATA_CHUNK_SIZE >=frame_size)){
+ return 0;
+ }
+ /*st->codec->width = AV_RL16(&sector[0x28]);
+ st->codec->height = AV_RL16(&sector[0x2A]);*/
+
+// if (current_sector == sector_count-1) {
+ vid++;
+// }
+
+ }
+ break;
+ case CDXA_TYPE_AUDIO:
+ if(sector[0x13]&0x2A)
+ return 0;
+ aud++;
+ break;
+ default:
+ if(sector[0x12] & CDXA_TYPE_MASK)
+ return 0;
+ }
+ sector += RAW_CD_SECTOR_SIZE;
+ }
/* MPEG files (like those ripped from VCDs) can also look like this;
* only return half certainty */
- return 50;
+ if(vid+aud > 3) return 50;
+ else if(vid+aud) return 1;
+ else return 0;
}
static int str_read_header(AVFormatContext *s,
@@ -162,7 +196,7 @@ static int str_read_packet(AVFormatContext *s,
if(str->channels[channel].video_stream_index < 0){
/* allocate a new AVStream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 64, 1, 15);
@@ -210,7 +244,7 @@ static int str_read_packet(AVFormatContext *s,
if(str->channels[channel].audio_stream_index < 0){
int fmt = sector[0x13];
/* allocate a new AVStream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -240,7 +274,7 @@ static int str_read_packet(AVFormatContext *s,
break;
}
- if (pb->eof_reached)
+ if (url_feof(pb))
return AVERROR(EIO);
}
}
@@ -258,11 +292,11 @@ static int str_read_close(AVFormatContext *s)
}
AVInputFormat ff_str_demuxer = {
- "psxstr",
- NULL_IF_CONFIG_SMALL("Sony Playstation STR format"),
- sizeof(StrDemuxContext),
- str_probe,
- str_read_header,
- str_read_packet,
- str_read_close,
+ .name = "psxstr",
+ .long_name = NULL_IF_CONFIG_SMALL("Sony Playstation STR format"),
+ .priv_data_size = sizeof(StrDemuxContext),
+ .read_probe = str_probe,
+ .read_header = str_read_header,
+ .read_packet = str_read_packet,
+ .read_close = str_read_close,
};
diff --git a/libavformat/pva.c b/libavformat/pva.c
index 79b959cef6..7e8fa8eb73 100644
--- a/libavformat/pva.c
+++ b/libavformat/pva.c
@@ -2,20 +2,20 @@
* TechnoTrend PVA (.pva) demuxer
* Copyright (c) 2007, 2008 Ivo van Poorten
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -31,19 +31,32 @@ typedef struct {
int continue_pes;
} PVAContext;
+static int pva_check(uint8_t *p) {
+ int length = AV_RB16(p + 6);
+ if (AV_RB16(p) != PVA_MAGIC || !p[2] || p[2] > 2 || p[4] != 0x55 ||
+ (p[5] & 0xe0) || length > PVA_MAX_PAYLOAD_LENGTH)
+ return -1;
+ return length + 8;
+}
+
static int pva_probe(AVProbeData * pd) {
unsigned char *buf = pd->buf;
+ int len = pva_check(buf);
- if (AV_RB16(buf) == PVA_MAGIC && buf[2] && buf[2] < 3 && buf[4] == 0x55)
+ if (len < 0)
+ return 0;
+
+ if (pd->buf_size >= len + 8 &&
+ pva_check(buf + len) >= 0)
return AVPROBE_SCORE_MAX / 2;
- return 0;
+ return AVPROBE_SCORE_MAX / 4;
}
static int pva_read_header(AVFormatContext *s, AVFormatParameters *ap) {
AVStream *st;
- if (!(st = av_new_stream(s, 0)))
+ if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_MPEG2VIDEO;
@@ -51,7 +64,7 @@ static int pva_read_header(AVFormatContext *s, AVFormatParameters *ap) {
av_set_pts_info(st, 32, 1, 90000);
av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME);
- if (!(st = av_new_stream(s, 1)))
+ if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_MP2;
@@ -201,11 +214,11 @@ static int64_t pva_read_timestamp(struct AVFormatContext *s, int stream_index,
}
AVInputFormat ff_pva_demuxer = {
- "pva",
- NULL_IF_CONFIG_SMALL("TechnoTrend PVA file and stream format"),
- sizeof(PVAContext),
- pva_probe,
- pva_read_header,
- pva_read_packet,
+ .name = "pva",
+ .long_name = NULL_IF_CONFIG_SMALL("TechnoTrend PVA file and stream format"),
+ .priv_data_size = sizeof(PVAContext),
+ .read_probe = pva_probe,
+ .read_header = pva_read_header,
+ .read_packet = pva_read_packet,
.read_timestamp = pva_read_timestamp
};
diff --git a/libavformat/qcp.c b/libavformat/qcp.c
index 635d531f44..c88c39b25d 100644
--- a/libavformat/qcp.c
+++ b/libavformat/qcp.c
@@ -2,20 +2,20 @@
* QCP format (.qcp) demuxer
* Copyright (c) 2009 Kenan Gillet
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -23,7 +23,7 @@
* @file
* QCP format (.qcp) demuxer
* @author Kenan Gillet
- * @sa RFC 3625: "The QCP File Format and Media Types for Speech Data"
+ * @see RFC 3625: "The QCP File Format and Media Types for Speech Data"
* http://tools.ietf.org/html/rfc3625
*/
@@ -84,7 +84,7 @@ static int qcp_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
AVIOContext *pb = s->pb;
QCPContext *c = s->priv_data;
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
uint8_t buf[16];
int i, nb_rates;
@@ -92,8 +92,7 @@ static int qcp_read_header(AVFormatContext *s, AVFormatParameters *ap)
return AVERROR(ENOMEM);
avio_rb32(pb); // "RIFF"
- s->file_size = avio_rl32(pb) + 8;
- avio_skip(pb, 8 + 4 + 1 + 1); // "QLCMfmt " + chunk-size + major-version + minor-version
+ avio_skip(pb, 4 + 8 + 4 + 1 + 1); // filesize + "QLCMfmt " + chunk-size + major-version + minor-version
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->channels = 1;
@@ -140,7 +139,7 @@ static int qcp_read_packet(AVFormatContext *s, AVPacket *pkt)
QCPContext *c = s->priv_data;
unsigned int chunk_size, tag;
- while(!pb->eof_reached) {
+ while(!url_feof(pb)) {
if (c->data_size) {
int pkt_size, ret, mode = avio_r8(pb);
diff --git a/libavformat/qtpalette.h b/libavformat/qtpalette.h
index ecc85d3408..7d6802f73c 100644
--- a/libavformat/qtpalette.h
+++ b/libavformat/qtpalette.h
@@ -3,20 +3,20 @@
* Automatically generated from a utility derived from XAnim:
* http://xanim.va.pubnix.com/home.html
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/r3d.c b/libavformat/r3d.c
index 5dd7f997e5..75fc4a4c96 100644
--- a/libavformat/r3d.c
+++ b/libavformat/r3d.c
@@ -2,20 +2,20 @@
* R3D REDCODE demuxer
* Copyright (c) 2008 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -52,7 +52,7 @@ static int read_atom(AVFormatContext *s, Atom *atom)
static int r3d_read_red1(AVFormatContext *s)
{
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
char filename[258];
int tmp;
int av_unused tmp2;
@@ -89,7 +89,7 @@ static int r3d_read_red1(AVFormatContext *s)
tmp = avio_r8(s->pb); // audio channels
av_dlog(s, "audio channels %d\n", tmp);
if (tmp > 0) {
- AVStream *ast = av_new_stream(s, 1);
+ AVStream *ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -365,7 +365,8 @@ static int r3d_seek(AVFormatContext *s, int stream_index, int64_t sample_time, i
frame_num, sample_time);
if (frame_num < r3d->video_offsets_count) {
- avio_seek(s->pb, r3d->video_offsets_count, SEEK_SET);
+ if (avio_seek(s->pb, r3d->video_offsets_count, SEEK_SET) < 0)
+ return -1;
} else {
av_log(s, AV_LOG_ERROR, "could not seek to frame %d\n", frame_num);
return -1;
@@ -384,12 +385,12 @@ static int r3d_close(AVFormatContext *s)
}
AVInputFormat ff_r3d_demuxer = {
- "r3d",
- NULL_IF_CONFIG_SMALL("REDCODE R3D format"),
- sizeof(R3DContext),
- r3d_probe,
- r3d_read_header,
- r3d_read_packet,
- r3d_close,
- r3d_seek,
+ .name = "r3d",
+ .long_name = NULL_IF_CONFIG_SMALL("REDCODE R3D format"),
+ .priv_data_size = sizeof(R3DContext),
+ .read_probe = r3d_probe,
+ .read_header = r3d_read_header,
+ .read_packet = r3d_read_packet,
+ .read_close = r3d_close,
+ .read_seek = r3d_seek,
};
diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c
index cc05c353e9..37e9b0c8f1 100644
--- a/libavformat/rawdec.c
+++ b/libavformat/rawdec.c
@@ -3,20 +3,20 @@
* Copyright (c) 2001 Fabrice Bellard
* Copyright (c) 2005 Alex Beregszaszi
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -33,7 +33,7 @@ int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap)
AVStream *st;
enum CodecID id;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -49,17 +49,14 @@ int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap)
case AVMEDIA_TYPE_AUDIO: {
RawAudioDemuxerContext *s1 = s->priv_data;
-#if FF_API_FORMAT_PARAMETERS
- if (ap->sample_rate)
- st->codec->sample_rate = ap->sample_rate;
- if (ap->channels)
- st->codec->channels = ap->channels;
- else st->codec->channels = 1;
-#endif
+ st->codec->channels = 1;
+
+ if (id == CODEC_ID_ADPCM_G722)
+ st->codec->sample_rate = 16000;
- if (s1->sample_rate)
+ if (s1 && s1->sample_rate)
st->codec->sample_rate = s1->sample_rate;
- if (s1->channels)
+ if (s1 && s1->channels)
st->codec->channels = s1->channels;
st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
@@ -87,16 +84,6 @@ int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap)
av_log(s, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s1->framerate);
goto fail;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->width > 0)
- width = ap->width;
- if (ap->height > 0)
- height = ap->height;
- if (ap->pix_fmt)
- pix_fmt = ap->pix_fmt;
- if (ap->time_base.num)
- framerate = (AVRational){ap->time_base.den, ap->time_base.num};
-#endif
av_set_pts_info(st, 64, framerate.den, framerate.num);
st->codec->width = width;
st->codec->height = height;
@@ -135,12 +122,13 @@ int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt)
int ff_raw_audio_read_header(AVFormatContext *s,
AVFormatParameters *ap)
{
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = s->iformat->value;
st->need_parsing = AVSTREAM_PARSE_FULL;
+ st->start_time = 0;
/* the parameters will be extracted from the compressed bitstream */
return 0;
@@ -156,7 +144,7 @@ int ff_raw_video_read_header(AVFormatContext *s,
int ret = 0;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st) {
ret = AVERROR(ENOMEM);
goto fail;
@@ -170,10 +158,6 @@ int ff_raw_video_read_header(AVFormatContext *s,
av_log(s, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s1->framerate);
goto fail;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->time_base.num)
- framerate = (AVRational){ap->time_base.den, ap->time_base.num};
-#endif
st->codec->time_base = (AVRational){framerate.den, framerate.num};
av_set_pts_info(st, 64, 1, 1200000);
@@ -184,78 +168,59 @@ fail:
/* Note: Do not forget to add new entries to the Makefile as well. */
-static const AVOption audio_options[] = {
- { "sample_rate", "", offsetof(RawAudioDemuxerContext, sample_rate), FF_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
- { "channels", "", offsetof(RawAudioDemuxerContext, channels), FF_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
- { NULL },
-};
-
-const AVClass ff_rawaudio_demuxer_class = {
- .class_name = "rawaudio demuxer",
- .item_name = av_default_item_name,
- .option = audio_options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
#define OFFSET(x) offsetof(FFRawVideoDemuxerContext, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
-static const AVOption video_options[] = {
- { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
- { "pixel_format", "", OFFSET(pixel_format), FF_OPT_TYPE_STRING, {.str = "yuv420p"}, 0, 0, DEC },
- { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+const AVOption ff_rawvideo_options[] = {
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC},
{ NULL },
};
-#undef OFFSET
-#undef DEC
-
-const AVClass ff_rawvideo_demuxer_class = {
- .class_name = "rawvideo demuxer",
- .item_name = av_default_item_name,
- .option = video_options,
- .version = LIBAVUTIL_VERSION_INT,
-};
#if CONFIG_G722_DEMUXER
AVInputFormat ff_g722_demuxer = {
- "g722",
- NULL_IF_CONFIG_SMALL("raw G.722"),
- sizeof(RawAudioDemuxerContext),
- NULL,
- ff_raw_read_header,
- ff_raw_read_partial_packet,
+ .name = "g722",
+ .long_name = NULL_IF_CONFIG_SMALL("raw G.722"),
+ .read_header = ff_raw_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "g722,722",
.value = CODEC_ID_ADPCM_G722,
- .priv_class = &ff_rawaudio_demuxer_class,
};
#endif
#if CONFIG_GSM_DEMUXER
AVInputFormat ff_gsm_demuxer = {
- "gsm",
- NULL_IF_CONFIG_SMALL("raw GSM"),
- 0,
- NULL,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
+ .name = "gsm",
+ .long_name = NULL_IF_CONFIG_SMALL("raw GSM"),
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "gsm",
.value = CODEC_ID_GSM,
};
#endif
+#if CONFIG_LATM_DEMUXER
+AVInputFormat ff_latm_demuxer = {
+ .name = "latm",
+ .long_name = NULL_IF_CONFIG_SMALL("raw LOAS/LATM"),
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
+ .flags= AVFMT_GENERIC_INDEX,
+ .extensions = "latm",
+ .value = CODEC_ID_AAC_LATM,
+};
+#endif
+
#if CONFIG_MJPEG_DEMUXER
FF_DEF_RAWVIDEO_DEMUXER(mjpeg, "raw MJPEG video", NULL, "mjpg,mjpeg", CODEC_ID_MJPEG)
#endif
#if CONFIG_MLP_DEMUXER
AVInputFormat ff_mlp_demuxer = {
- "mlp",
- NULL_IF_CONFIG_SMALL("raw MLP"),
- 0,
- NULL,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
+ .name = "mlp",
+ .long_name = NULL_IF_CONFIG_SMALL("raw MLP"),
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "mlp",
.value = CODEC_ID_MLP,
@@ -264,12 +229,10 @@ AVInputFormat ff_mlp_demuxer = {
#if CONFIG_TRUEHD_DEMUXER
AVInputFormat ff_truehd_demuxer = {
- "truehd",
- NULL_IF_CONFIG_SMALL("raw TrueHD"),
- 0,
- NULL,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
+ .name = "truehd",
+ .long_name = NULL_IF_CONFIG_SMALL("raw TrueHD"),
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "thd",
.value = CODEC_ID_TRUEHD,
@@ -278,13 +241,11 @@ AVInputFormat ff_truehd_demuxer = {
#if CONFIG_SHORTEN_DEMUXER
AVInputFormat ff_shorten_demuxer = {
- "shn",
- NULL_IF_CONFIG_SMALL("raw Shorten"),
- 0,
- NULL,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
- .flags= AVFMT_GENERIC_INDEX,
+ .name = "shn",
+ .long_name = NULL_IF_CONFIG_SMALL("raw Shorten"),
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
+ .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK,
.extensions = "shn",
.value = CODEC_ID_SHORTEN,
};
diff --git a/libavformat/rawdec.h b/libavformat/rawdec.h
index 76e8053f6d..a2011ebcba 100644
--- a/libavformat/rawdec.h
+++ b/libavformat/rawdec.h
@@ -2,20 +2,20 @@
* RAW demuxers
* Copyright (C) 2007 Aurelien Jacobs <aurel@gnuage.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -24,6 +24,7 @@
#include "avformat.h"
#include "libavutil/log.h"
+#include "libavutil/opt.h"
typedef struct RawAudioDemuxerContext {
AVClass *class;
@@ -38,8 +39,7 @@ typedef struct FFRawVideoDemuxerContext {
char *framerate; /**< String describing framerate, set by a private option. */
} FFRawVideoDemuxerContext;
-extern const AVClass ff_rawaudio_demuxer_class;
-extern const AVClass ff_rawvideo_demuxer_class;
+extern const AVOption ff_rawvideo_options[];
int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap);
@@ -49,7 +49,16 @@ int ff_raw_audio_read_header(AVFormatContext *s, AVFormatParameters *ap);
int ff_raw_video_read_header(AVFormatContext *s, AVFormatParameters *ap);
+#define FF_RAWVIDEO_DEMUXER_CLASS(name)\
+static const AVClass name ## _demuxer_class = {\
+ .class_name = #name " demuxer",\
+ .item_name = av_default_item_name,\
+ .option = ff_rawvideo_options,\
+ .version = LIBAVUTIL_VERSION_INT,\
+};
+
#define FF_DEF_RAWVIDEO_DEMUXER(shortname, longname, probe, ext, id)\
+FF_RAWVIDEO_DEMUXER_CLASS(shortname)\
AVInputFormat ff_ ## shortname ## _demuxer = {\
.name = #shortname,\
.long_name = NULL_IF_CONFIG_SMALL(longname),\
@@ -60,7 +69,7 @@ AVInputFormat ff_ ## shortname ## _demuxer = {\
.flags = AVFMT_GENERIC_INDEX,\
.value = id,\
.priv_data_size = sizeof(FFRawVideoDemuxerContext),\
- .priv_class = &ff_rawvideo_demuxer_class,\
+ .priv_class = &shortname ## _demuxer_class,\
};
#endif /* AVFORMAT_RAWDEC_H */
diff --git a/libavformat/rawenc.c b/libavformat/rawenc.c
index 00e43df9a7..b2ff79abf3 100644
--- a/libavformat/rawenc.c
+++ b/libavformat/rawenc.c
@@ -3,20 +3,20 @@
* Copyright (c) 2001 Fabrice Bellard
* Copyright (c) 2005 Alex Beregszaszi
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -34,195 +34,176 @@ int ff_raw_write_packet(AVFormatContext *s, AVPacket *pkt)
#if CONFIG_AC3_MUXER
AVOutputFormat ff_ac3_muxer = {
- "ac3",
- NULL_IF_CONFIG_SMALL("raw AC-3"),
- "audio/x-ac3",
- "ac3",
- 0,
- CODEC_ID_AC3,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
+ .name = "ac3",
+ .long_name = NULL_IF_CONFIG_SMALL("raw AC-3"),
+ .mime_type = "audio/x-ac3",
+ .extensions = "ac3",
+ .audio_codec = CODEC_ID_AC3,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_DIRAC_MUXER
AVOutputFormat ff_dirac_muxer = {
- "dirac",
- NULL_IF_CONFIG_SMALL("raw Dirac"),
- NULL,
- "drc",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_DIRAC,
- NULL,
- ff_raw_write_packet,
+ .name = "dirac",
+ .long_name = NULL_IF_CONFIG_SMALL("raw Dirac"),
+ .extensions = "drc",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_DIRAC,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_DNXHD_MUXER
AVOutputFormat ff_dnxhd_muxer = {
- "dnxhd",
- NULL_IF_CONFIG_SMALL("raw DNxHD (SMPTE VC-3)"),
- NULL,
- "dnxhd",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_DNXHD,
- NULL,
- ff_raw_write_packet,
+ .name = "dnxhd",
+ .long_name = NULL_IF_CONFIG_SMALL("raw DNxHD (SMPTE VC-3)"),
+ .extensions = "dnxhd",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_DNXHD,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_DTS_MUXER
AVOutputFormat ff_dts_muxer = {
- "dts",
- NULL_IF_CONFIG_SMALL("raw DTS"),
- "audio/x-dca",
- "dts",
- 0,
- CODEC_ID_DTS,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
+ .name = "dts",
+ .long_name = NULL_IF_CONFIG_SMALL("raw DTS"),
+ .mime_type = "audio/x-dca",
+ .extensions = "dts",
+ .audio_codec = CODEC_ID_DTS,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_EAC3_MUXER
AVOutputFormat ff_eac3_muxer = {
- "eac3",
- NULL_IF_CONFIG_SMALL("raw E-AC-3"),
- "audio/x-eac3",
- "eac3",
- 0,
- CODEC_ID_EAC3,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
+ .name = "eac3",
+ .long_name = NULL_IF_CONFIG_SMALL("raw E-AC-3"),
+ .mime_type = "audio/x-eac3",
+ .extensions = "eac3",
+ .audio_codec = CODEC_ID_EAC3,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_G722_MUXER
AVOutputFormat ff_g722_muxer = {
- "g722",
- NULL_IF_CONFIG_SMALL("raw G.722"),
- "audio/G722",
- "g722",
- 0,
- CODEC_ID_ADPCM_G722,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
+ .name = "g722",
+ .long_name = NULL_IF_CONFIG_SMALL("raw G.722"),
+ .mime_type = "audio/G722",
+ .extensions = "g722",
+ .audio_codec = CODEC_ID_ADPCM_G722,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
+ .flags= AVFMT_NOTIMESTAMPS,
+};
+#endif
+
+#if CONFIG_G723_1_MUXER
+AVOutputFormat ff_g723_1_muxer = {
+ .name = "g723_1",
+ .long_name = NULL_IF_CONFIG_SMALL("raw G.723.1"),
+ .mime_type = "audio/g723",
+ .extensions = "tco,rco",
+ .audio_codec = CODEC_ID_G723_1,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_H261_MUXER
AVOutputFormat ff_h261_muxer = {
- "h261",
- NULL_IF_CONFIG_SMALL("raw H.261"),
- "video/x-h261",
- "h261",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_H261,
- NULL,
- ff_raw_write_packet,
+ .name = "h261",
+ .long_name = NULL_IF_CONFIG_SMALL("raw H.261"),
+ .mime_type = "video/x-h261",
+ .extensions = "h261",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_H261,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_H263_MUXER
AVOutputFormat ff_h263_muxer = {
- "h263",
- NULL_IF_CONFIG_SMALL("raw H.263"),
- "video/x-h263",
- "h263",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_H263,
- NULL,
- ff_raw_write_packet,
+ .name = "h263",
+ .long_name = NULL_IF_CONFIG_SMALL("raw H.263"),
+ .mime_type = "video/x-h263",
+ .extensions = "h263",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_H263,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_H264_MUXER
AVOutputFormat ff_h264_muxer = {
- "h264",
- NULL_IF_CONFIG_SMALL("raw H.264 video format"),
- NULL,
- "h264",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_H264,
- NULL,
- ff_raw_write_packet,
+ .name = "h264",
+ .long_name = NULL_IF_CONFIG_SMALL("raw H.264 video format"),
+ .extensions = "h264",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_H264,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_CAVSVIDEO_MUXER
AVOutputFormat ff_cavsvideo_muxer = {
- "cavsvideo",
- NULL_IF_CONFIG_SMALL("raw Chinese AVS video"),
- NULL,
- "cavs",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_CAVS,
- NULL,
- ff_raw_write_packet,
+ .name = "cavsvideo",
+ .long_name = NULL_IF_CONFIG_SMALL("raw Chinese AVS video"),
+ .extensions = "cavs",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_CAVS,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_M4V_MUXER
AVOutputFormat ff_m4v_muxer = {
- "m4v",
- NULL_IF_CONFIG_SMALL("raw MPEG-4 video format"),
- NULL,
- "m4v",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_MPEG4,
- NULL,
- ff_raw_write_packet,
+ .name = "m4v",
+ .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-4 video format"),
+ .extensions = "m4v",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_MPEG4,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_MJPEG_MUXER
AVOutputFormat ff_mjpeg_muxer = {
- "mjpeg",
- NULL_IF_CONFIG_SMALL("raw MJPEG video"),
- "video/x-mjpeg",
- "mjpg,mjpeg",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_MJPEG,
- NULL,
- ff_raw_write_packet,
+ .name = "mjpeg",
+ .long_name = NULL_IF_CONFIG_SMALL("raw MJPEG video"),
+ .mime_type = "video/x-mjpeg",
+ .extensions = "mjpg,mjpeg",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_MJPEG,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_MLP_MUXER
AVOutputFormat ff_mlp_muxer = {
- "mlp",
- NULL_IF_CONFIG_SMALL("raw MLP"),
- NULL,
- "mlp",
- 0,
- CODEC_ID_MLP,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
+ .name = "mlp",
+ .long_name = NULL_IF_CONFIG_SMALL("raw MLP"),
+ .extensions = "mlp",
+ .audio_codec = CODEC_ID_MLP,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
@@ -241,60 +222,49 @@ AVOutputFormat ff_srt_muxer = {
#if CONFIG_TRUEHD_MUXER
AVOutputFormat ff_truehd_muxer = {
- "truehd",
- NULL_IF_CONFIG_SMALL("raw TrueHD"),
- NULL,
- "thd",
- 0,
- CODEC_ID_TRUEHD,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
+ .name = "truehd",
+ .long_name = NULL_IF_CONFIG_SMALL("raw TrueHD"),
+ .extensions = "thd",
+ .audio_codec = CODEC_ID_TRUEHD,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_MPEG1VIDEO_MUXER
AVOutputFormat ff_mpeg1video_muxer = {
- "mpeg1video",
- NULL_IF_CONFIG_SMALL("raw MPEG-1 video"),
- "video/x-mpeg",
- "mpg,mpeg,m1v",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_MPEG1VIDEO,
- NULL,
- ff_raw_write_packet,
+ .name = "mpeg1video",
+ .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-1 video"),
+ .mime_type = "video/x-mpeg",
+ .extensions = "mpg,mpeg,m1v",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_MPEG1VIDEO,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_MPEG2VIDEO_MUXER
AVOutputFormat ff_mpeg2video_muxer = {
- "mpeg2video",
- NULL_IF_CONFIG_SMALL("raw MPEG-2 video"),
- NULL,
- "m2v",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_MPEG2VIDEO,
- NULL,
- ff_raw_write_packet,
+ .name = "mpeg2video",
+ .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-2 video"),
+ .extensions = "m2v",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_RAWVIDEO_MUXER
AVOutputFormat ff_rawvideo_muxer = {
- "rawvideo",
- NULL_IF_CONFIG_SMALL("raw video format"),
- NULL,
- "yuv,rgb",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_RAWVIDEO,
- NULL,
- ff_raw_write_packet,
+ .name = "rawvideo",
+ .long_name = NULL_IF_CONFIG_SMALL("raw video format"),
+ .extensions = "yuv,rgb",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
diff --git a/libavformat/rawenc.h b/libavformat/rawenc.h
index daa5489da8..b5523090b8 100644
--- a/libavformat/rawenc.h
+++ b/libavformat/rawenc.h
@@ -2,20 +2,20 @@
* RAW muxers
* Copyright (C) 2007 Aurelien Jacobs <aurel@gnuage.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rawvideodec.c b/libavformat/rawvideodec.c
index f8d9b65f36..8bd0dc92f0 100644
--- a/libavformat/rawvideodec.c
+++ b/libavformat/rawvideodec.c
@@ -2,20 +2,20 @@
* RAW video demuxer
* Copyright (c) 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -44,15 +44,30 @@ static int rawvideo_read_packet(AVFormatContext *s, AVPacket *pkt)
return 0;
}
+#define OFFSET(x) offsetof(FFRawVideoDemuxerContext, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+static const AVOption rawvideo_options[] = {
+ { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = "yuv420p"}, 0, 0, DEC },
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+ { NULL },
+};
+
+static const AVClass rawvideo_demuxer_class = {
+ .class_name = "rawvideo demuxer",
+ .item_name = av_default_item_name,
+ .option = rawvideo_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_rawvideo_demuxer = {
- "rawvideo",
- NULL_IF_CONFIG_SMALL("raw video format"),
- sizeof(FFRawVideoDemuxerContext),
- NULL,
- ff_raw_read_header,
- rawvideo_read_packet,
+ .name = "rawvideo",
+ .long_name = NULL_IF_CONFIG_SMALL("raw video format"),
+ .priv_data_size = sizeof(FFRawVideoDemuxerContext),
+ .read_header = ff_raw_read_header,
+ .read_packet = rawvideo_read_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "yuv,cif,qcif,rgb",
.value = CODEC_ID_RAWVIDEO,
- .priv_class = &ff_rawvideo_demuxer_class,
+ .priv_class = &rawvideo_demuxer_class,
};
diff --git a/libavformat/rdt.c b/libavformat/rdt.c
index 9155cfc480..74f9c55fba 100644
--- a/libavformat/rdt.c
+++ b/libavformat/rdt.c
@@ -2,20 +2,20 @@
* Realmedia RTSP protocol (RDT) support.
* Copyright (c) 2007 Ronald S. Bultje
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -459,8 +459,9 @@ add_dstream(AVFormatContext *s, AVStream *orig_st)
{
AVStream *st;
- if (!(st = av_new_stream(s, orig_st->id)))
+ if (!(st = avformat_new_stream(s, NULL)))
return NULL;
+ st->id = orig_st->id;
st->codec->codec_type = orig_st->codec->codec_type;
st->first_dts = orig_st->first_dts;
diff --git a/libavformat/rdt.h b/libavformat/rdt.h
index 08b17bc397..c2ec94b8b4 100644
--- a/libavformat/rdt.h
+++ b/libavformat/rdt.h
@@ -2,20 +2,20 @@
* Realmedia RTSP (RDT) definitions
* Copyright (c) 2007 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -80,16 +80,16 @@ void ff_rdt_subscribe_rule(char *cmd, int size,
*
* @param buf input buffer
* @param len length of input buffer
- * @param set_id will be set to the set ID this packet belongs to
- * @param seq_no will be set to the sequence number of the packet
- * @param stream_id will be set to the stream ID this packet belongs to
- * @param is_keyframe will be whether this packet belongs to a keyframe
- * @param timestamp will be set to the timestamp of the packet
+ * @param pset_id will be set to the set ID this packet belongs to
+ * @param pseq_no will be set to the sequence number of the packet
+ * @param pstream_id will be set to the stream ID this packet belongs to
+ * @param pis_keyframe will be whether this packet belongs to a keyframe
+ * @param ptimestamp will be set to the timestamp of the packet
* @return the amount of bytes consumed, or negative on error
*/
int ff_rdt_parse_header(const uint8_t *buf, int len,
- int *set_id, int *seq_no, int *stream_id,
- int *is_keyframe, uint32_t *timestamp);
+ int *pset_id, int *pseq_no, int *pstream_id,
+ int *pis_keyframe, uint32_t *ptimestamp);
/**
* Parse RDT-style packet data (header + media data).
diff --git a/libavformat/riff.c b/libavformat/riff.c
index 27f45b91d9..7492df7c0b 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -2,20 +2,20 @@
* RIFF codec tags
* Copyright (c) 2000 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -36,6 +36,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
{ CODEC_ID_H264, MKTAG('D', 'A', 'V', 'C') },
{ CODEC_ID_H264, MKTAG('V', 'S', 'S', 'H') },
+ { CODEC_ID_H264, MKTAG('Q', '2', '6', '4') }, /* QNAP surveillance system */
{ CODEC_ID_H263, MKTAG('H', '2', '6', '3') },
{ CODEC_ID_H263, MKTAG('X', '2', '6', '3') },
{ CODEC_ID_H263, MKTAG('T', '2', '6', '3') },
@@ -87,6 +88,8 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_MPEG4, MKTAG('G', 'E', 'O', 'V') },
{ CODEC_ID_MPEG4, MKTAG('S', 'I', 'P', 'P') }, /* Samsung SHR-6040 */
{ CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'X') },
+ { CODEC_ID_MPEG4, MKTAG('D', 'r', 'e', 'X') },
+ { CODEC_ID_MPEG4, MKTAG('Q', 'M', 'P', '4') }, /* QNAP Systems */
{ CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') },
{ CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '3') },
{ CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', 'G', '3') },
@@ -131,6 +134,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_MPEG2VIDEO, MKTAG('s', 'l', 'i', 'f') },
{ CODEC_ID_MPEG2VIDEO, MKTAG('E', 'M', '2', 'V') },
{ CODEC_ID_MPEG2VIDEO, MKTAG('M', '7', '0', '1') }, /* Matrox MPEG2 intra-only */
+ { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', 'g', 'v') },
{ CODEC_ID_MJPEG, MKTAG('M', 'J', 'P', 'G') },
{ CODEC_ID_MJPEG, MKTAG('L', 'J', 'P', 'G') },
{ CODEC_ID_MJPEG, MKTAG('d', 'm', 'b', '1') },
@@ -172,10 +176,13 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', 's') },
{ CODEC_ID_RAWVIDEO, MKTAG('P', '4', '2', '2') },
{ CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', '1', '2') },
+ { CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', '1', '6') },
+ { CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', '2', '4') },
{ CODEC_ID_RAWVIDEO, MKTAG('U', 'Y', 'V', 'Y') },
{ CODEC_ID_RAWVIDEO, MKTAG('V', 'Y', 'U', 'Y') },
{ CODEC_ID_RAWVIDEO, MKTAG('I', 'Y', 'U', 'V') },
{ CODEC_ID_RAWVIDEO, MKTAG('Y', '8', '0', '0') },
+ { CODEC_ID_RAWVIDEO, MKTAG('Y', '8', ' ', ' ') },
{ CODEC_ID_RAWVIDEO, MKTAG('H', 'D', 'Y', 'C') },
{ CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', 'U', '9') },
{ CODEC_ID_RAWVIDEO, MKTAG('V', 'D', 'T', 'Z') }, /* SoftLab-NSK VideoTizer */
@@ -236,10 +243,10 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_QPEG, MKTAG('Q', '1', '.', '0') },
{ CODEC_ID_QPEG, MKTAG('Q', '1', '.', '1') },
{ CODEC_ID_WMV3, MKTAG('W', 'M', 'V', '3') },
- { CODEC_ID_WMV3, MKTAG('W', 'M', 'V', 'P') },
+ { CODEC_ID_WMV3IMAGE, MKTAG('W', 'M', 'V', 'P') },
{ CODEC_ID_VC1, MKTAG('W', 'V', 'C', '1') },
{ CODEC_ID_VC1, MKTAG('W', 'M', 'V', 'A') },
- { CODEC_ID_VC1, MKTAG('W', 'V', 'P', '2') },
+ { CODEC_ID_VC1IMAGE, MKTAG('W', 'V', 'P', '2') },
{ CODEC_ID_LOCO, MKTAG('L', 'O', 'C', 'O') },
{ CODEC_ID_WNV1, MKTAG('W', 'N', 'V', '1') },
{ CODEC_ID_AASC, MKTAG('A', 'A', 'S', 'C') },
@@ -253,6 +260,8 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_CAVS, MKTAG('C', 'A', 'V', 'S') },
{ CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') },
{ CODEC_ID_JPEG2000, MKTAG('M', 'J', '2', 'C') },
+ { CODEC_ID_JPEG2000, MKTAG('L', 'J', '2', 'C') },
+ { CODEC_ID_JPEG2000, MKTAG('L', 'J', '2', 'K') },
{ CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') },
{ CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') },
{ CODEC_ID_PNG, MKTAG('M', 'P', 'N', 'G') },
@@ -268,6 +277,14 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') },
{ CODEC_ID_KGV1, MKTAG('K', 'G', 'V', '1') },
{ CODEC_ID_LAGARITH, MKTAG('L', 'A', 'G', 'S') },
+ { CODEC_ID_G2M, MKTAG('G', '2', 'M', '2') },
+ { CODEC_ID_G2M, MKTAG('G', '2', 'M', '3') },
+ { CODEC_ID_G2M, MKTAG('G', '2', 'M', '4') },
+ { CODEC_ID_AMV, MKTAG('A', 'M', 'V', 'F') },
+ { CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'R', 'A') },
+ { CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'R', 'G') },
+ { CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'Y', '0') },
+ { CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'Y', '2') },
{ CODEC_ID_NONE, 0 }
};
@@ -287,6 +304,7 @@ const AVCodecTag ff_codec_wav_tags[] = {
{ CODEC_ID_ADPCM_YAMAHA, 0x0020 },
{ CODEC_ID_TRUESPEECH, 0x0022 },
{ CODEC_ID_GSM_MS, 0x0031 },
+ { CODEC_ID_AMR_NB, 0x0038 }, /* rogue format number */
{ CODEC_ID_ADPCM_G726, 0x0045 },
{ CODEC_ID_MP2, 0x0050 },
{ CODEC_ID_MP3, 0x0055 },
@@ -317,6 +335,7 @@ const AVCodecTag ff_codec_wav_tags[] = {
{ CODEC_ID_PCM_MULAW, 0x6c75 },
{ CODEC_ID_AAC, 0x706d },
{ CODEC_ID_AAC, 0x4143 },
+ { CODEC_ID_SPEEX, 0xA109 },
{ CODEC_ID_FLAC, 0xF1AC },
{ CODEC_ID_ADPCM_SWF, ('S'<<8)+'F' },
{ CODEC_ID_VORBIS, ('V'<<8)+'o' }, //HACK/FIXME, does vorbis in WAV/AVI have an (in)official id?
@@ -329,6 +348,14 @@ const AVCodecTag ff_codec_wav_tags[] = {
{ CODEC_ID_NONE, 0 },
};
+const AVCodecGuid ff_codec_wav_guids[] = {
+ {CODEC_ID_AC3, {0x2C,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA}},
+ {CODEC_ID_ATRAC3P, {0xBF,0xAA,0x23,0xE9,0x58,0xCB,0x71,0x44,0xA1,0x19,0xFF,0xFA,0x01,0xE4,0xCE,0x62}},
+ {CODEC_ID_EAC3, {0xAF,0x87,0xFB,0xA7,0x02,0x2D,0xFB,0x42,0xA4,0xD4,0x05,0xCD,0x93,0x84,0x3B,0xDD}},
+ {CODEC_ID_MP2, {0x2B,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA}},
+ {CODEC_ID_NONE}
+};
+
#if CONFIG_MUXERS
int64_t ff_start_tag(AVIOContext *pb, const char *tag)
{
@@ -431,20 +458,18 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
riff_extradata_start= enc->extradata;
riff_extradata= enc->extradata + enc->extradata_size;
hdrsize += enc->extradata_size;
- } else if (!waveformatextensible){
- hdrsize -= 2;
}
if(waveformatextensible) { /* write WAVEFORMATEXTENSIBLE extensions */
hdrsize += 22;
avio_wl16(pb, riff_extradata - riff_extradata_start + 22); /* 22 is WAVEFORMATEXTENSIBLE size */
- avio_wl16(pb, enc->bits_per_coded_sample); /* ValidBitsPerSample || SamplesPerBlock || Reserved */
+ avio_wl16(pb, bps); /* ValidBitsPerSample || SamplesPerBlock || Reserved */
avio_wl32(pb, enc->channel_layout); /* dwChannelMask */
avio_wl32(pb, enc->codec_tag); /* GUID + next 3 */
avio_wl32(pb, 0x00100000);
avio_wl32(pb, 0xAA000080);
avio_wl32(pb, 0x719B3800);
- } else if(riff_extradata - riff_extradata_start) {
- avio_wl16(pb, riff_extradata - riff_extradata_start);
+ } else {
+ avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
}
avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
if(hdrsize&1){
@@ -494,7 +519,6 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size)
id = avio_rl16(pb);
codec->codec_type = AVMEDIA_TYPE_AUDIO;
- codec->codec_tag = id;
codec->channels = avio_rl16(pb);
codec->sample_rate = avio_rl32(pb);
codec->bit_rate = avio_rl32(pb) * 8;
@@ -503,15 +527,29 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size)
codec->bits_per_coded_sample = 8;
}else
codec->bits_per_coded_sample = avio_rl16(pb);
+ if (id == 0xFFFE) {
+ codec->codec_tag = 0;
+ } else {
+ codec->codec_tag = id;
+ codec->codec_id = ff_wav_codec_get_id(id, codec->bits_per_coded_sample);
+ }
if (size >= 18) { /* We're obviously dealing with WAVEFORMATEX */
int cbSize = avio_rl16(pb); /* cbSize */
size -= 18;
cbSize = FFMIN(size, cbSize);
if (cbSize >= 22 && id == 0xfffe) { /* WAVEFORMATEXTENSIBLE */
+ ff_asf_guid subformat;
codec->bits_per_coded_sample = avio_rl16(pb);
codec->channel_layout = avio_rl32(pb); /* dwChannelMask */
- id = avio_rl32(pb); /* 4 first bytes of GUID */
- avio_skip(pb, 12); /* skip end of GUID */
+ ff_get_guid(pb, &subformat);
+ if (!memcmp(subformat + 4, (const uint8_t[]){FF_MEDIASUBTYPE_BASE_GUID}, 12)) {
+ codec->codec_tag = AV_RL32(subformat);
+ codec->codec_id = ff_wav_codec_get_id(codec->codec_tag, codec->bits_per_coded_sample);
+ } else {
+ codec->codec_id = ff_codec_guid_get_id(ff_codec_wav_guids, subformat);
+ if (!codec->codec_id)
+ av_log(codec, AV_LOG_WARNING, "unknown subformat:"FF_PRI_GUID"\n", FF_ARG_GUID(subformat));
+ }
cbSize -= 22;
size -= 22;
}
@@ -529,7 +567,6 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size)
if (size > 0)
avio_skip(pb, size);
}
- codec->codec_id = ff_wav_codec_get_id(id, codec->bits_per_coded_sample);
if (codec->codec_id == CODEC_ID_AAC_LATM) {
/* channels and sample_rate values are those prior to applying SBR and/or PS */
codec->channels = 0;
@@ -599,3 +636,19 @@ void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssiz
*au_scale /= gcd;
*au_rate /= gcd;
}
+
+void ff_get_guid(AVIOContext *s, ff_asf_guid *g)
+{
+ assert(sizeof(*g) == 16);
+ avio_read(s, *g, sizeof(*g));
+}
+
+enum CodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid)
+{
+ int i;
+ for (i = 0; guids[i].id != CODEC_ID_NONE; i++) {
+ if (!ff_guidcmp(guids[i].guid, guid))
+ return guids[i].id;
+ }
+ return CODEC_ID_NONE;
+}
diff --git a/libavformat/riff.h b/libavformat/riff.h
index a2fa8b7b1c..85caacbb69 100644
--- a/libavformat/riff.h
+++ b/libavformat/riff.h
@@ -2,20 +2,20 @@
* RIFF codec tags
* copyright (c) 2000 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -54,4 +54,30 @@ unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum CodecID id);
enum CodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag);
void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssize, int *au_scale);
+typedef uint8_t ff_asf_guid[16];
+
+#define FF_PRI_GUID \
+ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
+#define FF_ARG_GUID(g) \
+ g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]
+
+static av_always_inline int ff_guidcmp(const void *g1, const void *g2)
+{
+ return memcmp(g1, g2, sizeof(ff_asf_guid));
+}
+
+void ff_get_guid(AVIOContext *s, ff_asf_guid *g);
+
+typedef struct {
+ enum CodecID id;
+ ff_asf_guid guid;
+} AVCodecGuid;
+
+enum CodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid);
+
+extern const AVCodecGuid ff_codec_wav_guids[];
+
+#define FF_MEDIASUBTYPE_BASE_GUID \
+ 0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71
+
#endif /* AVFORMAT_RIFF_H */
diff --git a/libavformat/rl2.c b/libavformat/rl2.c
index 12cb391ad8..743250a922 100644
--- a/libavformat/rl2.c
+++ b/libavformat/rl2.c
@@ -2,20 +2,20 @@
* RL2 Format Demuxer
* Copyright (c) 2008 Sascha Sommer (saschasommer@freenet.de)
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -23,8 +23,7 @@
* RL2 file demuxer
* @file
* @author Sascha Sommer (saschasommer@freenet.de)
- * For more information regarding the RL2 file format, visit:
- * http://wiki.multimedia.cx/index.php?title=RL2
+ * @see http://wiki.multimedia.cx/index.php?title=RL2
*
* extradata:
* 2 byte le initial drawing offset within 320x200 viewport
@@ -111,7 +110,7 @@ static av_cold int rl2_read_header(AVFormatContext *s,
def_sound_size = avio_rl16(pb);
/** setup video stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if(!st)
return AVERROR(ENOMEM);
@@ -141,7 +140,7 @@ static av_cold int rl2_read_header(AVFormatContext *s,
pts_num = def_sound_size;
pts_den = rate;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -287,13 +286,12 @@ static int rl2_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
}
AVInputFormat ff_rl2_demuxer = {
- "rl2",
- NULL_IF_CONFIG_SMALL("RL2 format"),
- sizeof(Rl2DemuxContext),
- rl2_probe,
- rl2_read_header,
- rl2_read_packet,
- NULL,
- rl2_read_seek,
+ .name = "rl2",
+ .long_name = NULL_IF_CONFIG_SMALL("RL2 format"),
+ .priv_data_size = sizeof(Rl2DemuxContext),
+ .read_probe = rl2_probe,
+ .read_header = rl2_read_header,
+ .read_packet = rl2_read_packet,
+ .read_seek = rl2_read_seek,
};
diff --git a/libavformat/rm.c b/libavformat/rm.c
index 9c0ad4a58b..f2942964d4 100644
--- a/libavformat/rm.c
+++ b/libavformat/rm.c
@@ -2,20 +2,20 @@
* "Real" compatible muxer and demuxer common code.
* Copyright (c) 2009 Aurelien Jacobs <aurel@gnuage.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rm.h b/libavformat/rm.h
index 9d104ad74c..6de10924ab 100644
--- a/libavformat/rm.h
+++ b/libavformat/rm.h
@@ -2,20 +2,20 @@
* "Real" compatible muxer and demuxer.
* Copyright (c) 2000, 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index fbc4d0cee6..b73b51aaf8 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -2,20 +2,20 @@
* "Real" compatible demuxer.
* Copyright (c) 2000, 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -26,6 +26,13 @@
#include "riff.h"
#include "rm.h"
+#define DEINT_ID_GENR MKTAG('g', 'e', 'n', 'r') ///< interleaving for Cooker/Atrac
+#define DEINT_ID_INT0 MKTAG('I', 'n', 't', '0') ///< no interleaving needed
+#define DEINT_ID_INT4 MKTAG('I', 'n', 't', '4') ///< interleaving for 28.8
+#define DEINT_ID_SIPR MKTAG('s', 'i', 'p', 'r') ///< interleaving for Sipro
+#define DEINT_ID_VBRF MKTAG('v', 'b', 'r', 'f') ///< VBR case for AAC
+#define DEINT_ID_VBRS MKTAG('v', 'b', 'r', 's') ///< VBR case for AAC
+
struct RMStream {
AVPacket pkt; ///< place to store merged video frame / reordered audio data
int videobufsize; ///< current assembled frame size
@@ -39,6 +46,7 @@ struct RMStream {
int sub_packet_size, sub_packet_h, coded_framesize; ///< Descrambling parameters from container
int audio_framesize; /// Audio frame size from container
int sub_packet_lengths[16]; /// Length of each subpacket
+ int32_t deint_id; ///< deinterleaver used in audio stream
};
typedef struct {
@@ -147,6 +155,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
st->codec->channels = 1;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_RA_144;
+ ast->deint_id = DEINT_ID_INT0;
} else {
int flavor, sub_packet_h, coded_framesize, sub_packet_size;
int codecdata_length;
@@ -172,17 +181,19 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
avio_rb32(pb);
st->codec->channels = avio_rb16(pb);
if (version == 5) {
- avio_rb32(pb);
+ ast->deint_id = avio_rl32(pb);
avio_read(pb, buf, 4);
buf[4] = 0;
} else {
get_str8(pb, buf, sizeof(buf)); /* desc */
+ ast->deint_id = AV_RL32(buf);
get_str8(pb, buf, sizeof(buf)); /* desc */
}
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_tag = AV_RL32(buf);
st->codec->codec_id = ff_codec_get_id(ff_rm_codec_tags,
st->codec->codec_tag);
+
switch (st->codec->codec_id) {
case CODEC_ID_AC3:
st->need_parsing = AVSTREAM_PARSE_FULL;
@@ -191,13 +202,6 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
st->codec->extradata_size= 0;
ast->audio_framesize = st->codec->block_align;
st->codec->block_align = coded_framesize;
-
- if(ast->audio_framesize >= UINT_MAX / sub_packet_h){
- av_log(s, AV_LOG_ERROR, "ast->audio_framesize * sub_packet_h too large\n");
- return -1;
- }
-
- av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h);
break;
case CODEC_ID_COOK:
case CODEC_ID_ATRAC3:
@@ -229,12 +233,6 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0)
return ret;
- if(ast->audio_framesize >= UINT_MAX / sub_packet_h){
- av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n");
- return -1;
- }
-
- av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h);
break;
case CODEC_ID_AAC:
avio_rb16(pb); avio_r8(pb);
@@ -254,6 +252,37 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
default:
av_strlcpy(st->codec->codec_name, buf, sizeof(st->codec->codec_name));
}
+ if (ast->deint_id == DEINT_ID_INT4 ||
+ ast->deint_id == DEINT_ID_GENR ||
+ ast->deint_id == DEINT_ID_SIPR) {
+ if (st->codec->block_align <= 0 ||
+ ast->audio_framesize * sub_packet_h > (unsigned)INT_MAX ||
+ ast->audio_framesize * sub_packet_h < st->codec->block_align)
+ return AVERROR_INVALIDDATA;
+ if (av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h) < 0)
+ return AVERROR(ENOMEM);
+ }
+ switch (ast->deint_id) {
+ case DEINT_ID_INT4:
+ if (ast->coded_framesize > ast->audio_framesize ||
+ ast->coded_framesize * sub_packet_h > (2 + (sub_packet_h & 1)) * ast->audio_framesize)
+ return AVERROR_INVALIDDATA;
+ break;
+ case DEINT_ID_GENR:
+ if (ast->sub_packet_size <= 0 ||
+ ast->sub_packet_size > ast->audio_framesize)
+ return AVERROR_INVALIDDATA;
+ break;
+ case DEINT_ID_SIPR:
+ case DEINT_ID_INT0:
+ case DEINT_ID_VBRS:
+ case DEINT_ID_VBRF:
+ break;
+ default:
+ av_log(NULL,0,"Unknown interleaver %X\n", ast->deint_id);
+ return AVERROR_INVALIDDATA;
+ }
+
if (read_all) {
avio_r8(pb);
avio_r8(pb);
@@ -293,30 +322,21 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb,
// av_log(s, AV_LOG_DEBUG, "%X %X\n", st->codec->codec_tag, MKTAG('R', 'V', '2', '0'));
if (st->codec->codec_id == CODEC_ID_NONE)
goto fail1;
- st->codec->width = avio_rb16(pb);
+ st->codec->width = avio_rb16(pb);
st->codec->height = avio_rb16(pb);
- st->codec->time_base.num= 1;
- fps= avio_rb16(pb);
+ avio_skip(pb, 2); // looks like bits per sample
+ avio_skip(pb, 4); // always zero?
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- avio_rb32(pb);
- avio_skip(pb, 2);
- avio_rb16(pb);
+ st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
+ fps = avio_rb32(pb);
if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (avio_tell(pb) - codec_pos))) < 0)
return ret;
-// av_log(s, AV_LOG_DEBUG, "fps= %d fps2= %d\n", fps, fps2);
- st->codec->time_base.den = fps * st->codec->time_base.num;
- //XXX: do we really need that?
- switch(st->codec->extradata[4]>>4){
- case 1: st->codec->codec_id = CODEC_ID_RV10; break;
- case 2: st->codec->codec_id = CODEC_ID_RV20; break;
- case 3: st->codec->codec_id = CODEC_ID_RV30; break;
- case 4: st->codec->codec_id = CODEC_ID_RV40; break;
- default:
- av_log(st->codec, AV_LOG_ERROR, "extra:%02X %02X %02X %02X %02X\n", st->codec->extradata[0], st->codec->extradata[1], st->codec->extradata[2], st->codec->extradata[3], st->codec->extradata[4]);
- goto fail1;
- }
+ av_reduce(&st->codec->time_base.num, &st->codec->time_base.den,
+ 0x10000, fps, (1 << 30) - 1);
+ st->avg_frame_rate.num = st->codec->time_base.den;
+ st->avg_frame_rate.den = st->codec->time_base.num;
}
skip:
@@ -371,13 +391,13 @@ skip:
return 0;
}
-static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap)
+static int rm_read_header_old(AVFormatContext *s)
{
RMDemuxContext *rm = s->priv_data;
AVStream *st;
rm->old_format = 1;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
st->priv_data = ff_rm_alloc_rmstream();
@@ -399,7 +419,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
tag = avio_rl32(pb);
if (tag == MKTAG('.', 'r', 'a', 0xfd)) {
/* very old .ra format */
- return rm_read_header_old(s, ap);
+ return rm_read_header_old(s);
} else if (tag != MKTAG('.', 'R', 'M', 'F')) {
return AVERROR(EIO);
}
@@ -410,7 +430,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
avio_rb32(pb); /* number of headers */
for(;;) {
- if (pb->eof_reached)
+ if (url_feof(pb))
return -1;
tag = avio_rl32(pb);
tag_size = avio_rb32(pb);
@@ -443,7 +463,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
rm_read_metadata(s, 1);
break;
case MKTAG('M', 'D', 'P', 'R'):
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->id = avio_rb16(pb);
@@ -514,7 +534,7 @@ static int sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_
AVStream *st;
uint32_t state=0xFFFFFFFF;
- while(!pb->eof_reached){
+ while(!url_feof(pb)){
int len, num, i;
*pos= avio_tell(pb) - 3;
if(rm->remaining_len > 0){
@@ -578,7 +598,8 @@ skip:
static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,
RMDemuxContext *rm, RMStream *vst,
- AVPacket *pkt, int len, int *pseq)
+ AVPacket *pkt, int len, int *pseq,
+ int64_t *timestamp)
{
int hdr, seq, pic_num, len2, pos;
int type;
@@ -598,8 +619,10 @@ static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,
return -1;
rm->remaining_len = len;
if(type&1){ // frame, not slice
- if(type == 3) // frame as a part of packet
+ if(type == 3){ // frame as a part of packet
len= len2;
+ *timestamp = pos;
+ }
if(rm->remaining_len < len)
return -1;
rm->remaining_len -= len;
@@ -707,13 +730,12 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb,
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
rm->current_stream= st->id;
- if(rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq))
+ if(rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq, &timestamp))
return -1; //got partial frame
} else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- if ((st->codec->codec_id == CODEC_ID_RA_288) ||
- (st->codec->codec_id == CODEC_ID_COOK) ||
- (st->codec->codec_id == CODEC_ID_ATRAC3) ||
- (st->codec->codec_id == CODEC_ID_SIPR)) {
+ if ((ast->deint_id == DEINT_ID_GENR) ||
+ (ast->deint_id == DEINT_ID_INT4) ||
+ (ast->deint_id == DEINT_ID_SIPR)) {
int x;
int sps = ast->sub_packet_size;
int cfs = ast->coded_framesize;
@@ -726,30 +748,30 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb,
if (!y)
ast->audiotimestamp = timestamp;
- switch(st->codec->codec_id) {
- case CODEC_ID_RA_288:
+ switch (ast->deint_id) {
+ case DEINT_ID_INT4:
for (x = 0; x < h/2; x++)
avio_read(pb, ast->pkt.data+x*2*w+y*cfs, cfs);
break;
- case CODEC_ID_ATRAC3:
- case CODEC_ID_COOK:
+ case DEINT_ID_GENR:
for (x = 0; x < w/sps; x++)
avio_read(pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps);
break;
- case CODEC_ID_SIPR:
+ case DEINT_ID_SIPR:
avio_read(pb, ast->pkt.data + y * w, w);
break;
}
if (++(ast->sub_packet_cnt) < h)
return -1;
- if (st->codec->codec_id == CODEC_ID_SIPR)
+ if (ast->deint_id == DEINT_ID_SIPR)
ff_rm_reorder_sipr_data(ast->pkt.data, h, w);
ast->sub_packet_cnt = 0;
rm->audio_stream_num = st->index;
rm->audio_pkt_cnt = h * w / st->codec->block_align;
- } else if (st->codec->codec_id == CODEC_ID_AAC) {
+ } else if ((ast->deint_id == DEINT_ID_VBRF) ||
+ (ast->deint_id == DEINT_ID_VBRS)) {
int x;
rm->audio_stream_num = st->index;
ast->sub_packet_cnt = (avio_rb16(pb) & 0xf0) >> 4;
@@ -782,7 +804,7 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb,
}
#endif
- pkt->pts= timestamp;
+ pkt->pts = timestamp;
if (flags & 2)
pkt->flags |= AV_PKT_FLAG_KEY;
@@ -797,7 +819,8 @@ ff_rm_retrieve_cache (AVFormatContext *s, AVIOContext *pb,
assert (rm->audio_pkt_cnt > 0);
- if (st->codec->codec_id == CODEC_ID_AAC)
+ if (ast->deint_id == DEINT_ID_VBRF ||
+ ast->deint_id == DEINT_ID_VBRS)
av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]);
else {
av_new_packet(pkt, st->codec->block_align);
@@ -847,7 +870,7 @@ static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
st = s->streams[i];
}
- if(len<0 || s->pb->eof_reached)
+ if(len<0 || url_feof(s->pb))
return AVERROR(EIO);
res = ff_rm_parse_packet (s, s->pb, st, st->priv_data, len, pkt,
@@ -903,7 +926,9 @@ static int64_t rm_read_dts(AVFormatContext *s, int stream_index,
if(rm->old_format)
return AV_NOPTS_VALUE;
- avio_seek(s->pb, pos, SEEK_SET);
+ if (avio_seek(s->pb, pos, SEEK_SET) < 0)
+ return AV_NOPTS_VALUE;
+
rm->remaining_len=0;
for(;;){
int seq=1;
@@ -935,23 +960,19 @@ static int64_t rm_read_dts(AVFormatContext *s, int stream_index,
}
AVInputFormat ff_rm_demuxer = {
- "rm",
- NULL_IF_CONFIG_SMALL("RealMedia format"),
- sizeof(RMDemuxContext),
- rm_probe,
- rm_read_header,
- rm_read_packet,
- rm_read_close,
- NULL,
- rm_read_dts,
+ .name = "rm",
+ .long_name = NULL_IF_CONFIG_SMALL("RealMedia format"),
+ .priv_data_size = sizeof(RMDemuxContext),
+ .read_probe = rm_probe,
+ .read_header = rm_read_header,
+ .read_packet = rm_read_packet,
+ .read_close = rm_read_close,
+ .read_timestamp = rm_read_dts,
};
AVInputFormat ff_rdt_demuxer = {
- "rdt",
- NULL_IF_CONFIG_SMALL("RDT demuxer"),
- sizeof(RMDemuxContext),
- NULL,
- NULL,
- NULL,
- rm_read_close,
+ .name = "rdt",
+ .long_name = NULL_IF_CONFIG_SMALL("RDT demuxer"),
+ .priv_data_size = sizeof(RMDemuxContext),
+ .read_close = rm_read_close,
};
diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c
index 2476cb0590..a601331e2e 100644
--- a/libavformat/rmenc.c
+++ b/libavformat/rmenc.c
@@ -2,20 +2,20 @@
* "Real" compatible muxer.
* Copyright (c) 2000, 2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
@@ -461,15 +461,15 @@ static int rm_write_trailer(AVFormatContext *s)
AVOutputFormat ff_rm_muxer = {
- "rm",
- NULL_IF_CONFIG_SMALL("RealMedia format"),
- "application/vnd.rn-realmedia",
- "rm,ra",
- sizeof(RMMuxContext),
- CODEC_ID_AC3,
- CODEC_ID_RV10,
- rm_write_header,
- rm_write_packet,
- rm_write_trailer,
+ .name = "rm",
+ .long_name = NULL_IF_CONFIG_SMALL("RealMedia format"),
+ .mime_type = "application/vnd.rn-realmedia",
+ .extensions = "rm,ra",
+ .priv_data_size = sizeof(RMMuxContext),
+ .audio_codec = CODEC_ID_AC3,
+ .video_codec = CODEC_ID_RV10,
+ .write_header = rm_write_header,
+ .write_packet = rm_write_packet,
+ .write_trailer = rm_write_trailer,
.codec_tag= (const AVCodecTag* const []){ff_rm_codec_tags, 0},
};
diff --git a/libavformat/rpl.c b/libavformat/rpl.c
index f67d3cd7c4..b8214e3604 100644
--- a/libavformat/rpl.c
+++ b/libavformat/rpl.c
@@ -2,20 +2,20 @@
* ARMovie/RPL demuxer
* Copyright (c) 2007 Christian Ohm, 2008 Eli Friedman
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -139,7 +139,7 @@ static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap)
av_dict_set(&s->metadata, "author" , line, 0);
// video headers
- vst = av_new_stream(s, 0);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -181,7 +181,7 @@ static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap)
// samples, though. This code will ignore additional tracks.
audio_format = read_line_and_int(pb, &error); // audio format ID
if (audio_format) {
- ast = av_new_stream(s, 0);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -351,10 +351,10 @@ static int rpl_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_rpl_demuxer = {
- "rpl",
- NULL_IF_CONFIG_SMALL("RPL/ARMovie format"),
- sizeof(RPLContext),
- rpl_probe,
- rpl_read_header,
- rpl_read_packet,
+ .name = "rpl",
+ .long_name = NULL_IF_CONFIG_SMALL("RPL/ARMovie format"),
+ .priv_data_size = sizeof(RPLContext),
+ .read_probe = rpl_probe,
+ .read_header = rpl_read_header,
+ .read_packet = rpl_read_packet,
};
diff --git a/libavformat/rso.c b/libavformat/rso.c
index fc39abcc8a..178fd3f224 100644
--- a/libavformat/rso.c
+++ b/libavformat/rso.c
@@ -2,20 +2,20 @@
* RSO format common data
* Copyright (c) 2010 Rafael Carre
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rso.h b/libavformat/rso.h
index bdb39e8d7f..acb0f14063 100644
--- a/libavformat/rso.h
+++ b/libavformat/rso.h
@@ -2,20 +2,20 @@
* RSO format common data
* Copyright (c) 2010 Rafael Carre
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rsodec.c b/libavformat/rsodec.c
index 98de8fe669..14adc04b4b 100644
--- a/libavformat/rsodec.c
+++ b/libavformat/rsodec.c
@@ -3,20 +3,20 @@
* Copyright (c) 2001 Fabrice Bellard (original AU code)
* Copyright (c) 2010 Rafael Carre
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -54,7 +54,7 @@ static int rso_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
/* now we are ready: build format streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
diff --git a/libavformat/rsoenc.c b/libavformat/rsoenc.c
index 338ecf0173..ca9985b070 100644
--- a/libavformat/rsoenc.c
+++ b/libavformat/rsoenc.c
@@ -3,20 +3,20 @@
* Copyright (c) 2001 Fabrice Bellard (original AU code)
* Copyright (c) 2010 Rafael Carre
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtmp.h b/libavformat/rtmp.h
index 45de73ef2b..b0436c0391 100644
--- a/libavformat/rtmp.h
+++ b/libavformat/rtmp.h
@@ -2,20 +2,20 @@
* RTMP definitions
* Copyright (c) 2009 Kostya Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 6bf641a742..7e2ccdc6ac 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -2,20 +2,20 @@
* RTMP input format
* Copyright (c) 2009 Kostya Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtmppkt.h b/libavformat/rtmppkt.h
index 8372484fbd..8acbfc116b 100644
--- a/libavformat/rtmppkt.h
+++ b/libavformat/rtmppkt.h
@@ -2,20 +2,20 @@
* RTMP packet utilities
* Copyright (c) 2009 Kostya Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index de4eb0fd23..ed483cf37f 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -2,20 +2,20 @@
* RTMP network protocol
* Copyright (c) 2009 Kostya Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -71,6 +71,9 @@ typedef struct RTMPContext {
uint32_t client_report_size; ///< number of bytes after which client should report to server
uint32_t bytes_read; ///< number of bytes read from server
uint32_t last_bytes_read; ///< number of bytes read last reported to server
+ int skip_bytes; ///< number of bytes to skip from the input FLV stream in the next write call
+ uint8_t flv_header[11]; ///< partial incoming flv packet header
+ int flv_header_bytes; ///< number of initialized bytes in flv_header
} RTMPContext;
#define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing
@@ -879,6 +882,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
rt->flv_size = 0;
rt->flv_data = NULL;
rt->flv_off = 0;
+ rt->skip_bytes = 13;
}
s->max_packet_size = rt->stream->max_packet_size;
@@ -925,25 +929,29 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
uint32_t ts;
const uint8_t *buf_temp = buf;
- if (size < 11) {
- av_log(s, AV_LOG_DEBUG, "FLV packet too small %d\n", size);
- return 0;
- }
-
do {
- if (!rt->flv_off) {
- //skip flv header
- if (buf_temp[0] == 'F' && buf_temp[1] == 'L' && buf_temp[2] == 'V') {
- buf_temp += 9 + 4;
- size_temp -= 9 + 4;
- }
+ if (rt->skip_bytes) {
+ int skip = FFMIN(rt->skip_bytes, size_temp);
+ buf_temp += skip;
+ size_temp -= skip;
+ rt->skip_bytes -= skip;
+ continue;
+ }
+
+ if (rt->flv_header_bytes < 11) {
+ const uint8_t *header = rt->flv_header;
+ int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
+ bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
+ rt->flv_header_bytes += copy;
+ size_temp -= copy;
+ if (rt->flv_header_bytes < 11)
+ break;
- pkttype = bytestream_get_byte(&buf_temp);
- pktsize = bytestream_get_be24(&buf_temp);
- ts = bytestream_get_be24(&buf_temp);
- ts |= bytestream_get_byte(&buf_temp) << 24;
- bytestream_get_be24(&buf_temp);
- size_temp -= 11;
+ pkttype = bytestream_get_byte(&header);
+ pktsize = bytestream_get_be24(&header);
+ ts = bytestream_get_be24(&header);
+ ts |= bytestream_get_byte(&header) << 24;
+ bytestream_get_be24(&header);
rt->flv_size = pktsize;
//force 12bytes header
@@ -966,20 +974,23 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
if (rt->flv_size - rt->flv_off > size_temp) {
bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
rt->flv_off += size_temp;
+ size_temp = 0;
} else {
bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
+ size_temp -= rt->flv_size - rt->flv_off;
rt->flv_off += rt->flv_size - rt->flv_off;
}
if (rt->flv_off == rt->flv_size) {
- bytestream_get_be32(&buf_temp);
+ rt->skip_bytes = 4;
ff_rtmp_packet_write(rt->stream, &rt->out_pkt, rt->chunk_size, rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&rt->out_pkt);
rt->flv_size = 0;
rt->flv_off = 0;
+ rt->flv_header_bytes = 0;
}
- } while (buf_temp - buf < size_temp);
+ } while (buf_temp - buf < size);
return size;
}
diff --git a/libavformat/rtp.c b/libavformat/rtp.c
index d59b6941b6..98d96160db 100644
--- a/libavformat/rtp.c
+++ b/libavformat/rtp.c
@@ -2,23 +2,24 @@
* RTP input/output format
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <libavutil/opt.h>
#include "avformat.h"
#include "rtp.h"
@@ -43,7 +44,7 @@ static const struct
{
{0, "PCMU", AVMEDIA_TYPE_AUDIO, CODEC_ID_PCM_MULAW, 8000, 1},
{3, "GSM", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
- {4, "G723", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
+ {4, "G723", AVMEDIA_TYPE_AUDIO, CODEC_ID_G723_1, 8000, 1},
{5, "DVI4", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
{6, "DVI4", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 16000, 1},
{7, "LPC", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
@@ -89,21 +90,32 @@ int ff_rtp_get_codec_info(AVCodecContext *codec, int payload_type)
return -1;
}
-int ff_rtp_get_payload_type(AVCodecContext *codec)
+int ff_rtp_get_payload_type(AVFormatContext *fmt, AVCodecContext *codec)
{
- int i, payload_type;
+ int i;
+ AVOutputFormat *ofmt = fmt ? fmt->oformat : NULL;
+
+ /* Was the payload type already specified for the RTP muxer? */
+ if (ofmt && ofmt->priv_class) {
+ int64_t payload_type;
+ if (av_opt_get_int(fmt->priv_data, "payload_type", 0, &payload_type) >= 0 &&
+ payload_type >= 0)
+ return (int)payload_type;
+ }
- /* compute the payload type */
- for (payload_type = -1, i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i)
+ /* static payload type */
+ for (i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i)
if (AVRtpPayloadTypes[i].codec_id == codec->codec_id) {
if (codec->codec_id == CODEC_ID_H263)
continue;
if (codec->codec_id == CODEC_ID_PCM_S16BE)
if (codec->channels != AVRtpPayloadTypes[i].audio_channels)
continue;
- payload_type = AVRtpPayloadTypes[i].pt;
+ return AVRtpPayloadTypes[i].pt;
}
- return payload_type;
+
+ /* dynamic payload type */
+ return RTP_PT_PRIVATE + (codec->codec_type == AVMEDIA_TYPE_AUDIO);
}
const char *ff_rtp_enc_name(int payload_type)
diff --git a/libavformat/rtp.h b/libavformat/rtp.h
index 36157ce172..5297e17f6a 100644
--- a/libavformat/rtp.h
+++ b/libavformat/rtp.h
@@ -2,36 +2,36 @@
* RTP definitions
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * 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_RTP_H
#define AVFORMAT_RTP_H
+#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
/**
- * Return the payload type for a given codec.
+ * Return the payload type for a given codec used in the given format context.
*
+ * @param fmt The context of the format
* @param codec The context of the codec
- * @return In case of unknown payload type or dynamic payload type, a
- * negative value is returned; otherwise, the payload type (the 'PT' field
- * in the RTP header) is returned.
+ * @return The payload type (the 'PT' field in the RTP header).
*/
-int ff_rtp_get_payload_type(AVCodecContext *codec);
+int ff_rtp_get_payload_type(AVFormatContext *fmt, AVCodecContext *codec);
/**
* Initialize a codec context based on the payload type.
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 2c262d9bd3..9023dd6985 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -2,20 +2,20 @@
* RTP input format
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -112,14 +112,15 @@ RTPDynamicProtocolHandler *ff_rtp_handler_find_by_id(int id,
static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len)
{
int payload_len;
- while (len >= 2) {
+ while (len >= 4) {
+ payload_len = FFMIN(len, (AV_RB16(buf + 2) + 1) * 4);
+
switch (buf[1]) {
case RTCP_SR:
- if (len < 16) {
+ if (payload_len < 20) {
av_log(NULL, AV_LOG_ERROR, "Invalid length for RTCP SR packet\n");
return AVERROR_INVALIDDATA;
}
- payload_len = (AV_RB16(buf + 2) + 1) * 4;
s->last_rtcp_ntp_time = AV_RB64(buf + 8);
s->last_rtcp_timestamp = AV_RB32(buf + 16);
@@ -130,14 +131,13 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int l
s->rtcp_ts_offset = s->last_rtcp_timestamp - s->base_timestamp;
}
- buf += payload_len;
- len -= payload_len;
break;
case RTCP_BYE:
return -RTCP_BYE;
- default:
- return -1;
}
+
+ buf += payload_len;
+ len -= payload_len;
}
return -1;
}
@@ -218,23 +218,7 @@ static int rtp_valid_packet_in_sequence(RTPStatistics *s, uint16_t seq)
return 1;
}
-#if 0
-/**
-* This function is currently unused; without a valid local ntp time, I don't see how we could calculate the
-* difference between the arrival and sent timestamp. As a result, the jitter and transit statistics values
-* never change. I left this in in case someone else can see a way. (rdm)
-*/
-static void rtcp_update_jitter(RTPStatistics *s, uint32_t sent_timestamp, uint32_t arrival_timestamp)
-{
- uint32_t transit= arrival_timestamp - sent_timestamp;
- int d;
- s->transit= transit;
- d= FFABS(transit - s->transit);
- s->jitter += d - ((s->jitter + 8)>>4);
-}
-#endif
-
-int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
+int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
{
AVIOContext *pb;
uint8_t *buf;
@@ -331,7 +315,7 @@ int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
return 0;
}
-void rtp_send_punch_packets(URLContext* rtp_handle)
+void ff_rtp_send_punch_packets(URLContext* rtp_handle)
{
AVIOContext *pb;
uint8_t *buf;
@@ -375,7 +359,7 @@ void rtp_send_punch_packets(URLContext* rtp_handle)
* MPEG2TS streams to indicate that they should be demuxed inside the
* rtp demux (otherwise CODEC_ID_MPEG2TS packets are returned)
*/
-RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, int queue_size)
+RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, int queue_size)
{
RTPDemuxContext *s;
@@ -423,8 +407,8 @@ RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *r
}
void
-rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
- RTPDynamicProtocolHandler *handler)
+ff_rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
+ RTPDynamicProtocolHandler *handler)
{
s->dynamic_protocol_context = ctx;
s->parse_packet = handler->parse_packet;
@@ -738,8 +722,8 @@ static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt,
* @return 0 if a packet is returned, 1 if a packet is returned and more can follow
* (use buf as NULL to read the next). -1 if no packet (error or no more packet).
*/
-int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
- uint8_t **bufptr, int len)
+int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
+ uint8_t **bufptr, int len)
{
int rv = rtp_parse_one_packet(s, pkt, bufptr, len);
s->prev_ret = rv;
@@ -748,7 +732,7 @@ int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
return rv ? rv : has_next_packet(s);
}
-void rtp_parse_close(RTPDemuxContext *s)
+void ff_rtp_parse_close(RTPDemuxContext *s)
{
ff_rtp_reset_packet_queue(s);
if (!strcmp(ff_rtp_enc_name(s->payload_type), "MP2T")) {
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index a4d21aa688..dbb45f5709 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -3,20 +3,20 @@
* Copyright (c) 2002 Fabrice Bellard
* Copyright (c) 2006 Ryan Martell <rdm4@martellventures.com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * 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_RTPDEC_H
@@ -38,18 +38,18 @@ typedef struct RTPDynamicProtocolHandler_s RTPDynamicProtocolHandler;
#define RTP_NOTS_VALUE ((uint32_t)-1)
typedef struct RTPDemuxContext RTPDemuxContext;
-RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, int queue_size);
-void rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
- RTPDynamicProtocolHandler *handler);
-int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
- uint8_t **buf, int len);
-void rtp_parse_close(RTPDemuxContext *s);
+RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, int queue_size);
+void ff_rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
+ RTPDynamicProtocolHandler *handler);
+int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
+ uint8_t **buf, int len);
+void ff_rtp_parse_close(RTPDemuxContext *s);
int64_t ff_rtp_queued_packet_time(RTPDemuxContext *s);
void ff_rtp_reset_packet_queue(RTPDemuxContext *s);
-int rtp_get_local_rtp_port(URLContext *h);
-int rtp_get_local_rtcp_port(URLContext *h);
+int ff_rtp_get_local_rtp_port(URLContext *h);
+int ff_rtp_get_local_rtcp_port(URLContext *h);
-int rtp_set_remote_url(URLContext *h, const char *uri);
+int ff_rtp_set_remote_url(URLContext *h, const char *uri);
/**
* Send a dummy packet on both port pairs to set up the connection
@@ -62,19 +62,19 @@ int rtp_set_remote_url(URLContext *h, const char *uri);
* The same routine is used with RDT too, even if RDT doesn't use normal
* RTP packets otherwise.
*/
-void rtp_send_punch_packets(URLContext* rtp_handle);
+void ff_rtp_send_punch_packets(URLContext* rtp_handle);
/**
* some rtp servers assume client is dead if they don't hear from them...
* so we send a Receiver Report to the provided ByteIO context
* (we don't have access to the rtcp handle from here)
*/
-int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count);
+int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, int count);
/**
* Get the file handle for the RTCP socket.
*/
-int rtp_get_rtcp_file_handle(URLContext *h);
+int ff_rtp_get_rtcp_file_handle(URLContext *h);
// these statistics are used for rtcp receiver reports...
typedef struct {
diff --git a/libavformat/rtpdec_amr.c b/libavformat/rtpdec_amr.c
index b7ff3aa05e..fbf4321698 100644
--- a/libavformat/rtpdec_amr.c
+++ b/libavformat/rtpdec_amr.c
@@ -2,20 +2,20 @@
* RTP AMR Depacketizer, RFC 3267
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c
index 287025f377..b481c37c82 100644
--- a/libavformat/rtpdec_asf.c
+++ b/libavformat/rtpdec_asf.c
@@ -2,20 +2,20 @@
* Microsoft RTP/ASF support.
* Copyright (c) 2008 Ronald S. Bultje
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -233,8 +233,14 @@ static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,
int cur_len = start_off + len_off - off;
int prev_len = out_len;
+ void *newmem;
out_len += cur_len;
- asf->buf = av_realloc(asf->buf, out_len);
+ if (FFMIN(cur_len, len - off) < 0)
+ return -1;
+ newmem = av_realloc(asf->buf, out_len);
+ if (!newmem)
+ return -1;
+ asf->buf = newmem;
memcpy(asf->buf + prev_len, buf + off,
FFMIN(cur_len, len - off));
avio_skip(pb, cur_len);
diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h
index 708c2996d6..16f5a9d3e4 100644
--- a/libavformat/rtpdec_formats.h
+++ b/libavformat/rtpdec_formats.h
@@ -2,20 +2,20 @@
* RTP depacketizer declarations
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpdec_h263.c b/libavformat/rtpdec_h263.c
index 0fb1b25eb0..ea42fff320 100644
--- a/libavformat/rtpdec_h263.c
+++ b/libavformat/rtpdec_h263.c
@@ -2,20 +2,20 @@
* RTP H.263 Depacketizer, RFC 4629
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpdec_h264.c b/libavformat/rtpdec_h264.c
index effdc1fe66..730ed14807 100644
--- a/libavformat/rtpdec_h264.c
+++ b/libavformat/rtpdec_h264.c
@@ -2,20 +2,20 @@
* RTP H264 Protocol (RFC3984)
* Copyright (c) 2006 Ryan Martell
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpdec_latm.c b/libavformat/rtpdec_latm.c
index 42317a9529..4bf2c3fb23 100644
--- a/libavformat/rtpdec_latm.c
+++ b/libavformat/rtpdec_latm.c
@@ -2,20 +2,20 @@
* RTP Depacketization of MP4A-LATM, RFC 3016
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c
index 7a63cc315b..07f07ae10a 100644
--- a/libavformat/rtpdec_mpeg4.c
+++ b/libavformat/rtpdec_mpeg4.c
@@ -3,20 +3,20 @@
* Copyright (c) 2010 Fabrice Bellard
* Romain Degez
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpdec_qcelp.c b/libavformat/rtpdec_qcelp.c
index 325683c396..5eb6770297 100644
--- a/libavformat/rtpdec_qcelp.c
+++ b/libavformat/rtpdec_qcelp.c
@@ -2,20 +2,20 @@
* RTP Depacketization of QCELP/PureVoice, RFC 2658
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpdec_qdm2.c b/libavformat/rtpdec_qdm2.c
index 66dd874003..c4314ec2c4 100644
--- a/libavformat/rtpdec_qdm2.c
+++ b/libavformat/rtpdec_qdm2.c
@@ -2,20 +2,20 @@
* QDesign Music 2 (QDM2) payload for RTP
* Copyright (c) 2010 Ronald S. Bultje
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpdec_qt.c b/libavformat/rtpdec_qt.c
index 8dd2968398..fd63aa7d43 100644
--- a/libavformat/rtpdec_qt.c
+++ b/libavformat/rtpdec_qt.c
@@ -2,20 +2,20 @@
* RTP/Quicktime support.
* Copyright (c) 2009 Ronald S. Bultje
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpdec_svq3.c b/libavformat/rtpdec_svq3.c
index 331434245e..7800766ecf 100644
--- a/libavformat/rtpdec_svq3.c
+++ b/libavformat/rtpdec_svq3.c
@@ -2,28 +2,28 @@
* Sorenson-3 (SVQ3/SV3V) payload for RTP
* Copyright (c) 2010 Ronald S. Bultje
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* @brief RTP support for the SV3V (SVQ3) payload
- * (http://wiki.multimedia.cx/index.php?title=Sorenson_Video_3#Packetization)
* @author Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ * @see http://wiki.multimedia.cx/index.php?title=Sorenson_Video_3#Packetization
*/
#include <string.h>
diff --git a/libavformat/rtpdec_vp8.c b/libavformat/rtpdec_vp8.c
index 026728ec9d..bfc96570d1 100644
--- a/libavformat/rtpdec_vp8.c
+++ b/libavformat/rtpdec_vp8.c
@@ -2,20 +2,20 @@
* RTP VP8 Depacketizer
* Copyright (c) 2010 Josh Allmann
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -23,7 +23,7 @@
* @file
* @brief RTP support for the VP8 payload
* @author Josh Allmann <joshua.allmann@gmail.com>
- * ( http://www.webmproject.org/code/specs/rtp/ )
+ * @see http://www.webmproject.org/code/specs/rtp/
*/
#include "libavcodec/bytestream.h"
diff --git a/libavformat/rtpdec_xiph.c b/libavformat/rtpdec_xiph.c
index a7f36ef59a..6aeea2fd3c 100644
--- a/libavformat/rtpdec_xiph.c
+++ b/libavformat/rtpdec_xiph.c
@@ -3,20 +3,20 @@
* Copyright (c) 2009 Colin McQuillian
* Copyright (c) 2010 Josh Allmann
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index c412158778..83f728bc37 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -2,20 +2,20 @@
* RTP output format
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -32,6 +32,7 @@
static const AVOption options[] = {
FF_RTP_FLAG_OPTS(RTPMuxContext, flags),
+ { "payload_type", "Specify RTP payload type", offsetof(RTPMuxContext, payload_type), AV_OPT_TYPE_INT, {.dbl = -1 }, -1, 127, AV_OPT_FLAG_ENCODING_PARAM },
{ NULL },
};
@@ -87,15 +88,13 @@ static int rtp_write_header(AVFormatContext *s1)
return -1;
st = s1->streams[0];
if (!is_supported(st->codec->codec_id)) {
- av_log(s1, AV_LOG_ERROR, "Unsupported codec %x\n", st->codec->codec_id);
+ av_log(s1, AV_LOG_ERROR, "Unsupported codec %s\n", avcodec_get_name(st->codec->codec_id));
return -1;
}
- s->payload_type = ff_rtp_get_payload_type(st->codec);
if (s->payload_type < 0)
- s->payload_type = RTP_PT_PRIVATE + (st->codec->codec_type == AVMEDIA_TYPE_AUDIO);
-
+ s->payload_type = ff_rtp_get_payload_type(s1, st->codec);
s->base_timestamp = av_get_random_seed();
s->timestamp = s->base_timestamp;
s->cur_timestamp = 0;
@@ -462,15 +461,13 @@ static int rtp_write_trailer(AVFormatContext *s1)
}
AVOutputFormat ff_rtp_muxer = {
- "rtp",
- NULL_IF_CONFIG_SMALL("RTP output format"),
- NULL,
- NULL,
- sizeof(RTPMuxContext),
- CODEC_ID_PCM_MULAW,
- CODEC_ID_NONE,
- rtp_write_header,
- rtp_write_packet,
- rtp_write_trailer,
+ .name = "rtp",
+ .long_name = NULL_IF_CONFIG_SMALL("RTP output format"),
+ .priv_data_size = sizeof(RTPMuxContext),
+ .audio_codec = CODEC_ID_PCM_MULAW,
+ .video_codec = CODEC_ID_MPEG4,
+ .write_header = rtp_write_header,
+ .write_packet = rtp_write_packet,
+ .write_trailer = rtp_write_trailer,
.priv_class = &rtp_muxer_class,
};
diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h
index 3a9e19be06..901336322d 100644
--- a/libavformat/rtpenc.h
+++ b/libavformat/rtpenc.h
@@ -2,20 +2,20 @@
* RTP muxer definitions
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * 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_RTPENC_H
@@ -66,8 +66,8 @@ typedef struct RTPMuxContext RTPMuxContext;
#define FF_RTP_FLAG_MP4A_LATM 1
#define FF_RTP_FLAG_OPTS(ctx, fieldname) \
- { "rtpflags", "RTP muxer flags", offsetof(ctx, fieldname), FF_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
- { "latm", "Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC", 0, FF_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_MP4A_LATM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" } \
+ { "rtpflags", "RTP muxer flags", offsetof(ctx, fieldname), AV_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
+ { "latm", "Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC", 0, AV_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_MP4A_LATM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" } \
void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m);
diff --git a/libavformat/rtpenc_aac.c b/libavformat/rtpenc_aac.c
index 86318dfa6e..e19b28697e 100644
--- a/libavformat/rtpenc_aac.c
+++ b/libavformat/rtpenc_aac.c
@@ -1,20 +1,20 @@
/*
* copyright (c) 2007 Luca Abeni
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpenc_amr.c b/libavformat/rtpenc_amr.c
index 4da7ace32a..367789fccd 100644
--- a/libavformat/rtpenc_amr.c
+++ b/libavformat/rtpenc_amr.c
@@ -3,20 +3,20 @@
* Copyright (c) 2007 Luca Abeni
* Copyright (c) 2009 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c
index 0fb47f6234..f4590faa08 100644
--- a/libavformat/rtpenc_chain.c
+++ b/libavformat/rtpenc_chain.c
@@ -2,20 +2,20 @@
* RTP muxer chaining code
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -31,6 +31,8 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
AVFormatContext *rtpctx;
int ret;
AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
+ uint8_t *rtpflags;
+ AVDictionary *opts = NULL;
if (!rtp_format)
return NULL;
@@ -41,7 +43,7 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
return NULL;
rtpctx->oformat = rtp_format;
- if (!av_new_stream(rtpctx, 0)) {
+ if (!avformat_new_stream(rtpctx, NULL)) {
av_free(rtpctx);
return NULL;
}
@@ -49,13 +51,10 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
rtpctx->max_delay = s->max_delay;
/* Copy other stream parameters. */
rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio;
+ rtpctx->flags |= s->flags & AVFMT_FLAG_MP4A_LATM;
- av_set_parameters(rtpctx, NULL);
- /* Copy the rtpflags values straight through */
- if (s->oformat->priv_class &&
- av_find_opt(s->priv_data, "rtpflags", NULL, 0, 0))
- av_set_int(rtpctx->priv_data, "rtpflags",
- av_get_int(s->priv_data, "rtpflags", NULL));
+ if (av_opt_get(s, "rtpflags", AV_OPT_SEARCH_CHILDREN, &rtpflags) >= 0)
+ av_dict_set(&opts, "rtpflags", rtpflags, AV_DICT_DONT_STRDUP_VAL);
/* Set the synchronized start time. */
rtpctx->start_time_realtime = s->start_time_realtime;
@@ -66,7 +65,8 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
ffio_fdopen(&rtpctx->pb, handle);
} else
ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size);
- ret = avformat_write_header(rtpctx, NULL);
+ ret = avformat_write_header(rtpctx, &opts);
+ av_dict_free(&opts);
if (ret) {
if (handle) {
diff --git a/libavformat/rtpenc_chain.h b/libavformat/rtpenc_chain.h
index 6bdddcfe99..8e6b80aa3f 100644
--- a/libavformat/rtpenc_chain.h
+++ b/libavformat/rtpenc_chain.h
@@ -2,20 +2,20 @@
* RTP muxer chaining code
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpenc_h263.c b/libavformat/rtpenc_h263.c
index fbc696e1b4..84403a1069 100644
--- a/libavformat/rtpenc_h263.c
+++ b/libavformat/rtpenc_h263.c
@@ -3,20 +3,20 @@
* Copyright (c) 2009 Luca Abeni
* Copyright (c) 2009 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpenc_h264.c b/libavformat/rtpenc_h264.c
index 9ca6f7f68e..11074d0d51 100644
--- a/libavformat/rtpenc_h264.c
+++ b/libavformat/rtpenc_h264.c
@@ -2,20 +2,20 @@
* RTP packetization for H.264 (RFC3984)
* Copyright (c) 2008 Luca Abeni
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -29,6 +29,24 @@
#include "avc.h"
#include "rtpenc.h"
+static const uint8_t *avc_mp4_find_startcode(const uint8_t *start, const uint8_t *end, int nal_length_size)
+{
+ int res = 0;
+
+ if (end - start < nal_length_size) {
+ return NULL;
+ }
+ while (nal_length_size--) {
+ res = (res << 8) | *start++;
+ }
+
+ if (end - start < res) {
+ return NULL;
+ }
+
+ return res + start;
+}
+
static void nal_send(AVFormatContext *s1, const uint8_t *buf, int size, int last)
{
RTPMuxContext *s = s1->priv_data;
@@ -66,12 +84,20 @@ void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size)
RTPMuxContext *s = s1->priv_data;
s->timestamp = s->cur_timestamp;
- r = ff_avc_find_startcode(buf1, buf1 + size);
+ r = s->nal_length_size ? (avc_mp4_find_startcode(buf1, buf1 + size, s->nal_length_size) ? buf1 : buf1 + size) : ff_avc_find_startcode(buf1, buf1 + size);
while (r < buf1 + size) {
const uint8_t *r1;
- while(!*(r++));
- r1 = ff_avc_find_startcode(r, buf1 + size);
+ if (s->nal_length_size) {
+ r1 = avc_mp4_find_startcode(r, buf1 + size, s->nal_length_size);
+ if (!r1) {
+ r1 = buf1 + size;
+ }
+ r += s->nal_length_size;
+ } else {
+ while(!*(r++));
+ r1 = ff_avc_find_startcode(r, buf1 + size);
+ }
nal_send(s1, r, r1 - r, (r1 == buf1 + size));
r = r1;
}
diff --git a/libavformat/rtpenc_latm.c b/libavformat/rtpenc_latm.c
index 64676771a7..7535a0fd5f 100644
--- a/libavformat/rtpenc_latm.c
+++ b/libavformat/rtpenc_latm.c
@@ -2,9 +2,9 @@
* RTP Packetization of MPEG-4 Audio (RFC 3016)
* Copyright (c) 2011 Juan Carlos Rodriguez <ing.juancarlosrodriguez@hotmail.com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
diff --git a/libavformat/rtpenc_mpv.c b/libavformat/rtpenc_mpv.c
index f6a5d7726a..0c617337b2 100644
--- a/libavformat/rtpenc_mpv.c
+++ b/libavformat/rtpenc_mpv.c
@@ -3,20 +3,20 @@
* Copyright (c) 2002 Fabrice Bellard
* Copyright (c) 2007 Luca Abeni
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -56,7 +56,7 @@ void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size)
r1 = buf1;
while (1) {
start_code = -1;
- r = ff_find_start_code(r1, end, &start_code);
+ r = avpriv_mpv_find_start_code(r1, end, &start_code);
if((start_code & 0xFFFFFF00) == 0x100) {
/* New start code found */
if (start_code == 0x100) {
diff --git a/libavformat/rtpenc_vp8.c b/libavformat/rtpenc_vp8.c
index afedbb49c0..e865514cef 100644
--- a/libavformat/rtpenc_vp8.c
+++ b/libavformat/rtpenc_vp8.c
@@ -2,20 +2,20 @@
* RTP VP8 Packetizer
* Copyright (c) 2010 Josh Allmann
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpenc_xiph.c b/libavformat/rtpenc_xiph.c
index 07086b1a12..57686326a8 100644
--- a/libavformat/rtpenc_xiph.c
+++ b/libavformat/rtpenc_xiph.c
@@ -2,20 +2,20 @@
* RTP packetization for Xiph audio and video
* Copyright (c) 2010 Josh Allmann
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c
index dba1d35b03..4f4cde621c 100644
--- a/libavformat/rtpproto.c
+++ b/libavformat/rtpproto.c
@@ -2,20 +2,20 @@
* RTP network protocol
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -60,7 +60,7 @@ typedef struct RTPContext {
* @return zero if no error.
*/
-int rtp_set_remote_url(URLContext *h, const char *uri)
+int ff_rtp_set_remote_url(URLContext *h, const char *uri)
{
RTPContext *s = h->priv_data;
char hostname[256];
@@ -115,6 +115,7 @@ static void build_udp_url(char *buf, int buf_size,
url_add_option(buf, buf_size, "pkt_size=%d", max_packet_size);
if (connect)
url_add_option(buf, buf_size, "connect=1");
+ url_add_option(buf, buf_size, "fifo_size=0");
}
/**
@@ -225,20 +226,6 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
int len, n;
struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}};
-#if 0
- for(;;) {
- from_len = sizeof(from);
- len = recvfrom (s->rtp_fd, buf, size, 0,
- (struct sockaddr *)&from, &from_len);
- if (len < 0) {
- if (ff_neterrno() == AVERROR(EAGAIN) ||
- ff_neterrno() == AVERROR(EINTR))
- continue;
- return AVERROR(EIO);
- }
- break;
- }
-#else
for(;;) {
if (url_interrupt_cb())
return AVERROR_EXIT;
@@ -277,7 +264,6 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
return AVERROR(EIO);
}
}
-#endif
return len;
}
@@ -296,14 +282,6 @@ static int rtp_write(URLContext *h, const uint8_t *buf, int size)
}
ret = ffurl_write(hd, buf, size);
-#if 0
- {
- struct timespec ts;
- ts.tv_sec = 0;
- ts.tv_nsec = 10 * 1000000;
- nanosleep(&ts, NULL);
- }
-#endif
return ret;
}
@@ -323,7 +301,7 @@ static int rtp_close(URLContext *h)
* @return the local port number
*/
-int rtp_get_local_rtp_port(URLContext *h)
+int ff_rtp_get_local_rtp_port(URLContext *h)
{
RTPContext *s = h->priv_data;
return ff_udp_get_local_port(s->rtp_hd);
@@ -335,7 +313,7 @@ int rtp_get_local_rtp_port(URLContext *h)
* @return the local port number
*/
-int rtp_get_local_rtcp_port(URLContext *h)
+int ff_rtp_get_local_rtcp_port(URLContext *h)
{
RTPContext *s = h->priv_data;
return ff_udp_get_local_port(s->rtcp_hd);
@@ -347,7 +325,7 @@ static int rtp_get_file_handle(URLContext *h)
return s->rtp_fd;
}
-int rtp_get_rtcp_file_handle(URLContext *h) {
+int ff_rtp_get_rtcp_file_handle(URLContext *h) {
RTPContext *s = h->priv_data;
return s->rtcp_fd;
}
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index ce9bf1e1eb..11533968eb 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -2,20 +2,20 @@
* RTSP/SDP client
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -45,6 +45,7 @@
#include "rtpdec_formats.h"
#include "rtpenc_chain.h"
#include "url.h"
+#include "rtpenc.h"
//#define DEBUG
@@ -56,6 +57,36 @@
#define SDP_MAX_SIZE 16384
#define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
+#define OFFSET(x) offsetof(RTSPState, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+
+#define RTSP_FLAG_OPTS(name, longname) \
+ { name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, DEC, "rtsp_flags" }, \
+ { "filter_src", "Only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" }
+
+const AVOption ff_rtsp_options[] = {
+ { "initial_pause", "Don't start playing the stream immediately", OFFSET(initial_pause), AV_OPT_TYPE_INT, {0}, 0, 1, DEC },
+ FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags),
+ { "rtsp_transport", "RTSP transport protocols", OFFSET(lower_transport_mask), AV_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, DEC|ENC, "rtsp_transport" }, \
+ { "udp", "UDP", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_UDP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
+ { "tcp", "TCP", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_TCP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
+ { "udp_multicast", "UDP multicast", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_UDP_MULTICAST}, 0, 0, DEC, "rtsp_transport" },
+ { "http", "HTTP tunneling", 0, AV_OPT_TYPE_CONST, {(1 << RTSP_LOWER_TRANSPORT_HTTP)}, 0, 0, DEC, "rtsp_transport" },
+ RTSP_FLAG_OPTS("rtsp_flags", "RTSP flags"),
+ { NULL },
+};
+
+static const AVOption sdp_options[] = {
+ RTSP_FLAG_OPTS("sdp_flags", "SDP flags"),
+ { NULL },
+};
+
+static const AVOption rtp_options[] = {
+ RTSP_FLAG_OPTS("rtp_flags", "RTP flags"),
+ { NULL },
+};
+
static void get_word_until_chars(char *buf, int buf_size,
const char *sep, const char **pp)
{
@@ -326,9 +357,10 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
/* no corresponding stream */
} else {
- st = av_new_stream(s, rt->nb_rtsp_streams - 1);
+ st = avformat_new_stream(s, NULL);
if (!st)
return;
+ st->id = rt->nb_rtsp_streams - 1;
rtsp_st->stream_index = st->index;
st->codec->codec_type = codec_type;
if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
@@ -501,7 +533,7 @@ void ff_rtsp_undo_setup(AVFormatContext *s)
} else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC)
ff_rdt_parse_close(rtsp_st->transport_priv);
else if (CONFIG_RTPDEC)
- rtp_parse_close(rtsp_st->transport_priv);
+ ff_rtp_parse_close(rtsp_st->transport_priv);
}
rtsp_st->transport_priv = NULL;
if (rtsp_st->rtp_handle)
@@ -558,7 +590,7 @@ static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
rtsp_st->dynamic_protocol_context,
rtsp_st->dynamic_handler);
else if (CONFIG_RTPDEC)
- rtsp_st->transport_priv = rtp_parse_open(s, st, rtsp_st->rtp_handle,
+ rtsp_st->transport_priv = ff_rtp_parse_open(s, st, rtsp_st->rtp_handle,
rtsp_st->sdp_payload_type,
(rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP || !s->max_delay)
? 0 : RTP_REORDER_QUEUE_DEFAULT_SIZE);
@@ -567,9 +599,9 @@ static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
return AVERROR(ENOMEM);
} else if (rt->transport != RTSP_TRANSPORT_RDT && CONFIG_RTPDEC) {
if (rtsp_st->dynamic_handler) {
- rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
- rtsp_st->dynamic_protocol_context,
- rtsp_st->dynamic_handler);
+ ff_rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
+ rtsp_st->dynamic_protocol_context,
+ rtsp_st->dynamic_handler);
}
}
@@ -808,6 +840,9 @@ void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
if (strstr(p, "GET_PARAMETER") &&
method && !strcmp(method, "OPTIONS"))
rt->get_parameter_supported = 1;
+ } else if (av_stristart(p, "x-Accept-Dynamic-Rate:", &p) && rt) {
+ p += strspn(p, SPACE_CHARS);
+ rt->accept_dynamic_rate = atoi(p);
}
}
@@ -1116,20 +1151,12 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
}
}
-#if 0
- /* then try on any port */
- if (ffurl_open(&rtsp_st->rtp_handle, "rtp://", AVIO_FLAG_READ) < 0) {
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
-#else
av_log(s, AV_LOG_ERROR, "Unable to open an input RTP port\n");
err = AVERROR(EIO);
goto fail;
-#endif
rtp_opened:
- port = rtp_get_local_rtp_port(rtsp_st->rtp_handle);
+ port = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
have_port:
snprintf(transport, sizeof(transport) - 1,
"%s/UDP;", trans_pref);
@@ -1173,6 +1200,8 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
snprintf(cmd, sizeof(cmd),
"Transport: %s\r\n",
transport);
+ if (rt->accept_dynamic_rate)
+ av_strlcat(cmd, "x-Dynamic-Rate: 0\r\n", sizeof(cmd));
if (i == 0 && rt->server_type == RTSP_SERVER_REAL && CONFIG_RTPDEC) {
char real_res[41], real_csum[9];
ff_rdt_calc_response_and_checksum(real_res, real_csum,
@@ -1221,7 +1250,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
case RTSP_LOWER_TRANSPORT_UDP: {
char url[1024], options[30] = "";
- if (rt->filter_source)
+ if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)
av_strlcpy(options, "?connect=1", sizeof(options));
/* Use source address if specified */
if (reply->transports[0].source[0]) {
@@ -1233,7 +1262,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
reply->transports[0].server_port_min, "%s", options);
}
if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
- rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
+ ff_rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
err = AVERROR_INVALIDDATA;
goto fail;
}
@@ -1243,7 +1272,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
*/
if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat &&
CONFIG_RTPDEC)
- rtp_send_punch_packets(rtsp_st->rtp_handle);
+ ff_rtp_send_punch_packets(rtsp_st->rtp_handle);
break;
}
case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
@@ -1311,8 +1340,17 @@ int ff_rtsp_connect(AVFormatContext *s)
if (!ff_network_init())
return AVERROR(EIO);
-redirect:
+
rt->control_transport = RTSP_MODE_PLAIN;
+ if (rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_HTTP)) {
+ rt->lower_transport_mask = 1 << RTSP_LOWER_TRANSPORT_TCP;
+ rt->control_transport = RTSP_MODE_TUNNEL;
+ }
+ /* Only pass through valid flags from here */
+ rt->lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
+
+redirect:
+ lower_transport_mask = rt->lower_transport_mask;
/* extract hostname and port */
av_url_split(NULL, 0, auth, sizeof(auth),
host, sizeof(host), &port, path, sizeof(path), s->filename);
@@ -1322,6 +1360,7 @@ redirect:
if (port < 0)
port = RTSP_DEFAULT_PORT;
+#if FF_API_RTSP_URL_OPTIONS
/* search for options */
option_list = strrchr(path, '?');
if (option_list) {
@@ -1329,6 +1368,7 @@ redirect:
* the options back into the same string. */
filename = option_list;
while (option_list) {
+ int handled = 1;
/* move the option pointer */
option = ++option_list;
option_list = strchr(option_list, '&');
@@ -1346,7 +1386,7 @@ redirect:
lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP);
rt->control_transport = RTSP_MODE_TUNNEL;
} else if (!strcmp(option, "filter_src")) {
- rt->filter_source = 1;
+ rt->rtsp_flags |= RTSP_FLAG_FILTER_SRC;
} else {
/* Write options back into the buffer, using memmove instead
* of strcpy since the strings may overlap. */
@@ -1354,10 +1394,16 @@ redirect:
memmove(++filename, option, len);
filename += len;
if (option_list) *filename = '&';
+ handled = 0;
}
+ if (handled)
+ av_log(s, AV_LOG_WARNING, "Options passed via URL are "
+ "deprecated, use -rtsp_transport "
+ "and -rtsp_flags instead.\n");
}
*filename = 0;
}
+#endif
if (!lower_transport_mask)
lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
@@ -1577,7 +1623,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
if (rtsp_st->rtp_handle) {
p[max_p].fd = ffurl_get_file_handle(rtsp_st->rtp_handle);
p[max_p++].events = POLLIN;
- p[max_p].fd = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
+ p[max_p].fd = ff_rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
p[max_p++].events = POLLIN;
}
}
@@ -1632,7 +1678,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
if (rt->transport == RTSP_TRANSPORT_RDT) {
ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
} else
- ret = rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
+ ret = ff_rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
if (ret == 0) {
rt->cur_transport_priv = NULL;
return 0;
@@ -1680,13 +1726,13 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
len = udp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end);
if (len > 0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
- rtp_check_and_send_back_rr(rtsp_st->transport_priv, len);
+ ff_rtp_check_and_send_back_rr(rtsp_st->transport_priv, len);
break;
}
if (len == AVERROR(EAGAIN) && first_queue_st &&
rt->transport == RTSP_TRANSPORT_RTP) {
rtsp_st = first_queue_st;
- ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
+ ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
goto end;
}
if (len < 0)
@@ -1696,7 +1742,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
if (rt->transport == RTSP_TRANSPORT_RDT) {
ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
} else {
- ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
+ ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
if (ret < 0) {
/* Either bad packet, or a RTCP packet. Check if the
* first_rtcp_ntp_time field was initialized. */
@@ -1800,8 +1846,9 @@ static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap)
namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
ff_url_join(url, sizeof(url), "rtp", NULL,
namebuf, rtsp_st->sdp_port,
- "?localport=%d&ttl=%d", rtsp_st->sdp_port,
- rtsp_st->sdp_ttl);
+ "?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port,
+ rtsp_st->sdp_ttl,
+ rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0);
if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) {
err = AVERROR_INVALIDDATA;
goto fail;
@@ -1823,14 +1870,22 @@ static int sdp_read_close(AVFormatContext *s)
return 0;
}
+static const AVClass sdp_demuxer_class = {
+ .class_name = "SDP demuxer",
+ .item_name = av_default_item_name,
+ .option = sdp_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_sdp_demuxer = {
- "sdp",
- NULL_IF_CONFIG_SMALL("SDP"),
- sizeof(RTSPState),
- sdp_probe,
- sdp_read_header,
- ff_rtsp_fetch_packet,
- sdp_read_close,
+ .name = "sdp",
+ .long_name = NULL_IF_CONFIG_SMALL("SDP"),
+ .priv_data_size = sizeof(RTSPState),
+ .read_probe = sdp_probe,
+ .read_header = sdp_read_header,
+ .read_packet = ff_rtsp_fetch_packet,
+ .read_close = sdp_read_close,
+ .priv_class = &sdp_demuxer_class
};
#endif /* CONFIG_SDP_DEMUXER */
@@ -1927,15 +1982,23 @@ fail:
return ret;
}
+static const AVClass rtp_demuxer_class = {
+ .class_name = "RTP demuxer",
+ .item_name = av_default_item_name,
+ .option = rtp_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_rtp_demuxer = {
- "rtp",
- NULL_IF_CONFIG_SMALL("RTP input format"),
- sizeof(RTSPState),
- rtp_probe,
- rtp_read_header,
- ff_rtsp_fetch_packet,
- sdp_read_close,
+ .name = "rtp",
+ .long_name = NULL_IF_CONFIG_SMALL("RTP input format"),
+ .priv_data_size = sizeof(RTSPState),
+ .read_probe = rtp_probe,
+ .read_header = rtp_read_header,
+ .read_packet = ff_rtsp_fetch_packet,
+ .read_close = sdp_read_close,
.flags = AVFMT_NOFILE,
+ .priv_class = &rtp_demuxer_class
};
#endif /* CONFIG_RTP_DEMUXER */
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 7d2460fe2f..da61829da2 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -2,20 +2,20 @@
* RTSP definitions
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * 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_RTSP_H
@@ -29,6 +29,7 @@
#include "httpauth.h"
#include "libavutil/log.h"
+#include "libavutil/opt.h"
/**
* Network layer over which RTP/etc packet data will be transported.
@@ -37,7 +38,10 @@ enum RTSPLowerTransport {
RTSP_LOWER_TRANSPORT_UDP = 0, /**< UDP/unicast */
RTSP_LOWER_TRANSPORT_TCP = 1, /**< TCP; interleaved in RTSP */
RTSP_LOWER_TRANSPORT_UDP_MULTICAST = 2, /**< UDP/multicast */
- RTSP_LOWER_TRANSPORT_NB
+ RTSP_LOWER_TRANSPORT_NB,
+ RTSP_LOWER_TRANSPORT_HTTP = 8, /**< HTTP tunneled - not a proper
+ transport mode as such,
+ only for use via AVOptions */
};
/**
@@ -220,9 +224,6 @@ typedef struct RTSPState {
* see rtsp_read_play() and rtsp_read_seek(). */
int64_t seek_timestamp;
- /* XXX: currently we use unbuffered input */
- // AVIOContext rtsp_gb;
-
int seq; /**< RTSP command sequence number */
/** copy of RTSPMessageHeader->session_id, i.e. the server-provided session
@@ -316,10 +317,6 @@ typedef struct RTSPState {
/** Reusable buffer for receiving packets */
uint8_t* recvbuf;
- /** Filter incoming UDP packets - receive packets only from the right
- * source address and port. */
- int filter_source;
-
/**
* A mask with all requested transport methods
*/
@@ -349,8 +346,20 @@ typedef struct RTSPState {
* Option flags for the chained RTP muxer.
*/
int rtp_muxer_flags;
+
+ /** Whether the server accepts the x-Dynamic-Rate header */
+ int accept_dynamic_rate;
+
+ /**
+ * Various option flags for the RTSP muxer/demuxer.
+ */
+ int rtsp_flags;
} RTSPState;
+#define RTSP_FLAG_FILTER_SRC 0x1 /**< Filter incoming UDP packets -
+ receive packets only from the right
+ source address and port. */
+
/**
* Describes a single stream, as identified by a single m= line block in the
* SDP content. In the case of RDT, one RTSPStream can represent multiple
@@ -488,9 +497,9 @@ void ff_rtsp_close_streams(AVFormatContext *s);
/**
* Close all connection handles within the RTSP (de)muxer
*
- * @param rt RTSP (de)muxer context
+ * @param s RTSP (de)muxer context
*/
-void ff_rtsp_close_connections(AVFormatContext *rt);
+void ff_rtsp_close_connections(AVFormatContext *s);
/**
* Get the description of the stream and set up the RTSPStream child
@@ -537,4 +546,6 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
*/
void ff_rtsp_undo_setup(AVFormatContext *s);
+extern const AVOption ff_rtsp_options[];
+
#endif /* AVFORMAT_RTSP_H */
diff --git a/libavformat/rtspcodes.h b/libavformat/rtspcodes.h
index 63ceb66cfe..9ee96bfcd0 100644
--- a/libavformat/rtspcodes.h
+++ b/libavformat/rtspcodes.h
@@ -2,20 +2,20 @@
* RTSP definitions
* copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 2dff46d1de..f55b8cf2a2 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -2,27 +2,26 @@
* RTSP demuxer
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
-#include "libavutil/opt.h"
#include "avformat.h"
#include "internal.h"
@@ -164,11 +163,6 @@ static int rtsp_read_header(AVFormatContext *s,
return AVERROR(ENOMEM);
rt->real_setup = rt->real_setup_cache + s->nb_streams;
-#if FF_API_FORMAT_PARAMETERS
- if (ap->initial_pause)
- rt->initial_pause = ap->initial_pause;
-#endif
-
if (rt->initial_pause) {
/* do not start immediately */
} else {
@@ -209,7 +203,7 @@ redo:
id = buf[0];
len = AV_RB16(buf + 1);
av_dlog(s, "id=%d len=%d\n", id, len);
- if (len > buf_size || len < 12)
+ if (len > buf_size || len < 8)
goto redo;
/* get the data */
ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
@@ -383,12 +377,6 @@ static int rtsp_read_close(AVFormatContext *s)
{
RTSPState *rt = s->priv_data;
-#if 0
- /* NOTE: it is valid to flush the buffer here */
- if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
- avio_close(&rt->rtsp_gb);
- }
-#endif
ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
ff_rtsp_close_streams(s);
@@ -399,27 +387,22 @@ static int rtsp_read_close(AVFormatContext *s)
return 0;
}
-static const AVOption options[] = {
- { "initial_pause", "Don't start playing the stream immediately", offsetof(RTSPState, initial_pause), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
- { NULL },
-};
-
const AVClass rtsp_demuxer_class = {
.class_name = "RTSP demuxer",
.item_name = av_default_item_name,
- .option = options,
+ .option = ff_rtsp_options,
.version = LIBAVUTIL_VERSION_INT,
};
AVInputFormat ff_rtsp_demuxer = {
- "rtsp",
- NULL_IF_CONFIG_SMALL("RTSP input format"),
- sizeof(RTSPState),
- rtsp_probe,
- rtsp_read_header,
- rtsp_read_packet,
- rtsp_read_close,
- rtsp_read_seek,
+ .name = "rtsp",
+ .long_name = NULL_IF_CONFIG_SMALL("RTSP input format"),
+ .priv_data_size = sizeof(RTSPState),
+ .read_probe = rtsp_probe,
+ .read_header = rtsp_read_header,
+ .read_packet = rtsp_read_packet,
+ .read_close = rtsp_read_close,
+ .read_seek = rtsp_read_seek,
.flags = AVFMT_NOFILE,
.read_play = rtsp_read_play,
.read_pause = rtsp_read_pause,
diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c
index b76b6adb99..b54ae28eb8 100644
--- a/libavformat/rtspenc.c
+++ b/libavformat/rtspenc.c
@@ -2,20 +2,20 @@
* RTSP muxer
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -33,20 +33,13 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
#include "url.h"
-#include "libavutil/opt.h"
-#include "rtpenc.h"
#define SDP_MAX_SIZE 16384
-static const AVOption options[] = {
- FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags),
- { NULL },
-};
-
static const AVClass rtsp_muxer_class = {
.class_name = "RTSP muxer",
.item_name = av_default_item_name,
- .option = options,
+ .option = ff_rtsp_options,
.version = LIBAVUTIL_VERSION_INT,
};
@@ -241,16 +234,14 @@ static int rtsp_write_close(AVFormatContext *s)
}
AVOutputFormat ff_rtsp_muxer = {
- "rtsp",
- NULL_IF_CONFIG_SMALL("RTSP output format"),
- NULL,
- NULL,
- sizeof(RTSPState),
- CODEC_ID_AAC,
- CODEC_ID_MPEG4,
- rtsp_write_header,
- rtsp_write_packet,
- rtsp_write_close,
+ .name = "rtsp",
+ .long_name = NULL_IF_CONFIG_SMALL("RTSP output format"),
+ .priv_data_size = sizeof(RTSPState),
+ .audio_codec = CODEC_ID_AAC,
+ .video_codec = CODEC_ID_MPEG4,
+ .write_header = rtsp_write_header,
+ .write_packet = rtsp_write_packet,
+ .write_trailer = rtsp_write_close,
.flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER,
.priv_class = &rtsp_muxer_class,
};
diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c
index 15d772c780..68e3c5c095 100644
--- a/libavformat/sapdec.c
+++ b/libavformat/sapdec.c
@@ -2,20 +2,20 @@
* Session Announcement Protocol (RFC 2974) demuxer
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -163,11 +163,12 @@ static int sap_read_header(AVFormatContext *s,
if (sap->sdp_ctx->ctx_flags & AVFMTCTX_NOHEADER)
s->ctx_flags |= AVFMTCTX_NOHEADER;
for (i = 0; i < sap->sdp_ctx->nb_streams; i++) {
- AVStream *st = av_new_stream(s, i);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st) {
ret = AVERROR(ENOMEM);
goto fail;
}
+ st->id = i;
avcodec_copy_context(st->codec, sap->sdp_ctx->streams[i]->codec);
st->time_base = sap->sdp_ctx->streams[i]->time_base;
}
@@ -211,11 +212,12 @@ static int sap_fetch_packet(AVFormatContext *s, AVPacket *pkt)
if (s->ctx_flags & AVFMTCTX_NOHEADER) {
while (sap->sdp_ctx->nb_streams > s->nb_streams) {
int i = s->nb_streams;
- AVStream *st = av_new_stream(s, i);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st) {
av_free_packet(pkt);
return AVERROR(ENOMEM);
}
+ st->id = i;
avcodec_copy_context(st->codec, sap->sdp_ctx->streams[i]->codec);
st->time_base = sap->sdp_ctx->streams[i]->time_base;
}
@@ -224,13 +226,13 @@ static int sap_fetch_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_sap_demuxer = {
- "sap",
- NULL_IF_CONFIG_SMALL("SAP input format"),
- sizeof(struct SAPState),
- sap_probe,
- sap_read_header,
- sap_fetch_packet,
- sap_read_close,
+ .name = "sap",
+ .long_name = NULL_IF_CONFIG_SMALL("SAP input format"),
+ .priv_data_size = sizeof(struct SAPState),
+ .read_probe = sap_probe,
+ .read_header = sap_read_header,
+ .read_packet = sap_fetch_packet,
+ .read_close = sap_read_close,
.flags = AVFMT_NOFILE,
};
diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c
index 3abd79e4e8..b84cce50a4 100644
--- a/libavformat/sapenc.c
+++ b/libavformat/sapenc.c
@@ -2,20 +2,20 @@
* Session Announcement Protocol (RFC 2974) muxer
* Copyright (c) 2010 Martin Storsjo
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -250,16 +250,14 @@ static int sap_write_packet(AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_sap_muxer = {
- "sap",
- NULL_IF_CONFIG_SMALL("SAP output format"),
- NULL,
- NULL,
- sizeof(struct SAPState),
- CODEC_ID_AAC,
- CODEC_ID_MPEG4,
- sap_write_header,
- sap_write_packet,
- sap_write_close,
+ .name = "sap",
+ .long_name = NULL_IF_CONFIG_SMALL("SAP output format"),
+ .priv_data_size = sizeof(struct SAPState),
+ .audio_codec = CODEC_ID_AAC,
+ .video_codec = CODEC_ID_MPEG4,
+ .write_header = sap_write_header,
+ .write_packet = sap_write_packet,
+ .write_trailer = sap_write_close,
.flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER,
};
diff --git a/libavformat/sauce.c b/libavformat/sauce.c
index a125241335..21cc95bccb 100644
--- a/libavformat/sauce.c
+++ b/libavformat/sauce.c
@@ -2,20 +2,20 @@
* SAUCE header parser
* Copyright (c) 2010 Peter Ross <pross@xvid.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/sauce.h b/libavformat/sauce.h
index 62d8e688a4..0ba9ae5b4a 100644
--- a/libavformat/sauce.h
+++ b/libavformat/sauce.h
@@ -2,20 +2,20 @@
* SAUCE header parser
* Copyright (c) 2010 Peter Ross <pross@xvid.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/sdp.c b/libavformat/sdp.c
index c227c7f603..37eee26485 100644
--- a/libavformat/sdp.c
+++ b/libavformat/sdp.c
@@ -1,20 +1,20 @@
/*
* copyright (c) 2007 Luca Abeni
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -252,7 +252,7 @@ static char *xiph_extradata2config(AVCodecContext *c)
return NULL;
}
- if (ff_split_xiph_headers(c->extradata, c->extradata_size,
+ if (avpriv_split_xiph_headers(c->extradata, c->extradata_size,
first_header_size, header_start,
header_len) < 0) {
av_log(c, AV_LOG_ERROR, "Extradata corrupt.\n");
@@ -342,7 +342,7 @@ static char *latm_context2config(AVCodecContext *c)
char *config;
for (rate_index = 0; rate_index < 16; rate_index++)
- if (ff_mpeg4audio_sample_rates[rate_index] == c->sample_rate)
+ if (avpriv_mpeg4audio_sample_rates[rate_index] == c->sample_rate)
break;
if (rate_index == 16) {
av_log(c, AV_LOG_ERROR, "Unsupported sample rate\n");
@@ -532,10 +532,7 @@ void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *des
const char *type;
int payload_type;
- payload_type = ff_rtp_get_payload_type(c);
- if (payload_type < 0) {
- payload_type = RTP_PT_PRIVATE + (c->codec_type == AVMEDIA_TYPE_AUDIO);
- }
+ payload_type = ff_rtp_get_payload_type(fmt, c);
switch (c->codec_type) {
case AVMEDIA_TYPE_VIDEO : type = "video" ; break;
diff --git a/libavformat/seek-test.c b/libavformat/seek-test.c
new file mode 100644
index 0000000000..cea36cabb2
--- /dev/null
+++ b/libavformat/seek-test.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2007 Michael Niedermayer
+ *
+ * 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 <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libavutil/common.h"
+#include "libavutil/mathematics.h"
+#include "libavformat/avformat.h"
+
+#undef exit
+#undef printf
+#undef fprintf
+
+static char buffer[20];
+
+static const char *ret_str(int v)
+{
+ switch (v) {
+ case AVERROR_EOF: return "-EOF";
+ case AVERROR(EIO): return "-EIO";
+ case AVERROR(ENOMEM): return "-ENOMEM";
+ case AVERROR(EINVAL): return "-EINVAL";
+ default:
+ snprintf(buffer, sizeof(buffer), "%2d", v);
+ return buffer;
+ }
+}
+
+static void ts_str(char buffer[60], int64_t ts, AVRational base)
+{
+ double tsval;
+ if (ts == AV_NOPTS_VALUE) {
+ strcpy(buffer, " NOPTS ");
+ return;
+ }
+ tsval = ts * av_q2d(base);
+ snprintf(buffer, 60, "%9f", tsval);
+}
+
+int main(int argc, char **argv)
+{
+ const char *filename;
+ AVFormatContext *ic = NULL;
+ int i, ret, stream_id;
+ int64_t timestamp;
+ AVFormatParameters params, *ap= &params;
+ memset(ap, 0, sizeof(params));
+ ap->channels=1;
+ ap->sample_rate= 22050;
+
+ /* initialize libavcodec, and register all codecs and formats */
+ av_register_all();
+
+ if (argc != 2) {
+ printf("usage: %s input_file\n"
+ "\n", argv[0]);
+ exit(1);
+ }
+
+ filename = argv[1];
+
+ ret = av_open_input_file(&ic, filename, NULL, 0, ap);
+ if (ret < 0) {
+ fprintf(stderr, "cannot open %s\n", filename);
+ exit(1);
+ }
+
+ ret = avformat_find_stream_info(ic, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "%s: could not find codec parameters\n", filename);
+ exit(1);
+ }
+
+ for(i=0; ; i++){
+ AVPacket pkt;
+ AVStream *av_uninit(st);
+ char ts_buf[60];
+
+ memset(&pkt, 0, sizeof(pkt));
+ if(ret>=0){
+ ret= av_read_frame(ic, &pkt);
+ if(ret>=0){
+ char dts_buf[60];
+ st= ic->streams[pkt.stream_index];
+ ts_str(dts_buf, pkt.dts, st->time_base);
+ ts_str(ts_buf, pkt.pts, st->time_base);
+ printf("ret:%-10s st:%2d flags:%d dts:%s pts:%s pos:%7" PRId64 " size:%6d", ret_str(ret), pkt.stream_index, pkt.flags, dts_buf, ts_buf, pkt.pos, pkt.size);
+ av_free_packet(&pkt);
+ } else
+ printf("ret:%s", ret_str(ret)); // necessary to avoid trailing whitespace
+ printf("\n");
+ }
+
+ if(i>25) break;
+
+ stream_id= (i>>1)%(ic->nb_streams+1) - 1;
+ timestamp= (i*19362894167LL) % (4*AV_TIME_BASE) - AV_TIME_BASE;
+ if(stream_id>=0){
+ st= ic->streams[stream_id];
+ timestamp= av_rescale_q(timestamp, AV_TIME_BASE_Q, st->time_base);
+ }
+ //FIXME fully test the new seek API
+ if(i&1) ret = avformat_seek_file(ic, stream_id, INT64_MIN, timestamp, timestamp, 0);
+ else ret = avformat_seek_file(ic, stream_id, timestamp, timestamp, INT64_MAX, 0);
+ ts_str(ts_buf, timestamp, stream_id < 0 ? AV_TIME_BASE_Q : st->time_base);
+ printf("ret:%-10s st:%2d flags:%d ts:%s\n", ret_str(ret), stream_id, i&1, ts_buf);
+ }
+
+ av_close_input_file(ic);
+
+ return 0;
+}
diff --git a/libavformat/seek.c b/libavformat/seek.c
index 6c4286bb8e..65211bfacf 100644
--- a/libavformat/seek.c
+++ b/libavformat/seek.c
@@ -3,20 +3,20 @@
*
* Copyright (c) 2009 Ivan Schreter
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/seek.h b/libavformat/seek.h
index fd95f497d6..408f7d6ac7 100644
--- a/libavformat/seek.h
+++ b/libavformat/seek.h
@@ -3,20 +3,20 @@
*
* Copyright (c) 2009 Ivan Schreter
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c
index 0ad5fbbe0b..1ae105eb77 100644
--- a/libavformat/segafilm.c
+++ b/libavformat/segafilm.c
@@ -2,20 +2,20 @@
* Sega FILM Format (CPK) Demuxer
* Copyright (c) 2003 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -111,11 +111,16 @@ static int film_read_header(AVFormatContext *s,
film->audio_samplerate = AV_RB16(&scratch[24]);
film->audio_channels = scratch[21];
film->audio_bits = scratch[22];
- if (film->audio_bits == 8)
- film->audio_type = CODEC_ID_PCM_S8;
- else if (film->audio_bits == 16)
- film->audio_type = CODEC_ID_PCM_S16BE;
- else
+ if (scratch[23] == 2)
+ film->audio_type = CODEC_ID_ADPCM_ADX;
+ else if (film->audio_channels > 0) {
+ if (film->audio_bits == 8)
+ film->audio_type = CODEC_ID_PCM_S8;
+ else if (film->audio_bits == 16)
+ film->audio_type = CODEC_ID_PCM_S16BE;
+ else
+ film->audio_type = CODEC_ID_NONE;
+ } else
film->audio_type = CODEC_ID_NONE;
}
@@ -129,7 +134,7 @@ static int film_read_header(AVFormatContext *s,
/* initialize the decoder streams */
if (film->video_type) {
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
film->video_stream_index = st->index;
@@ -141,7 +146,7 @@ static int film_read_header(AVFormatContext *s,
}
if (film->audio_type) {
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
film->audio_stream_index = st->index;
@@ -149,12 +154,19 @@ static int film_read_header(AVFormatContext *s,
st->codec->codec_id = film->audio_type;
st->codec->codec_tag = 1;
st->codec->channels = film->audio_channels;
- st->codec->bits_per_coded_sample = film->audio_bits;
st->codec->sample_rate = film->audio_samplerate;
+
+ if (film->audio_type == CODEC_ID_ADPCM_ADX) {
+ st->codec->bits_per_coded_sample = 18 * 8 / 32;
+ st->codec->block_align = st->codec->channels * 18;
+ } else {
+ st->codec->bits_per_coded_sample = film->audio_bits;
+ st->codec->block_align = st->codec->channels *
+ st->codec->bits_per_coded_sample / 8;
+ }
+
st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
st->codec->bits_per_coded_sample;
- st->codec->block_align = st->codec->channels *
- st->codec->bits_per_coded_sample / 8;
}
/* load the sample table */
@@ -167,6 +179,8 @@ static int film_read_header(AVFormatContext *s,
if(film->sample_count >= UINT_MAX / sizeof(film_sample))
return -1;
film->sample_table = av_malloc(film->sample_count * sizeof(film_sample));
+ if (!film->sample_table)
+ return AVERROR(ENOMEM);
for(i=0; i<s->nb_streams; i++)
av_set_pts_info(s->streams[i], 33, 1, film->base_clock);
@@ -187,8 +201,12 @@ static int film_read_header(AVFormatContext *s,
film->sample_table[i].pts *= film->base_clock;
film->sample_table[i].pts /= film->audio_samplerate;
- audio_frame_counter += (film->sample_table[i].sample_size /
- (film->audio_channels * film->audio_bits / 8));
+ if (film->audio_type == CODEC_ID_ADPCM_ADX)
+ audio_frame_counter += (film->sample_table[i].sample_size * 32 /
+ (18 * film->audio_channels));
+ else if (film->audio_type != CODEC_ID_NONE)
+ audio_frame_counter += (film->sample_table[i].sample_size /
+ (film->audio_channels * film->audio_bits / 8));
} else {
film->sample_table[i].stream = film->video_stream_index;
film->sample_table[i].pts = AV_RB32(&scratch[8]) & 0x7FFFFFFF;
@@ -227,7 +245,8 @@ static int film_read_packet(AVFormatContext *s,
return AVERROR(ENOMEM);
avio_read(pb, pkt->data, sample->sample_size);
} else if ((sample->stream == film->audio_stream_index) &&
- (film->audio_channels == 2)) {
+ (film->audio_channels == 2) &&
+ (film->audio_type != CODEC_ID_ADPCM_ADX)) {
/* stereo PCM needs to be interleaved */
if (av_new_packet(pkt, sample->sample_size))
@@ -238,6 +257,10 @@ static int film_read_packet(AVFormatContext *s,
av_free(film->stereo_buffer);
film->stereo_buffer_size = sample->sample_size;
film->stereo_buffer = av_malloc(film->stereo_buffer_size);
+ if (!film->stereo_buffer) {
+ film->stereo_buffer_size = 0;
+ return AVERROR(ENOMEM);
+ }
}
pkt->pos= avio_tell(pb);
@@ -283,11 +306,11 @@ static int film_read_close(AVFormatContext *s)
}
AVInputFormat ff_segafilm_demuxer = {
- "film_cpk",
- NULL_IF_CONFIG_SMALL("Sega FILM/CPK format"),
- sizeof(FilmDemuxContext),
- film_probe,
- film_read_header,
- film_read_packet,
- film_read_close,
+ .name = "film_cpk",
+ .long_name = NULL_IF_CONFIG_SMALL("Sega FILM/CPK format"),
+ .priv_data_size = sizeof(FilmDemuxContext),
+ .read_probe = film_probe,
+ .read_header = film_read_header,
+ .read_packet = film_read_packet,
+ .read_close = film_read_close,
};
diff --git a/libavformat/segment.c b/libavformat/segment.c
new file mode 100644
index 0000000000..80716bcf90
--- /dev/null
+++ b/libavformat/segment.c
@@ -0,0 +1,234 @@
+/*
+ * Generic Segmenter
+ * Copyright (c) 2011, Luca Barbato
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/parseutils.h"
+#include "avformat.h"
+#include "internal.h"
+#include <strings.h>
+#include <float.h>
+
+typedef struct {
+ const AVClass *class; /**< Class for private options. */
+ int number;
+ AVFormatContext *avf;
+ char *format; /**< Set by a private option. */
+ char *pattern; /**< Set by a private option. */
+ char *path; /**< Set by a private option. */
+ float time; /**< Set by a private option. */
+ int64_t offset_time;
+ int64_t recording_time;
+} SegmentContext;
+
+#if CONFIG_SEGMENT_MUXER
+
+static int segment_header(SegmentContext *s)
+{
+ AVFormatContext *oc = s->avf;
+ int err = 0;
+
+ av_strlcpy(oc->filename, s->path, sizeof(oc->filename));
+
+ av_strlcatf(oc->filename, sizeof(oc->filename),
+ s->pattern, s->number++);
+
+ if ((err = avio_open(&oc->pb, oc->filename, AVIO_FLAG_WRITE)) < 0) {
+ return err;
+ }
+
+ if (!oc->priv_data && oc->oformat->priv_data_size > 0) {
+ oc->priv_data = av_mallocz(oc->oformat->priv_data_size);
+ if (!oc->priv_data) {
+ avio_close(oc->pb);
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ if ((err = oc->oformat->write_header(oc)) < 0) {
+ avio_close(oc->pb);
+ av_freep(&oc->priv_data);
+ }
+
+ return err;
+}
+
+static int segment_trailer(AVFormatContext *oc)
+{
+ int ret = 0;
+
+ if(oc->oformat->write_trailer)
+ ret = oc->oformat->write_trailer(oc);
+
+ avio_close(oc->pb);
+ av_freep(&oc->priv_data);
+
+ return ret;
+}
+
+static int seg_write_header(AVFormatContext *s)
+{
+ SegmentContext *seg = s->priv_data;
+ AVFormatContext *oc;
+ int ret;
+
+ seg->number = 0;
+ seg->recording_time = seg->time*1000000;
+ seg->offset_time = 0;
+
+ if (!seg->path) {
+ char *t;
+ seg->path = av_strdup(s->filename);
+ t = strrchr(seg->path, '.');
+ if (t) *t = '\0';
+ }
+
+ oc = avformat_alloc_context();
+
+ if (!oc) {
+ return AVERROR(ENOMEM);
+ }
+
+ oc->oformat = av_guess_format(seg->format, NULL, NULL);
+
+ if (!oc->oformat) {
+ avformat_free_context(oc);
+ return AVERROR_MUXER_NOT_FOUND;
+ }
+
+ seg->avf = oc;
+
+ oc->streams = s->streams;
+ oc->nb_streams = s->nb_streams;
+
+ av_strlcpy(oc->filename, seg->path, sizeof(oc->filename));
+
+ av_strlcatf(oc->filename, sizeof(oc->filename),
+ seg->pattern, seg->number++);
+
+ if ((ret = avio_open(&oc->pb, oc->filename, AVIO_FLAG_WRITE)) < 0) {
+ avformat_free_context(oc);
+ return ret;
+ }
+
+ if ((ret = avformat_write_header(oc, NULL)) < 0) {
+ avio_close(oc->pb);
+ }
+
+ if (ret)
+ avformat_free_context(oc);
+
+ avio_printf(s->pb, "%s\n", oc->filename);
+ avio_flush(s->pb);
+
+ return ret;
+}
+
+static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ SegmentContext *seg = s->priv_data;
+ AVFormatContext *oc = seg->avf;
+ AVStream *st = oc->streams[pkt->stream_index];
+ int ret;
+
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+ av_compare_ts(pkt->pts, st->time_base,
+ seg->recording_time*seg->number,
+ (AVRational){1, 1000000}) >= 0 &&
+ pkt->flags & AV_PKT_FLAG_KEY) {
+ av_log(s, AV_LOG_INFO, "I'd reset at %d %"PRId64"\n",
+ pkt->stream_index, pkt->pts);
+
+ ret = segment_trailer(oc);
+ if (!ret)
+ ret = segment_header(seg);
+
+ if (ret) {
+ avformat_free_context(oc);
+ return ret;
+ }
+ avio_printf(s->pb, "%s\n", oc->filename);
+ avio_flush(s->pb);
+ }
+
+ ret = oc->oformat->write_packet(oc, pkt);
+
+ return ret;
+}
+
+static int seg_write_trailer(struct AVFormatContext *s)
+{
+ SegmentContext *seg = s->priv_data;
+ AVFormatContext *oc = seg->avf;
+
+ return segment_trailer(oc);
+}
+
+#endif /* CONFIG_SEGMENT_MUXER */
+
+#define OFFSET(x) offsetof(SegmentContext, x)
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "container_format", "container format used for the segments", OFFSET(format), AV_OPT_TYPE_STRING, {.str = "nut"}, 0, 0, E },
+ { "segment_time", "segment lenght in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E },
+ { "segment_pattern", "pattern to use in segment files", OFFSET(pattern),AV_OPT_TYPE_STRING, {.str = "%03d"}, 0, 0, E },
+ { "segment_basename", "basename to use in segment files", OFFSET(path ),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
+ { NULL },
+};
+
+static const AVClass seg_class = {
+ .class_name = "segment muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+/* input
+#if CONFIG_IMAGE2_DEMUXER
+AVInputFormat ff_image2_demuxer = {
+ .name = "image2",
+ .long_name = NULL_IF_CONFIG_SMALL("image2 sequence"),
+ .priv_data_size = sizeof(VideoData),
+ .read_probe = read_probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
+ .flags = AVFMT_NOFILE,
+ .priv_class = &img2_class,
+};
+#endif
+*/
+
+/* output */
+#if CONFIG_SEGMENT_MUXER
+AVOutputFormat ff_segment_muxer = {
+ .name = "segment",
+ .long_name = NULL_IF_CONFIG_SMALL("segment muxer"),
+ .extensions = "m3u8",
+ .priv_data_size = sizeof(SegmentContext),
+ .flags = AVFMT_GLOBALHEADER,
+ .write_header = seg_write_header,
+ .write_packet = seg_write_packet,
+ .write_trailer = seg_write_trailer,
+ .priv_class = &seg_class,
+};
+#endif
diff --git a/libavformat/sierravmd.c b/libavformat/sierravmd.c
index c0fb22211b..e1367c29ae 100644
--- a/libavformat/sierravmd.c
+++ b/libavformat/sierravmd.c
@@ -2,20 +2,20 @@
* Sierra VMD Format Demuxer
* Copyright (c) 2004 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -104,7 +104,7 @@ static int vmd_read_header(AVFormatContext *s,
else
vmd->is_indeo3 = 0;
/* start up the decoders */
- vst = av_new_stream(s, 0);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
av_set_pts_info(vst, 33, 1, 10);
@@ -125,7 +125,7 @@ static int vmd_read_header(AVFormatContext *s,
/* if sample rate is 0, assume no audio */
vmd->sample_rate = AV_RL16(&vmd->vmd_header[804]);
if (vmd->sample_rate) {
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
vmd->audio_stream_index = st->index;
@@ -281,11 +281,11 @@ static int vmd_read_close(AVFormatContext *s)
}
AVInputFormat ff_vmd_demuxer = {
- "vmd",
- NULL_IF_CONFIG_SMALL("Sierra VMD format"),
- sizeof(VmdDemuxContext),
- vmd_probe,
- vmd_read_header,
- vmd_read_packet,
- vmd_read_close,
+ .name = "vmd",
+ .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD format"),
+ .priv_data_size = sizeof(VmdDemuxContext),
+ .read_probe = vmd_probe,
+ .read_header = vmd_read_header,
+ .read_packet = vmd_read_packet,
+ .read_close = vmd_read_close,
};
diff --git a/libavformat/siff.c b/libavformat/siff.c
index 23c122f7a7..77cbc66804 100644
--- a/libavformat/siff.c
+++ b/libavformat/siff.c
@@ -2,20 +2,20 @@
* Beam Software SIFF demuxer
* Copyright (c) 2007 Konstantin Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -71,7 +71,7 @@ static int siff_probe(AVProbeData *p)
static int create_audio_stream(AVFormatContext *s, SIFFContext *c)
{
AVStream *ast;
- ast = av_new_stream(s, 0);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return -1;
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -115,7 +115,7 @@ static int siff_parse_vbv1(AVFormatContext *s, SIFFContext *c, AVIOContext *pb)
avio_skip(pb, 16); //zeroes
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -228,11 +228,11 @@ static int siff_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_siff_demuxer = {
- "siff",
- NULL_IF_CONFIG_SMALL("Beam Software SIFF"),
- sizeof(SIFFContext),
- siff_probe,
- siff_read_header,
- siff_read_packet,
+ .name = "siff",
+ .long_name = NULL_IF_CONFIG_SMALL("Beam Software SIFF"),
+ .priv_data_size = sizeof(SIFFContext),
+ .read_probe = siff_probe,
+ .read_header = siff_read_header,
+ .read_packet = siff_read_packet,
.extensions = "vb,son"
};
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index db9a02bb6c..3ffb65eee0 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -2,20 +2,20 @@
* Smacker demuxer
* Copyright (c) 2006 Konstantin Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -31,11 +31,11 @@
#define SMACKER_FLAG_RING_FRAME 0x01
enum SAudFlags {
- SMK_AUD_PACKED = 0x80000000,
- SMK_AUD_16BITS = 0x20000000,
- SMK_AUD_STEREO = 0x10000000,
- SMK_AUD_BINKAUD = 0x08000000,
- SMK_AUD_USEDCT = 0x04000000
+ SMK_AUD_PACKED = 0x80,
+ SMK_AUD_16BITS = 0x20,
+ SMK_AUD_STEREO = 0x10,
+ SMK_AUD_BINKAUD = 0x08,
+ SMK_AUD_USEDCT = 0x04
};
typedef struct SmackerContext {
@@ -48,6 +48,7 @@ typedef struct SmackerContext {
uint32_t audio[7];
uint32_t treesize;
uint32_t mmap_size, mclr_size, full_size, type_size;
+ uint8_t aflags[7];
uint32_t rates[7];
uint32_t pad;
/* frame info */
@@ -129,8 +130,10 @@ static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap)
smk->mclr_size = avio_rl32(pb);
smk->full_size = avio_rl32(pb);
smk->type_size = avio_rl32(pb);
- for(i = 0; i < 7; i++)
- smk->rates[i] = avio_rl32(pb);
+ for(i = 0; i < 7; i++) {
+ smk->rates[i] = avio_rl24(pb);
+ smk->aflags[i] = avio_r8(pb);
+ }
smk->pad = avio_rl32(pb);
/* setup data */
if(smk->frames > 0xFFFFFF) {
@@ -151,7 +154,7 @@ static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
/* init video codec */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
smk->videoindex = st->index;
@@ -173,23 +176,23 @@ static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap)
/* handle possible audio streams */
for(i = 0; i < 7; i++) {
smk->indexes[i] = -1;
- if(smk->rates[i] & 0xFFFFFF){
- ast[i] = av_new_stream(s, 0);
+ if (smk->rates[i]) {
+ ast[i] = avformat_new_stream(s, NULL);
smk->indexes[i] = ast[i]->index;
ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- if (smk->rates[i] & SMK_AUD_BINKAUD) {
+ if (smk->aflags[i] & SMK_AUD_BINKAUD) {
ast[i]->codec->codec_id = CODEC_ID_BINKAUDIO_RDFT;
- } else if (smk->rates[i] & SMK_AUD_USEDCT) {
+ } else if (smk->aflags[i] & SMK_AUD_USEDCT) {
ast[i]->codec->codec_id = CODEC_ID_BINKAUDIO_DCT;
- } else if (smk->rates[i] & SMK_AUD_PACKED){
+ } else if (smk->aflags[i] & SMK_AUD_PACKED){
ast[i]->codec->codec_id = CODEC_ID_SMACKAUDIO;
ast[i]->codec->codec_tag = MKTAG('S', 'M', 'K', 'A');
} else {
ast[i]->codec->codec_id = CODEC_ID_PCM_U8;
}
- ast[i]->codec->channels = (smk->rates[i] & SMK_AUD_STEREO) ? 2 : 1;
- ast[i]->codec->sample_rate = smk->rates[i] & 0xFFFFFF;
- ast[i]->codec->bits_per_coded_sample = (smk->rates[i] & SMK_AUD_16BITS) ? 16 : 8;
+ ast[i]->codec->channels = (smk->aflags[i] & SMK_AUD_STEREO) ? 2 : 1;
+ ast[i]->codec->sample_rate = smk->rates[i];
+ ast[i]->codec->bits_per_coded_sample = (smk->aflags[i] & SMK_AUD_16BITS) ? 16 : 8;
if(ast[i]->codec->bits_per_coded_sample == 16 && ast[i]->codec->codec_id == CODEC_ID_PCM_U8)
ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE;
av_set_pts_info(ast[i], 64, 1, ast[i]->codec->sample_rate
@@ -234,7 +237,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
int frame_size = 0;
int palchange = 0;
- if (s->pb->eof_reached || smk->cur_frame >= smk->frames)
+ if (url_feof(s->pb) || smk->cur_frame >= smk->frames)
return AVERROR_EOF;
/* if we demuxed all streams, pass another frame */
@@ -286,11 +289,16 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
for(i = 0; i < 7; i++) {
if(flags & 1) {
int size;
+ uint8_t *tmpbuf;
+
size = avio_rl32(s->pb) - 4;
frame_size -= size;
frame_size -= 4;
smk->curstream++;
- smk->bufs[smk->curstream] = av_realloc(smk->bufs[smk->curstream], size);
+ tmpbuf = av_realloc(smk->bufs[smk->curstream], size);
+ if (!tmpbuf)
+ return AVERROR(ENOMEM);
+ smk->bufs[smk->curstream] = tmpbuf;
smk->buf_sizes[smk->curstream] = size;
ret = avio_read(s->pb, smk->bufs[smk->curstream], size);
if(ret != size)
@@ -299,7 +307,9 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
}
flags >>= 1;
}
- if (av_new_packet(pkt, frame_size + 768))
+ if (frame_size < 0)
+ return AVERROR_INVALIDDATA;
+ if (av_new_packet(pkt, frame_size + 769))
return AVERROR(ENOMEM);
if(smk->frm_size[smk->cur_frame] & 1)
palchange |= 2;
@@ -340,11 +350,11 @@ static int smacker_read_close(AVFormatContext *s)
}
AVInputFormat ff_smacker_demuxer = {
- "smk",
- NULL_IF_CONFIG_SMALL("Smacker video"),
- sizeof(SmackerContext),
- smacker_probe,
- smacker_read_header,
- smacker_read_packet,
- smacker_read_close,
+ .name = "smk",
+ .long_name = NULL_IF_CONFIG_SMALL("Smacker video"),
+ .priv_data_size = sizeof(SmackerContext),
+ .read_probe = smacker_probe,
+ .read_header = smacker_read_header,
+ .read_packet = smacker_read_packet,
+ .read_close = smacker_read_close,
};
diff --git a/libavformat/sol.c b/libavformat/sol.c
index 1ebb4d2e30..cd5b2d75a4 100644
--- a/libavformat/sol.c
+++ b/libavformat/sol.c
@@ -2,20 +2,20 @@
* Sierra SOL demuxer
* Copyright Konstantin Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -110,7 +110,7 @@ static int sol_read_header(AVFormatContext *s,
else id = 0;
/* now we are ready: build format streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -129,9 +129,11 @@ static int sol_read_packet(AVFormatContext *s,
{
int ret;
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR(EIO);
ret= av_get_packet(s->pb, pkt, MAX_SIZE);
+ if (ret < 0)
+ return ret;
pkt->stream_index = 0;
/* note: we need to modify the packet size here to handle the last
@@ -141,12 +143,10 @@ static int sol_read_packet(AVFormatContext *s,
}
AVInputFormat ff_sol_demuxer = {
- "sol",
- NULL_IF_CONFIG_SMALL("Sierra SOL format"),
- 0,
- sol_probe,
- sol_read_header,
- sol_read_packet,
- NULL,
- pcm_read_seek,
+ .name = "sol",
+ .long_name = NULL_IF_CONFIG_SMALL("Sierra SOL format"),
+ .read_probe = sol_probe,
+ .read_header = sol_read_header,
+ .read_packet = sol_read_packet,
+ .read_seek = pcm_read_seek,
};
diff --git a/libavformat/sox.h b/libavformat/sox.h
index e59531bea3..f4a12e93ff 100644
--- a/libavformat/sox.h
+++ b/libavformat/sox.h
@@ -2,20 +2,20 @@
* SoX native format common data
* Copyright (c) 2009 Daniel Verkamp <daniel@drv.nu>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/soxdec.c b/libavformat/soxdec.c
index b3b35b12fd..dac4bedfb3 100644
--- a/libavformat/soxdec.c
+++ b/libavformat/soxdec.c
@@ -5,28 +5,28 @@
* Based on libSoX sox-fmt.c
* Copyright (c) 2008 robs@users.sourceforge.net
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
- * SoX native format demuxer
* @file
+ * SoX native format demuxer
* @author Daniel Verkamp
- * @sa http://wiki.multimedia.cx/index.php?title=SoX_native_intermediate_format
+ * @see http://wiki.multimedia.cx/index.php?title=SoX_native_intermediate_format
*/
#include "libavutil/intreadwrite.h"
@@ -51,7 +51,7 @@ static int sox_read_header(AVFormatContext *s,
double sample_rate, sample_rate_frac;
AVStream *st;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -129,7 +129,7 @@ static int sox_read_packet(AVFormatContext *s,
{
int ret, size;
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR_EOF;
size = SOX_SAMPLES*s->streams[0]->codec->block_align;
@@ -143,12 +143,10 @@ static int sox_read_packet(AVFormatContext *s,
}
AVInputFormat ff_sox_demuxer = {
- "sox",
- NULL_IF_CONFIG_SMALL("SoX native format"),
- 0,
- sox_probe,
- sox_read_header,
- sox_read_packet,
- NULL,
- pcm_read_seek,
+ .name = "sox",
+ .long_name = NULL_IF_CONFIG_SMALL("SoX native format"),
+ .read_probe = sox_probe,
+ .read_header = sox_read_header,
+ .read_packet = sox_read_packet,
+ .read_seek = pcm_read_seek,
};
diff --git a/libavformat/soxenc.c b/libavformat/soxenc.c
index a0faa466df..a8549b0ffa 100644
--- a/libavformat/soxenc.c
+++ b/libavformat/soxenc.c
@@ -5,28 +5,28 @@
* Based on libSoX sox-fmt.c
* Copyright (c) 2008 robs@users.sourceforge.net
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
- * SoX native format muxer
* @file
+ * SoX native format muxer
* @author Daniel Verkamp
- * @sa http://wiki.multimedia.cx/index.php?title=SoX_native_intermediate_format
+ * @see http://wiki.multimedia.cx/index.php?title=SoX_native_intermediate_format
*/
#include "libavutil/intreadwrite.h"
@@ -116,14 +116,13 @@ static int sox_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_sox_muxer = {
- "sox",
- NULL_IF_CONFIG_SMALL("SoX native format"),
- NULL,
- "sox",
- sizeof(SoXContext),
- CODEC_ID_PCM_S32LE,
- CODEC_ID_NONE,
- sox_write_header,
- sox_write_packet,
- sox_write_trailer,
+ .name = "sox",
+ .long_name = NULL_IF_CONFIG_SMALL("SoX native format"),
+ .extensions = "sox",
+ .priv_data_size = sizeof(SoXContext),
+ .audio_codec = CODEC_ID_PCM_S32LE,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = sox_write_header,
+ .write_packet = sox_write_packet,
+ .write_trailer = sox_write_trailer,
};
diff --git a/libavformat/spdif.c b/libavformat/spdif.c
index 777ac47ba5..604141a261 100644
--- a/libavformat/spdif.c
+++ b/libavformat/spdif.c
@@ -2,20 +2,20 @@
* IEC 61937 common code
* Copyright (c) 2009 Bartlomiej Wolowiec
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/spdif.h b/libavformat/spdif.h
index b2a6b63be4..4b11de20d1 100644
--- a/libavformat/spdif.h
+++ b/libavformat/spdif.h
@@ -2,20 +2,20 @@
* IEC 61937 common header
* Copyright (c) 2009 Bartlomiej Wolowiec
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/spdifdec.c b/libavformat/spdifdec.c
index 1c0902548c..b0e9afb7b3 100644
--- a/libavformat/spdifdec.c
+++ b/libavformat/spdifdec.c
@@ -2,20 +2,20 @@
* IEC 61937 demuxer
* Copyright (c) 2010 Anssi Hannula <anssi.hannula at iki.fi>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -57,7 +57,7 @@ static int spdif_get_offset_and_codec(AVFormatContext *s,
break;
case IEC61937_MPEG2_AAC:
init_get_bits(&gbc, buf, AAC_ADTS_HEADER_SIZE * 8);
- if (ff_aac_parse_header(&gbc, &aac_hdr)) {
+ if (avpriv_aac_parse_header(&gbc, &aac_hdr)) {
if (s) /* be silent during a probe */
av_log(s, AV_LOG_ERROR, "Invalid AAC packet in IEC 61937\n");
return AVERROR_INVALIDDATA;
@@ -171,7 +171,7 @@ static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) {
state = (state << 8) | avio_r8(pb);
- if (pb->eof_reached)
+ if (url_feof(pb))
return AVERROR_EOF;
}
@@ -205,7 +205,7 @@ static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
if (!s->nb_streams) {
/* first packet, create a stream */
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st) {
av_free_packet(pkt);
return AVERROR(ENOMEM);
@@ -226,11 +226,10 @@ static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_spdif_demuxer = {
- "spdif",
- NULL_IF_CONFIG_SMALL("IEC 61937 (compressed data in S/PDIF)"),
- 0,
- spdif_probe,
- spdif_read_header,
- spdif_read_packet,
+ .name = "spdif",
+ .long_name = NULL_IF_CONFIG_SMALL("IEC 61937 (compressed data in S/PDIF)"),
+ .read_probe = spdif_probe,
+ .read_header = spdif_read_header,
+ .read_packet = spdif_read_packet,
.flags = AVFMT_GENERIC_INDEX,
};
diff --git a/libavformat/spdifenc.c b/libavformat/spdifenc.c
index 735546096f..53aa27c446 100644
--- a/libavformat/spdifenc.c
+++ b/libavformat/spdifenc.c
@@ -4,20 +4,20 @@
* Copyright (c) 2010 Anssi Hannula
* Copyright (c) 2010 Carl Eugen Hoyos
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -86,10 +86,10 @@ typedef struct IEC61937Context {
} IEC61937Context;
static const AVOption options[] = {
-{ "spdif_flags", "IEC 61937 encapsulation flags", offsetof(IEC61937Context, spdif_flags), FF_OPT_TYPE_FLAGS, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "spdif_flags" },
-{ "be", "output in big-endian format (for use as s16be)", 0, FF_OPT_TYPE_CONST, {.dbl = SPDIF_FLAG_BIGENDIAN}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "spdif_flags" },
-{ "dtshd_rate", "mux complete DTS frames in HD mode at the specified IEC958 rate (in Hz, default 0=disabled)", offsetof(IEC61937Context, dtshd_rate), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 768000, AV_OPT_FLAG_ENCODING_PARAM },
-{ "dtshd_fallback_time", "min secs to strip HD for after an overflow (-1: till the end, default 60)", offsetof(IEC61937Context, dtshd_fallback), FF_OPT_TYPE_INT, {.dbl = 60}, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+{ "spdif_flags", "IEC 61937 encapsulation flags", offsetof(IEC61937Context, spdif_flags), AV_OPT_TYPE_FLAGS, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "spdif_flags" },
+{ "be", "output in big-endian format (for use as s16be)", 0, AV_OPT_TYPE_CONST, {.dbl = SPDIF_FLAG_BIGENDIAN}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "spdif_flags" },
+{ "dtshd_rate", "mux complete DTS frames in HD mode at the specified IEC958 rate (in Hz, default 0=disabled)", offsetof(IEC61937Context, dtshd_rate), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 768000, AV_OPT_FLAG_ENCODING_PARAM },
+{ "dtshd_fallback_time", "min secs to strip HD for after an overflow (-1: till the end, default 60)", offsetof(IEC61937Context, dtshd_fallback), AV_OPT_TYPE_INT, {.dbl = 60}, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
{ NULL },
};
@@ -349,7 +349,7 @@ static int spdif_header_aac(AVFormatContext *s, AVPacket *pkt)
int ret;
init_get_bits(&gbc, pkt->data, AAC_ADTS_HEADER_SIZE * 8);
- ret = ff_aac_parse_header(&gbc, &hdr);
+ ret = avpriv_aac_parse_header(&gbc, &hdr);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Wrong AAC file format\n");
return AVERROR_INVALIDDATA;
@@ -518,13 +518,13 @@ static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt)
}
if (ctx->extra_bswap ^ (ctx->spdif_flags & SPDIF_FLAG_BIGENDIAN)) {
- avio_write(s->pb, ctx->out_buf, ctx->out_bytes & ~1);
+ avio_write(s->pb, ctx->out_buf, ctx->out_bytes & ~1);
} else {
- av_fast_malloc(&ctx->buffer, &ctx->buffer_size, ctx->out_bytes + FF_INPUT_BUFFER_PADDING_SIZE);
- if (!ctx->buffer)
- return AVERROR(ENOMEM);
- ff_spdif_bswap_buf16((uint16_t *)ctx->buffer, (uint16_t *)ctx->out_buf, ctx->out_bytes >> 1);
- avio_write(s->pb, ctx->buffer, ctx->out_bytes & ~1);
+ av_fast_malloc(&ctx->buffer, &ctx->buffer_size, ctx->out_bytes + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!ctx->buffer)
+ return AVERROR(ENOMEM);
+ ff_spdif_bswap_buf16((uint16_t *)ctx->buffer, (uint16_t *)ctx->out_buf, ctx->out_bytes >> 1);
+ avio_write(s->pb, ctx->buffer, ctx->out_bytes & ~1);
}
/* a final lone byte has to be MSB aligned */
@@ -541,16 +541,15 @@ static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_spdif_muxer = {
- "spdif",
- NULL_IF_CONFIG_SMALL("IEC 61937 (used on S/PDIF - IEC958)"),
- NULL,
- "spdif",
- sizeof(IEC61937Context),
- CODEC_ID_AC3,
- CODEC_ID_NONE,
- spdif_write_header,
- spdif_write_packet,
- spdif_write_trailer,
+ .name = "spdif",
+ .long_name = NULL_IF_CONFIG_SMALL("IEC 61937 (used on S/PDIF - IEC958)"),
+ .extensions = "spdif",
+ .priv_data_size = sizeof(IEC61937Context),
+ .audio_codec = CODEC_ID_AC3,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = spdif_write_header,
+ .write_packet = spdif_write_packet,
+ .write_trailer = spdif_write_trailer,
.flags = AVFMT_NOTIMESTAMPS,
.priv_class = &class,
};
diff --git a/libavformat/srtdec.c b/libavformat/srtdec.c
index 72c5c80f6b..2828cc7af3 100644
--- a/libavformat/srtdec.c
+++ b/libavformat/srtdec.c
@@ -2,20 +2,20 @@
* SubRip subtitle demuxer
* Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -42,7 +42,7 @@ static int srt_probe(AVProbeData *p)
static int srt_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return -1;
av_set_pts_info(st, 64, 1, 1000);
@@ -81,7 +81,7 @@ static int srt_read_packet(AVFormatContext *s, AVPacket *pkt)
do {
ptr2 = ptr;
ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
- } while (!is_eol(*ptr2) && !s->pb->eof_reached && ptr-buffer<sizeof(buffer)-1);
+ } while (!is_eol(*ptr2) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);
if (buffer[0] && !(res = av_new_packet(pkt, ptr-buffer))) {
memcpy(pkt->data, buffer, pkt->size);
diff --git a/libavformat/swf.h b/libavformat/swf.h
index 2be6cd5795..affebe9c73 100644
--- a/libavformat/swf.h
+++ b/libavformat/swf.h
@@ -3,20 +3,20 @@
* Copyright (c) 2000 Fabrice Bellard
* Copyright (c) 2003 Tinic Uro
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c
index c838fa8e61..175e40ee19 100644
--- a/libavformat/swfdec.c
+++ b/libavformat/swfdec.c
@@ -3,20 +3,20 @@
* Copyright (c) 2000 Fabrice Bellard
* Copyright (c) 2003 Tinic Uro
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -27,8 +27,8 @@ static int get_swf_tag(AVIOContext *pb, int *len_ptr)
{
int tag, len;
- if (pb->eof_reached)
- return -1;
+ if (url_feof(pb))
+ return AVERROR_EOF;
tag = avio_rl16(pb);
len = tag & 0x3f;
@@ -90,7 +90,7 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
uint64_t pos = avio_tell(pb);
tag = get_swf_tag(pb, &len);
if (tag < 0)
- return AVERROR(EIO);
+ return tag;
if (tag == TAG_VIDEOSTREAM) {
int ch_id = avio_rl16(pb);
len -= 2;
@@ -106,9 +106,10 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
avio_rl16(pb);
avio_r8(pb);
/* Check for FLV1 */
- vst = av_new_stream(s, ch_id);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return -1;
+ vst->id = ch_id;
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
vst->codec->codec_id = ff_codec_get_id(swf_codec_tags, avio_r8(pb));
av_set_pts_info(vst, 16, 256, swf->frame_rate);
@@ -127,17 +128,19 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
avio_r8(pb);
v = avio_r8(pb);
swf->samples_per_frame = avio_rl16(pb);
- ast = av_new_stream(s, -1); /* -1 to avoid clash with video stream ch_id */
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return -1;
+ ast->id = -1; /* -1 to avoid clash with video stream ch_id */
ast->codec->channels = 1 + (v&1);
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
ast->codec->codec_id = ff_codec_get_id(swf_audio_codec_tags, (v>>4) & 15);
ast->need_parsing = AVSTREAM_PARSE_FULL;
sample_rate_code= (v>>2) & 3;
if (!sample_rate_code)
- return AVERROR(EIO);
- ast->codec->sample_rate = 11025 << (sample_rate_code-1);
+ ast->codec->sample_rate = 5512;
+ else
+ ast->codec->sample_rate = 11025 << (sample_rate_code-1);
av_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
len -= 4;
} else if (tag == TAG_VIDEOFRAME) {
@@ -176,9 +179,10 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
break;
}
if (i == s->nb_streams) {
- vst = av_new_stream(s, -2); /* -2 to avoid clash with video stream and audio stream */
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return -1;
+ vst->id = -2; /* -2 to avoid clash with video stream and audio stream */
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
vst->codec->codec_id = CODEC_ID_MJPEG;
av_set_pts_info(vst, 64, 256, swf->frame_rate);
@@ -207,10 +211,10 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_swf_demuxer = {
- "swf",
- NULL_IF_CONFIG_SMALL("Flash format"),
- sizeof(SWFContext),
- swf_probe,
- swf_read_header,
- swf_read_packet,
+ .name = "swf",
+ .long_name = NULL_IF_CONFIG_SMALL("Flash format"),
+ .priv_data_size = sizeof(SWFContext),
+ .read_probe = swf_probe,
+ .read_header = swf_read_header,
+ .read_packet = swf_read_packet,
};
diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c
index 4c5c3155ab..af812d09eb 100644
--- a/libavformat/swfenc.c
+++ b/libavformat/swfenc.c
@@ -3,20 +3,20 @@
* Copyright (c) 2000 Fabrice Bellard
* Copyright (c) 2003 Tinic Uro
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -421,7 +421,7 @@ static int swf_write_video(AVFormatContext *s,
put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG);
avio_wl16(pb, swf->sound_samples);
avio_wl16(pb, 0); // seek samples
- av_fifo_generic_read(swf->audio_fifo, pb, frame_size, &avio_write);
+ av_fifo_generic_read(swf->audio_fifo, pb, frame_size, (void*)avio_write);
put_swf_end_tag(s);
/* update FIFO */
@@ -507,29 +507,28 @@ static int swf_write_trailer(AVFormatContext *s)
#if CONFIG_SWF_MUXER
AVOutputFormat ff_swf_muxer = {
- "swf",
- NULL_IF_CONFIG_SMALL("Flash format"),
- "application/x-shockwave-flash",
- "swf",
- sizeof(SWFContext),
- CODEC_ID_MP3,
- CODEC_ID_FLV1,
- swf_write_header,
- swf_write_packet,
- swf_write_trailer,
+ .name = "swf",
+ .long_name = NULL_IF_CONFIG_SMALL("Flash format"),
+ .mime_type = "application/x-shockwave-flash",
+ .extensions = "swf",
+ .priv_data_size = sizeof(SWFContext),
+ .audio_codec = CODEC_ID_MP3,
+ .video_codec = CODEC_ID_FLV1,
+ .write_header = swf_write_header,
+ .write_packet = swf_write_packet,
+ .write_trailer = swf_write_trailer,
};
#endif
#if CONFIG_AVM2_MUXER
AVOutputFormat ff_avm2_muxer = {
- "avm2",
- NULL_IF_CONFIG_SMALL("Flash 9 (AVM2) format"),
- "application/x-shockwave-flash",
- NULL,
- sizeof(SWFContext),
- CODEC_ID_MP3,
- CODEC_ID_FLV1,
- swf_write_header,
- swf_write_packet,
- swf_write_trailer,
+ .name = "avm2",
+ .long_name = NULL_IF_CONFIG_SMALL("Flash 9 (AVM2) format"),
+ .mime_type = "application/x-shockwave-flash",
+ .priv_data_size = sizeof(SWFContext),
+ .audio_codec = CODEC_ID_MP3,
+ .video_codec = CODEC_ID_FLV1,
+ .write_header = swf_write_header,
+ .write_packet = swf_write_packet,
+ .write_trailer = swf_write_trailer,
};
#endif
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index e602a556d2..eb982d5675 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -2,20 +2,20 @@
* TCP protocol
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
@@ -45,7 +45,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
char buf[256];
int ret;
socklen_t optlen;
- int timeout = 100;
+ int timeout = 50;
char hostname[1024],proto[1024],path[1024];
char portstr[10];
diff --git a/libavformat/thp.c b/libavformat/thp.c
index 51dbd810cd..e2aba3bc32 100644
--- a/libavformat/thp.c
+++ b/libavformat/thp.c
@@ -2,20 +2,20 @@
* THP Demuxer
* Copyright (c) 2007 Marco Gerards
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -94,7 +94,7 @@ static int thp_read_header(AVFormatContext *s,
break;
/* Video component. */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -117,7 +117,7 @@ static int thp_read_header(AVFormatContext *s,
break;
/* Audio component. */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -189,10 +189,10 @@ static int thp_read_packet(AVFormatContext *s,
}
AVInputFormat ff_thp_demuxer = {
- "thp",
- NULL_IF_CONFIG_SMALL("THP"),
- sizeof(ThpDemuxContext),
- thp_probe,
- thp_read_header,
- thp_read_packet
+ .name = "thp",
+ .long_name = NULL_IF_CONFIG_SMALL("THP"),
+ .priv_data_size = sizeof(ThpDemuxContext),
+ .read_probe = thp_probe,
+ .read_header = thp_read_header,
+ .read_packet = thp_read_packet
};
diff --git a/libavformat/tiertexseq.c b/libavformat/tiertexseq.c
index 7ca0464550..dfed70ceae 100644
--- a/libavformat/tiertexseq.c
+++ b/libavformat/tiertexseq.c
@@ -2,20 +2,20 @@
* Tiertex Limited SEQ File Demuxer
* Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -206,7 +206,7 @@ static int seq_read_header(AVFormatContext *s, AVFormatParameters *ap)
seq->audio_buffer_full = 0;
/* initialize the video decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -219,7 +219,7 @@ static int seq_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->height = SEQ_FRAME_H;
/* initialize the audio decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -303,11 +303,11 @@ static int seq_read_close(AVFormatContext *s)
}
AVInputFormat ff_tiertexseq_demuxer = {
- "tiertexseq",
- NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ format"),
- sizeof(SeqDemuxContext),
- seq_probe,
- seq_read_header,
- seq_read_packet,
- seq_read_close,
+ .name = "tiertexseq",
+ .long_name = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ format"),
+ .priv_data_size = sizeof(SeqDemuxContext),
+ .read_probe = seq_probe,
+ .read_header = seq_read_header,
+ .read_packet = seq_read_packet,
+ .read_close = seq_read_close,
};
diff --git a/libavformat/timefilter.c b/libavformat/timefilter.c
deleted file mode 100644
index 4860a4ff70..0000000000
--- a/libavformat/timefilter.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Delay Locked Loop based time filter
- * Copyright (c) 2009 Samalyse
- * Copyright (c) 2009 Michael Niedermayer
- * Author: Olivier Guilyardi <olivier samalyse com>
- * Michael Niedermayer <michaelni gmx at>
- *
- * This file is part of Libav.
- *
- * Libav 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.
- *
- * Libav 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 Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-#include "config.h"
-#include "avformat.h"
-#include "timefilter.h"
-
-struct TimeFilter {
- /// Delay Locked Loop data. These variables refer to mathematical
- /// concepts described in: http://www.kokkinizita.net/papers/usingdll.pdf
- double cycle_time;
- double feedback2_factor;
- double feedback3_factor;
- double clock_period;
- int count;
-};
-
-TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor)
-{
- TimeFilter *self = av_mallocz(sizeof(TimeFilter));
- self->clock_period = clock_period;
- self->feedback2_factor = feedback2_factor;
- self->feedback3_factor = feedback3_factor;
- return self;
-}
-
-void ff_timefilter_destroy(TimeFilter *self)
-{
- av_freep(&self);
-}
-
-void ff_timefilter_reset(TimeFilter *self)
-{
- self->count = 0;
-}
-
-double ff_timefilter_update(TimeFilter *self, double system_time, double period)
-{
- self->count++;
- if (self->count==1) {
- /// init loop
- self->cycle_time = system_time;
- } else {
- double loop_error;
- self->cycle_time += self->clock_period * period;
- /// calculate loop error
- loop_error = system_time - self->cycle_time;
-
- /// update loop
- self->cycle_time += FFMAX(self->feedback2_factor, 1.0/(self->count)) * loop_error;
- self->clock_period += self->feedback3_factor * loop_error / period;
- }
- return self->cycle_time;
-}
-
-#ifdef TEST
-#include "libavutil/lfg.h"
-#define LFG_MAX ((1LL << 32) - 1)
-
-#undef printf
-
-int main(void)
-{
- AVLFG prng;
- double n0,n1;
-#define SAMPLES 1000
- double ideal[SAMPLES];
- double samples[SAMPLES];
-#if 1
- for(n0= 0; n0<40; n0=2*n0+1){
- for(n1= 0; n1<10; n1=2*n1+1){
-#else
- {{
- n0=7;
- n1=1;
-#endif
- double best_error= 1000000000;
- double bestpar0=1;
- double bestpar1=0.001;
- int better, i;
-
- av_lfg_init(&prng, 123);
- for(i=0; i<SAMPLES; i++){
- ideal[i] = 10 + i + n1*i/(1000);
- samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2)
- / (LFG_MAX * 10LL);
- }
-
- do{
- double par0, par1;
- better=0;
- for(par0= bestpar0*0.8; par0<=bestpar0*1.21; par0+=bestpar0*0.05){
- for(par1= bestpar1*0.8; par1<=bestpar1*1.21; par1+=bestpar1*0.05){
- double error=0;
- TimeFilter *tf= ff_timefilter_new(1, par0, par1);
- for(i=0; i<SAMPLES; i++){
- double filtered;
- filtered= ff_timefilter_update(tf, samples[i], 1);
- error += (filtered - ideal[i]) * (filtered - ideal[i]);
- }
- ff_timefilter_destroy(tf);
- if(error < best_error){
- best_error= error;
- bestpar0= par0;
- bestpar1= par1;
- better=1;
- }
- }
- }
- }while(better);
-#if 0
- double lastfil=9;
- TimeFilter *tf= ff_timefilter_new(1, bestpar0, bestpar1);
- for(i=0; i<SAMPLES; i++){
- double filtered;
- filtered= ff_timefilter_update(tf, samples[i], 1);
- printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i], samples[FFMAX(i, 1)] - samples[FFMAX(i-1, 0)], filtered - lastfil);
- lastfil= filtered;
- }
- ff_timefilter_destroy(tf);
-#else
- printf(" [%f %f %9f]", bestpar0, bestpar1, best_error);
-#endif
- }
- printf("\n");
- }
- return 0;
-}
-#endif
diff --git a/libavformat/timefilter.h b/libavformat/timefilter.h
deleted file mode 100644
index aa7db533b4..0000000000
--- a/libavformat/timefilter.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Delay Locked Loop based time filter prototypes and declarations
- * Copyright (c) 2009 Samalyse
- * Copyright (c) 2009 Michael Niedermayer
- * Author: Olivier Guilyardi <olivier samalyse com>
- * Michael Niedermayer <michaelni gmx at>
- *
- * This file is part of Libav.
- *
- * Libav 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.
- *
- * Libav 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 Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVFORMAT_TIMEFILTER_H
-#define AVFORMAT_TIMEFILTER_H
-
-/**
- * Opaque type representing a time filter state
- *
- * The purpose of this filter is to provide a way to compute accurate time
- * stamps that can be compared to wall clock time, especially when dealing
- * with two clocks: the system clock and a hardware device clock, such as
- * a soundcard.
- */
-typedef struct TimeFilter TimeFilter;
-
-
-/**
- * Create a new Delay Locked Loop time filter
- *
- * feedback2_factor and feedback3_factor are the factors used for the
- * multiplications that are respectively performed in the second and third
- * feedback paths of the loop.
- *
- * Unless you know what you are doing, you should set these as follow:
- *
- * o = 2 * M_PI * bandwidth * period
- * feedback2_factor = sqrt(2 * o)
- * feedback3_factor = o * o
- *
- * Where bandwidth is up to you to choose. Smaller values will filter out more
- * of the jitter, but also take a longer time for the loop to settle. A good
- * starting point is something between 0.3 and 3 Hz.
- *
- * @param clock_period period of the hardware clock in seconds
- * (for example 1.0/44100)
- *
- * For more details about these parameters and background concepts please see:
- * http://www.kokkinizita.net/papers/usingdll.pdf
- */
-TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor);
-
-/**
- * Update the filter
- *
- * This function must be called in real time, at each process cycle.
- *
- * @param period the device cycle duration in clock_periods. For example, at
- * 44.1kHz and a buffer size of 512 frames, period = 512 when clock_period
- * was 1.0/44100, or 512/44100 if clock_period was 1.
- *
- * system_time, in seconds, should be the value of the system clock time,
- * at (or as close as possible to) the moment the device hardware interrupt
- * occured (or any other event the device clock raises at the beginning of a
- * cycle).
- *
- * @return the filtered time, in seconds
- */
-double ff_timefilter_update(TimeFilter *self, double system_time, double period);
-
-/**
- * Reset the filter
- *
- * This function should mainly be called in case of XRUN.
- *
- * Warning: after calling this, the filter is in an undetermined state until
- * the next call to ff_timefilter_update()
- */
-void ff_timefilter_reset(TimeFilter *);
-
-/**
- * Free all resources associated with the filter
- */
-void ff_timefilter_destroy(TimeFilter *);
-
-#endif /* AVFORMAT_TIMEFILTER_H */
diff --git a/libavformat/tmv.c b/libavformat/tmv.c
index f894eab46a..03d6e08f0e 100644
--- a/libavformat/tmv.c
+++ b/libavformat/tmv.c
@@ -2,28 +2,28 @@
* 8088flex TMV file demuxer
* Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
- * 8088flex TMV file demuxer
* @file
+ * 8088flex TMV file demuxer
* @author Daniel Verkamp
- * @sa http://www.oldskool.org/pc/8088_Corruption
+ * @see http://www.oldskool.org/pc/8088_Corruption
*/
#include "libavutil/intreadwrite.h"
@@ -73,10 +73,10 @@ static int tmv_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (avio_rl32(pb) != TMV_TAG)
return -1;
- if (!(vst = av_new_stream(s, 0)))
+ if (!(vst = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
- if (!(ast = av_new_stream(s, 0)))
+ if (!(ast = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
ast->codec->sample_rate = avio_rl16(pb);
@@ -146,7 +146,7 @@ static int tmv_read_packet(AVFormatContext *s, AVPacket *pkt)
int ret, pkt_size = tmv->stream_index ?
tmv->audio_chunk_size : tmv->video_chunk_size;
- if (pb->eof_reached)
+ if (url_feof(pb))
return AVERROR_EOF;
ret = av_get_packet(pb, pkt, pkt_size);
@@ -173,19 +173,19 @@ static int tmv_read_seek(AVFormatContext *s, int stream_index,
pos = timestamp *
(tmv->audio_chunk_size + tmv->video_chunk_size + tmv->padding);
- avio_seek(s->pb, pos + TMV_HEADER_SIZE, SEEK_SET);
+ if (avio_seek(s->pb, pos + TMV_HEADER_SIZE, SEEK_SET) < 0)
+ return -1;
tmv->stream_index = 0;
return 0;
}
AVInputFormat ff_tmv_demuxer = {
- "tmv",
- NULL_IF_CONFIG_SMALL("8088flex TMV"),
- sizeof(TMVContext),
- tmv_probe,
- tmv_read_header,
- tmv_read_packet,
- NULL,
- tmv_read_seek,
+ .name = "tmv",
+ .long_name = NULL_IF_CONFIG_SMALL("8088flex TMV"),
+ .priv_data_size = sizeof(TMVContext),
+ .read_probe = tmv_probe,
+ .read_header = tmv_read_header,
+ .read_packet = tmv_read_packet,
+ .read_seek = tmv_read_seek,
.flags = AVFMT_GENERIC_INDEX,
};
diff --git a/libavformat/tta.c b/libavformat/tta.c
index 49234a81e4..ca2d36b44f 100644
--- a/libavformat/tta.c
+++ b/libavformat/tta.c
@@ -2,20 +2,20 @@
* TTA demuxer
* Copyright (c) 2006 Alex Beregszaszi
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -77,7 +77,7 @@ static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap)
return -1;
}
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -137,21 +137,21 @@ static int tta_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
int index = av_index_search_timestamp(st, timestamp, flags);
if (index < 0)
return -1;
+ if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0)
+ return -1;
c->currentframe = index;
- avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
return 0;
}
AVInputFormat ff_tta_demuxer = {
- "tta",
- NULL_IF_CONFIG_SMALL("True Audio"),
- sizeof(TTAContext),
- tta_probe,
- tta_read_header,
- tta_read_packet,
- NULL,
- tta_read_seek,
+ .name = "tta",
+ .long_name = NULL_IF_CONFIG_SMALL("True Audio"),
+ .priv_data_size = sizeof(TTAContext),
+ .read_probe = tta_probe,
+ .read_header = tta_read_header,
+ .read_packet = tta_read_packet,
+ .read_seek = tta_read_seek,
.extensions = "tta",
};
diff --git a/libavformat/tty.c b/libavformat/tty.c
index ee6b2f1334..5c9fee7908 100644
--- a/libavformat/tty.c
+++ b/libavformat/tty.c
@@ -2,20 +2,20 @@
* Tele-typewriter demuxer
* Copyright (c) 2010 Peter Ross <pross@xvid.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -76,7 +76,7 @@ static int read_header(AVFormatContext *avctx,
{
TtyDemuxContext *s = avctx->priv_data;
int width = 0, height = 0, ret = 0;
- AVStream *st = av_new_stream(avctx, 0);
+ AVStream *st = avformat_new_stream(avctx, NULL);
AVRational framerate;
if (!st) {
@@ -95,23 +95,11 @@ static int read_header(AVFormatContext *avctx,
av_log(avctx, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s->framerate);
goto fail;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->width > 0)
- width = ap->width;
- if (ap->height > 0)
- height = ap->height;
- if (ap->time_base.num)
- framerate = (AVRational){ap->time_base.den, ap->time_base.num};
-#endif
st->codec->width = width;
st->codec->height = height;
av_set_pts_info(st, 60, framerate.den, framerate.num);
/* simulate tty display speed */
-#if FF_API_FORMAT_PARAMETERS
- if (ap->sample_rate)
- s->chars_per_frame = ap->sample_rate;
-#endif
s->chars_per_frame = FFMAX(av_q2d(st->time_base)*s->chars_per_frame, 1);
if (avctx->pb->seekable) {
@@ -133,7 +121,7 @@ static int read_packet(AVFormatContext *avctx, AVPacket *pkt)
TtyDemuxContext *s = avctx->priv_data;
int n;
- if (avctx->pb->eof_reached)
+ if (url_feof(avctx->pb))
return AVERROR_EOF;
n = s->chars_per_frame;
@@ -154,9 +142,9 @@ static int read_packet(AVFormatContext *avctx, AVPacket *pkt)
#define OFFSET(x) offsetof(TtyDemuxContext, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- { "chars_per_frame", "", offsetof(TtyDemuxContext, chars_per_frame), FF_OPT_TYPE_INT, {.dbl = 6000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM},
- { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
- { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+ { "chars_per_frame", "", offsetof(TtyDemuxContext, chars_per_frame), AV_OPT_TYPE_INT, {.dbl = 6000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM},
+ { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
{ NULL },
};
diff --git a/libavformat/txd.c b/libavformat/txd.c
index 0a93b7c760..5d9f969270 100644
--- a/libavformat/txd.c
+++ b/libavformat/txd.c
@@ -2,20 +2,20 @@
* Renderware TeXture Dictionary (.txd) demuxer
* Copyright (c) 2007 Ivo van Poorten
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -40,7 +40,7 @@ static int txd_probe(AVProbeData * pd) {
static int txd_read_header(AVFormatContext *s, AVFormatParameters *ap) {
AVStream *st;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -61,7 +61,7 @@ next_chunk:
chunk_size = avio_rl32(pb);
marker = avio_rl32(pb);
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR_EOF;
if (marker != TXD_MARKER && marker != TXD_MARKER2) {
av_log(s, AV_LOG_ERROR, "marker does not match\n");
@@ -90,12 +90,10 @@ next_chunk:
return 0;
}
-AVInputFormat ff_txd_demuxer =
-{
- "txd",
- NULL_IF_CONFIG_SMALL("Renderware TeXture Dictionary"),
- 0,
- txd_probe,
- txd_read_header,
- txd_read_packet,
+AVInputFormat ff_txd_demuxer = {
+ .name = "txd",
+ .long_name = NULL_IF_CONFIG_SMALL("Renderware TeXture Dictionary"),
+ .read_probe = txd_probe,
+ .read_header = txd_read_header,
+ .read_packet = txd_read_packet,
};
diff --git a/libavformat/udp.c b/libavformat/udp.c
index bd95a811de..151e070d19 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -2,20 +2,20 @@
* UDP prototype streaming system
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -29,11 +29,18 @@
#include "avformat.h"
#include "avio_internal.h"
#include "libavutil/parseutils.h"
+#include "libavutil/fifo.h"
+#include "libavutil/intreadwrite.h"
#include <unistd.h>
#include "internal.h"
#include "network.h"
#include "os_support.h"
#include "url.h"
+
+#if HAVE_PTHREADS
+#include <pthread.h>
+#endif
+
#include <sys/time.h>
#ifndef IPV6_ADD_MEMBERSHIP
@@ -41,6 +48,9 @@
#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
#endif
+#define UDP_TX_BUF_SIZE 32768
+#define UDP_MAX_PKT_SIZE 65536
+
typedef struct {
int udp_fd;
int ttl;
@@ -51,10 +61,17 @@ typedef struct {
struct sockaddr_storage dest_addr;
int dest_addr_len;
int is_connected;
-} UDPContext;
-#define UDP_TX_BUF_SIZE 32768
-#define UDP_MAX_PKT_SIZE 65536
+ /* Circular Buffer variables for use in UDP receive code */
+ int circular_buffer_size;
+ AVFifoBuffer *fifo;
+ int circular_buffer_error;
+#if HAVE_PTHREADS
+ pthread_t circular_buffer_thread;
+#endif
+ uint8_t tmp[UDP_MAX_PKT_SIZE+4];
+ int remaining_in_dg;
+} UDPContext;
static int udp_set_multicast_ttl(int sockfd, int mcastTTL,
struct sockaddr *addr)
@@ -298,6 +315,64 @@ static int udp_get_file_handle(URLContext *h)
return s->udp_fd;
}
+static void *circular_buffer_task( void *_URLContext)
+{
+ URLContext *h = _URLContext;
+ UDPContext *s = h->priv_data;
+ fd_set rfds;
+ struct timeval tv;
+
+ for(;;) {
+ int left;
+ int ret;
+ int len;
+
+ if (url_interrupt_cb()) {
+ s->circular_buffer_error = EINTR;
+ return NULL;
+ }
+
+ FD_ZERO(&rfds);
+ FD_SET(s->udp_fd, &rfds);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv);
+ if (ret < 0) {
+ if (ff_neterrno() == AVERROR(EINTR))
+ continue;
+ s->circular_buffer_error = EIO;
+ return NULL;
+ }
+
+ if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds)))
+ continue;
+
+ /* How much do we have left to the end of the buffer */
+ /* Whats the minimum we can read so that we dont comletely fill the buffer */
+ left = av_fifo_space(s->fifo);
+
+ /* No Space left, error, what do we do now */
+ if(left < UDP_MAX_PKT_SIZE + 4) {
+ av_log(h, AV_LOG_ERROR, "circular_buffer: OVERRUN\n");
+ s->circular_buffer_error = EIO;
+ return NULL;
+ }
+ left = FFMIN(left, s->fifo->end - s->fifo->wptr);
+ len = recv(s->udp_fd, s->tmp+4, sizeof(s->tmp)-4, 0);
+ if (len < 0) {
+ if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) {
+ s->circular_buffer_error = EIO;
+ return NULL;
+ }
+ continue;
+ }
+ AV_WL32(s->tmp, len);
+ av_fifo_generic_write(s->fifo, s->tmp, len+4, NULL);
+ }
+
+ return NULL;
+}
+
/* put it in UDP context */
/* return non zero if error */
static int udp_open(URLContext *h, const char *uri, int flags)
@@ -325,6 +400,8 @@ static int udp_open(URLContext *h, const char *uri, int flags)
s->ttl = 16;
s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_MAX_PKT_SIZE;
+ s->circular_buffer_size = 7*188*4096;
+
p = strchr(uri, '?');
if (p) {
if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) {
@@ -350,6 +427,9 @@ static int udp_open(URLContext *h, const char *uri, int flags)
if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
s->is_connected = strtol(buf, NULL, 10);
}
+ if (av_find_info_tag(buf, sizeof(buf), "fifo_size", p)) {
+ s->circular_buffer_size = strtol(buf, NULL, 10)*188;
+ }
}
/* fill the dest addr */
@@ -431,10 +511,23 @@ static int udp_open(URLContext *h, const char *uri, int flags)
}
s->udp_fd = udp_fd;
+
+#if HAVE_PTHREADS
+ if (!is_output && s->circular_buffer_size) {
+ /* start the task going */
+ s->fifo = av_fifo_alloc(s->circular_buffer_size);
+ if (pthread_create(&s->circular_buffer_thread, NULL, circular_buffer_task, h)) {
+ av_log(h, AV_LOG_ERROR, "pthread_create failed\n");
+ goto fail;
+ }
+ }
+#endif
+
return 0;
fail:
if (udp_fd >= 0)
closesocket(udp_fd);
+ av_fifo_free(s->fifo);
av_free(s);
return AVERROR(EIO);
}
@@ -443,6 +536,38 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
{
UDPContext *s = h->priv_data;
int ret;
+ int avail;
+ fd_set rfds;
+ struct timeval tv;
+
+ if (s->fifo) {
+
+ do {
+ avail = av_fifo_size(s->fifo);
+ if (avail) { // >=size) {
+ uint8_t tmp[4];
+
+ av_fifo_generic_read(s->fifo, tmp, 4, NULL);
+ avail= AV_RL32(tmp);
+ if(avail > size){
+ av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n");
+ avail= size;
+ }
+
+ av_fifo_generic_read(s->fifo, buf, avail, NULL);
+ return avail;
+ }
+ else {
+ FD_ZERO(&rfds);
+ FD_SET(s->udp_fd, &rfds);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv);
+ if (ret<0)
+ return ret;
+ }
+ } while( 1);
+ }
if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
ret = ff_network_wait_fd(s->udp_fd, 0);
@@ -450,6 +575,7 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
return ret;
}
ret = recv(s->udp_fd, buf, size, 0);
+
return ret < 0 ? ff_neterrno() : ret;
}
@@ -481,6 +607,7 @@ static int udp_close(URLContext *h)
if (s->is_multicast && (h->flags & AVIO_FLAG_READ))
udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr);
closesocket(s->udp_fd);
+ av_fifo_free(s->fifo);
av_free(s);
return 0;
}
diff --git a/libavformat/url.h b/libavformat/url.h
index caafe07cce..103f7b6c00 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -1,19 +1,19 @@
/*
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -74,12 +74,12 @@ typedef struct URLProtocol {
* @return 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
-int ffurl_alloc(URLContext **h, const char *url, int flags);
+int ffurl_alloc(URLContext **puc, const char *filename, int flags);
/**
* Connect an URLContext that has been allocated by ffurl_alloc
*/
-int ffurl_connect(URLContext *h);
+int ffurl_connect(URLContext *uc);
/**
* Create an URLContext for accessing to the resource indicated by
@@ -92,7 +92,7 @@ int ffurl_connect(URLContext *h);
* @return 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
-int ffurl_open(URLContext **h, const char *url, int flags);
+int ffurl_open(URLContext **puc, const char *filename, int flags);
/**
* Read up to size bytes from the resource accessed by h, and store
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 060e58e9b2..db27024904 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1,21 +1,21 @@
/*
- * various utility functions for use within Libav
+ * various utility functions for use within FFmpeg
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -25,6 +25,7 @@
#include "avio_internal.h"
#include "internal.h"
#include "libavcodec/internal.h"
+#include "libavcodec/raw.h"
#include "libavutil/opt.h"
#include "libavutil/dict.h"
#include "libavutil/pixdesc.h"
@@ -48,7 +49,7 @@
/**
* @file
- * various utility functions for use within Libav
+ * various utility functions for use within FFmpeg
*/
unsigned avformat_version(void)
@@ -58,13 +59,13 @@ unsigned avformat_version(void)
const char *avformat_configuration(void)
{
- return LIBAV_CONFIGURATION;
+ return FFMPEG_CONFIGURATION;
}
const char *avformat_license(void)
{
#define LICENSE_PREFIX "libavformat license: "
- return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+ return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
}
/* fraction handling */
@@ -79,7 +80,7 @@ const char *avformat_license(void)
* @param num must be >= 0
* @param den must be >= 1
*/
-static void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
+static void frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
{
num += (den >> 1);
if (num >= den) {
@@ -97,7 +98,7 @@ static void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
* @param f fractional number
* @param incr increment, can be positive or negative
*/
-static void av_frac_add(AVFrac *f, int64_t incr)
+static void frac_add(AVFrac *f, int64_t incr)
{
int64_t num, den;
@@ -304,11 +305,11 @@ int av_filename_number_test(const char *filename)
return filename && (av_get_frame_filename(buf, sizeof(buf), filename, 1)>=0);
}
-AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)
+AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret)
{
AVProbeData lpd = *pd;
AVInputFormat *fmt1 = NULL, *fmt;
- int score, id3 = 0;
+ int score, score_max=0;
if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
int id3len = ff_id3v2_tag_len(lpd.buf);
@@ -316,7 +317,6 @@ AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score
lpd.buf += id3len;
lpd.buf_size -= id3len;
}
- id3 = 1;
}
fmt = NULL;
@@ -326,36 +326,40 @@ AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score
score = 0;
if (fmt1->read_probe) {
score = fmt1->read_probe(&lpd);
+ if(!score && fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions))
+ score = 1;
} else if (fmt1->extensions) {
if (av_match_ext(lpd.filename, fmt1->extensions)) {
score = 50;
}
}
- if (score > *score_max) {
- *score_max = score;
+ if (score > score_max) {
+ score_max = score;
fmt = fmt1;
- }else if (score == *score_max)
+ }else if (score == score_max)
fmt = NULL;
}
-
- /* a hack for files with huge id3v2 tags -- try to guess by file extension. */
- if (!fmt && id3 && *score_max < AVPROBE_SCORE_MAX/4) {
- while ((fmt = av_iformat_next(fmt)))
- if (fmt->extensions && av_match_ext(lpd.filename, fmt->extensions)) {
- *score_max = AVPROBE_SCORE_MAX/4;
- break;
- }
- }
-
+ *score_ret= score_max;
return fmt;
}
+AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)
+{
+ int score_ret;
+ AVInputFormat *fmt= av_probe_input_format3(pd, is_opened, &score_ret);
+ if(score_ret > *score_max){
+ *score_max= score_ret;
+ return fmt;
+ }else
+ return NULL;
+}
+
AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened){
int score=0;
return av_probe_input_format2(pd, is_opened, &score);
}
-static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeData *pd, int score)
+static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeData *pd)
{
static const struct {
const char *name; enum CodecID id; enum AVMediaType type;
@@ -365,12 +369,14 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa
{ "dts" , CODEC_ID_DTS , AVMEDIA_TYPE_AUDIO },
{ "eac3" , CODEC_ID_EAC3 , AVMEDIA_TYPE_AUDIO },
{ "h264" , CODEC_ID_H264 , AVMEDIA_TYPE_VIDEO },
+ { "loas" , CODEC_ID_AAC_LATM , AVMEDIA_TYPE_AUDIO },
{ "m4v" , CODEC_ID_MPEG4 , AVMEDIA_TYPE_VIDEO },
{ "mp3" , CODEC_ID_MP3 , AVMEDIA_TYPE_AUDIO },
{ "mpegvideo", CODEC_ID_MPEG2VIDEO, AVMEDIA_TYPE_VIDEO },
{ 0 }
};
- AVInputFormat *fmt = av_probe_input_format2(pd, 1, &score);
+ int score;
+ AVInputFormat *fmt = av_probe_input_format3(pd, 1, &score);
if (fmt) {
int i;
@@ -384,7 +390,7 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa
}
}
}
- return !!fmt;
+ return score;
}
/************************************************************/
@@ -399,6 +405,7 @@ static AVDictionary *convert_format_parameters(AVFormatParameters *ap)
if (!ap)
return NULL;
+ AV_NOWARN_DEPRECATED(
if (ap->time_base.num) {
snprintf(buf, sizeof(buf), "%d/%d", ap->time_base.den, ap->time_base.num);
av_dict_set(&opts, "framerate", buf, 0);
@@ -431,6 +438,7 @@ static AVDictionary *convert_format_parameters(AVFormatParameters *ap)
if (ap->initial_pause) {
av_dict_set(&opts, "initial_pause", "1", 0);
}
+ )
return opts;
}
@@ -452,10 +460,12 @@ int av_open_input_stream(AVFormatContext **ic_ptr,
}
opts = convert_format_parameters(ap);
+ AV_NOWARN_DEPRECATED(
if(!ap->prealloced_context)
- ic = avformat_alloc_context();
+ *ic_ptr = ic = avformat_alloc_context();
else
ic = *ic_ptr;
+ )
if (!ic) {
err = AVERROR(ENOMEM);
goto fail;
@@ -466,16 +476,33 @@ int av_open_input_stream(AVFormatContext **ic_ptr,
else
ic->pb = pb;
- err = avformat_open_input(&ic, filename, fmt, &opts);
+ if ((err = avformat_open_input(&ic, filename, fmt, &opts)) < 0)
+ goto fail;
ic->pb = ic->pb ? ic->pb : pb; // don't leak custom pb if it wasn't set above
- *ic_ptr = ic;
fail:
+ *ic_ptr = ic;
av_dict_free(&opts);
return err;
}
#endif
+int av_demuxer_open(AVFormatContext *ic, AVFormatParameters *ap){
+ int err;
+
+ if (ic->iformat->read_header) {
+ err = ic->iformat->read_header(ic, ap);
+ if (err < 0)
+ return err;
+ }
+
+ if (ic->pb && !ic->data_offset)
+ ic->data_offset = avio_tell(ic->pb);
+
+ return 0;
+}
+
+
/** size of probe buffer, for guessing file type from file contents */
#define PROBE_BUF_MIN 2048
#define PROBE_BUF_MAX (1<<20)
@@ -500,17 +527,23 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
return AVERROR(EINVAL);
}
- for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt && ret >= 0;
+ for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt;
probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) {
- int ret, score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0;
+ int score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0;
int buf_offset = (probe_size == PROBE_BUF_MIN) ? 0 : probe_size>>1;
+ void *buftmp;
if (probe_size < offset) {
continue;
}
/* read probe data */
- buf = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE);
+ buftmp = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE);
+ if(!buftmp){
+ av_free(buf);
+ return AVERROR(ENOMEM);
+ }
+ buf=buftmp;
if ((ret = avio_read(pb, buf + buf_offset, probe_size - buf_offset)) < 0) {
/* fail if error was not end of file, otherwise, lower score */
if (ret != AVERROR_EOF) {
@@ -529,9 +562,9 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
*fmt = av_probe_input_format2(&pd, 1, &score);
if(*fmt){
if(score <= AVPROBE_SCORE_MAX/4){ //this can only be true in the last iteration
- av_log(logctx, AV_LOG_WARNING, "Format detected only with low score of %d, misdetection possible!\n", score);
+ av_log(logctx, AV_LOG_WARNING, "Format %s detected only with low score of %d, misdetection possible!\n", (*fmt)->name, score);
}else
- av_log(logctx, AV_LOG_DEBUG, "Probed with size=%d and score=%d\n", probe_size, score);
+ av_log(logctx, AV_LOG_DEBUG, "Format %s probed with size=%d and score=%d\n", (*fmt)->name, probe_size, score);
}
}
@@ -556,8 +589,10 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
int err;
AVDictionary *opts = convert_format_parameters(ap);
+ AV_NOWARN_DEPRECATED(
if (!ap || !ap->prealloced_context)
*ic_ptr = NULL;
+ )
err = avformat_open_input(ic_ptr, filename, fmt, &opts);
@@ -577,7 +612,8 @@ static int init_input(AVFormatContext *s, const char *filename)
if (!s->iformat)
return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0);
else if (s->iformat->flags & AVFMT_NOFILE)
- return AVERROR(EINVAL);
+ av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
+ "will be ignored with AVFMT_NOFILE format.\n");
return 0;
}
@@ -586,7 +622,7 @@ static int init_input(AVFormatContext *s, const char *filename)
return 0;
if ((ret = avio_open(&s->pb, filename, AVIO_FLAG_READ)) < 0)
- return ret;
+ return ret;
if (s->iformat)
return 0;
return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0);
@@ -596,7 +632,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
{
AVFormatContext *s = *ps;
int ret = 0;
- AVFormatParameters ap = { 0 };
+ AVFormatParameters ap = { { 0 } };
AVDictionary *tmp = NULL;
if (!s && !(s = avformat_alloc_context()))
@@ -642,11 +678,11 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
if (s->pb)
ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC);
- if (s->iformat->read_header)
+ if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header)
if ((ret = s->iformat->read_header(s, &ap)) < 0)
goto fail;
- if (s->pb && !s->data_offset)
+ if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->pb && !s->data_offset)
s->data_offset = avio_tell(s->pb);
s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
@@ -696,12 +732,7 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
if (pktl) {
*pkt = pktl->pkt;
- if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE ||
- !s->streams[pkt->stream_index]->probe_packets ||
- s->raw_packet_buffer_remaining_size < pkt->size){
- AVProbeData *pd = &s->streams[pkt->stream_index]->probe_data;
- av_freep(&pd->buf);
- pd->buf_size = 0;
+ if(s->streams[pkt->stream_index]->request_probe <= 0){
s->raw_packet_buffer = pktl->next;
s->raw_packet_buffer_remaining_size += pkt->size;
av_free(pktl);
@@ -715,9 +746,28 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
if (!pktl || ret == AVERROR(EAGAIN))
return ret;
for (i = 0; i < s->nb_streams; i++)
- s->streams[i]->probe_packets = 0;
+ if(s->streams[i]->request_probe > 0)
+ s->streams[i]->request_probe = -1;
continue;
}
+
+ if ((s->flags & AVFMT_FLAG_DISCARD_CORRUPT) &&
+ (pkt->flags & AV_PKT_FLAG_CORRUPT)) {
+ av_log(s, AV_LOG_WARNING,
+ "Dropped corrupted packet (stream = %d)\n",
+ pkt->stream_index);
+ av_free_packet(pkt);
+ continue;
+ }
+
+ if(!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA))
+ av_packet_merge_side_data(pkt);
+
+ if(pkt->stream_index >= (unsigned)s->nb_streams){
+ av_log(s, AV_LOG_ERROR, "Invalid stream index %d\n", pkt->stream_index);
+ continue;
+ }
+
st= s->streams[pkt->stream_index];
switch(st->codec->codec_type){
@@ -732,16 +782,16 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
break;
}
- if(!pktl && (st->codec->codec_id != CODEC_ID_PROBE ||
- !st->probe_packets))
+ if(!pktl && st->request_probe <= 0)
return ret;
add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
s->raw_packet_buffer_remaining_size -= pkt->size;
- if(st->codec->codec_id == CODEC_ID_PROBE){
+ if(st->request_probe>0){
AVProbeData *pd = &st->probe_data;
- av_log(s, AV_LOG_DEBUG, "probing stream %d\n", st->index);
+ int end;
+ av_log(s, AV_LOG_DEBUG, "probing stream %d pp:%d\n", st->index, st->probe_packets);
--st->probe_packets;
pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
@@ -749,13 +799,20 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
pd->buf_size += pkt->size;
memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
- if(av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){
- //FIXME we dont reduce score to 0 for the case of running out of buffer space in bytes
- set_codec_from_probe_data(s, st, pd, st->probe_packets > 0 ? AVPROBE_SCORE_MAX/4 : 0);
- if(st->codec->codec_id != CODEC_ID_PROBE){
+ end= s->raw_packet_buffer_remaining_size <= 0
+ || st->probe_packets<=0;
+
+ if(end || av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){
+ int score= set_codec_from_probe_data(s, st, pd);
+ if( (st->codec->codec_id != CODEC_ID_NONE && score > AVPROBE_SCORE_MAX/4)
+ || end){
pd->buf_size=0;
av_freep(&pd->buf);
+ st->request_probe= -1;
+ if(st->codec->codec_id != CODEC_ID_NONE){
av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index);
+ }else
+ av_log(s, AV_LOG_WARNING, "probed stream %d failed\n", st->index);
}
}
}
@@ -842,6 +899,7 @@ static int is_intra_only(AVCodecContext *enc){
case CODEC_ID_MJPEG:
case CODEC_ID_MJPEGB:
case CODEC_ID_LJPEG:
+ case CODEC_ID_PRORES:
case CODEC_ID_RAWVIDEO:
case CODEC_ID_DVVIDEO:
case CODEC_ID_HUFFYUV:
@@ -954,8 +1012,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
pc && pc->pict_type != AV_PICTURE_TYPE_B)
presentation_delayed = 1;
- if(pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && pkt->dts > pkt->pts && st->pts_wrap_bits<63
- /*&& pkt->dts-(1LL<<st->pts_wrap_bits) < pkt->pts*/){
+ if(pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && pkt->dts - (1LL<<(st->pts_wrap_bits-1)) > pkt->pts && st->pts_wrap_bits<63){
pkt->dts -= 1LL<<st->pts_wrap_bits;
}
@@ -963,7 +1020,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
// we take the conservative approach and discard both
// Note, if this is misbehaving for a H.264 file then possibly presentation_delayed is not set correctly.
if(delay==1 && pkt->dts == pkt->pts && pkt->dts != AV_NOPTS_VALUE && presentation_delayed){
- av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination\n");
+ av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination %"PRIi64"\n", pkt->dts);
pkt->dts= pkt->pts= AV_NOPTS_VALUE;
}
@@ -1087,7 +1144,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
}
-static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
+static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
{
AVStream *st;
int len, ret, i;
@@ -1101,7 +1158,10 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
if (!st->need_parsing || !st->parser) {
/* no parsing needed: we just output the packet as is */
/* raw data support */
- *pkt = st->cur_pkt; st->cur_pkt.data= NULL;
+ *pkt = st->cur_pkt;
+ st->cur_pkt.data= NULL;
+ st->cur_pkt.side_data_elems = 0;
+ st->cur_pkt.side_data = NULL;
compute_pkt_fields(s, st, NULL, pkt);
s->cur_st = NULL;
if ((s->iformat->flags & AVFMT_GENERIC_INDEX) &&
@@ -1136,13 +1196,14 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
st->cur_pkt.data = NULL;
assert(st->cur_len == 0);
}else{
- pkt->destruct = NULL;
+ pkt->destruct = NULL;
}
compute_pkt_fields(s, st, st->parser, pkt);
if((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & AV_PKT_FLAG_KEY){
+ int64_t pos= (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->pos : st->parser->frame_offset;
ff_reduce_index(s, st->index);
- av_add_index_entry(st, st->parser->frame_offset, pkt->dts,
+ av_add_index_entry(st, pos, pkt->dts,
0, 0, AVINDEX_KEYFRAME);
}
@@ -1206,6 +1267,9 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
if (st->need_parsing && !st->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) {
st->parser = av_parser_init(st->codec->codec_id);
if (!st->parser) {
+ av_log(s, AV_LOG_WARNING, "parser not found for codec "
+ "%s, packets or times may be invalid.\n",
+ avcodec_get_name(st->codec->codec_id));
/* no parser available: just output the raw packets */
st->need_parsing = AVSTREAM_PARSE_NONE;
}else if(st->need_parsing == AVSTREAM_PARSE_HEADERS){
@@ -1217,7 +1281,7 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
}
}
if(s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_DEBUG, "av_read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n",
+ av_log(s, AV_LOG_DEBUG, "read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n",
pkt->stream_index,
pkt->pts,
pkt->dts,
@@ -1263,7 +1327,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
}
}
if(genpts){
- int ret= av_read_frame_internal(s, pkt);
+ int ret= read_frame_internal(s, pkt);
if(ret<0){
if(pktl && ret != AVERROR(EAGAIN)){
eof=1;
@@ -1277,7 +1341,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
return AVERROR(ENOMEM);
}else{
assert(!s->packet_buffer);
- return av_read_frame_internal(s, pkt);
+ return read_frame_internal(s, pkt);
}
}
}
@@ -1538,6 +1602,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
if ((ret = avio_seek(s->pb, pos, SEEK_SET)) < 0)
return ret;
+ ff_read_frame_flush(s);
av_update_cur_dts(s, st, ts);
return 0;
@@ -1557,6 +1622,11 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i
return -1;
}
+ if(ts_min >= target_ts){
+ *ts_ret= ts_min;
+ return pos_min;
+ }
+
if(ts_max == AV_NOPTS_VALUE){
int step= 1024;
filesize = avio_size(s->pb);
@@ -1582,6 +1652,11 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i
pos_limit= pos_max;
}
+ if(ts_max <= target_ts){
+ *ts_ret= ts_max;
+ return pos_max;
+ }
+
if(ts_min > ts_max){
return -1;
}else if(ts_min == ts_max){
@@ -1639,17 +1714,19 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i
pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max;
ts = (flags & AVSEEK_FLAG_BACKWARD) ? ts_min : ts_max;
+#if 0
pos_min = pos;
ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
pos_min++;
ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
av_dlog(s, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n",
pos, ts_min, target_ts, ts_max);
+#endif
*ts_ret= ts;
return pos;
}
-static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){
+static int seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){
int64_t pos_min, pos_max;
#if 0
AVStream *st;
@@ -1674,7 +1751,7 @@ static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos,
return 0;
}
-static int av_seek_frame_generic(AVFormatContext *s,
+static int seek_frame_generic(AVFormatContext *s,
int stream_index, int64_t timestamp, int flags)
{
int index;
@@ -1690,8 +1767,8 @@ static int av_seek_frame_generic(AVFormatContext *s,
return -1;
if(index < 0 || index==st->nb_index_entries-1){
- int i;
AVPacket pkt;
+ int nonkey=0;
if(st->nb_index_entries){
assert(st->index_entries);
@@ -1703,17 +1780,21 @@ static int av_seek_frame_generic(AVFormatContext *s,
if ((ret = avio_seek(s->pb, s->data_offset, SEEK_SET)) < 0)
return ret;
}
- for(i=0;; i++) {
- int ret;
+ for (;;) {
+ int read_status;
do{
- ret = av_read_frame(s, &pkt);
- }while(ret == AVERROR(EAGAIN));
- if(ret<0)
+ read_status = av_read_frame(s, &pkt);
+ } while (read_status == AVERROR(EAGAIN));
+ if (read_status < 0)
break;
av_free_packet(&pkt);
- if(stream_index == pkt.stream_index){
- if((pkt.flags & AV_PKT_FLAG_KEY) && pkt.dts > timestamp)
+ if(stream_index == pkt.stream_index && pkt.dts > timestamp){
+ if(pkt.flags & AV_PKT_FLAG_KEY)
+ break;
+ if(nonkey++ > 1000){
+ av_log(s, AV_LOG_ERROR,"seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, %d non keyframes found\n", nonkey);
break;
+ }
}
}
index = av_index_search_timestamp(st, timestamp, flags);
@@ -1722,10 +1803,12 @@ static int av_seek_frame_generic(AVFormatContext *s,
return -1;
ff_read_frame_flush(s);
+ AV_NOWARN_DEPRECATED(
if (s->iformat->read_seek){
if(s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0)
return 0;
}
+ )
ie = &st->index_entries[index];
if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
return ret;
@@ -1739,10 +1822,12 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int f
int ret;
AVStream *st;
- ff_read_frame_flush(s);
-
- if(flags & AVSEEK_FLAG_BYTE)
- return av_seek_frame_byte(s, stream_index, timestamp, flags);
+ if (flags & AVSEEK_FLAG_BYTE) {
+ if (s->iformat->flags & AVFMT_NO_BYTE_SEEK)
+ return -1;
+ ff_read_frame_flush(s);
+ return seek_frame_byte(s, stream_index, timestamp, flags);
+ }
if(stream_index < 0){
stream_index= av_find_default_stream_index(s);
@@ -1750,23 +1835,29 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int f
return -1;
st= s->streams[stream_index];
- /* timestamp for default must be expressed in AV_TIME_BASE units */
+ /* timestamp for default must be expressed in AV_TIME_BASE units */
timestamp = av_rescale(timestamp, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num);
}
/* first, we try the format specific seek */
- if (s->iformat->read_seek)
+ AV_NOWARN_DEPRECATED(
+ if (s->iformat->read_seek) {
+ ff_read_frame_flush(s);
ret = s->iformat->read_seek(s, stream_index, timestamp, flags);
- else
+ } else
ret = -1;
+ )
if (ret >= 0) {
return 0;
}
- if(s->iformat->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH))
+ if (s->iformat->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH)) {
+ ff_read_frame_flush(s);
return av_seek_frame_binary(s, stream_index, timestamp, flags);
- else if (!(s->iformat->flags & AVFMT_NOGENSEARCH))
- return av_seek_frame_generic(s, stream_index, timestamp, flags);
+ } else if (!(s->iformat->flags & AVFMT_NOGENSEARCH)) {
+ ff_read_frame_flush(s);
+ return seek_frame_generic(s, stream_index, timestamp, flags);
+ }
else
return -1;
}
@@ -1776,10 +1867,10 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int
if(min_ts > ts || max_ts < ts)
return -1;
- ff_read_frame_flush(s);
-
- if (s->iformat->read_seek2)
+ if (s->iformat->read_seek2) {
+ ff_read_frame_flush(s);
return s->iformat->read_seek2(s, stream_index, min_ts, ts, max_ts, flags);
+ }
if(s->iformat->read_timestamp){
//try to seek via read_timestamp()
@@ -1787,10 +1878,12 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int
//Fallback to old API if new is not implemented but old is
//Note the old has somewat different sematics
+ AV_NOWARN_DEPRECATED(
if(s->iformat->read_seek || 1)
return av_seek_frame(s, stream_index, ts, flags | (ts - min_ts > (uint64_t)(max_ts - ts) ? AVSEEK_FLAG_BACKWARD : 0));
+ )
- // try some generic seek like av_seek_frame_generic() but with new ts semantics
+ // try some generic seek like seek_frame_generic() but with new ts semantics
}
/*******************************************************/
@@ -1800,10 +1893,12 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int
*
* @return TRUE if the stream has accurate duration for at least one component.
*/
-static int av_has_duration(AVFormatContext *ic)
+static int has_duration(AVFormatContext *ic)
{
int i;
AVStream *st;
+ if(ic->duration != AV_NOPTS_VALUE)
+ return 1;
for(i = 0;i < ic->nb_streams; i++) {
st = ic->streams[i];
@@ -1818,20 +1913,25 @@ static int av_has_duration(AVFormatContext *ic)
*
* Also computes the global bitrate if possible.
*/
-static void av_update_stream_timings(AVFormatContext *ic)
+static void update_stream_timings(AVFormatContext *ic)
{
- int64_t start_time, start_time1, end_time, end_time1;
- int64_t duration, duration1;
+ int64_t start_time, start_time1, start_time_text, end_time, end_time1;
+ int64_t duration, duration1, filesize;
int i;
AVStream *st;
start_time = INT64_MAX;
+ start_time_text = INT64_MAX;
end_time = INT64_MIN;
duration = INT64_MIN;
for(i = 0;i < ic->nb_streams; i++) {
st = ic->streams[i];
if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);
+ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+ if (start_time1 < start_time_text)
+ start_time_text = start_time1;
+ } else
if (start_time1 < start_time)
start_time = start_time1;
if (st->duration != AV_NOPTS_VALUE) {
@@ -1847,6 +1947,8 @@ static void av_update_stream_timings(AVFormatContext *ic)
duration = duration1;
}
}
+ if (start_time == INT64_MAX || (start_time > start_time_text && start_time - start_time_text < AV_TIME_BASE))
+ start_time = start_time_text;
if (start_time != INT64_MAX) {
ic->start_time = start_time;
if (end_time != INT64_MIN) {
@@ -1854,14 +1956,14 @@ static void av_update_stream_timings(AVFormatContext *ic)
duration = end_time - start_time;
}
}
- if (duration != INT64_MIN) {
+ if (duration != INT64_MIN && ic->duration == AV_NOPTS_VALUE) {
ic->duration = duration;
- if (ic->file_size > 0) {
+ }
+ if (ic->pb && (filesize = avio_size(ic->pb)) > 0 && ic->duration != AV_NOPTS_VALUE) {
/* compute the bitrate */
- ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE /
+ ic->bit_rate = (double)filesize * 8.0 * AV_TIME_BASE /
(double)ic->duration;
}
- }
}
static void fill_all_stream_timings(AVFormatContext *ic)
@@ -1869,7 +1971,7 @@ static void fill_all_stream_timings(AVFormatContext *ic)
int i;
AVStream *st;
- av_update_stream_timings(ic);
+ update_stream_timings(ic);
for(i = 0;i < ic->nb_streams; i++) {
st = ic->streams[i];
if (st->start_time == AV_NOPTS_VALUE) {
@@ -1881,7 +1983,7 @@ static void fill_all_stream_timings(AVFormatContext *ic)
}
}
-static void av_estimate_timings_from_bit_rate(AVFormatContext *ic)
+static void estimate_timings_from_bit_rate(AVFormatContext *ic)
{
int64_t filesize, duration;
int bit_rate, i;
@@ -1900,9 +2002,8 @@ static void av_estimate_timings_from_bit_rate(AVFormatContext *ic)
/* if duration is already set, we believe it */
if (ic->duration == AV_NOPTS_VALUE &&
- ic->bit_rate != 0 &&
- ic->file_size != 0) {
- filesize = ic->file_size;
+ ic->bit_rate != 0) {
+ filesize = ic->pb ? avio_size(ic->pb) : 0;
if (filesize > 0) {
for(i = 0; i < ic->nb_streams; i++) {
st = ic->streams[i];
@@ -1918,7 +2019,7 @@ static void av_estimate_timings_from_bit_rate(AVFormatContext *ic)
#define DURATION_MAX_RETRY 3
/* only usable for MPEG-PS streams */
-static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
+static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
{
AVPacket pkt1, *pkt = &pkt1;
AVStream *st;
@@ -1935,7 +2036,7 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset
for (i=0; i<ic->nb_streams; i++) {
st = ic->streams[i];
if (st->start_time == AV_NOPTS_VALUE && st->first_dts == AV_NOPTS_VALUE)
- av_log(st->codec, AV_LOG_WARNING, "start time is not set in av_estimate_timings_from_pts\n");
+ av_log(st->codec, AV_LOG_WARNING, "start time is not set in estimate_timings_from_pts\n");
if (st->parser) {
av_parser_close(st->parser);
@@ -1946,42 +2047,43 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset
/* estimate the end time (duration) */
/* XXX: may need to support wrapping */
- filesize = ic->file_size;
+ filesize = ic->pb ? avio_size(ic->pb) : 0;
end_time = AV_NOPTS_VALUE;
do{
- offset = filesize - (DURATION_MAX_READ_SIZE<<retry);
- if (offset < 0)
- offset = 0;
+ offset = filesize - (DURATION_MAX_READ_SIZE<<retry);
+ if (offset < 0)
+ offset = 0;
- avio_seek(ic->pb, offset, SEEK_SET);
- read_size = 0;
- for(;;) {
- if (read_size >= DURATION_MAX_READ_SIZE<<(FFMAX(retry-1,0)))
- break;
+ avio_seek(ic->pb, offset, SEEK_SET);
+ read_size = 0;
+ for(;;) {
+ if (read_size >= DURATION_MAX_READ_SIZE<<(FFMAX(retry-1,0)))
+ break;
- do{
- ret = av_read_packet(ic, pkt);
- }while(ret == AVERROR(EAGAIN));
- if (ret != 0)
- break;
- read_size += pkt->size;
- st = ic->streams[pkt->stream_index];
- if (pkt->pts != AV_NOPTS_VALUE &&
- (st->start_time != AV_NOPTS_VALUE ||
- st->first_dts != AV_NOPTS_VALUE)) {
- duration = end_time = pkt->pts;
- if (st->start_time != AV_NOPTS_VALUE) duration -= st->start_time;
- else duration -= st->first_dts;
- if (duration < 0)
- duration += 1LL<<st->pts_wrap_bits;
- if (duration > 0) {
- if (st->duration == AV_NOPTS_VALUE ||
- st->duration < duration)
- st->duration = duration;
+ do {
+ ret = av_read_packet(ic, pkt);
+ } while(ret == AVERROR(EAGAIN));
+ if (ret != 0)
+ break;
+ read_size += pkt->size;
+ st = ic->streams[pkt->stream_index];
+ if (pkt->pts != AV_NOPTS_VALUE &&
+ (st->start_time != AV_NOPTS_VALUE ||
+ st->first_dts != AV_NOPTS_VALUE)) {
+ duration = end_time = pkt->pts;
+ if (st->start_time != AV_NOPTS_VALUE)
+ duration -= st->start_time;
+ else
+ duration -= st->first_dts;
+ if (duration < 0)
+ duration += 1LL<<st->pts_wrap_bits;
+ if (duration > 0) {
+ if (st->duration == AV_NOPTS_VALUE || st->duration < duration)
+ st->duration = duration;
+ }
}
+ av_free_packet(pkt);
}
- av_free_packet(pkt);
- }
}while( end_time==AV_NOPTS_VALUE
&& filesize > (DURATION_MAX_READ_SIZE<<retry)
&& ++retry <= DURATION_MAX_RETRY);
@@ -1997,7 +2099,7 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset
}
}
-static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset)
+static void estimate_timings(AVFormatContext *ic, int64_t old_offset)
{
int64_t file_size;
@@ -2009,23 +2111,22 @@ static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset)
if (file_size < 0)
file_size = 0;
}
- ic->file_size = file_size;
if ((!strcmp(ic->iformat->name, "mpeg") ||
!strcmp(ic->iformat->name, "mpegts")) &&
file_size && ic->pb->seekable) {
/* get accurate estimate from the PTSes */
- av_estimate_timings_from_pts(ic, old_offset);
- } else if (av_has_duration(ic)) {
+ estimate_timings_from_pts(ic, old_offset);
+ } else if (has_duration(ic)) {
/* at least one component has timings - we use them for all
the components */
fill_all_stream_timings(ic);
} else {
av_log(ic, AV_LOG_WARNING, "Estimating duration from bitrate, this may be inaccurate\n");
/* less precise: use bitrate info */
- av_estimate_timings_from_bit_rate(ic);
+ estimate_timings_from_bit_rate(ic);
}
- av_update_stream_timings(ic);
+ update_stream_timings(ic);
{
int i;
@@ -2043,29 +2144,31 @@ static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset)
}
}
-static int has_codec_parameters(AVCodecContext *enc)
+static int has_codec_parameters(AVCodecContext *avctx)
{
int val;
- switch(enc->codec_type) {
+ switch (avctx->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- val = enc->sample_rate && enc->channels && enc->sample_fmt != AV_SAMPLE_FMT_NONE;
- if(!enc->frame_size &&
- (enc->codec_id == CODEC_ID_VORBIS ||
- enc->codec_id == CODEC_ID_AAC ||
- enc->codec_id == CODEC_ID_MP1 ||
- enc->codec_id == CODEC_ID_MP2 ||
- enc->codec_id == CODEC_ID_MP3 ||
- enc->codec_id == CODEC_ID_SPEEX))
+ val = avctx->sample_rate && avctx->channels && avctx->sample_fmt != AV_SAMPLE_FMT_NONE;
+ if (!avctx->frame_size &&
+ (avctx->codec_id == CODEC_ID_VORBIS ||
+ avctx->codec_id == CODEC_ID_AAC ||
+ avctx->codec_id == CODEC_ID_MP1 ||
+ avctx->codec_id == CODEC_ID_MP2 ||
+ avctx->codec_id == CODEC_ID_MP3 ||
+ avctx->codec_id == CODEC_ID_CELT))
return 0;
break;
case AVMEDIA_TYPE_VIDEO:
- val = enc->width && enc->pix_fmt != PIX_FMT_NONE;
+ val = avctx->width && avctx->pix_fmt != PIX_FMT_NONE;
break;
+ case AVMEDIA_TYPE_DATA:
+ if(avctx->codec_id == CODEC_ID_NONE) return 1;
default:
val = 1;
break;
}
- return enc->codec_id != CODEC_ID_NONE && val != 0;
+ return avctx->codec_id != CODEC_ID_NONE && val != 0;
}
static int has_decode_delay_been_guessed(AVStream *st)
@@ -2074,7 +2177,7 @@ static int has_decode_delay_been_guessed(AVStream *st)
st->codec_info_nb_frames >= 6 + st->codec->has_b_frames;
}
-static int try_decode_frame(AVStream *st, AVPacket *avpkt)
+static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options)
{
int16_t *samples;
AVCodec *codec;
@@ -2085,12 +2188,13 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt)
codec = avcodec_find_decoder(st->codec->codec_id);
if (!codec)
return -1;
- ret = avcodec_open(st->codec, codec);
+ ret = avcodec_open2(st->codec, codec, options);
if (ret < 0)
return ret;
}
- if(!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st)){
+ if(!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st) ||
+ (!st->codec_info_nb_frames && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF)) {
switch(st->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO:
avcodec_get_frame_defaults(&picture);
@@ -2132,7 +2236,7 @@ enum CodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
return tags[i].id;
}
for(i=0; tags[i].id != CODEC_ID_NONE; i++) {
- if (ff_toupper4(tag) == ff_toupper4(tags[i].tag))
+ if (avpriv_toupper4(tag) == avpriv_toupper4(tags[i].tag))
return tags[i].id;
}
return CODEC_ID_NONE;
@@ -2204,12 +2308,20 @@ static int tb_unreliable(AVCodecContext *c){
return 0;
}
+#if FF_API_FORMAT_PARAMETERS
int av_find_stream_info(AVFormatContext *ic)
{
+ return avformat_find_stream_info(ic, NULL);
+}
+#endif
+
+int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
+{
int i, count, ret, read_size, j;
AVStream *st;
AVPacket pkt1, *pkt;
int64_t old_offset = avio_tell(ic->pb);
+ int orig_nb_streams = ic->nb_streams; // new streams might appear, no options for those
for(i=0;i<ic->nb_streams;i++) {
AVCodec *codec;
@@ -2235,12 +2347,19 @@ int av_find_stream_info(AVFormatContext *ic)
/* Ensure that subtitle_header is properly set. */
if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
&& codec && !st->codec->codec)
- avcodec_open(st->codec, codec);
+ avcodec_open2(st->codec, codec, options ? &options[i] : NULL);
//try to just open decoders, in case this is enough to get parameters
if(!has_codec_parameters(st->codec)){
- if (codec && !st->codec->codec)
- avcodec_open(st->codec, codec);
+ if (codec && !st->codec->codec){
+ AVDictionary *tmp = NULL;
+ if (options){
+ av_dict_copy(&tmp, options[i], 0);
+ av_dict_set(&tmp, "threads", 0, 0);
+ }
+ avcodec_open2(st->codec, codec, options ? &tmp : NULL);
+ av_dict_free(&tmp);
+ }
}
}
@@ -2278,7 +2397,7 @@ int av_find_stream_info(AVFormatContext *ic)
break;
if(st->parser && st->parser->parser->split && !st->codec->extradata)
break;
- if(st->first_dts == AV_NOPTS_VALUE)
+ if(st->first_dts == AV_NOPTS_VALUE && (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || st->codec->codec_type == AVMEDIA_TYPE_AUDIO))
break;
}
if (i == ic->nb_streams) {
@@ -2301,7 +2420,7 @@ int av_find_stream_info(AVFormatContext *ic)
/* NOTE: a new stream can be added there if no header in file
(AVFMTCTX_NOHEADER) */
- ret = av_read_frame_internal(ic, &pkt1);
+ ret = read_frame_internal(ic, &pkt1);
if (ret == AVERROR(EAGAIN))
continue;
@@ -2329,28 +2448,31 @@ int av_find_stream_info(AVFormatContext *ic)
st = ic->streams[pkt->stream_index];
if (st->codec_info_nb_frames>1) {
- if (st->time_base.den > 0 && av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration) {
- av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n");
+ int64_t t;
+ if (st->time_base.den > 0 && (t=av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q)) >= ic->max_analyze_duration) {
+ av_log(ic, AV_LOG_WARNING, "max_analyze_duration %d reached at %"PRId64"\n", ic->max_analyze_duration, t);
break;
}
st->info->codec_info_duration += pkt->duration;
}
{
int64_t last = st->info->last_dts;
- int64_t duration= pkt->dts - last;
- if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){
- double dur= duration * av_q2d(st->time_base);
+ if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && pkt->dts > last){
+ double dts= pkt->dts * av_q2d(st->time_base);
+ int64_t duration= pkt->dts - last;
// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
// av_log(NULL, AV_LOG_ERROR, "%f\n", dur);
- if (st->info->duration_count < 2)
- memset(st->info->duration_error, 0, sizeof(st->info->duration_error));
- for (i=1; i<FF_ARRAY_ELEMS(st->info->duration_error); i++) {
+ for (i=1; i<FF_ARRAY_ELEMS(st->info->duration_error[0][0]); i++) {
int framerate= get_std_framerate(i);
- int ticks= lrintf(dur*framerate/(1001*12));
- double error= dur - ticks*1001*12/(double)framerate;
- st->info->duration_error[i] += error*error;
+ double sdts= dts*framerate/(1001*12);
+ for(j=0; j<2; j++){
+ int ticks= lrintf(sdts+j*0.5);
+ double error= sdts - ticks + j*0.5;
+ st->info->duration_error[j][0][i] += error;
+ st->info->duration_error[j][1][i] += error*error;
+ }
}
st->info->duration_count++;
// ignore the first 4 values, they might have some random jitter
@@ -2379,11 +2501,7 @@ int av_find_stream_info(AVFormatContext *ic)
least one frame of codec data, this makes sure the codec initializes
the channel configuration and does not only trust the values from the container.
*/
- if (!has_codec_parameters(st->codec) ||
- !has_decode_delay_been_guessed(st) ||
- (st->codec->codec &&
- st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))
- try_decode_frame(st, pkt);
+ try_decode_frame(st, pkt, (options && i < orig_nb_streams )? &options[i] : NULL);
st->codec_info_nb_frames++;
count++;
@@ -2402,29 +2520,40 @@ int av_find_stream_info(AVFormatContext *ic)
(st->codec_info_nb_frames-2)*(int64_t)st->time_base.den,
st->info->codec_info_duration*(int64_t)st->time_base.num, 60000);
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample)
- st->codec->codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
+ if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample){
+ uint32_t tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
+ if(ff_find_pix_fmt(ff_raw_pix_fmt_tags, tag) == st->codec->pix_fmt)
+ st->codec->codec_tag= tag;
+ }
// the check for tb_unreliable() is not completely correct, since this is not about handling
// a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
// ipmovie.c produces.
- if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > 1 && !st->r_frame_rate.num)
+ if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num)
av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX);
if (st->info->duration_count && !st->r_frame_rate.num
&& tb_unreliable(st->codec) /*&&
//FIXME we should not special-case MPEG-2, but this needs testing with non-MPEG-2 ...
st->time_base.num*duration_sum[i]/st->info->duration_count*101LL > st->time_base.den*/){
int num = 0;
- double best_error= 2*av_q2d(st->time_base);
- best_error = best_error*best_error*st->info->duration_count*1000*12*30;
-
- for (j=1; j<FF_ARRAY_ELEMS(st->info->duration_error); j++) {
- double error = st->info->duration_error[j] * get_std_framerate(j);
-// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
-// av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error);
- if(error < best_error){
- best_error= error;
- num = get_std_framerate(j);
+ double best_error= 0.01;
+
+ for (j=1; j<FF_ARRAY_ELEMS(st->info->duration_error[0][0]); j++) {
+ int k;
+
+ if(st->info->codec_info_duration && st->info->codec_info_duration*av_q2d(st->time_base) < (1001*12.0)/get_std_framerate(j))
+ continue;
+ for(k=0; k<2; k++){
+ int n= st->info->duration_count;
+ double a= st->info->duration_error[k][0][j] / n;
+ double error= st->info->duration_error[k][1][j]/n - a*a;
+
+ if(error < best_error && best_error> 0.000000001){
+ best_error= error;
+ num = get_std_framerate(j);
+ }
+ if(error < 0.02)
+ av_log(NULL, AV_LOG_DEBUG, "rfps: %f %f\n", get_std_framerate(j) / 12.0/1001, error);
}
}
// do not increase frame rate by more than 1 % in order to match a standard rate.
@@ -2461,7 +2590,7 @@ int av_find_stream_info(AVFormatContext *ic)
}
}
- av_estimate_timings(ic, old_offset);
+ estimate_timings(ic, old_offset);
compute_chapters_end(ic);
@@ -2496,14 +2625,20 @@ int av_find_stream_info(AVFormatContext *ic)
return ret;
}
-static AVProgram *find_program_from_stream(AVFormatContext *ic, int s)
+AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s)
{
int i, j;
- for (i = 0; i < ic->nb_programs; i++)
- for (j = 0; j < ic->programs[i]->nb_stream_indexes; j++)
- if (ic->programs[i]->stream_index[j] == s)
- return ic->programs[i];
+ for (i = 0; i < ic->nb_programs; i++) {
+ if (ic->programs[i] == last) {
+ last = NULL;
+ } else {
+ if (!last)
+ for (j = 0; j < ic->programs[i]->nb_stream_indexes; j++)
+ if (ic->programs[i]->stream_index[j] == s)
+ return ic->programs[i];
+ }
+ }
return NULL;
}
@@ -2520,7 +2655,7 @@ int av_find_best_stream(AVFormatContext *ic,
AVCodec *decoder = NULL, *best_decoder = NULL;
if (related_stream >= 0 && wanted_stream_nb < 0) {
- AVProgram *p = find_program_from_stream(ic, related_stream);
+ AVProgram *p = av_find_program_from_stream(ic, NULL, related_stream);
if (p) {
program = p->stream_index;
nb_streams = p->nb_stream_indexes;
@@ -2605,13 +2740,13 @@ void avformat_free_context(AVFormatContext *s)
av_free_packet(&st->cur_pkt);
}
av_dict_free(&st->metadata);
- av_free(st->index_entries);
- av_free(st->codec->extradata);
- av_free(st->codec->subtitle_header);
- av_free(st->codec);
- av_free(st->priv_data);
- av_free(st->info);
- av_free(st);
+ av_freep(&st->index_entries);
+ av_freep(&st->codec->extradata);
+ av_freep(&st->codec->subtitle_header);
+ av_freep(&st->codec);
+ av_freep(&st->priv_data);
+ av_freep(&st->info);
+ av_freep(&st);
}
for(i=s->nb_programs-1; i>=0; i--) {
av_dict_free(&s->programs[i]->metadata);
@@ -2622,7 +2757,7 @@ void avformat_free_context(AVFormatContext *s)
av_freep(&s->priv_data);
while(s->nb_chapters--) {
av_dict_free(&s->chapters[s->nb_chapters]->metadata);
- av_free(s->chapters[s->nb_chapters]);
+ av_freep(&s->chapters[s->nb_chapters]);
}
av_freep(&s->chapters);
av_dict_free(&s->metadata);
@@ -2639,8 +2774,18 @@ void av_close_input_file(AVFormatContext *s)
avio_close(pb);
}
+#if FF_API_NEW_STREAM
AVStream *av_new_stream(AVFormatContext *s, int id)
{
+ AVStream *st = avformat_new_stream(s, NULL);
+ if (st)
+ st->id = id;
+ return st;
+}
+#endif
+
+AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
+{
AVStream *st;
int i;
AVStream **streams;
@@ -2660,13 +2805,12 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
return NULL;
}
- st->codec= avcodec_alloc_context();
+ st->codec = avcodec_alloc_context3(c);
if (s->iformat) {
/* no default bitrate if decoding */
st->codec->bit_rate = 0;
}
st->index = s->nb_streams;
- st->id = id;
st->start_time = AV_NOPTS_VALUE;
st->duration = AV_NOPTS_VALUE;
/* we set the current DTS to 0 so that formats without any timestamps
@@ -2713,7 +2857,7 @@ AVProgram *av_new_program(AVFormatContext *ac, int id)
return program;
}
-AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, int64_t start, int64_t end, const char *title)
+AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, int64_t start, int64_t end, const char *title)
{
AVChapter *chapter = NULL;
int i;
@@ -2743,8 +2887,6 @@ AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, int6
#if FF_API_FORMAT_PARAMETERS
int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
{
- int ret;
-
if (s->oformat->priv_data_size > 0) {
s->priv_data = av_mallocz(s->oformat->priv_data_size);
if (!s->priv_data)
@@ -2756,12 +2898,70 @@ int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
} else
s->priv_data = NULL;
- if (s->oformat->set_parameters) {
- ret = s->oformat->set_parameters(s, ap);
- if (ret < 0)
- return ret;
+ return 0;
+}
+#endif
+
+int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat,
+ const char *format, const char *filename)
+{
+ AVFormatContext *s = avformat_alloc_context();
+ int ret = 0;
+
+ *avctx = NULL;
+ if (!s)
+ goto nomem;
+
+ if (!oformat) {
+ if (format) {
+ oformat = av_guess_format(format, NULL, NULL);
+ if (!oformat) {
+ av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format);
+ ret = AVERROR(EINVAL);
+ goto error;
+ }
+ } else {
+ oformat = av_guess_format(NULL, filename, NULL);
+ if (!oformat) {
+ ret = AVERROR(EINVAL);
+ av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n",
+ filename);
+ goto error;
+ }
+ }
}
+
+ s->oformat = oformat;
+ if (s->oformat->priv_data_size > 0) {
+ s->priv_data = av_mallocz(s->oformat->priv_data_size);
+ if (!s->priv_data)
+ goto nomem;
+ if (s->oformat->priv_class) {
+ *(const AVClass**)s->priv_data= s->oformat->priv_class;
+ av_opt_set_defaults(s->priv_data);
+ }
+ } else
+ s->priv_data = NULL;
+
+ if (filename)
+ av_strlcpy(s->filename, filename, sizeof(s->filename));
+ *avctx = s;
return 0;
+nomem:
+ av_log(s, AV_LOG_ERROR, "Out of memory\n");
+ ret = AVERROR(ENOMEM);
+error:
+ avformat_free_context(s);
+ return ret;
+}
+
+#if FF_API_ALLOC_OUTPUT_CONTEXT
+AVFormatContext *avformat_alloc_output_context(const char *format,
+ AVOutputFormat *oformat, const char *filename)
+{
+ AVFormatContext *avctx;
+ int ret = avformat_alloc_output_context2(&avctx, oformat, format, filename);
+ return ret < 0 ? NULL : avctx;
}
#endif
@@ -2781,7 +2981,7 @@ static int validate_codec_tag(AVFormatContext *s, AVStream *st)
for (n = 0; s->oformat->codec_tag[n]; n++) {
avctag = s->oformat->codec_tag[n];
while (avctag->id != CODEC_ID_NONE) {
- if (ff_toupper4(avctag->tag) == ff_toupper4(st->codec->codec_tag)) {
+ if (avpriv_toupper4(avctag->tag) == avpriv_toupper4(st->codec->codec_tag)) {
id = avctag->id;
if (id == st->codec->codec_id)
return 1;
@@ -2815,6 +3015,9 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options)
av_dict_copy(&tmp, *options, 0);
if ((ret = av_opt_set_dict(s, &tmp)) < 0)
goto fail;
+ if (s->priv_data && s->oformat->priv_class && *(const AVClass**)s->priv_data==s->oformat->priv_class &&
+ (ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)
+ goto fail;
// some sanity checks
if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) {
@@ -2848,7 +3051,9 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options)
ret = AVERROR(EINVAL);
goto fail;
}
- if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)){
+ if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)
+ && FFABS(av_q2d(st->sample_aspect_ratio) - av_q2d(st->codec->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio)
+ ){
av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between encoder and muxer layer\n");
ret = AVERROR(EINVAL);
goto fail;
@@ -2925,7 +3130,7 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options)
ret = AVERROR_INVALIDDATA;
goto fail;
}
- av_frac_init(&st->pts, 0, 0, den);
+ frac_init(&st->pts, 0, 0, den);
}
}
@@ -2979,7 +3184,7 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt){
pkt->dts= st->pts_buffer[0];
}
- if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && st->cur_dts >= pkt->dts){
+ if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) && st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)){
av_log(s, AV_LOG_ERROR,
"Application provided invalid, non monotonically increasing dts to muxer in stream %d: %"PRId64" >= %"PRId64"\n",
st->index, st->cur_dts, pkt->dts);
@@ -3003,11 +3208,11 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt){
likely equal to the encoder delay, but it would be better if we
had the real timestamps from the encoder */
if (frame_size >= 0 && (pkt->size || st->pts.num!=st->pts.den>>1 || st->pts.val)) {
- av_frac_add(&st->pts, (int64_t)st->time_base.den * frame_size);
+ frac_add(&st->pts, (int64_t)st->time_base.den * frame_size);
}
break;
case AVMEDIA_TYPE_VIDEO:
- av_frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num);
+ frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num);
break;
default:
break;
@@ -3023,6 +3228,9 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt)
return ret;
ret= s->oformat->write_packet(s, pkt);
+
+ if (ret >= 0)
+ s->streams[pkt->stream_index]->nb_frames++;
return ret;
}
@@ -3076,17 +3284,44 @@ static int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacke
int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush){
AVPacketList *pktl;
- int stream_count=0;
+ int stream_count=0, noninterleaved_count=0;
+ int64_t delta_dts_max = 0;
int i;
if(pkt){
ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
}
- for(i=0; i < s->nb_streams; i++)
- stream_count+= !!s->streams[i]->last_in_packet_buffer;
+ for(i=0; i < s->nb_streams; i++) {
+ if (s->streams[i]->last_in_packet_buffer) {
+ ++stream_count;
+ } else if(s->streams[i]->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+ ++noninterleaved_count;
+ }
+ }
- if(stream_count && (s->nb_streams == stream_count || flush)){
+ if (s->nb_streams == stream_count) {
+ flush = 1;
+ } else if (!flush){
+ for(i=0; i < s->nb_streams; i++) {
+ if (s->streams[i]->last_in_packet_buffer) {
+ int64_t delta_dts =
+ av_rescale_q(s->streams[i]->last_in_packet_buffer->pkt.dts,
+ s->streams[i]->time_base,
+ AV_TIME_BASE_Q) -
+ av_rescale_q(s->packet_buffer->pkt.dts,
+ s->streams[s->packet_buffer->pkt.stream_index]->time_base,
+ AV_TIME_BASE_Q);
+ delta_dts_max= FFMAX(delta_dts_max, delta_dts);
+ }
+ }
+ if(s->nb_streams == stream_count+noninterleaved_count &&
+ delta_dts_max > 20*AV_TIME_BASE) {
+ av_log(s, AV_LOG_DEBUG, "flushing with %d noninterleaved\n", noninterleaved_count);
+ flush = 1;
+ }
+ }
+ if(stream_count && flush){
pktl= s->packet_buffer;
*out= pktl->pkt;
@@ -3113,7 +3348,7 @@ int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pk
* @return 1 if a packet was output, 0 if no packet could be output,
* < 0 if an error occurred
*/
-static int av_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush){
+static int interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush){
if(s->oformat->interleave_packet)
return s->oformat->interleave_packet(s, out, in, flush);
else
@@ -3138,17 +3373,21 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){
for(;;){
AVPacket opkt;
- int ret= av_interleave_packet(s, &opkt, pkt, 0);
+ int ret= interleave_packet(s, &opkt, pkt, 0);
if(ret<=0) //FIXME cleanup needed for ret<0 ?
return ret;
ret= s->oformat->write_packet(s, &opkt);
+ if (ret >= 0)
+ s->streams[opkt.stream_index]->nb_frames++;
av_free_packet(&opkt);
pkt= NULL;
if(ret<0)
return ret;
+ if(s->pb && s->pb->error)
+ return s->pb->error;
}
}
@@ -3158,23 +3397,29 @@ int av_write_trailer(AVFormatContext *s)
for(;;){
AVPacket pkt;
- ret= av_interleave_packet(s, &pkt, NULL, 1);
+ ret= interleave_packet(s, &pkt, NULL, 1);
if(ret<0) //FIXME cleanup needed for ret<0 ?
goto fail;
if(!ret)
break;
ret= s->oformat->write_packet(s, &pkt);
+ if (ret >= 0)
+ s->streams[pkt.stream_index]->nb_frames++;
av_free_packet(&pkt);
if(ret<0)
goto fail;
+ if(s->pb && s->pb->error)
+ goto fail;
}
if(s->oformat->write_trailer)
ret = s->oformat->write_trailer(s);
fail:
+ if(ret == 0)
+ ret = s->pb ? s->pb->error : 0;
for(i=0;i<s->nb_streams;i++) {
av_freep(&s->streams[i]->priv_data);
av_freep(&s->streams[i]->index_entries);
@@ -3185,6 +3430,15 @@ fail:
return ret;
}
+int av_get_output_timestamp(struct AVFormatContext *s, int stream,
+ int64_t *dts, int64_t *wall)
+{
+ if (!s->oformat || !s->oformat->get_output_timestamp)
+ return AVERROR(ENOSYS);
+ s->oformat->get_output_timestamp(s, stream, dts, wall);
+ return 0;
+}
+
void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx)
{
int i, j;
@@ -3227,8 +3481,13 @@ static void dump_metadata(void *ctx, AVDictionary *m, const char *indent)
av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent);
while((tag=av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX))) {
- if(strcmp("language", tag->key))
- av_log(ctx, AV_LOG_INFO, "%s %-16s: %s\n", indent, tag->key, tag->value);
+ if(strcmp("language", tag->key)){
+ char tmp[256];
+ int i;
+ av_strlcpy(tmp, tag->value, sizeof(tmp));
+ for(i=0; i<strlen(tmp); i++) if(tmp[i]==0xd) tmp[i]=' ';
+ av_log(ctx, AV_LOG_INFO, "%s %-16s: %s\n", indent, tag->key, tmp);
+ }
}
}
}
@@ -3242,7 +3501,7 @@ static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_out
int g = av_gcd(st->time_base.num, st->time_base.den);
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
avcodec_string(buf, sizeof(buf), st->codec, is_output);
- av_log(NULL, AV_LOG_INFO, " Stream #%d.%d", index, i);
+ av_log(NULL, AV_LOG_INFO, " Stream #%d:%d", index, i);
/* the pid is an important information, so we display it */
/* XXX: add a generic system */
if (flags & AVFMT_SHOW_IDS)
@@ -3258,7 +3517,7 @@ static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_out
st->codec->width*st->sample_aspect_ratio.num,
st->codec->height*st->sample_aspect_ratio.den,
1024*1024);
- av_log(NULL, AV_LOG_INFO, ", PAR %d:%d DAR %d:%d",
+ av_log(NULL, AV_LOG_INFO, ", SAR %d:%d DAR %d:%d",
st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
display_aspect_ratio.num, display_aspect_ratio.den);
}
@@ -3312,7 +3571,7 @@ void av_dump_format(AVFormatContext *ic,
int is_output)
{
int i;
- uint8_t *printed = av_mallocz(ic->nb_streams);
+ uint8_t *printed = ic->nb_streams ? av_mallocz(ic->nb_streams) : NULL;
if (ic->nb_streams && !printed)
return;
@@ -3869,3 +4128,30 @@ void ff_make_absolute_url(char *buf, int size, const char *base,
}
av_strlcat(buf, rel, size);
}
+
+int64_t ff_iso8601_to_unix_time(const char *datestr)
+{
+#if HAVE_STRPTIME
+ struct tm time = {0};
+ strptime(datestr, "%Y - %m - %dT%T", &time);
+ return mktime(&time);
+#else
+ av_log(NULL, AV_LOG_WARNING, "strptime() unavailable on this system, cannot convert "
+ "the date string.\n");
+ return 0;
+#endif
+}
+
+int avformat_query_codec(AVOutputFormat *ofmt, enum CodecID codec_id, int std_compliance)
+{
+ if (ofmt) {
+ if (ofmt->query_codec)
+ return ofmt->query_codec(codec_id, std_compliance);
+ else if (ofmt->codec_tag)
+ return !!av_codec_get_tag(ofmt->codec_tag, codec_id);
+ else if (codec_id == ofmt->video_codec || codec_id == ofmt->audio_codec ||
+ codec_id == ofmt->subtitle_codec)
+ return 1;
+ }
+ return AVERROR_PATCHWELCOME;
+}
diff --git a/libavformat/vc1test.c b/libavformat/vc1test.c
index 07f3247aa3..ed72119188 100644
--- a/libavformat/vc1test.c
+++ b/libavformat/vc1test.c
@@ -2,20 +2,20 @@
* VC1 Test Bitstreams Format Demuxer
* Copyright (c) 2006, 2008 Konstantin Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -54,7 +54,7 @@ static int vc1t_read_header(AVFormatContext *s,
return -1;
/* init video codec */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
@@ -92,7 +92,7 @@ static int vc1t_read_packet(AVFormatContext *s,
int keyframe = 0;
uint32_t pts;
- if(pb->eof_reached)
+ if(url_feof(pb))
return AVERROR(EIO);
frame_size = avio_rl24(pb);
@@ -110,11 +110,10 @@ static int vc1t_read_packet(AVFormatContext *s,
}
AVInputFormat ff_vc1t_demuxer = {
- "vc1test",
- NULL_IF_CONFIG_SMALL("VC-1 test bitstream format"),
- 0,
- vc1t_probe,
- vc1t_read_header,
- vc1t_read_packet,
+ .name = "vc1test",
+ .long_name = NULL_IF_CONFIG_SMALL("VC-1 test bitstream format"),
+ .read_probe = vc1t_probe,
+ .read_header = vc1t_read_header,
+ .read_packet = vc1t_read_packet,
.flags = AVFMT_GENERIC_INDEX,
};
diff --git a/libavformat/vc1testenc.c b/libavformat/vc1testenc.c
index 2b0728d248..20580fb3cf 100644
--- a/libavformat/vc1testenc.c
+++ b/libavformat/vc1testenc.c
@@ -2,20 +2,20 @@
* VC-1 test bitstreams format muxer.
* Copyright (c) 2008 Konstantin Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
@@ -82,14 +82,14 @@ static int vc1test_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_vc1t_muxer = {
- "rcv",
- NULL_IF_CONFIG_SMALL("VC-1 test bitstream"),
- "",
- "rcv",
- sizeof(RCVContext),
- CODEC_ID_NONE,
- CODEC_ID_WMV3,
- vc1test_write_header,
- vc1test_write_packet,
- vc1test_write_trailer,
+ .name = "rcv",
+ .long_name = NULL_IF_CONFIG_SMALL("VC-1 test bitstream"),
+ .mime_type = "",
+ .extensions = "rcv",
+ .priv_data_size = sizeof(RCVContext),
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_WMV3,
+ .write_header = vc1test_write_header,
+ .write_packet = vc1test_write_packet,
+ .write_trailer = vc1test_write_trailer,
};
diff --git a/libavformat/version.h b/libavformat/version.h
index 3cc1718f2b..333a3a0125 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -1,20 +1,20 @@
/*
* Version macros.
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -24,7 +24,7 @@
#include "libavutil/avutil.h"
#define LIBAVFORMAT_VERSION_MAJOR 53
-#define LIBAVFORMAT_VERSION_MINOR 2
+#define LIBAVFORMAT_VERSION_MINOR 17
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
@@ -68,11 +68,38 @@
#ifndef FF_API_SDP_CREATE
#define FF_API_SDP_CREATE (LIBAVFORMAT_VERSION_MAJOR < 54)
#endif
+#ifndef FF_API_ALLOC_OUTPUT_CONTEXT
+#define FF_API_ALLOC_OUTPUT_CONTEXT (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
#ifndef FF_API_FORMAT_PARAMETERS
#define FF_API_FORMAT_PARAMETERS (LIBAVFORMAT_VERSION_MAJOR < 54)
#endif
#ifndef FF_API_FLAG_RTP_HINT
#define FF_API_FLAG_RTP_HINT (LIBAVFORMAT_VERSION_MAJOR < 54)
#endif
+#ifndef FF_API_AVSTREAM_QUALITY
+#define FF_API_AVSTREAM_QUALITY (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_LOOP_INPUT
+#define FF_API_LOOP_INPUT (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_LOOP_OUTPUT
+#define FF_API_LOOP_OUTPUT (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_TIMESTAMP
+#define FF_API_TIMESTAMP (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_FILESIZE
+#define FF_API_FILESIZE (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_MUXRATE
+#define FF_API_MUXRATE (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_RTSP_URL_OPTIONS
+#define FF_API_RTSP_URL_OPTIONS (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_NEW_STREAM
+#define FF_API_NEW_STREAM (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
#endif /* AVFORMAT_VERSION_H */
diff --git a/libavformat/voc.c b/libavformat/voc.c
index 314623ee74..53e02f9464 100644
--- a/libavformat/voc.c
+++ b/libavformat/voc.c
@@ -2,20 +2,20 @@
* Creative Voice File common data.
* Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/voc.h b/libavformat/voc.h
index abd8fdbfff..3f995ad31f 100644
--- a/libavformat/voc.h
+++ b/libavformat/voc.h
@@ -2,20 +2,20 @@
* Creative Voice File demuxer.
* Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/vocdec.c b/libavformat/vocdec.c
index eaa2f25492..6ee8d33964 100644
--- a/libavformat/vocdec.c
+++ b/libavformat/vocdec.c
@@ -2,20 +2,20 @@
* Creative Voice File demuxer.
* Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -52,7 +52,7 @@ static int voc_read_header(AVFormatContext *s, AVFormatParameters *ap)
return AVERROR(ENOSYS);
}
avio_skip(pb, header_size);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -142,7 +142,7 @@ voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size)
}
}
- dec->bit_rate = dec->sample_rate * dec->bits_per_coded_sample;
+ dec->bit_rate = dec->sample_rate * dec->channels * dec->bits_per_coded_sample;
if (max_size <= 0)
max_size = 2048;
@@ -157,11 +157,11 @@ static int voc_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_voc_demuxer = {
- "voc",
- NULL_IF_CONFIG_SMALL("Creative Voice file format"),
- sizeof(VocDecContext),
- voc_probe,
- voc_read_header,
- voc_read_packet,
+ .name = "voc",
+ .long_name = NULL_IF_CONFIG_SMALL("Creative Voice file format"),
+ .priv_data_size = sizeof(VocDecContext),
+ .read_probe = voc_probe,
+ .read_header = voc_read_header,
+ .read_packet = voc_read_packet,
.codec_tag=(const AVCodecTag* const []){ff_voc_codec_tags, 0},
};
diff --git a/libavformat/vocenc.c b/libavformat/vocenc.c
index bbb69c8c01..0a9f24bdc2 100644
--- a/libavformat/vocenc.c
+++ b/libavformat/vocenc.c
@@ -2,20 +2,20 @@
* Creative Voice File muxer.
* Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -90,15 +90,15 @@ static int voc_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_voc_muxer = {
- "voc",
- NULL_IF_CONFIG_SMALL("Creative Voice file format"),
- "audio/x-voc",
- "voc",
- sizeof(VocEncContext),
- CODEC_ID_PCM_U8,
- CODEC_ID_NONE,
- voc_write_header,
- voc_write_packet,
- voc_write_trailer,
+ .name = "voc",
+ .long_name = NULL_IF_CONFIG_SMALL("Creative Voice file format"),
+ .mime_type = "audio/x-voc",
+ .extensions = "voc",
+ .priv_data_size = sizeof(VocEncContext),
+ .audio_codec = CODEC_ID_PCM_U8,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = voc_write_header,
+ .write_packet = voc_write_packet,
+ .write_trailer = voc_write_trailer,
.codec_tag=(const AVCodecTag* const []){ff_voc_codec_tags, 0},
};
diff --git a/libavformat/vorbiscomment.c b/libavformat/vorbiscomment.c
index 56936d7666..9b38e6a791 100644
--- a/libavformat/vorbiscomment.c
+++ b/libavformat/vorbiscomment.c
@@ -2,20 +2,20 @@
* VorbisComment writer
* Copyright (c) 2009 James Darnley
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/vorbiscomment.h b/libavformat/vorbiscomment.h
index 7b82dc1c95..b147092071 100644
--- a/libavformat/vorbiscomment.h
+++ b/libavformat/vorbiscomment.h
@@ -2,20 +2,20 @@
* VorbisComment writer
* Copyright (c) 2009 James Darnley
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/libavformat/vqf.c b/libavformat/vqf.c
index dd02abd70a..1530128f4a 100644
--- a/libavformat/vqf.c
+++ b/libavformat/vqf.c
@@ -2,20 +2,20 @@
* VQF demuxer
* Copyright (c) 2009 Vitor Sessak
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -64,7 +64,7 @@ static void add_metadata(AVFormatContext *s, const char *tag,
static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
VqfContext *c = s->priv_data;
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
int chunk_tag;
int rate_flag = -1;
int header_size;
@@ -250,13 +250,12 @@ static int vqf_read_seek(AVFormatContext *s,
}
AVInputFormat ff_vqf_demuxer = {
- "vqf",
- NULL_IF_CONFIG_SMALL("Nippon Telegraph and Telephone Corporation (NTT) TwinVQ"),
- sizeof(VqfContext),
- vqf_probe,
- vqf_read_header,
- vqf_read_packet,
- NULL,
- vqf_read_seek,
+ .name = "vqf",
+ .long_name = NULL_IF_CONFIG_SMALL("Nippon Telegraph and Telephone Corporation (NTT) TwinVQ"),
+ .priv_data_size = sizeof(VqfContext),
+ .read_probe = vqf_probe,
+ .read_header = vqf_read_header,
+ .read_packet = vqf_read_packet,
+ .read_seek = vqf_read_seek,
.extensions = "vqf",
};
diff --git a/libavformat/wav.c b/libavformat/wav.c
index 391461044b..b690cc1a8f 100644
--- a/libavformat/wav.c
+++ b/libavformat/wav.c
@@ -6,39 +6,109 @@
* RF64 demuxer
* Copyright (c) 2009 Daniel Verkamp
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/avassert.h"
+#include "libavutil/dict.h"
+#include "libavutil/log.h"
#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
#include "avformat.h"
#include "avio_internal.h"
#include "pcm.h"
#include "riff.h"
+#include "avio.h"
+#include "avio_internal.h"
+#include "metadata.h"
typedef struct {
+ const AVClass *class;
int64_t data;
int64_t data_end;
int64_t minpts;
int64_t maxpts;
int last_duration;
int w64;
+ int write_bext;
+ int64_t smv_data_ofs;
+ int smv_block_size;
+ int smv_frames_per_jpeg;
+ int smv_block;
+ int smv_last_stream;
+ int smv_eof;
+ int audio_eof;
} WAVContext;
#if CONFIG_WAV_MUXER
+static inline void bwf_write_bext_string(AVFormatContext *s, const char *key, int maxlen)
+{
+ AVDictionaryEntry *tag;
+ int len = 0;
+
+ if (tag = av_dict_get(s->metadata, key, NULL, 0)) {
+ len = strlen(tag->value);
+ len = FFMIN(len, maxlen);
+ avio_write(s->pb, tag->value, len);
+ }
+
+ ffio_fill(s->pb, 0, maxlen - len);
+}
+
+static void bwf_write_bext_chunk(AVFormatContext *s)
+{
+ AVDictionaryEntry *tmp_tag;
+ uint64_t time_reference = 0;
+ int64_t bext = ff_start_tag(s->pb, "bext");
+
+ bwf_write_bext_string(s, "description", 256);
+ bwf_write_bext_string(s, "originator", 32);
+ bwf_write_bext_string(s, "originator_reference", 32);
+ bwf_write_bext_string(s, "origination_date", 10);
+ bwf_write_bext_string(s, "origination_time", 8);
+
+ if (tmp_tag = av_dict_get(s->metadata, "time_reference", NULL, 0))
+ time_reference = strtoll(tmp_tag->value, NULL, 10);
+ avio_wl64(s->pb, time_reference);
+ avio_wl16(s->pb, 1); // set version to 1
+
+ if (tmp_tag = av_dict_get(s->metadata, "umid", NULL, 0)) {
+ unsigned char umidpart_str[17] = {0};
+ int i;
+ uint64_t umidpart;
+ int len = strlen(tmp_tag->value+2);
+
+ for (i = 0; i < len/16; i++) {
+ memcpy(umidpart_str, tmp_tag->value + 2 + (i*16), 16);
+ umidpart = strtoll(umidpart_str, NULL, 16);
+ avio_wb64(s->pb, umidpart);
+ }
+ ffio_fill(s->pb, 0, 64 - i*8);
+ } else
+ ffio_fill(s->pb, 0, 64); // zero UMID
+
+ ffio_fill(s->pb, 0, 190); // Reserved
+
+ if (tmp_tag = av_dict_get(s->metadata, "coding_history", NULL, 0))
+ avio_put_str(s->pb, tmp_tag->value);
+
+ ff_end_tag(s->pb, bext);
+}
+
static int wav_write_header(AVFormatContext *s)
{
WAVContext *wav = s->priv_data;
@@ -65,6 +135,9 @@ static int wav_write_header(AVFormatContext *s)
ff_end_tag(pb, fact);
}
+ if (wav->write_bext)
+ bwf_write_bext_chunk(s);
+
av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
wav->maxpts = wav->last_duration = 0;
wav->minpts = INT64_MAX;
@@ -125,18 +198,33 @@ static int wav_write_trailer(AVFormatContext *s)
return 0;
}
+#define OFFSET(x) offsetof(WAVContext, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "write_bext", "Write BEXT chunk.", OFFSET(write_bext), AV_OPT_TYPE_INT, { 0 }, 0, 1, ENC },
+ { NULL },
+};
+
+static const AVClass wav_muxer_class = {
+ .class_name = "WAV muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVOutputFormat ff_wav_muxer = {
- "wav",
- NULL_IF_CONFIG_SMALL("WAV format"),
- "audio/x-wav",
- "wav",
- sizeof(WAVContext),
- CODEC_ID_PCM_S16LE,
- CODEC_ID_NONE,
- wav_write_header,
- wav_write_packet,
- wav_write_trailer,
+ .name = "wav",
+ .long_name = NULL_IF_CONFIG_SMALL("WAV format"),
+ .mime_type = "audio/x-wav",
+ .extensions = "wav",
+ .priv_data_size = sizeof(WAVContext),
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = wav_write_header,
+ .write_packet = wav_write_packet,
+ .write_trailer = wav_write_trailer,
.codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0},
+ .priv_class = &wav_muxer_class,
};
#endif /* CONFIG_WAV_MUXER */
@@ -156,7 +244,7 @@ static int64_t find_tag(AVIOContext *pb, uint32_t tag1)
int64_t size;
for (;;) {
- if (pb->eof_reached)
+ if (url_feof(pb))
return -1;
size = next_tag(pb, &tag);
if (tag == tag1)
@@ -186,6 +274,117 @@ static int wav_probe(AVProbeData *p)
return 0;
}
+static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
+{
+ AVIOContext *pb = s->pb;
+ int ret;
+
+ /* parse fmt header */
+ *st = avformat_new_stream(s, NULL);
+ if (!*st)
+ return AVERROR(ENOMEM);
+
+ ret = ff_get_wav_header(pb, (*st)->codec, size);
+ if (ret < 0)
+ return ret;
+ (*st)->need_parsing = AVSTREAM_PARSE_FULL;
+
+ av_set_pts_info(*st, 64, 1, (*st)->codec->sample_rate);
+
+ return 0;
+}
+
+static inline int wav_parse_bext_string(AVFormatContext *s, const char *key,
+ int length)
+{
+ char temp[257];
+ int ret;
+
+ av_assert0(length <= sizeof(temp));
+ if ((ret = avio_read(s->pb, temp, length)) < 0)
+ return ret;
+
+ temp[length] = 0;
+
+ if (strlen(temp))
+ return av_dict_set(&s->metadata, key, temp, 0);
+
+ return 0;
+}
+
+static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
+{
+ char temp[131], *coding_history;
+ int ret, x;
+ uint64_t time_reference;
+ int64_t umid_parts[8], umid_mask = 0;
+
+ if ((ret = wav_parse_bext_string(s, "description", 256)) < 0 ||
+ (ret = wav_parse_bext_string(s, "originator", 32)) < 0 ||
+ (ret = wav_parse_bext_string(s, "originator_reference", 32)) < 0 ||
+ (ret = wav_parse_bext_string(s, "origination_date", 10)) < 0 ||
+ (ret = wav_parse_bext_string(s, "origination_time", 8)) < 0)
+ return ret;
+
+ time_reference = avio_rl64(s->pb);
+ snprintf(temp, sizeof(temp), "%"PRIu64, time_reference);
+ if ((ret = av_dict_set(&s->metadata, "time_reference", temp, 0)) < 0)
+ return ret;
+
+ /* check if version is >= 1, in which case an UMID may be present */
+ if (avio_rl16(s->pb) >= 1) {
+ for (x = 0; x < 8; x++)
+ umid_mask |= umid_parts[x] = avio_rb64(s->pb);
+
+ if (umid_mask) {
+ /* the string formatting below is per SMPTE 330M-2004 Annex C */
+ if (umid_parts[4] == 0 && umid_parts[5] == 0 && umid_parts[6] == 0 && umid_parts[7] == 0) {
+ /* basic UMID */
+ snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+ umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3]);
+ } else {
+ /* extended UMID */
+ snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
+ "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+ umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3],
+ umid_parts[4], umid_parts[5], umid_parts[6], umid_parts[7]);
+ }
+
+ if ((ret = av_dict_set(&s->metadata, "umid", temp, 0)) < 0)
+ return ret;
+ }
+
+ avio_skip(s->pb, 190);
+ } else
+ avio_skip(s->pb, 254);
+
+ if (size > 602) {
+ /* CodingHistory present */
+ size -= 602;
+
+ if (!(coding_history = av_malloc(size+1)))
+ return AVERROR(ENOMEM);
+
+ if ((ret = avio_read(s->pb, coding_history, size)) < 0)
+ return ret;
+
+ coding_history[size] = 0;
+ if ((ret = av_dict_set(&s->metadata, "coding_history", coding_history,
+ AV_DICT_DONT_STRDUP_VAL)) < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const AVMetadataConv wav_metadata_conv[] = {
+ {"description", "comment" },
+ {"originator", "encoded_by" },
+ {"origination_date", "date" },
+ {"origination_time", "creation_time"},
+ {0},
+};
+
/* wav input */
static int wav_read_header(AVFormatContext *s,
AVFormatParameters *ap)
@@ -195,9 +394,12 @@ static int wav_read_header(AVFormatContext *s,
int rf64;
unsigned int tag;
AVIOContext *pb = s->pb;
- AVStream *st;
+ AVStream *st = NULL;
WAVContext *wav = s->priv_data;
- int ret;
+ int ret, got_fmt = 0;
+ int64_t next_tag_ofs, data_ofs = -1;
+
+ wav->smv_data_ofs = -1;
/* check RIFF header */
tag = avio_rl32(pb);
@@ -214,54 +416,116 @@ static int wav_read_header(AVFormatContext *s,
if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
return -1;
size = avio_rl32(pb);
- if (size < 16)
+ if (size < 24)
return -1;
avio_rl64(pb); /* RIFF size */
data_size = avio_rl64(pb);
sample_count = avio_rl64(pb);
- avio_skip(pb, size - 16); /* skip rest of ds64 chunk */
+ if (data_size < 0 || sample_count < 0) {
+ av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in "
+ "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n",
+ data_size, sample_count);
+ return AVERROR_INVALIDDATA;
+ }
+ avio_skip(pb, size - 24); /* skip rest of ds64 chunk */
+
}
- /* parse fmt header */
- size = find_tag(pb, MKTAG('f', 'm', 't', ' '));
- if (size < 0)
- return -1;
- st = av_new_stream(s, 0);
- if (!st)
- return AVERROR(ENOMEM);
+ for (;;) {
+ AVStream *vst;
+ size = next_tag(pb, &tag);
+ next_tag_ofs = avio_tell(pb) + size;
- ret = ff_get_wav_header(pb, st->codec, size);
- if (ret < 0)
- return ret;
- st->need_parsing = AVSTREAM_PARSE_FULL;
+ if (url_feof(pb))
+ break;
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ switch (tag) {
+ case MKTAG('f', 'm', 't', ' '):
+ /* only parse the first 'fmt ' tag found */
+ if (!got_fmt && (ret = wav_parse_fmt_tag(s, size, &st) < 0)) {
+ return ret;
+ } else if (got_fmt)
+ av_log(s, AV_LOG_WARNING, "found more than one 'fmt ' tag\n");
- for (;;) {
- if (pb->eof_reached)
- return -1;
- size = next_tag(pb, &tag);
- if (tag == MKTAG('d', 'a', 't', 'a')){
+ got_fmt = 1;
+ break;
+ case MKTAG('d', 'a', 't', 'a'):
+ if (!got_fmt) {
+ av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'data' tag\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (rf64) {
+ next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
+ } else {
+ data_size = size;
+ next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
+ }
+
+ data_ofs = avio_tell(pb);
+
+ /* don't look for footer metadata if we can't seek or if we don't
+ * know where the data tag ends
+ */
+ if (!pb->seekable || (!rf64 && !size))
+ goto break_loop;
+ break;
+ case MKTAG('f','a','c','t'):
+ if (!sample_count)
+ sample_count = avio_rl32(pb);
+ break;
+ case MKTAG('b','e','x','t'):
+ if ((ret = wav_parse_bext_tag(s, size)) < 0)
+ return ret;
+ break;
+ case MKTAG('S','M','V','0'):
+ // SMV file, a wav file with video appended.
+ if (size != MKTAG('0','2','0','0')) {
+ av_log(s, AV_LOG_ERROR, "Unknown SMV version found\n");
+ goto break_loop;
+ }
+ av_log(s, AV_LOG_DEBUG, "Found SMV data\n");
+ vst = av_new_stream(s, 1);
+ if (!vst)
+ return AVERROR(ENOMEM);
+ avio_r8(pb);
+ vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ vst->codec->codec_id = CODEC_ID_MJPEG;
+ vst->codec->width = avio_rl24(pb);
+ vst->codec->height = avio_rl24(pb);
+ size = avio_rl24(pb);
+ wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3;
+ avio_rl24(pb);
+ wav->smv_block_size = avio_rl24(pb);
+ av_set_pts_info(vst, 32, 1, avio_rl24(pb));
+ vst->duration = avio_rl24(pb);
+ avio_rl24(pb);
+ avio_rl24(pb);
+ wav->smv_frames_per_jpeg = avio_rl24(pb);
+ goto break_loop;
+ }
+
+ /* seek to next tag unless we know that we'll run into EOF */
+ if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) ||
+ avio_seek(pb, next_tag_ofs, SEEK_SET) < 0) {
break;
- }else if (tag == MKTAG('f','a','c','t') && !sample_count){
- sample_count = avio_rl32(pb);
- size -= 4;
}
- avio_skip(pb, size);
}
- if (rf64)
- size = data_size;
- if (size < 0)
- return -1;
- if (!size) {
- wav->data_end = INT64_MAX;
- } else
- wav->data_end= avio_tell(pb) + size;
+break_loop:
+ if (data_ofs < 0) {
+ av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ avio_seek(pb, data_ofs, SEEK_SET);
if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id))
- sample_count = (size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
+ sample_count = (data_size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
if (sample_count)
st->duration = sample_count;
+
+ ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
+
return 0;
}
@@ -273,7 +537,7 @@ static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16])
uint8_t guid[16];
int64_t size;
- while (!pb->eof_reached) {
+ while (!url_feof(pb)) {
avio_read(pb, guid, 16);
size = avio_rl64(pb);
if (size <= 24)
@@ -298,6 +562,45 @@ static int wav_read_packet(AVFormatContext *s,
AVStream *st;
WAVContext *wav = s->priv_data;
+ if (wav->smv_data_ofs > 0) {
+ int64_t audio_dts, video_dts;
+smv_retry:
+ audio_dts = s->streams[0]->cur_dts;
+ video_dts = s->streams[1]->cur_dts;
+ if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) {
+ audio_dts = av_rescale_q(audio_dts, s->streams[0]->time_base, AV_TIME_BASE_Q);
+ video_dts = av_rescale_q(video_dts, s->streams[1]->time_base, AV_TIME_BASE_Q);
+ wav->smv_last_stream = video_dts >= audio_dts;
+ }
+ wav->smv_last_stream = !wav->smv_last_stream;
+ wav->smv_last_stream |= wav->audio_eof;
+ wav->smv_last_stream &= !wav->smv_eof;
+ if (wav->smv_last_stream) {
+ uint64_t old_pos = avio_tell(s->pb);
+ uint64_t new_pos = wav->smv_data_ofs +
+ wav->smv_block * wav->smv_block_size;
+ if (avio_seek(s->pb, new_pos, SEEK_SET) < 0) {
+ ret = AVERROR_EOF;
+ goto smv_out;
+ }
+ size = avio_rl24(s->pb);
+ ret = av_get_packet(s->pb, pkt, size);
+ if (ret < 0)
+ goto smv_out;
+ pkt->pos -= 3;
+ pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg;
+ wav->smv_block++;
+ pkt->stream_index = 1;
+smv_out:
+ avio_seek(s->pb, old_pos, SEEK_SET);
+ if (ret == AVERROR_EOF) {
+ wav->smv_eof = 1;
+ goto smv_retry;
+ }
+ return ret;
+ }
+ }
+
st = s->streams[0];
left = wav->data_end - avio_tell(s->pb);
@@ -306,8 +609,12 @@ static int wav_read_packet(AVFormatContext *s,
left = find_guid(s->pb, guid_data) - 24;
else
left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a'));
- if (left < 0)
+ if (left < 0) {
+ wav->audio_eof = 1;
+ if (wav->smv_data_ofs > 0 && !wav->smv_eof)
+ goto smv_retry;
return AVERROR_EOF;
+ }
wav->data_end= avio_tell(s->pb) + left;
}
@@ -329,7 +636,18 @@ static int wav_read_packet(AVFormatContext *s,
static int wav_read_seek(AVFormatContext *s,
int stream_index, int64_t timestamp, int flags)
{
+ WAVContext *wav = s->priv_data;
AVStream *st;
+ wav->smv_eof = 0;
+ wav->audio_eof = 0;
+ if (wav->smv_data_ofs > 0) {
+ int64_t smv_timestamp = timestamp;
+ if (stream_index == 0)
+ smv_timestamp = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[1]->time_base);
+ else
+ timestamp = av_rescale_q(smv_timestamp, s->streams[1]->time_base, s->streams[0]->time_base);
+ wav->smv_block = smv_timestamp / wav->smv_frames_per_jpeg;
+ }
st = s->streams[0];
switch (st->codec->codec_id) {
@@ -346,14 +664,13 @@ static int wav_read_seek(AVFormatContext *s,
}
AVInputFormat ff_wav_demuxer = {
- "wav",
- NULL_IF_CONFIG_SMALL("WAV format"),
- sizeof(WAVContext),
- wav_probe,
- wav_read_header,
- wav_read_packet,
- NULL,
- wav_read_seek,
+ .name = "wav",
+ .long_name = NULL_IF_CONFIG_SMALL("WAV format"),
+ .priv_data_size = sizeof(WAVContext),
+ .read_probe = wav_probe,
+ .read_header = wav_read_header,
+ .read_packet = wav_read_packet,
+ .read_seek = wav_read_seek,
.flags= AVFMT_GENERIC_INDEX,
.codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0},
};
@@ -409,7 +726,7 @@ static int w64_read_header(AVFormatContext *s, AVFormatParameters *ap)
return -1;
}
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -435,14 +752,13 @@ static int w64_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
AVInputFormat ff_w64_demuxer = {
- "w64",
- NULL_IF_CONFIG_SMALL("Sony Wave64 format"),
- sizeof(WAVContext),
- w64_probe,
- w64_read_header,
- wav_read_packet,
- NULL,
- wav_read_seek,
+ .name = "w64",
+ .long_name = NULL_IF_CONFIG_SMALL("Sony Wave64 format"),
+ .priv_data_size = sizeof(WAVContext),
+ .read_probe = w64_probe,
+ .read_header = w64_read_header,
+ .read_packet = wav_read_packet,
+ .read_seek = wav_read_seek,
.flags = AVFMT_GENERIC_INDEX,
.codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0},
};
diff --git a/libavformat/wc3movie.c b/libavformat/wc3movie.c
index 03483de737..9190a1a035 100644
--- a/libavformat/wc3movie.c
+++ b/libavformat/wc3movie.c
@@ -2,20 +2,20 @@
* Wing Commander III Movie (.mve) File Demuxer
* Copyright (c) 2003 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -157,13 +157,13 @@ static int wc3_read_header(AVFormatContext *s,
fourcc_tag = avio_rl32(pb);
/* chunk sizes are 16-bit aligned */
size = (avio_rb32(pb) + 1) & (~1);
- if (pb->eof_reached)
+ if (url_feof(pb))
return AVERROR(EIO);
} while (fourcc_tag != BRCH_TAG);
/* initialize the decoder streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 33, 1, WC3_FRAME_FPS);
@@ -174,7 +174,7 @@ static int wc3_read_header(AVFormatContext *s,
st->codec->width = wc3->width;
st->codec->height = wc3->height;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 33, 1, WC3_FRAME_FPS);
@@ -208,7 +208,7 @@ static int wc3_read_packet(AVFormatContext *s,
fourcc_tag = avio_rl32(pb);
/* chunk sizes are 16-bit aligned */
size = (avio_rb32(pb) + 1) & (~1);
- if (pb->eof_reached)
+ if (url_feof(pb))
return AVERROR(EIO);
switch (fourcc_tag) {
@@ -292,11 +292,11 @@ static int wc3_read_close(AVFormatContext *s)
}
AVInputFormat ff_wc3_demuxer = {
- "wc3movie",
- NULL_IF_CONFIG_SMALL("Wing Commander III movie format"),
- sizeof(Wc3DemuxContext),
- wc3_probe,
- wc3_read_header,
- wc3_read_packet,
- wc3_read_close,
+ .name = "wc3movie",
+ .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III movie format"),
+ .priv_data_size = sizeof(Wc3DemuxContext),
+ .read_probe = wc3_probe,
+ .read_header = wc3_read_header,
+ .read_packet = wc3_read_packet,
+ .read_close = wc3_read_close,
};
diff --git a/libavformat/westwood.c b/libavformat/westwood.c
index 7c2b17d11c..95aba13354 100644
--- a/libavformat/westwood.c
+++ b/libavformat/westwood.c
@@ -2,20 +2,20 @@
* Westwood Studios Multimedia Formats Demuxer (VQA, AUD)
* Copyright (c) 2003 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -144,7 +144,7 @@ static int wsaud_read_header(AVFormatContext *s,
wsaud->audio_bits = (((header[10] & 0x2) >> 1) + 1) * 8;
/* initialize the audio decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 33, 1, wsaud->audio_samplerate);
@@ -221,7 +221,7 @@ static int wsvqa_read_header(AVFormatContext *s,
unsigned int chunk_size;
/* initialize the video decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 33, 1, VQA_FRAMERATE);
@@ -247,7 +247,7 @@ static int wsvqa_read_header(AVFormatContext *s,
/* initialize the audio decoder stream for VQA v1 or nonzero samplerate */
if (AV_RL16(&header[24]) || (AV_RL16(&header[0]) == 1 && AV_RL16(&header[2]) == 1)) {
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
av_set_pts_info(st, 33, 1, VQA_FRAMERATE);
@@ -277,10 +277,8 @@ static int wsvqa_read_header(AVFormatContext *s,
/* there are 0 or more chunks before the FINF chunk; iterate until
* FINF has been skipped and the file will be ready to be demuxed */
do {
- if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) {
- av_free(st->codec->extradata);
+ if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE)
return AVERROR(EIO);
- }
chunk_tag = AV_RB32(&scratch[0]);
chunk_size = AV_RB32(&scratch[4]);
@@ -368,21 +366,21 @@ static int wsvqa_read_packet(AVFormatContext *s,
#if CONFIG_WSAUD_DEMUXER
AVInputFormat ff_wsaud_demuxer = {
- "wsaud",
- NULL_IF_CONFIG_SMALL("Westwood Studios audio format"),
- sizeof(WsAudDemuxContext),
- wsaud_probe,
- wsaud_read_header,
- wsaud_read_packet,
+ .name = "wsaud",
+ .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios audio format"),
+ .priv_data_size = sizeof(WsAudDemuxContext),
+ .read_probe = wsaud_probe,
+ .read_header = wsaud_read_header,
+ .read_packet = wsaud_read_packet,
};
#endif
#if CONFIG_WSVQA_DEMUXER
AVInputFormat ff_wsvqa_demuxer = {
- "wsvqa",
- NULL_IF_CONFIG_SMALL("Westwood Studios VQA format"),
- sizeof(WsVqaDemuxContext),
- wsvqa_probe,
- wsvqa_read_header,
- wsvqa_read_packet,
+ .name = "wsvqa",
+ .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios VQA format"),
+ .priv_data_size = sizeof(WsVqaDemuxContext),
+ .read_probe = wsvqa_probe,
+ .read_header = wsvqa_read_header,
+ .read_packet = wsvqa_read_packet,
};
#endif
diff --git a/libavformat/wtv.c b/libavformat/wtv.c
index cc6fc8be48..7a29309e58 100644
--- a/libavformat/wtv.c
+++ b/libavformat/wtv.c
@@ -1,1110 +1,76 @@
/*
- * Windows Television (WTV) demuxer
+ * Windows Television (WTV)
* Copyright (c) 2010-2011 Peter Ross <pross@xvid.org>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/**
- * @file
- * Windows Television (WTV) demuxer
- * @author Peter Ross <pross@xvid.org>
- */
-
-#include "libavutil/intreadwrite.h"
-#include "libavutil/intfloat_readwrite.h"
-#include "libavutil/dict.h"
-#include "avformat.h"
-#include "internal.h"
-#include "riff.h"
-#include "asf.h"
-#include "mpegts.h"
-#include <strings.h>
-
-/* Macros for formating GUIDs */
-#define PRI_GUID \
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
-#define ARG_GUID(g) \
- g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]
-
-#define PRI_PRETTY_GUID \
- "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x"
-#define ARG_PRETTY_GUID(g) \
- AV_RL32(g),AV_RL16(g+4),AV_RL16(g+6),g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]
-#define LEN_PRETTY_GUID 34
-
-/*
- *
- * File system routines
- *
- */
-
-#define WTV_SECTOR_BITS 12
-#define WTV_SECTOR_SIZE (1 << WTV_SECTOR_BITS)
-#define WTV_BIGSECTOR_BITS 18
-
-typedef struct {
- AVIOContext *pb_filesystem; /** file system (AVFormatContext->pb) */
-
- int sector_bits; /** sector shift bits; used to convert sector number into pb_filesystem offset */
- uint32_t *sectors; /** file allocation table */
- int nb_sectors; /** number of sectors */
-
- int error;
- int64_t position;
- int64_t length;
-} WtvFile;
-
-/**
- * @return bytes read, 0 on end of file, or <0 on error
- */
-static int wtvfile_read_packet(void *opaque, uint8_t *buf, int buf_size)
-{
- WtvFile *wf = opaque;
- AVIOContext *pb = wf->pb_filesystem;
- int nread = 0;
-
- if (wf->error || pb->error)
- return -1;
- if (wf->position >= wf->length || pb->eof_reached)
- return 0;
-
- buf_size = FFMIN(buf_size, wf->length - wf->position);
- while(nread < buf_size) {
- int n;
- int remaining_in_sector = (1 << wf->sector_bits) - (wf->position & ((1 << wf->sector_bits) - 1));
- int read_request = FFMIN(buf_size - nread, remaining_in_sector);
-
- n = avio_read(pb, buf, read_request);
- if (n <= 0)
- break;
- nread += n;
- buf += n;
- wf->position += n;
- if (n == remaining_in_sector) {
- int i = wf->position >> wf->sector_bits;
- if (i >= wf->nb_sectors ||
- (wf->sectors[i] != wf->sectors[i - 1] + (1 << (wf->sector_bits - WTV_SECTOR_BITS)) &&
- avio_seek(pb, (int64_t)wf->sectors[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)) {
- wf->error = 1;
- break;
- }
- }
- }
- return nread;
-}
+#include "wtv.h"
-/**
- * @return position (or file length)
- */
-static int64_t wtvfile_seek(void *opaque, int64_t offset, int whence)
-{
- WtvFile *wf = opaque;
- AVIOContext *pb = wf->pb_filesystem;
-
- if (whence == AVSEEK_SIZE)
- return wf->length;
- else if (whence == SEEK_CUR)
- offset = wf->position + offset;
- else if (whence == SEEK_END)
- offset = wf->length;
-
- wf->error = offset < 0 || offset >= wf->length ||
- avio_seek(pb, ((int64_t)wf->sectors[offset >> wf->sector_bits] << WTV_SECTOR_BITS)
- + (offset & ((1 << wf->sector_bits) - 1)), SEEK_SET) < 0;
- wf->position = offset;
- return offset;
-}
-
-/**
- * read non-zero integers (le32) from input stream
- * @param pb
- * @param[out] data destination
- * @param count maximum number of integers to read
- * @return total number of integers read
- */
-static int read_ints(AVIOContext *pb, uint32_t *data, int count)
-{
- int i, total = 0;
- for (i = 0; i < count; i++) {
- if ((data[total] = avio_rl32(pb)))
- total++;
- }
- return total;
-}
-
-/**
- * Open file
- * @param first_sector First sector
- * @param length Length of file (bytes)
- * @param depth File allocation table depth
- * @return NULL on error
- */
-static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int depth, AVFormatContext *s)
-{
- AVIOContext *pb;
- WtvFile *wf;
- uint8_t *buffer;
-
- if (avio_seek(s->pb, first_sector << WTV_SECTOR_BITS, SEEK_SET) < 0)
- return NULL;
-
- wf = av_mallocz(sizeof(WtvFile));
- if (!wf)
- return NULL;
-
- if (depth == 0) {
- wf->sectors = av_malloc(sizeof(uint32_t));
- if (!wf->sectors) {
- av_free(wf);
- return NULL;
- }
- wf->sectors[0] = first_sector;
- wf->nb_sectors = 1;
- wf->sector_bits = WTV_SECTOR_BITS;
- } else if (depth == 1) {
- wf->sectors = av_malloc(WTV_SECTOR_SIZE);
- if (!wf->sectors) {
- av_free(wf);
- return NULL;
- }
- wf->nb_sectors = read_ints(s->pb, wf->sectors, WTV_SECTOR_SIZE / 4);
- wf->sector_bits = length & (1ULL<<63) ? WTV_SECTOR_BITS : WTV_BIGSECTOR_BITS;
- } else if (depth == 2) {
- uint32_t sectors1[WTV_SECTOR_SIZE / 4];
- int nb_sectors1 = read_ints(s->pb, sectors1, WTV_SECTOR_SIZE / 4);
- int i;
-
- wf->sectors = av_malloc(nb_sectors1 << WTV_SECTOR_BITS);
- if (!wf->sectors) {
- av_free(wf);
- return NULL;
- }
- wf->nb_sectors = 0;
- for (i = 0; i < nb_sectors1; i++) {
- if (avio_seek(s->pb, (int64_t)sectors1[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)
- break;
- wf->nb_sectors += read_ints(s->pb, wf->sectors + i * WTV_SECTOR_SIZE / 4, WTV_SECTOR_SIZE / 4);
- }
- wf->sector_bits = length & (1ULL<<63) ? WTV_SECTOR_BITS : WTV_BIGSECTOR_BITS;
- } else {
- av_log(s, AV_LOG_ERROR, "unsupported file allocation table depth (0x%x)\n", depth);
- av_free(wf);
- return NULL;
- }
-
- if (!wf->nb_sectors) {
- av_free(wf->sectors);
- av_free(wf);
- return NULL;
- }
-
- /* check length */
- length &= 0xFFFFFFFFFFFF;
- if (length > ((int64_t)wf->nb_sectors << wf->sector_bits)) {
- av_log(s, AV_LOG_WARNING, "reported file length (0x%"PRIx64") exceeds number of available sectors (0x%"PRIx64")\n", length, (int64_t)wf->nb_sectors << wf->sector_bits);
- length = (int64_t)wf->nb_sectors << wf->sector_bits;
- }
- wf->length = length;
-
- /* seek to intial sector */
- wf->position = 0;
- if (avio_seek(s->pb, (int64_t)wf->sectors[0] << WTV_SECTOR_BITS, SEEK_SET) < 0) {
- av_free(wf->sectors);
- av_free(wf);
- return NULL;
- }
-
- wf->pb_filesystem = s->pb;
- buffer = av_malloc(1 << wf->sector_bits);
- if (!buffer) {
- av_free(wf->sectors);
- av_free(wf);
- return NULL;
- }
-
- pb = avio_alloc_context(buffer, 1 << wf->sector_bits, 0, wf,
- wtvfile_read_packet, NULL, wtvfile_seek);
- if (!pb) {
- av_free(buffer);
- av_free(wf->sectors);
- av_free(wf);
- }
- return pb;
-}
-
-static const ff_asf_guid dir_entry_guid =
+/* WTV GUIDs*/
+const ff_asf_guid ff_dir_entry_guid =
{0x92,0xB7,0x74,0x91,0x59,0x70,0x70,0x44,0x88,0xDF,0x06,0x3B,0x82,0xCC,0x21,0x3D};
-
-/**
- * Open file using filename
- * @param[in] buf directory buffer
- * @param buf_size directory buffer size
- * @param[in] filename
- * @param filename_size size of filename
- * @return NULL on error
- */
-static AVIOContext * wtvfile_open2(AVFormatContext *s, const uint8_t *buf, int buf_size, const uint8_t *filename, int filename_size)
-{
- const uint8_t *buf_end = buf + buf_size;
-
- while(buf + 48 <= buf_end) {
- int dir_length, name_size, first_sector, depth;
- uint64_t file_length;
- const uint8_t *name;
- if (ff_guidcmp(buf, dir_entry_guid)) {
- av_log(s, AV_LOG_ERROR, "unknown guid "PRI_GUID", expected dir_entry_guid; "
- "remaining directory entries ignored\n", ARG_GUID(buf));
- break;
- }
- dir_length = AV_RL16(buf + 16);
- file_length = AV_RL64(buf + 24);
- name_size = 2 * AV_RL32(buf + 32);
- if (buf + 48 + name_size > buf_end) {
- av_log(s, AV_LOG_ERROR, "filename exceeds buffer size; remaining directory entries ignored\n");
- break;
- }
- first_sector = AV_RL32(buf + 40 + name_size);
- depth = AV_RL32(buf + 44 + name_size);
-
- /* compare file name; test optional null terminator */
- name = buf + 40;
- if (name_size >= filename_size &&
- !memcmp(name, filename, filename_size) &&
- (name_size < filename_size + 2 || !AV_RN16(name + filename_size)))
- return wtvfile_open_sector(first_sector, file_length, depth, s);
-
- buf += dir_length;
- }
- return 0;
-}
-
-#define wtvfile_open(s, buf, buf_size, filename) \
- wtvfile_open2(s, buf, buf_size, filename, sizeof(filename))
-
-/**
- * Close file opened with wtvfile_open_sector(), or wtv_open()
- */
-static void wtvfile_close(AVIOContext *pb)
-{
- WtvFile *wf = pb->opaque;
- av_free(wf->sectors);
- av_free(pb);
-}
-
-/*
- *
- * Main demuxer
- *
- */
-
-typedef struct {
- int seen_data;
-} WtvStream;
-
-typedef struct {
- AVIOContext *pb; /** timeline file */
- int64_t epoch;
- int64_t pts; /** pts for next data chunk */
- int64_t last_valid_pts; /** latest valid pts, used for interative seeking */
-
- /* maintain private seek index, as the AVIndexEntry->pos is relative to the
- start of the 'timeline' file, not the file system (AVFormatContext->pb) */
- AVIndexEntry *index_entries;
- int nb_index_entries;
- unsigned int index_entries_allocated_size;
-} WtvContext;
-
-typedef struct {
- enum CodecID id;
- ff_asf_guid guid;
-} AVCodecGuid;
-
-static enum CodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid)
-{
- int i;
- for (i = 0; guids[i].id != CODEC_ID_NONE; i++) {
- if (!ff_guidcmp(guids[i].guid, guid))
- return guids[i].id;
- }
- return CODEC_ID_NONE;
-}
-
-/* WTV GUIDs */
-static const ff_asf_guid wtv_guid =
+const ff_asf_guid ff_wtv_guid =
{0xB7,0xD8,0x00,0x20,0x37,0x49,0xDA,0x11,0xA6,0x4E,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
-static const ff_asf_guid metadata_guid =
- {0x5A,0xFE,0xD7,0x6D,0xC8,0x1D,0x8F,0x4A,0x99,0x22,0xFA,0xB1,0x1C,0x38,0x14,0x53};
-static const ff_asf_guid timestamp_guid =
+const ff_asf_guid ff_timestamp_guid =
{0x5B,0x05,0xE6,0x1B,0x97,0xA9,0x49,0x43,0x88,0x17,0x1A,0x65,0x5A,0x29,0x8A,0x97};
-static const ff_asf_guid data_guid =
+const ff_asf_guid ff_data_guid =
{0x95,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
-static const ff_asf_guid stream_guid =
+const ff_asf_guid ff_stream_guid =
{0xED,0xA4,0x13,0x23,0x2D,0xBF,0x4F,0x45,0xAD,0x8A,0xD9,0x5B,0xA7,0xF9,0x1F,0xEE};
-static const ff_asf_guid stream2_guid =
- {0xA2,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
-static const ff_asf_guid EVENTID_SubtitleSpanningEvent =
- {0x48,0xC0,0xCE,0x5D,0xB9,0xD0,0x63,0x41,0x87,0x2C,0x4F,0x32,0x22,0x3B,0xE8,0x8A};
-static const ff_asf_guid EVENTID_LanguageSpanningEvent =
- {0x6D,0x66,0x92,0xE2,0x02,0x9C,0x8D,0x44,0xAA,0x8D,0x78,0x1A,0x93,0xFD,0xC3,0x95};
-static const ff_asf_guid EVENTID_AudioDescriptorSpanningEvent =
- {0x1C,0xD4,0x7B,0x10,0xDA,0xA6,0x91,0x46,0x83,0x69,0x11,0xB2,0xCD,0xAA,0x28,0x8E};
-static const ff_asf_guid EVENTID_CtxADescriptorSpanningEvent =
- {0xE6,0xA2,0xB4,0x3A,0x47,0x42,0x34,0x4B,0x89,0x6C,0x30,0xAF,0xA5,0xD2,0x1C,0x24};
-static const ff_asf_guid EVENTID_CSDescriptorSpanningEvent =
- {0xD9,0x79,0xE7,0xEf,0xF0,0x97,0x86,0x47,0x80,0x0D,0x95,0xCF,0x50,0x5D,0xDC,0x66};
-static const ff_asf_guid EVENTID_DVBScramblingControlSpanningEvent =
- {0xC4,0xE1,0xD4,0x4B,0xA1,0x90,0x09,0x41,0x82,0x36,0x27,0xF0,0x0E,0x7D,0xCC,0x5B};
-static const ff_asf_guid EVENTID_StreamIDSpanningEvent =
- {0x68,0xAB,0xF1,0xCA,0x53,0xE1,0x41,0x4D,0xA6,0xB3,0xA7,0xC9,0x98,0xDB,0x75,0xEE};
-static const ff_asf_guid EVENTID_TeletextSpanningEvent =
- {0x50,0xD9,0x99,0x95,0x33,0x5F,0x17,0x46,0xAF,0x7C,0x1E,0x54,0xB5,0x10,0xDA,0xA3};
-static const ff_asf_guid EVENTID_AudioTypeSpanningEvent =
- {0xBE,0xBF,0x1C,0x50,0x49,0xB8,0xCE,0x42,0x9B,0xE9,0x3D,0xB8,0x69,0xFB,0x82,0xB3};
-
-/* Windows media GUIDs */
+const ff_asf_guid ff_mediatype_audio =
+ {'a','u','d','s',FF_MEDIASUBTYPE_BASE_GUID};
+const ff_asf_guid ff_mediatype_video =
+ {'v','i','d','s',FF_MEDIASUBTYPE_BASE_GUID};
+const ff_asf_guid ff_format_none =
+ {0xD6,0x17,0x64,0x0F,0x18,0xC3,0xD0,0x11,0xA4,0x3F,0x00,0xA0,0xC9,0x22,0x31,0x96};
-#define MEDIASUBTYPE_BASE_GUID \
- 0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71
+/* declare utf16le strings */
+#define _ , 0,
+const uint8_t ff_timeline_le16[] =
+ {'t'_'i'_'m'_'e'_'l'_'i'_'n'_'e', 0};
+const uint8_t ff_timeline_table_0_entries_Events_le16[] =
+ {'t'_'i'_'m'_'e'_'l'_'i'_'n'_'e'_'.'_'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'e'_'n'_'t'_'r'_'i'_'e'_'s'_'.'_'E'_'v'_'e'_'n'_'t'_'s', 0};
+const uint8_t ff_table_0_entries_legacy_attrib_le16[] =
+ {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'e'_'n'_'t'_'r'_'i'_'e'_'s'_'.'_'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
+const uint8_t ff_table_0_entries_time_le16[] =
+ {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'e'_'n'_'t'_'r'_'i'_'e'_'s'_'.'_'t'_'i'_'m'_'e', 0};
+#undef _
-/* Media types */
-static const ff_asf_guid mediatype_audio =
- {'a','u','d','s',MEDIASUBTYPE_BASE_GUID};
-static const ff_asf_guid mediatype_video =
- {'v','i','d','s',MEDIASUBTYPE_BASE_GUID};
-static const ff_asf_guid mediasubtype_mpeg1payload =
- {0x81,0xEB,0x36,0xE4,0x4F,0x52,0xCE,0x11,0x9F,0x53,0x00,0x20,0xAF,0x0B,0xA7,0x70};
-static const ff_asf_guid mediatype_mpeg2_sections =
- {0x6C,0x17,0x5F,0x45,0x06,0x4B,0xCE,0x47,0x9A,0xEF,0x8C,0xAE,0xF7,0x3D,0xF7,0xB5};
-static const ff_asf_guid mediatype_mpeg2_pes =
- {0x20,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA};
-static const ff_asf_guid mediatype_mstvcaption =
- {0x89,0x8A,0x8B,0xB8,0x49,0xB0,0x80,0x4C,0xAD,0xCF,0x58,0x98,0x98,0x5E,0x22,0xC1};
+const ff_asf_guid ff_DSATTRIB_TRANSPORT_PROPERTIES =
+ {0x12,0xF6,0x22,0xB6,0xAD,0x47,0x71,0x46,0xAD,0x6C,0x05,0xA9,0x8E,0x65,0xDE,0x3A};
+const ff_asf_guid ff_metadata_guid =
+ {0x5A,0xFE,0xD7,0x6D,0xC8,0x1D,0x8F,0x4A,0x99,0x22,0xFA,0xB1,0x1C,0x38,0x14,0x53};
+const ff_asf_guid ff_stream2_guid =
+ {0xA2,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
/* Media subtypes */
-static const ff_asf_guid mediasubtype_cpfilters_processed =
+const ff_asf_guid ff_mediasubtype_cpfilters_processed =
{0x28,0xBD,0xAD,0x46,0xD0,0x6F,0x96,0x47,0x93,0xB2,0x15,0x5C,0x51,0xDC,0x04,0x8D};
-static const ff_asf_guid mediasubtype_dvb_subtitle =
- {0xC3,0xCB,0xFF,0x34,0xB3,0xD5,0x71,0x41,0x90,0x02,0xD4,0xC6,0x03,0x01,0x69,0x7F};
-static const ff_asf_guid mediasubtype_teletext =
- {0xE3,0x76,0x2A,0xF7,0x0A,0xEB,0xD0,0x11,0xAC,0xE4,0x00,0x00,0xC0,0xCC,0x16,0xBA};
-static const ff_asf_guid mediasubtype_dtvccdata =
- {0xAA,0xDD,0x2A,0xF5,0xF0,0x36,0xF5,0x43,0x95,0xEA,0x6D,0x86,0x64,0x84,0x26,0x2A};
-static const ff_asf_guid mediasubtype_mpeg2_sections =
- {0x79,0x85,0x9F,0x4A,0xF8,0x6B,0x92,0x43,0x8A,0x6D,0xD2,0xDD,0x09,0xFA,0x78,0x61};
/* Formats */
-static const ff_asf_guid format_cpfilters_processed =
+const ff_asf_guid ff_format_cpfilters_processed =
{0x6F,0xB3,0x39,0x67,0x5F,0x1D,0xC2,0x4A,0x81,0x92,0x28,0xBB,0x0E,0x73,0xD1,0x6A};
-static const ff_asf_guid format_waveformatex =
+const ff_asf_guid ff_format_waveformatex =
{0x81,0x9F,0x58,0x05,0x56,0xC3,0xCE,0x11,0xBF,0x01,0x00,0xAA,0x00,0x55,0x59,0x5A};
-static const ff_asf_guid format_videoinfo2 =
- {0xA0,0x76,0x2A,0xF7,0x0A,0xEB,0xD0,0x11,0xAC,0xE4,0x00,0x00,0xC0,0xCC,0x16,0xBA};
-static const ff_asf_guid format_mpeg2_video =
+const ff_asf_guid ff_format_mpeg2_video =
{0xE3,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA};
-static const ff_asf_guid format_none =
- {0xD6,0x17,0x64,0x0F,0x18,0xC3,0xD0,0x11,0xA4,0x3F,0x00,0xA0,0xC9,0x22,0x31,0x96};
-static const AVCodecGuid video_guids[] = {
+const AVCodecGuid ff_video_guids[] = {
{CODEC_ID_MPEG2VIDEO, {0x26,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA}},
{CODEC_ID_NONE}
};
-
-static const AVCodecGuid audio_guids[] = {
- {CODEC_ID_AC3, {0x2C,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA}},
- {CODEC_ID_EAC3, {0xAF,0x87,0xFB,0xA7,0x02,0x2D,0xFB,0x42,0xA4,0xD4,0x05,0xCD,0x93,0x84,0x3B,0xDD}},
- {CODEC_ID_MP2, {0x2B,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA}},
- {CODEC_ID_NONE}
-};
-
-static int read_probe(AVProbeData *p)
-{
- return ff_guidcmp(p->buf, wtv_guid) ? 0 : AVPROBE_SCORE_MAX;
-}
-
-/**
- * Convert win32 FILETIME to ISO-8601 string
- */
-static void filetime_to_iso8601(char *buf, int buf_size, int64_t value)
-{
- time_t t = (value / 10000000LL) - 11644473600LL;
- strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
-}
-
-/**
- * Convert crazy time (100ns since 1 Jan 0001) to ISO-8601 string
- */
-static void crazytime_to_iso8601(char *buf, int buf_size, int64_t value)
-{
- time_t t = (value / 10000000LL) - 719162LL*86400LL;
- strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
-}
-
-/**
- * Convert OLE DATE to ISO-8601 string
- */
-static void oledate_to_iso8601(char *buf, int buf_size, int64_t value)
-{
- time_t t = 631112400LL + 86400*av_int2dbl(value);
- strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
-}
-
-static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length)
-{
- char mime[1024];
- char description[1024];
- unsigned int filesize;
- AVStream *st;
- int64_t pos = avio_tell(pb);
-
- avio_get_str16le(pb, INT_MAX, mime, sizeof(mime));
- if (strcmp(mime, "image/jpeg"))
- goto done;
-
- avio_r8(pb);
- avio_get_str16le(pb, INT_MAX, description, sizeof(description));
- filesize = avio_rl32(pb);
- if (!filesize)
- goto done;
-
- st = av_new_stream(s, 0);
- if (!st)
- goto done;
- av_dict_set(&st->metadata, "title", description, 0);
- st->codec->codec_id = CODEC_ID_MJPEG;
- st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
- st->codec->extradata = av_mallocz(filesize);
- if (!st->codec->extradata)
- goto done;
- st->codec->extradata_size = filesize;
- avio_read(pb, st->codec->extradata, filesize);
-done:
- avio_seek(pb, pos + length, SEEK_SET);
-}
-
-static void get_tag(AVFormatContext *s, AVIOContext *pb, const char *key, int type, int length)
-{
- int buf_size = FFMAX(2*length, LEN_PRETTY_GUID) + 1;
- char *buf = av_malloc(buf_size);
- if (!buf)
- return;
-
- if (type == 0 && length == 4) {
- snprintf(buf, buf_size, "%"PRIi32, avio_rl32(pb));
- } else if (type == 1) {
- avio_get_str16le(pb, length, buf, buf_size);
- if (!strlen(buf)) {
- av_free(buf);
- return;
- }
- } else if (type == 3 && length == 4) {
- strcpy(buf, avio_rl32(pb) ? "true" : "false");
- } else if (type == 4 && length == 8) {
- int64_t num = avio_rl64(pb);
- if (!strcmp(key, "WM/EncodingTime") ||
- !strcmp(key, "WM/MediaOriginalBroadcastDateTime"))
- filetime_to_iso8601(buf, buf_size, num);
- else if (!strcmp(key, "WM/WMRVEncodeTime") ||
- !strcmp(key, "WM/WMRVEndTime"))
- crazytime_to_iso8601(buf, buf_size, num);
- else if (!strcmp(key, "WM/WMRVExpirationDate"))
- oledate_to_iso8601(buf, buf_size, num);
- else if (!strcmp(key, "WM/WMRVBitrate"))
- snprintf(buf, buf_size, "%f", av_int2dbl(num));
- else
- snprintf(buf, buf_size, "%"PRIi64, num);
- } else if (type == 5 && length == 2) {
- snprintf(buf, buf_size, "%"PRIi16, avio_rl16(pb));
- } else if (type == 6 && length == 16) {
- ff_asf_guid guid;
- avio_read(pb, guid, 16);
- snprintf(buf, buf_size, PRI_PRETTY_GUID, ARG_PRETTY_GUID(guid));
- } else if (type == 2 && !strcmp(key, "WM/Picture")) {
- get_attachment(s, pb, length);
- av_freep(&buf);
- return;
- } else {
- av_freep(&buf);
- av_log(s, AV_LOG_WARNING, "unsupported metadata entry; key:%s, type:%d, length:0x%x\n", key, type, length);
- avio_skip(pb, length);
- return;
- }
-
- av_dict_set(&s->metadata, key, buf, 0);
- av_freep(&buf);
-}
-
-/**
- * Parse metadata entries
- */
-static void parse_legacy_attrib(AVFormatContext *s, AVIOContext *pb)
-{
- ff_asf_guid guid;
- int length, type;
- while(!pb->eof_reached) {
- char key[1024];
- ff_get_guid(pb, &guid);
- type = avio_rl32(pb);
- length = avio_rl32(pb);
- if (!length)
- break;
- if (ff_guidcmp(&guid, metadata_guid)) {
- av_log(s, AV_LOG_WARNING, "unknown guid "PRI_GUID", expected metadata_guid; "
- "remaining metadata entries ignored\n", ARG_GUID(guid));
- break;
- }
- avio_get_str16le(pb, INT_MAX, key, sizeof(key));
- get_tag(s, pb, key, type, length);
- }
-
- ff_metadata_conv(&s->metadata, NULL, ff_asf_metadata_conv);
-}
-
-/**
- * parse VIDEOINFOHEADER2 structure
- * @return bytes consumed
- */
-static int parse_videoinfoheader2(AVFormatContext *s, AVStream *st)
-{
- WtvContext *wtv = s->priv_data;
- AVIOContext *pb = wtv->pb;
-
- avio_skip(pb, 72); // picture aspect ratio is unreliable
- ff_get_bmp_header(pb, st);
-
- return 72 + 40;
-}
-
-/**
- * Parse MPEG1WAVEFORMATEX extradata structure
- */
-static void parse_mpeg1waveformatex(AVStream *st)
-{
- /* fwHeadLayer */
- switch (AV_RL16(st->codec->extradata)) {
- case 0x0001 : st->codec->codec_id = CODEC_ID_MP1; break;
- case 0x0002 : st->codec->codec_id = CODEC_ID_MP2; break;
- case 0x0004 : st->codec->codec_id = CODEC_ID_MP3; break;
- }
-
- st->codec->bit_rate = AV_RL32(st->codec->extradata + 2); /* dwHeadBitrate */
-
- /* dwHeadMode */
- switch (AV_RL16(st->codec->extradata + 6)) {
- case 1 : case 2 : case 4 : st->codec->channels = 2; break;
- case 8 : st->codec->channels = 1; break;
- }
-}
-
-/**
- * Initialise stream
- * @param st Stream to initialise, or NULL to create and initialise new stream
- * @return NULL on error
- */
-static AVStream * new_stream(AVFormatContext *s, AVStream *st, int sid, int codec_type)
-{
- if (st) {
- if (st->codec->extradata) {
- av_freep(&st->codec->extradata);
- st->codec->extradata_size = 0;
- }
- } else {
- WtvStream *wst = av_mallocz(sizeof(WtvStream));
- if (!wst)
- return NULL;
- st = av_new_stream(s, sid);
- if (!st)
- return NULL;
- st->priv_data = wst;
- }
- st->codec->codec_type = codec_type;
- st->need_parsing = AVSTREAM_PARSE_FULL;
- av_set_pts_info(st, 64, 1, 10000000);
- return st;
-}
-
-/**
- * parse Media Type structure and populate stream
- * @param st Stream, or NULL to create new stream
- * @param mediatype Mediatype GUID
- * @param subtype Subtype GUID
- * @param formattype Format GUID
- * @param size Size of format buffer
- * @return NULL on error
- */
-static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid,
- ff_asf_guid mediatype, ff_asf_guid subtype,
- ff_asf_guid formattype, int size)
-{
- WtvContext *wtv = s->priv_data;
- AVIOContext *pb = wtv->pb;
- if (!ff_guidcmp(subtype, mediasubtype_cpfilters_processed) &&
- !ff_guidcmp(formattype, format_cpfilters_processed)) {
- ff_asf_guid actual_subtype;
- ff_asf_guid actual_formattype;
-
- if (size < 32) {
- av_log(s, AV_LOG_WARNING, "format buffer size underflow\n");
- avio_skip(pb, size);
- return NULL;
- }
-
- avio_skip(pb, size - 32);
- ff_get_guid(pb, &actual_subtype);
- ff_get_guid(pb, &actual_formattype);
- avio_seek(pb, -size, SEEK_CUR);
-
- st = parse_media_type(s, st, sid, mediatype, actual_subtype, actual_formattype, size - 32);
- avio_skip(pb, 32);
- return st;
- } else if (!ff_guidcmp(mediatype, mediatype_audio)) {
- st = new_stream(s, st, sid, AVMEDIA_TYPE_AUDIO);
- if (!st)
- return NULL;
- if (!ff_guidcmp(formattype, format_waveformatex)) {
- int ret = ff_get_wav_header(pb, st->codec, size);
- if (ret < 0)
- return NULL;
- } else {
- if (ff_guidcmp(formattype, format_none))
- av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
- avio_skip(pb, size);
- }
-
- if (!memcmp(subtype + 4, (const uint8_t[]){MEDIASUBTYPE_BASE_GUID}, 12)) {
- st->codec->codec_id = ff_wav_codec_get_id(AV_RL32(subtype), st->codec->bits_per_coded_sample);
- } else if (!ff_guidcmp(subtype, mediasubtype_mpeg1payload)) {
- if (st->codec->extradata && st->codec->extradata_size >= 22)
- parse_mpeg1waveformatex(st);
- else
- av_log(s, AV_LOG_WARNING, "MPEG1WAVEFORMATEX underflow\n");
- } else {
- st->codec->codec_id = ff_codec_guid_get_id(audio_guids, subtype);
- if (st->codec->codec_id == CODEC_ID_NONE)
- av_log(s, AV_LOG_WARNING, "unknown subtype:"PRI_GUID"\n", ARG_GUID(subtype));
- }
- return st;
- } else if (!ff_guidcmp(mediatype, mediatype_video)) {
- st = new_stream(s, st, sid, AVMEDIA_TYPE_VIDEO);
- if (!st)
- return NULL;
- if (!ff_guidcmp(formattype, format_videoinfo2)) {
- int consumed = parse_videoinfoheader2(s, st);
- avio_skip(pb, FFMAX(size - consumed, 0));
- } else if (!ff_guidcmp(formattype, format_mpeg2_video)) {
- int consumed = parse_videoinfoheader2(s, st);
- avio_skip(pb, FFMAX(size - consumed, 0));
- } else {
- if (ff_guidcmp(formattype, format_none))
- av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
- avio_skip(pb, size);
- }
-
- if (!memcmp(subtype + 4, (const uint8_t[]){MEDIASUBTYPE_BASE_GUID}, 12)) {
- st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, AV_RL32(subtype));
- } else {
- st->codec->codec_id = ff_codec_guid_get_id(video_guids, subtype);
- }
- if (st->codec->codec_id == CODEC_ID_NONE)
- av_log(s, AV_LOG_WARNING, "unknown subtype:"PRI_GUID"\n", ARG_GUID(subtype));
- return st;
- } else if (!ff_guidcmp(mediatype, mediatype_mpeg2_pes) &&
- !ff_guidcmp(subtype, mediasubtype_dvb_subtitle)) {
- st = new_stream(s, st, sid, AVMEDIA_TYPE_SUBTITLE);
- if (!st)
- return NULL;
- if (ff_guidcmp(formattype, format_none))
- av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
- avio_skip(pb, size);
- st->codec->codec_id = CODEC_ID_DVB_SUBTITLE;
- return st;
- } else if (!ff_guidcmp(mediatype, mediatype_mstvcaption) &&
- (!ff_guidcmp(subtype, mediasubtype_teletext) || !ff_guidcmp(subtype, mediasubtype_dtvccdata))) {
- st = new_stream(s, st, sid, AVMEDIA_TYPE_SUBTITLE);
- if (!st)
- return NULL;
- if (ff_guidcmp(formattype, format_none))
- av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
- avio_skip(pb, size);
- st->codec->codec_id = CODEC_ID_DVB_TELETEXT;
- return st;
- } else if (!ff_guidcmp(mediatype, mediatype_mpeg2_sections) &&
- !ff_guidcmp(subtype, mediasubtype_mpeg2_sections)) {
- if (ff_guidcmp(formattype, format_none))
- av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
- avio_skip(pb, size);
- return NULL;
- }
-
- av_log(s, AV_LOG_WARNING, "unknown media type, mediatype:"PRI_GUID
- ", subtype:"PRI_GUID", formattype:"PRI_GUID"\n",
- ARG_GUID(mediatype), ARG_GUID(subtype), ARG_GUID(formattype));
- avio_skip(pb, size);
- return NULL;
-}
-
-enum {
- SEEK_TO_DATA = 0,
- SEEK_TO_PTS,
-};
-
-/**
- * Parse WTV chunks
- * @param mode SEEK_TO_DATA or SEEK_TO_PTS
- * @param seekts timestamp
- * @param[out] len_ptr Length of data chunk
- * @return stream index of data chunk, or <0 on error
- */
-static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_ptr)
-{
- WtvContext *wtv = s->priv_data;
- AVIOContext *pb = wtv->pb;
- while (!pb->eof_reached) {
- ff_asf_guid g;
- int len, sid, consumed;
-
- ff_get_guid(pb, &g);
- len = avio_rl32(pb);
- if (len < 32)
- break;
- sid = avio_rl32(pb) & 0x7FFF;
- avio_skip(pb, 8);
- consumed = 32;
-
- if (!ff_guidcmp(g, stream_guid)) {
- if (ff_find_stream_index(s, sid) < 0) {
- ff_asf_guid mediatype, subtype, formattype;
- int size;
- avio_skip(pb, 28);
- ff_get_guid(pb, &mediatype);
- ff_get_guid(pb, &subtype);
- avio_skip(pb, 12);
- ff_get_guid(pb, &formattype);
- size = avio_rl32(pb);
- parse_media_type(s, 0, sid, mediatype, subtype, formattype, size);
- consumed += 92 + size;
- }
- } else if (!ff_guidcmp(g, stream2_guid)) {
- int stream_index = ff_find_stream_index(s, sid);
- if (stream_index >= 0 && !((WtvStream*)s->streams[stream_index]->priv_data)->seen_data) {
- ff_asf_guid mediatype, subtype, formattype;
- int size;
- avio_skip(pb, 12);
- ff_get_guid(pb, &mediatype);
- ff_get_guid(pb, &subtype);
- avio_skip(pb, 12);
- ff_get_guid(pb, &formattype);
- size = avio_rl32(pb);
- parse_media_type(s, s->streams[stream_index], sid, mediatype, subtype, formattype, size);
- consumed += 76 + size;
- }
- } else if (!ff_guidcmp(g, EVENTID_AudioDescriptorSpanningEvent) ||
- !ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) ||
- !ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent) ||
- !ff_guidcmp(g, EVENTID_StreamIDSpanningEvent) ||
- !ff_guidcmp(g, EVENTID_SubtitleSpanningEvent) ||
- !ff_guidcmp(g, EVENTID_TeletextSpanningEvent)) {
- int stream_index = ff_find_stream_index(s, sid);
- if (stream_index >= 0) {
- AVStream *st = s->streams[stream_index];
- uint8_t buf[258];
- const uint8_t *pbuf = buf;
- int buf_size;
-
- avio_skip(pb, 8);
- consumed += 8;
- if (!ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) ||
- !ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent)) {
- avio_skip(pb, 6);
- consumed += 6;
- }
-
- buf_size = FFMIN(len - consumed, sizeof(buf));
- avio_read(pb, buf, buf_size);
- consumed += buf_size;
- ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, 0, 0, 0, 0);
- }
- } else if (!ff_guidcmp(g, EVENTID_AudioTypeSpanningEvent)) {
- int stream_index = ff_find_stream_index(s, sid);
- if (stream_index >= 0) {
- AVStream *st = s->streams[stream_index];
- int audio_type;
- avio_skip(pb, 8);
- audio_type = avio_r8(pb);
- if (audio_type == 2)
- st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED;
- else if (audio_type == 3)
- st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
- consumed += 9;
- }
- } else if (!ff_guidcmp(g, EVENTID_DVBScramblingControlSpanningEvent)) {
- int stream_index = ff_find_stream_index(s, sid);
- if (stream_index >= 0) {
- avio_skip(pb, 12);
- if (avio_rl32(pb))
- av_log(s, AV_LOG_WARNING, "DVB scrambled stream detected (st:%d), decoding will likely fail\n", stream_index);
- consumed += 16;
- }
- } else if (!ff_guidcmp(g, EVENTID_LanguageSpanningEvent)) {
- int stream_index = ff_find_stream_index(s, sid);
- if (stream_index >= 0) {
- AVStream *st = s->streams[stream_index];
- uint8_t language[4];
- avio_skip(pb, 12);
- avio_read(pb, language, 3);
- if (language[0]) {
- language[3] = 0;
- av_dict_set(&st->metadata, "language", language, 0);
- if (!strcmp(language, "nar") || !strcmp(language, "NAR"))
- st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
- }
- consumed += 15;
- }
- } else if (!ff_guidcmp(g, timestamp_guid)) {
- int stream_index = ff_find_stream_index(s, sid);
- if (stream_index >= 0) {
- avio_skip(pb, 8);
- wtv->pts = avio_rl64(pb);
- consumed += 16;
- if (wtv->pts == -1)
- wtv->pts = AV_NOPTS_VALUE;
- else {
- wtv->last_valid_pts = wtv->pts;
- if (wtv->epoch == AV_NOPTS_VALUE || wtv->pts < wtv->epoch)
- wtv->epoch = wtv->pts;
- if (mode == SEEK_TO_PTS && wtv->pts >= seekts) {
-#define WTV_PAD8(x) (((x) + 7) & ~7)
- avio_skip(pb, WTV_PAD8(len) - consumed);
- return 0;
- }
- }
- }
- } else if (!ff_guidcmp(g, data_guid)) {
- int stream_index = ff_find_stream_index(s, sid);
- if (mode == SEEK_TO_DATA && stream_index >= 0 && len > 32) {
- WtvStream *wst = s->streams[stream_index]->priv_data;
- wst->seen_data = 1;
- if (len_ptr) {
- *len_ptr = len;
- }
- return stream_index;
- }
- } else if (
- !ff_guidcmp(g, /* DSATTRIB_CAPTURE_STREAMTIME */ (const ff_asf_guid){0x14,0x56,0x1A,0x0C,0xCD,0x30,0x40,0x4F,0xBC,0xBF,0xD0,0x3E,0x52,0x30,0x62,0x07}) ||
- !ff_guidcmp(g, /* DSATTRIB_PicSampleSeq */ (const ff_asf_guid){0x02,0xAE,0x5B,0x2F,0x8F,0x7B,0x60,0x4F,0x82,0xD6,0xE4,0xEA,0x2F,0x1F,0x4C,0x99}) ||
- !ff_guidcmp(g, /* DSATTRIB_TRANSPORT_PROPERTIES */ (const ff_asf_guid){0x12,0xF6,0x22,0xB6,0xAD,0x47,0x71,0x46,0xAD,0x6C,0x05,0xA9,0x8E,0x65,0xDE,0x3A}) ||
- !ff_guidcmp(g, /* dvr_ms_vid_frame_rep_data */ (const ff_asf_guid){0xCC,0x32,0x64,0xDD,0x29,0xE2,0xDB,0x40,0x80,0xF6,0xD2,0x63,0x28,0xD2,0x76,0x1F}) ||
- !ff_guidcmp(g, /* EVENTID_ChannelChangeSpanningEvent */ (const ff_asf_guid){0xE5,0xC5,0x67,0x90,0x5C,0x4C,0x05,0x42,0x86,0xC8,0x7A,0xFE,0x20,0xFE,0x1E,0xFA}) ||
- !ff_guidcmp(g, /* EVENTID_ChannelInfoSpanningEvent */ (const ff_asf_guid){0x80,0x6D,0xF3,0x41,0x32,0x41,0xC2,0x4C,0xB1,0x21,0x01,0xA4,0x32,0x19,0xD8,0x1B}) ||
- !ff_guidcmp(g, /* EVENTID_ChannelTypeSpanningEvent */ (const ff_asf_guid){0x51,0x1D,0xAB,0x72,0xD2,0x87,0x9B,0x48,0xBA,0x11,0x0E,0x08,0xDC,0x21,0x02,0x43}) ||
- !ff_guidcmp(g, /* EVENTID_PIDListSpanningEvent */ (const ff_asf_guid){0x65,0x8F,0xFC,0x47,0xBB,0xE2,0x34,0x46,0x9C,0xEF,0xFD,0xBF,0xE6,0x26,0x1D,0x5C}) ||
- !ff_guidcmp(g, /* EVENTID_SignalAndServiceStatusSpanningEvent */ (const ff_asf_guid){0xCB,0xC5,0x68,0x80,0x04,0x3C,0x2B,0x49,0xB4,0x7D,0x03,0x08,0x82,0x0D,0xCE,0x51}) ||
- !ff_guidcmp(g, /* EVENTID_StreamTypeSpanningEvent */ (const ff_asf_guid){0xBC,0x2E,0xAF,0x82,0xA6,0x30,0x64,0x42,0xA8,0x0B,0xAD,0x2E,0x13,0x72,0xAC,0x60}) ||
- !ff_guidcmp(g, (const ff_asf_guid){0x1E,0xBE,0xC3,0xC5,0x43,0x92,0xDC,0x11,0x85,0xE5,0x00,0x12,0x3F,0x6F,0x73,0xB9}) ||
- !ff_guidcmp(g, (const ff_asf_guid){0x3B,0x86,0xA2,0xB1,0xEB,0x1E,0xC3,0x44,0x8C,0x88,0x1C,0xA3,0xFF,0xE3,0xE7,0x6A}) ||
- !ff_guidcmp(g, (const ff_asf_guid){0x4E,0x7F,0x4C,0x5B,0xC4,0xD0,0x38,0x4B,0xA8,0x3E,0x21,0x7F,0x7B,0xBF,0x52,0xE7}) ||
- !ff_guidcmp(g, (const ff_asf_guid){0x63,0x36,0xEB,0xFE,0xA1,0x7E,0xD9,0x11,0x83,0x08,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
- !ff_guidcmp(g, (const ff_asf_guid){0x70,0xE9,0xF1,0xF8,0x89,0xA4,0x4C,0x4D,0x83,0x73,0xB8,0x12,0xE0,0xD5,0xF8,0x1E}) ||
- !ff_guidcmp(g, (const ff_asf_guid){0x96,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
- !ff_guidcmp(g, (const ff_asf_guid){0x97,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
- !ff_guidcmp(g, (const ff_asf_guid){0xA1,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D})) {
- //ignore known guids
- } else
- av_log(s, AV_LOG_WARNING, "unsupported chunk:"PRI_GUID"\n", ARG_GUID(g));
-
- avio_skip(pb, WTV_PAD8(len) - consumed);
- }
- return AVERROR_EOF;
-}
-
-/* declare utf16le strings */
-#define _ , 0,
-static const uint8_t timeline_le16[] =
- {'t'_'i'_'m'_'e'_'l'_'i'_'n'_'e', 0};
-static const uint8_t table_0_entries_legacy_attrib_le16[] =
- {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'e'_'n'_'t'_'r'_'i'_'e'_'s'_'.'_'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
-static const uint8_t table_0_entries_time_le16[] =
- {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'e'_'n'_'t'_'r'_'i'_'e'_'s'_'.'_'t'_'i'_'m'_'e', 0};
-static const uint8_t timeline_table_0_entries_Events_le16[] =
- {'t'_'i'_'m'_'e'_'l'_'i'_'n'_'e'_'.'_'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'e'_'n'_'t'_'r'_'i'_'e'_'s'_'.'_'E'_'v'_'e'_'n'_'t'_'s', 0};
-#undef _
-
-static int read_header(AVFormatContext *s, AVFormatParameters *ap)
-{
- WtvContext *wtv = s->priv_data;
- int root_sector, root_size;
- uint8_t root[WTV_SECTOR_SIZE];
- AVIOContext *pb;
- int64_t timeline_pos;
- int ret;
-
- wtv->epoch =
- wtv->pts =
- wtv->last_valid_pts = AV_NOPTS_VALUE;
-
- /* read root directory sector */
- avio_skip(s->pb, 0x30);
- root_size = avio_rl32(s->pb);
- if (root_size > sizeof(root)) {
- av_log(s, AV_LOG_ERROR, "root directory size exceeds sector size\n");
- return AVERROR_INVALIDDATA;
- }
- avio_skip(s->pb, 4);
- root_sector = avio_rl32(s->pb);
-
- avio_seek(s->pb, root_sector << WTV_SECTOR_BITS, SEEK_SET);
- root_size = avio_read(s->pb, root, root_size);
- if (root_size < 0)
- return AVERROR_INVALIDDATA;
-
- /* parse chunks up until first data chunk */
- wtv->pb = wtvfile_open(s, root, root_size, timeline_le16);
- if (!wtv->pb) {
- av_log(s, AV_LOG_ERROR, "timeline data missing\n");
- return AVERROR_INVALIDDATA;
- }
-
- ret = parse_chunks(s, SEEK_TO_DATA, 0, 0);
- if (ret < 0)
- return ret;
- avio_seek(wtv->pb, -32, SEEK_CUR);
-
- timeline_pos = avio_tell(s->pb); // save before opening another file
-
- /* read metadata */
- pb = wtvfile_open(s, root, root_size, table_0_entries_legacy_attrib_le16);
- if (pb) {
- parse_legacy_attrib(s, pb);
- wtvfile_close(pb);
- }
-
- /* read seek index */
- if (s->nb_streams) {
- AVStream *st = s->streams[0];
- pb = wtvfile_open(s, root, root_size, table_0_entries_time_le16);
- if (pb) {
- while(1) {
- uint64_t timestamp = avio_rl64(pb);
- uint64_t frame_nb = avio_rl64(pb);
- if (pb->eof_reached)
- break;
- ff_add_index_entry(&wtv->index_entries, &wtv->nb_index_entries, &wtv->index_entries_allocated_size,
- 0, timestamp, frame_nb, 0, AVINDEX_KEYFRAME);
- }
- wtvfile_close(pb);
-
- if (wtv->nb_index_entries) {
- pb = wtvfile_open(s, root, root_size, timeline_table_0_entries_Events_le16);
- if (pb) {
- int i;
- while (1) {
- uint64_t frame_nb = avio_rl64(pb);
- uint64_t position = avio_rl64(pb);
- if (pb->eof_reached)
- break;
- for (i = wtv->nb_index_entries - 1; i >= 0; i--) {
- AVIndexEntry *e = wtv->index_entries + i;
- if (frame_nb > e->size)
- break;
- if (position > e->pos)
- e->pos = position;
- }
- }
- wtvfile_close(pb);
- st->duration = wtv->index_entries[wtv->nb_index_entries - 1].timestamp;
- }
- }
- }
- }
-
- avio_seek(s->pb, timeline_pos, SEEK_SET);
- return 0;
-}
-
-static int read_packet(AVFormatContext *s, AVPacket *pkt)
-{
- WtvContext *wtv = s->priv_data;
- AVIOContext *pb = wtv->pb;
- int stream_index, len, ret;
-
- stream_index = parse_chunks(s, SEEK_TO_DATA, 0, &len);
- if (stream_index < 0)
- return stream_index;
-
- ret = av_get_packet(pb, pkt, len - 32);
- if (ret < 0)
- return ret;
- pkt->stream_index = stream_index;
- pkt->pts = wtv->pts;
- avio_skip(pb, WTV_PAD8(len) - len);
- return 0;
-}
-
-static int read_seek(AVFormatContext *s, int stream_index,
- int64_t ts, int flags)
-{
- WtvContext *wtv = s->priv_data;
- AVIOContext *pb = wtv->pb;
- AVStream *st = s->streams[0];
- int64_t ts_relative;
- int i;
-
- if ((flags & AVSEEK_FLAG_FRAME) || (flags & AVSEEK_FLAG_BYTE))
- return AVERROR(ENOSYS);
-
- /* timestamp adjustment is required because wtv->pts values are absolute,
- * whereas AVIndexEntry->timestamp values are relative to epoch. */
- ts_relative = ts;
- if (wtv->epoch != AV_NOPTS_VALUE)
- ts_relative -= wtv->epoch;
-
- i = ff_index_search_timestamp(wtv->index_entries, wtv->nb_index_entries, ts_relative, flags);
- if (i < 0) {
- if (wtv->last_valid_pts == AV_NOPTS_VALUE || ts < wtv->last_valid_pts)
- avio_seek(pb, 0, SEEK_SET);
- else if (st->duration != AV_NOPTS_VALUE && ts_relative > st->duration && wtv->nb_index_entries)
- avio_seek(pb, wtv->index_entries[wtv->nb_index_entries - 1].pos, SEEK_SET);
- if (parse_chunks(s, SEEK_TO_PTS, ts, 0) < 0)
- return AVERROR(ERANGE);
- return 0;
- }
- wtv->pts = wtv->index_entries[i].timestamp;
- if (wtv->epoch != AV_NOPTS_VALUE)
- wtv->pts += wtv->epoch;
- wtv->last_valid_pts = wtv->pts;
- avio_seek(pb, wtv->index_entries[i].pos, SEEK_SET);
- return 0;
-}
-
-static int read_close(AVFormatContext *s)
-{
- WtvContext *wtv = s->priv_data;
- wtvfile_close(wtv->pb);
- return 0;
-}
-
-AVInputFormat ff_wtv_demuxer = {
- .name = "wtv",
- .long_name = NULL_IF_CONFIG_SMALL("Windows Television (WTV)"),
- .priv_data_size = sizeof(WtvContext),
- .read_probe = read_probe,
- .read_header = read_header,
- .read_packet = read_packet,
- .read_seek = read_seek,
- .read_close = read_close,
- .flags = AVFMT_SHOW_IDS,
-};
diff --git a/libavformat/wtv.h b/libavformat/wtv.h
new file mode 100644
index 0000000000..7e4f243551
--- /dev/null
+++ b/libavformat/wtv.h
@@ -0,0 +1,55 @@
+/*
+ * Windows Television (WTV)
+ * Copyright (c) 2010-2011 Peter Ross <pross@xvid.org>
+ *
+ * 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_WTV_H
+#define AVFORMAT_WTV_H
+
+#include "riff.h"
+#include "asf.h"
+
+#define WTV_SECTOR_BITS 12
+#define WTV_SECTOR_SIZE (1 << WTV_SECTOR_BITS)
+#define WTV_BIGSECTOR_BITS 18
+#define WTV_PAD8(x) (((x) + 7) & ~7)
+
+extern const uint8_t ff_timeline_le16[16];
+extern const uint8_t ff_timeline_table_0_entries_Events_le16[62];
+extern const uint8_t ff_table_0_entries_legacy_attrib_le16[58];
+extern const uint8_t ff_table_0_entries_time_le16[40];
+
+extern const ff_asf_guid ff_dir_entry_guid;
+extern const ff_asf_guid ff_wtv_guid;
+extern const ff_asf_guid ff_timestamp_guid;
+extern const ff_asf_guid ff_data_guid;
+extern const ff_asf_guid ff_stream_guid;
+extern const ff_asf_guid ff_mediatype_audio;
+extern const ff_asf_guid ff_mediatype_video;
+extern const ff_asf_guid ff_format_none;
+extern const AVCodecGuid ff_video_guids[];
+
+extern const ff_asf_guid ff_DSATTRIB_TRANSPORT_PROPERTIES;
+extern const ff_asf_guid ff_metadata_guid;
+extern const ff_asf_guid ff_stream2_guid;
+extern const ff_asf_guid ff_mediasubtype_cpfilters_processed;
+extern const ff_asf_guid ff_format_cpfilters_processed;
+extern const ff_asf_guid ff_format_waveformatex;
+extern const ff_asf_guid ff_format_mpeg2_video;
+#endif /* AVFORMAT_WTV_H */
diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c
new file mode 100644
index 0000000000..88587c4b52
--- /dev/null
+++ b/libavformat/wtvdec.c
@@ -0,0 +1,1038 @@
+/*
+ * Windows Television (WTV) demuxer
+ * Copyright (c) 2010-2011 Peter Ross <pross@xvid.org>
+ *
+ * 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
+ * Windows Television (WTV) demuxer
+ * @author Peter Ross <pross@xvid.org>
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "libavutil/intfloat_readwrite.h"
+#include "avformat.h"
+#include "internal.h"
+#include "wtv.h"
+#include "mpegts.h"
+#include <strings.h>
+
+/* Macros for formating GUIDs */
+#define PRI_PRETTY_GUID \
+ "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x"
+#define ARG_PRETTY_GUID(g) \
+ AV_RL32(g),AV_RL16(g+4),AV_RL16(g+6),g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]
+#define LEN_PRETTY_GUID 34
+
+/*
+ *
+ * File system routines
+ *
+ */
+
+typedef struct {
+ AVIOContext *pb_filesystem; /** file system (AVFormatContext->pb) */
+
+ int sector_bits; /** sector shift bits; used to convert sector number into pb_filesystem offset */
+ uint32_t *sectors; /** file allocation table */
+ int nb_sectors; /** number of sectors */
+
+ int error;
+ int64_t position;
+ int64_t length;
+} WtvFile;
+
+/**
+ * @return bytes read, 0 on end of file, or <0 on error
+ */
+static int wtvfile_read_packet(void *opaque, uint8_t *buf, int buf_size)
+{
+ WtvFile *wf = opaque;
+ AVIOContext *pb = wf->pb_filesystem;
+ int nread = 0;
+
+ if (wf->error || pb->error)
+ return -1;
+ if (wf->position >= wf->length || url_feof(pb))
+ return 0;
+
+ buf_size = FFMIN(buf_size, wf->length - wf->position);
+ while(nread < buf_size) {
+ int n;
+ int remaining_in_sector = (1 << wf->sector_bits) - (wf->position & ((1 << wf->sector_bits) - 1));
+ int read_request = FFMIN(buf_size - nread, remaining_in_sector);
+
+ n = avio_read(pb, buf, read_request);
+ if (n <= 0)
+ break;
+ nread += n;
+ buf += n;
+ wf->position += n;
+ if (n == remaining_in_sector) {
+ int i = wf->position >> wf->sector_bits;
+ if (i >= wf->nb_sectors ||
+ (wf->sectors[i] != wf->sectors[i - 1] + (1 << (wf->sector_bits - WTV_SECTOR_BITS)) &&
+ avio_seek(pb, (int64_t)wf->sectors[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)) {
+ wf->error = 1;
+ break;
+ }
+ }
+ }
+ return nread;
+}
+
+/**
+ * @return position (or file length)
+ */
+static int64_t wtvfile_seek(void *opaque, int64_t offset, int whence)
+{
+ WtvFile *wf = opaque;
+ AVIOContext *pb = wf->pb_filesystem;
+
+ if (whence == AVSEEK_SIZE)
+ return wf->length;
+ else if (whence == SEEK_CUR)
+ offset = wf->position + offset;
+ else if (whence == SEEK_END)
+ offset = wf->length;
+
+ wf->error = offset < 0 || offset >= wf->length ||
+ avio_seek(pb, ((int64_t)wf->sectors[offset >> wf->sector_bits] << WTV_SECTOR_BITS)
+ + (offset & ((1 << wf->sector_bits) - 1)), SEEK_SET) < 0;
+ wf->position = offset;
+ return offset;
+}
+
+/**
+ * read non-zero integers (le32) from input stream
+ * @param pb
+ * @param[out] data destination
+ * @param count maximum number of integers to read
+ * @return total number of integers read
+ */
+static int read_ints(AVIOContext *pb, uint32_t *data, int count)
+{
+ int i, total = 0;
+ for (i = 0; i < count; i++) {
+ if ((data[total] = avio_rl32(pb)))
+ total++;
+ }
+ return total;
+}
+
+/**
+ * Open file
+ * @param first_sector First sector
+ * @param length Length of file (bytes)
+ * @param depth File allocation table depth
+ * @return NULL on error
+ */
+static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int depth, AVFormatContext *s)
+{
+ AVIOContext *pb;
+ WtvFile *wf;
+ uint8_t *buffer;
+
+ if (avio_seek(s->pb, first_sector << WTV_SECTOR_BITS, SEEK_SET) < 0)
+ return NULL;
+
+ wf = av_mallocz(sizeof(WtvFile));
+ if (!wf)
+ return NULL;
+
+ if (depth == 0) {
+ wf->sectors = av_malloc(sizeof(uint32_t));
+ if (!wf->sectors) {
+ av_free(wf);
+ return NULL;
+ }
+ wf->sectors[0] = first_sector;
+ wf->nb_sectors = 1;
+ } else if (depth == 1) {
+ wf->sectors = av_malloc(WTV_SECTOR_SIZE);
+ if (!wf->sectors) {
+ av_free(wf);
+ return NULL;
+ }
+ wf->nb_sectors = read_ints(s->pb, wf->sectors, WTV_SECTOR_SIZE / 4);
+ } else if (depth == 2) {
+ uint32_t sectors1[WTV_SECTOR_SIZE / 4];
+ int nb_sectors1 = read_ints(s->pb, sectors1, WTV_SECTOR_SIZE / 4);
+ int i;
+
+ wf->sectors = av_malloc(nb_sectors1 << WTV_SECTOR_BITS);
+ if (!wf->sectors) {
+ av_free(wf);
+ return NULL;
+ }
+ wf->nb_sectors = 0;
+ for (i = 0; i < nb_sectors1; i++) {
+ if (avio_seek(s->pb, (int64_t)sectors1[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)
+ break;
+ wf->nb_sectors += read_ints(s->pb, wf->sectors + i * WTV_SECTOR_SIZE / 4, WTV_SECTOR_SIZE / 4);
+ }
+ } else {
+ av_log(s, AV_LOG_ERROR, "unsupported file allocation table depth (0x%x)\n", depth);
+ av_free(wf);
+ return NULL;
+ }
+ wf->sector_bits = length & (1ULL<<63) ? WTV_SECTOR_BITS : WTV_BIGSECTOR_BITS;
+
+ if (!wf->nb_sectors) {
+ av_free(wf->sectors);
+ av_free(wf);
+ return NULL;
+ }
+
+ /* check length */
+ length &= 0xFFFFFFFFFFFF;
+ if (length > ((int64_t)wf->nb_sectors << wf->sector_bits)) {
+ av_log(s, AV_LOG_WARNING, "reported file length (0x%"PRIx64") exceeds number of available sectors (0x%"PRIx64")\n", length, (int64_t)wf->nb_sectors << wf->sector_bits);
+ length = (int64_t)wf->nb_sectors << wf->sector_bits;
+ }
+ wf->length = length;
+
+ /* seek to intial sector */
+ wf->position = 0;
+ if (avio_seek(s->pb, (int64_t)wf->sectors[0] << WTV_SECTOR_BITS, SEEK_SET) < 0) {
+ av_free(wf->sectors);
+ av_free(wf);
+ return NULL;
+ }
+
+ wf->pb_filesystem = s->pb;
+ buffer = av_malloc(1 << wf->sector_bits);
+ if (!buffer) {
+ av_free(wf->sectors);
+ av_free(wf);
+ return NULL;
+ }
+
+ pb = avio_alloc_context(buffer, 1 << wf->sector_bits, 0, wf,
+ wtvfile_read_packet, NULL, wtvfile_seek);
+ if (!pb) {
+ av_free(buffer);
+ av_free(wf->sectors);
+ av_free(wf);
+ }
+ return pb;
+}
+
+/**
+ * Open file using filename
+ * @param[in] buf directory buffer
+ * @param buf_size directory buffer size
+ * @param[in] filename
+ * @param filename_size size of filename
+ * @return NULL on error
+ */
+static AVIOContext * wtvfile_open2(AVFormatContext *s, const uint8_t *buf, int buf_size, const uint8_t *filename, int filename_size)
+{
+ const uint8_t *buf_end = buf + buf_size;
+
+ while(buf + 48 <= buf_end) {
+ int dir_length, name_size, first_sector, depth;
+ uint64_t file_length;
+ const uint8_t *name;
+ if (ff_guidcmp(buf, ff_dir_entry_guid)) {
+ av_log(s, AV_LOG_ERROR, "unknown guid "FF_PRI_GUID", expected dir_entry_guid; "
+ "remaining directory entries ignored\n", FF_ARG_GUID(buf));
+ break;
+ }
+ dir_length = AV_RL16(buf + 16);
+ file_length = AV_RL64(buf + 24);
+ name_size = 2 * AV_RL32(buf + 32);
+ if (buf + 48 + name_size > buf_end) {
+ av_log(s, AV_LOG_ERROR, "filename exceeds buffer size; remaining directory entries ignored\n");
+ break;
+ }
+ first_sector = AV_RL32(buf + 40 + name_size);
+ depth = AV_RL32(buf + 44 + name_size);
+
+ /* compare file name; test optional null terminator */
+ name = buf + 40;
+ if (name_size >= filename_size &&
+ !memcmp(name, filename, filename_size) &&
+ (name_size < filename_size + 2 || !AV_RN16(name + filename_size)))
+ return wtvfile_open_sector(first_sector, file_length, depth, s);
+
+ buf += dir_length;
+ }
+ return 0;
+}
+
+#define wtvfile_open(s, buf, buf_size, filename) \
+ wtvfile_open2(s, buf, buf_size, filename, sizeof(filename))
+
+/**
+ * Close file opened with wtvfile_open_sector(), or wtv_open()
+ */
+static void wtvfile_close(AVIOContext *pb)
+{
+ WtvFile *wf = pb->opaque;
+ av_free(wf->sectors);
+ av_free(pb);
+}
+
+/*
+ *
+ * Main demuxer
+ *
+ */
+
+typedef struct {
+ int seen_data;
+} WtvStream;
+
+typedef struct {
+ AVIOContext *pb; /** timeline file */
+ int64_t epoch;
+ int64_t pts; /** pts for next data chunk */
+ int64_t last_valid_pts; /** latest valid pts, used for interative seeking */
+
+ /* maintain private seek index, as the AVIndexEntry->pos is relative to the
+ start of the 'timeline' file, not the file system (AVFormatContext->pb) */
+ AVIndexEntry *index_entries;
+ int nb_index_entries;
+ unsigned int index_entries_allocated_size;
+} WtvContext;
+
+/* WTV GUIDs */
+static const ff_asf_guid EVENTID_SubtitleSpanningEvent =
+ {0x48,0xC0,0xCE,0x5D,0xB9,0xD0,0x63,0x41,0x87,0x2C,0x4F,0x32,0x22,0x3B,0xE8,0x8A};
+static const ff_asf_guid EVENTID_LanguageSpanningEvent =
+ {0x6D,0x66,0x92,0xE2,0x02,0x9C,0x8D,0x44,0xAA,0x8D,0x78,0x1A,0x93,0xFD,0xC3,0x95};
+static const ff_asf_guid EVENTID_AudioDescriptorSpanningEvent =
+ {0x1C,0xD4,0x7B,0x10,0xDA,0xA6,0x91,0x46,0x83,0x69,0x11,0xB2,0xCD,0xAA,0x28,0x8E};
+static const ff_asf_guid EVENTID_CtxADescriptorSpanningEvent =
+ {0xE6,0xA2,0xB4,0x3A,0x47,0x42,0x34,0x4B,0x89,0x6C,0x30,0xAF,0xA5,0xD2,0x1C,0x24};
+static const ff_asf_guid EVENTID_CSDescriptorSpanningEvent =
+ {0xD9,0x79,0xE7,0xEf,0xF0,0x97,0x86,0x47,0x80,0x0D,0x95,0xCF,0x50,0x5D,0xDC,0x66};
+static const ff_asf_guid EVENTID_DVBScramblingControlSpanningEvent =
+ {0xC4,0xE1,0xD4,0x4B,0xA1,0x90,0x09,0x41,0x82,0x36,0x27,0xF0,0x0E,0x7D,0xCC,0x5B};
+static const ff_asf_guid EVENTID_StreamIDSpanningEvent =
+ {0x68,0xAB,0xF1,0xCA,0x53,0xE1,0x41,0x4D,0xA6,0xB3,0xA7,0xC9,0x98,0xDB,0x75,0xEE};
+static const ff_asf_guid EVENTID_TeletextSpanningEvent =
+ {0x50,0xD9,0x99,0x95,0x33,0x5F,0x17,0x46,0xAF,0x7C,0x1E,0x54,0xB5,0x10,0xDA,0xA3};
+static const ff_asf_guid EVENTID_AudioTypeSpanningEvent =
+ {0xBE,0xBF,0x1C,0x50,0x49,0xB8,0xCE,0x42,0x9B,0xE9,0x3D,0xB8,0x69,0xFB,0x82,0xB3};
+
+/* Windows media GUIDs */
+
+/* Media types */
+static const ff_asf_guid mediasubtype_mpeg1payload =
+ {0x81,0xEB,0x36,0xE4,0x4F,0x52,0xCE,0x11,0x9F,0x53,0x00,0x20,0xAF,0x0B,0xA7,0x70};
+static const ff_asf_guid mediatype_mpeg2_sections =
+ {0x6C,0x17,0x5F,0x45,0x06,0x4B,0xCE,0x47,0x9A,0xEF,0x8C,0xAE,0xF7,0x3D,0xF7,0xB5};
+static const ff_asf_guid mediatype_mpeg2_pes =
+ {0x20,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA};
+static const ff_asf_guid mediatype_mstvcaption =
+ {0x89,0x8A,0x8B,0xB8,0x49,0xB0,0x80,0x4C,0xAD,0xCF,0x58,0x98,0x98,0x5E,0x22,0xC1};
+
+/* Media subtypes */
+static const ff_asf_guid mediasubtype_dvb_subtitle =
+ {0xC3,0xCB,0xFF,0x34,0xB3,0xD5,0x71,0x41,0x90,0x02,0xD4,0xC6,0x03,0x01,0x69,0x7F};
+static const ff_asf_guid mediasubtype_teletext =
+ {0xE3,0x76,0x2A,0xF7,0x0A,0xEB,0xD0,0x11,0xAC,0xE4,0x00,0x00,0xC0,0xCC,0x16,0xBA};
+static const ff_asf_guid mediasubtype_dtvccdata =
+ {0xAA,0xDD,0x2A,0xF5,0xF0,0x36,0xF5,0x43,0x95,0xEA,0x6D,0x86,0x64,0x84,0x26,0x2A};
+static const ff_asf_guid mediasubtype_mpeg2_sections =
+ {0x79,0x85,0x9F,0x4A,0xF8,0x6B,0x92,0x43,0x8A,0x6D,0xD2,0xDD,0x09,0xFA,0x78,0x61};
+
+/* Formats */
+static const ff_asf_guid format_videoinfo2 =
+ {0xA0,0x76,0x2A,0xF7,0x0A,0xEB,0xD0,0x11,0xAC,0xE4,0x00,0x00,0xC0,0xCC,0x16,0xBA};
+
+static int read_probe(AVProbeData *p)
+{
+ return ff_guidcmp(p->buf, ff_wtv_guid) ? 0 : AVPROBE_SCORE_MAX;
+}
+
+/**
+ * Convert win32 FILETIME to ISO-8601 string
+ */
+static void filetime_to_iso8601(char *buf, int buf_size, int64_t value)
+{
+ time_t t = (value / 10000000LL) - 11644473600LL;
+ strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
+}
+
+/**
+ * Convert crazy time (100ns since 1 Jan 0001) to ISO-8601 string
+ */
+static void crazytime_to_iso8601(char *buf, int buf_size, int64_t value)
+{
+ time_t t = (value / 10000000LL) - 719162LL*86400LL;
+ strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
+}
+
+/**
+ * Convert OLE DATE to ISO-8601 string
+ * @return <0 on error
+ */
+static int oledate_to_iso8601(char *buf, int buf_size, int64_t value)
+{
+ time_t t = (av_int2dbl(value) - 25569.0) * 86400;
+ struct tm *result= gmtime(&t);
+ if (!result)
+ return -1;
+ strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", result);
+ return 0;
+}
+
+static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length)
+{
+ char mime[1024];
+ char description[1024];
+ unsigned int filesize;
+ AVStream *st;
+ int64_t pos = avio_tell(pb);
+
+ avio_get_str16le(pb, INT_MAX, mime, sizeof(mime));
+ if (strcmp(mime, "image/jpeg"))
+ goto done;
+
+ avio_r8(pb);
+ avio_get_str16le(pb, INT_MAX, description, sizeof(description));
+ filesize = avio_rl32(pb);
+ if (!filesize)
+ goto done;
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ goto done;
+ av_dict_set(&st->metadata, "title", description, 0);
+ st->codec->codec_id = CODEC_ID_MJPEG;
+ st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
+ st->codec->extradata = av_mallocz(filesize);
+ if (!st->codec->extradata)
+ goto done;
+ st->codec->extradata_size = filesize;
+ avio_read(pb, st->codec->extradata, filesize);
+done:
+ avio_seek(pb, pos + length, SEEK_SET);
+}
+
+static void get_tag(AVFormatContext *s, AVIOContext *pb, const char *key, int type, int length)
+{
+ int buf_size = FFMAX(2*length, LEN_PRETTY_GUID) + 1;
+ char *buf = av_malloc(buf_size);
+ if (!buf)
+ return;
+
+ if (type == 0 && length == 4) {
+ snprintf(buf, buf_size, "%"PRIi32, avio_rl32(pb));
+ } else if (type == 1) {
+ avio_get_str16le(pb, length, buf, buf_size);
+ if (!strlen(buf)) {
+ av_free(buf);
+ return;
+ }
+ } else if (type == 3 && length == 4) {
+ strcpy(buf, avio_rl32(pb) ? "true" : "false");
+ } else if (type == 4 && length == 8) {
+ int64_t num = avio_rl64(pb);
+ if (!strcmp(key, "WM/EncodingTime") ||
+ !strcmp(key, "WM/MediaOriginalBroadcastDateTime"))
+ filetime_to_iso8601(buf, buf_size, num);
+ else if (!strcmp(key, "WM/WMRVEncodeTime") ||
+ !strcmp(key, "WM/WMRVEndTime"))
+ crazytime_to_iso8601(buf, buf_size, num);
+ else if (!strcmp(key, "WM/WMRVExpirationDate")) {
+ if (oledate_to_iso8601(buf, buf_size, num) < 0 ) {
+ av_free(buf);
+ return;
+ }
+ } else if (!strcmp(key, "WM/WMRVBitrate"))
+ snprintf(buf, buf_size, "%f", av_int2dbl(num));
+ else
+ snprintf(buf, buf_size, "%"PRIi64, num);
+ } else if (type == 5 && length == 2) {
+ snprintf(buf, buf_size, "%"PRIi16, avio_rl16(pb));
+ } else if (type == 6 && length == 16) {
+ ff_asf_guid guid;
+ avio_read(pb, guid, 16);
+ snprintf(buf, buf_size, PRI_PRETTY_GUID, ARG_PRETTY_GUID(guid));
+ } else if (type == 2 && !strcmp(key, "WM/Picture")) {
+ get_attachment(s, pb, length);
+ av_freep(&buf);
+ return;
+ } else {
+ av_freep(&buf);
+ av_log(s, AV_LOG_WARNING, "unsupported metadata entry; key:%s, type:%d, length:0x%x\n", key, type, length);
+ avio_skip(pb, length);
+ return;
+ }
+
+ av_dict_set(&s->metadata, key, buf, 0);
+ av_freep(&buf);
+}
+
+/**
+ * Parse metadata entries
+ */
+static void parse_legacy_attrib(AVFormatContext *s, AVIOContext *pb)
+{
+ ff_asf_guid guid;
+ int length, type;
+ while(!url_feof(pb)) {
+ char key[1024];
+ ff_get_guid(pb, &guid);
+ type = avio_rl32(pb);
+ length = avio_rl32(pb);
+ if (!length)
+ break;
+ if (ff_guidcmp(&guid, ff_metadata_guid)) {
+ av_log(s, AV_LOG_WARNING, "unknown guid "FF_PRI_GUID", expected metadata_guid; "
+ "remaining metadata entries ignored\n", FF_ARG_GUID(guid));
+ break;
+ }
+ avio_get_str16le(pb, INT_MAX, key, sizeof(key));
+ get_tag(s, pb, key, type, length);
+ }
+
+ ff_metadata_conv(&s->metadata, NULL, ff_asf_metadata_conv);
+}
+
+/**
+ * parse VIDEOINFOHEADER2 structure
+ * @return bytes consumed
+ */
+static int parse_videoinfoheader2(AVFormatContext *s, AVStream *st)
+{
+ WtvContext *wtv = s->priv_data;
+ AVIOContext *pb = wtv->pb;
+
+ avio_skip(pb, 72); // picture aspect ratio is unreliable
+ ff_get_bmp_header(pb, st);
+
+ return 72 + 40;
+}
+
+/**
+ * Parse MPEG1WAVEFORMATEX extradata structure
+ */
+static void parse_mpeg1waveformatex(AVStream *st)
+{
+ /* fwHeadLayer */
+ switch (AV_RL16(st->codec->extradata)) {
+ case 0x0001 : st->codec->codec_id = CODEC_ID_MP1; break;
+ case 0x0002 : st->codec->codec_id = CODEC_ID_MP2; break;
+ case 0x0004 : st->codec->codec_id = CODEC_ID_MP3; break;
+ }
+
+ st->codec->bit_rate = AV_RL32(st->codec->extradata + 2); /* dwHeadBitrate */
+
+ /* dwHeadMode */
+ switch (AV_RL16(st->codec->extradata + 6)) {
+ case 1 : case 2 : case 4 : st->codec->channels = 2; break;
+ case 8 : st->codec->channels = 1; break;
+ }
+}
+
+/**
+ * Initialise stream
+ * @param st Stream to initialise, or NULL to create and initialise new stream
+ * @return NULL on error
+ */
+static AVStream * new_stream(AVFormatContext *s, AVStream *st, int sid, int codec_type)
+{
+ if (st) {
+ if (st->codec->extradata) {
+ av_freep(&st->codec->extradata);
+ st->codec->extradata_size = 0;
+ }
+ } else {
+ WtvStream *wst = av_mallocz(sizeof(WtvStream));
+ if (!wst)
+ return NULL;
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return NULL;
+ st->id = sid;
+ st->priv_data = wst;
+ }
+ st->codec->codec_type = codec_type;
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+ av_set_pts_info(st, 64, 1, 10000000);
+ return st;
+}
+
+/**
+ * parse Media Type structure and populate stream
+ * @param st Stream, or NULL to create new stream
+ * @param mediatype Mediatype GUID
+ * @param subtype Subtype GUID
+ * @param formattype Format GUID
+ * @param size Size of format buffer
+ * @return NULL on error
+ */
+static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid,
+ ff_asf_guid mediatype, ff_asf_guid subtype,
+ ff_asf_guid formattype, int size)
+{
+ WtvContext *wtv = s->priv_data;
+ AVIOContext *pb = wtv->pb;
+ if (!ff_guidcmp(subtype, ff_mediasubtype_cpfilters_processed) &&
+ !ff_guidcmp(formattype, ff_format_cpfilters_processed)) {
+ ff_asf_guid actual_subtype;
+ ff_asf_guid actual_formattype;
+
+ if (size < 32) {
+ av_log(s, AV_LOG_WARNING, "format buffer size underflow\n");
+ avio_skip(pb, size);
+ return NULL;
+ }
+
+ avio_skip(pb, size - 32);
+ ff_get_guid(pb, &actual_subtype);
+ ff_get_guid(pb, &actual_formattype);
+ avio_seek(pb, -size, SEEK_CUR);
+
+ st = parse_media_type(s, st, sid, mediatype, actual_subtype, actual_formattype, size - 32);
+ avio_skip(pb, 32);
+ return st;
+ } else if (!ff_guidcmp(mediatype, ff_mediatype_audio)) {
+ st = new_stream(s, st, sid, AVMEDIA_TYPE_AUDIO);
+ if (!st)
+ return NULL;
+ if (!ff_guidcmp(formattype, ff_format_waveformatex)) {
+ int ret = ff_get_wav_header(pb, st->codec, size);
+ if (ret < 0)
+ return NULL;
+ } else {
+ if (ff_guidcmp(formattype, ff_format_none))
+ av_log(s, AV_LOG_WARNING, "unknown formattype:"FF_PRI_GUID"\n", FF_ARG_GUID(formattype));
+ avio_skip(pb, size);
+ }
+
+ if (!memcmp(subtype + 4, (const uint8_t[]){FF_MEDIASUBTYPE_BASE_GUID}, 12)) {
+ st->codec->codec_id = ff_wav_codec_get_id(AV_RL32(subtype), st->codec->bits_per_coded_sample);
+ } else if (!ff_guidcmp(subtype, mediasubtype_mpeg1payload)) {
+ if (st->codec->extradata && st->codec->extradata_size >= 22)
+ parse_mpeg1waveformatex(st);
+ else
+ av_log(s, AV_LOG_WARNING, "MPEG1WAVEFORMATEX underflow\n");
+ } else {
+ st->codec->codec_id = ff_codec_guid_get_id(ff_codec_wav_guids, subtype);
+ if (st->codec->codec_id == CODEC_ID_NONE)
+ av_log(s, AV_LOG_WARNING, "unknown subtype:"FF_PRI_GUID"\n", FF_ARG_GUID(subtype));
+ }
+ return st;
+ } else if (!ff_guidcmp(mediatype, ff_mediatype_video)) {
+ st = new_stream(s, st, sid, AVMEDIA_TYPE_VIDEO);
+ if (!st)
+ return NULL;
+ if (!ff_guidcmp(formattype, format_videoinfo2)) {
+ int consumed = parse_videoinfoheader2(s, st);
+ avio_skip(pb, FFMAX(size - consumed, 0));
+ } else if (!ff_guidcmp(formattype, ff_format_mpeg2_video)) {
+ int consumed = parse_videoinfoheader2(s, st);
+ avio_skip(pb, FFMAX(size - consumed, 0));
+ } else {
+ if (ff_guidcmp(formattype, ff_format_none))
+ av_log(s, AV_LOG_WARNING, "unknown formattype:"FF_PRI_GUID"\n", FF_ARG_GUID(formattype));
+ avio_skip(pb, size);
+ }
+
+ if (!memcmp(subtype + 4, (const uint8_t[]){FF_MEDIASUBTYPE_BASE_GUID}, 12)) {
+ st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, AV_RL32(subtype));
+ } else {
+ st->codec->codec_id = ff_codec_guid_get_id(ff_video_guids, subtype);
+ }
+ if (st->codec->codec_id == CODEC_ID_NONE)
+ av_log(s, AV_LOG_WARNING, "unknown subtype:"FF_PRI_GUID"\n", FF_ARG_GUID(subtype));
+ return st;
+ } else if (!ff_guidcmp(mediatype, mediatype_mpeg2_pes) &&
+ !ff_guidcmp(subtype, mediasubtype_dvb_subtitle)) {
+ st = new_stream(s, st, sid, AVMEDIA_TYPE_SUBTITLE);
+ if (!st)
+ return NULL;
+ if (ff_guidcmp(formattype, ff_format_none))
+ av_log(s, AV_LOG_WARNING, "unknown formattype:"FF_PRI_GUID"\n", FF_ARG_GUID(formattype));
+ avio_skip(pb, size);
+ st->codec->codec_id = CODEC_ID_DVB_SUBTITLE;
+ return st;
+ } else if (!ff_guidcmp(mediatype, mediatype_mstvcaption) &&
+ (!ff_guidcmp(subtype, mediasubtype_teletext) || !ff_guidcmp(subtype, mediasubtype_dtvccdata))) {
+ st = new_stream(s, st, sid, AVMEDIA_TYPE_SUBTITLE);
+ if (!st)
+ return NULL;
+ if (ff_guidcmp(formattype, ff_format_none))
+ av_log(s, AV_LOG_WARNING, "unknown formattype:"FF_PRI_GUID"\n", FF_ARG_GUID(formattype));
+ avio_skip(pb, size);
+ st->codec->codec_id = CODEC_ID_DVB_TELETEXT;
+ return st;
+ } else if (!ff_guidcmp(mediatype, mediatype_mpeg2_sections) &&
+ !ff_guidcmp(subtype, mediasubtype_mpeg2_sections)) {
+ if (ff_guidcmp(formattype, ff_format_none))
+ av_log(s, AV_LOG_WARNING, "unknown formattype:"FF_PRI_GUID"\n", FF_ARG_GUID(formattype));
+ avio_skip(pb, size);
+ return NULL;
+ }
+
+ av_log(s, AV_LOG_WARNING, "unknown media type, mediatype:"FF_PRI_GUID
+ ", subtype:"FF_PRI_GUID", formattype:"FF_PRI_GUID"\n",
+ FF_ARG_GUID(mediatype), FF_ARG_GUID(subtype), FF_ARG_GUID(formattype));
+ avio_skip(pb, size);
+ return NULL;
+}
+
+enum {
+ SEEK_TO_DATA = 0,
+ SEEK_TO_PTS,
+};
+
+/**
+ * Parse WTV chunks
+ * @param mode SEEK_TO_DATA or SEEK_TO_PTS
+ * @param seekts timestamp
+ * @param[out] len_ptr Length of data chunk
+ * @return stream index of data chunk, or <0 on error
+ */
+static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_ptr)
+{
+ WtvContext *wtv = s->priv_data;
+ AVIOContext *pb = wtv->pb;
+ while (!url_feof(pb)) {
+ ff_asf_guid g;
+ int len, sid, consumed;
+
+ ff_get_guid(pb, &g);
+ len = avio_rl32(pb);
+ if (len < 32)
+ break;
+ sid = avio_rl32(pb) & 0x7FFF;
+ avio_skip(pb, 8);
+ consumed = 32;
+
+ if (!ff_guidcmp(g, ff_stream_guid)) {
+ if (ff_find_stream_index(s, sid) < 0) {
+ ff_asf_guid mediatype, subtype, formattype;
+ int size;
+ avio_skip(pb, 28);
+ ff_get_guid(pb, &mediatype);
+ ff_get_guid(pb, &subtype);
+ avio_skip(pb, 12);
+ ff_get_guid(pb, &formattype);
+ size = avio_rl32(pb);
+ parse_media_type(s, 0, sid, mediatype, subtype, formattype, size);
+ consumed += 92 + size;
+ }
+ } else if (!ff_guidcmp(g, ff_stream2_guid)) {
+ int stream_index = ff_find_stream_index(s, sid);
+ if (stream_index >= 0 && !((WtvStream*)s->streams[stream_index]->priv_data)->seen_data) {
+ ff_asf_guid mediatype, subtype, formattype;
+ int size;
+ avio_skip(pb, 12);
+ ff_get_guid(pb, &mediatype);
+ ff_get_guid(pb, &subtype);
+ avio_skip(pb, 12);
+ ff_get_guid(pb, &formattype);
+ size = avio_rl32(pb);
+ parse_media_type(s, s->streams[stream_index], sid, mediatype, subtype, formattype, size);
+ consumed += 76 + size;
+ }
+ } else if (!ff_guidcmp(g, EVENTID_AudioDescriptorSpanningEvent) ||
+ !ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) ||
+ !ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent) ||
+ !ff_guidcmp(g, EVENTID_StreamIDSpanningEvent) ||
+ !ff_guidcmp(g, EVENTID_SubtitleSpanningEvent) ||
+ !ff_guidcmp(g, EVENTID_TeletextSpanningEvent)) {
+ int stream_index = ff_find_stream_index(s, sid);
+ if (stream_index >= 0) {
+ AVStream *st = s->streams[stream_index];
+ uint8_t buf[258];
+ const uint8_t *pbuf = buf;
+ int buf_size;
+
+ avio_skip(pb, 8);
+ consumed += 8;
+ if (!ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) ||
+ !ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent)) {
+ avio_skip(pb, 6);
+ consumed += 6;
+ }
+
+ buf_size = FFMIN(len - consumed, sizeof(buf));
+ avio_read(pb, buf, buf_size);
+ consumed += buf_size;
+ ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, 0, 0, 0, 0);
+ }
+ } else if (!ff_guidcmp(g, EVENTID_AudioTypeSpanningEvent)) {
+ int stream_index = ff_find_stream_index(s, sid);
+ if (stream_index >= 0) {
+ AVStream *st = s->streams[stream_index];
+ int audio_type;
+ avio_skip(pb, 8);
+ audio_type = avio_r8(pb);
+ if (audio_type == 2)
+ st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED;
+ else if (audio_type == 3)
+ st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
+ consumed += 9;
+ }
+ } else if (!ff_guidcmp(g, EVENTID_DVBScramblingControlSpanningEvent)) {
+ int stream_index = ff_find_stream_index(s, sid);
+ if (stream_index >= 0) {
+ avio_skip(pb, 12);
+ if (avio_rl32(pb))
+ av_log(s, AV_LOG_WARNING, "DVB scrambled stream detected (st:%d), decoding will likely fail\n", stream_index);
+ consumed += 16;
+ }
+ } else if (!ff_guidcmp(g, EVENTID_LanguageSpanningEvent)) {
+ int stream_index = ff_find_stream_index(s, sid);
+ if (stream_index >= 0) {
+ AVStream *st = s->streams[stream_index];
+ uint8_t language[4];
+ avio_skip(pb, 12);
+ avio_read(pb, language, 3);
+ if (language[0]) {
+ language[3] = 0;
+ av_dict_set(&st->metadata, "language", language, 0);
+ if (!strcmp(language, "nar") || !strcmp(language, "NAR"))
+ st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
+ }
+ consumed += 15;
+ }
+ } else if (!ff_guidcmp(g, ff_timestamp_guid)) {
+ int stream_index = ff_find_stream_index(s, sid);
+ if (stream_index >= 0) {
+ avio_skip(pb, 8);
+ wtv->pts = avio_rl64(pb);
+ consumed += 16;
+ if (wtv->pts == -1)
+ wtv->pts = AV_NOPTS_VALUE;
+ else {
+ wtv->last_valid_pts = wtv->pts;
+ if (wtv->epoch == AV_NOPTS_VALUE || wtv->pts < wtv->epoch)
+ wtv->epoch = wtv->pts;
+ if (mode == SEEK_TO_PTS && wtv->pts >= seekts) {
+ avio_skip(pb, WTV_PAD8(len) - consumed);
+ return 0;
+ }
+ }
+ }
+ } else if (!ff_guidcmp(g, ff_data_guid)) {
+ int stream_index = ff_find_stream_index(s, sid);
+ if (mode == SEEK_TO_DATA && stream_index >= 0 && len > 32) {
+ WtvStream *wst = s->streams[stream_index]->priv_data;
+ wst->seen_data = 1;
+ if (len_ptr) {
+ *len_ptr = len;
+ }
+ return stream_index;
+ }
+ } else if (
+ !ff_guidcmp(g, /* DSATTRIB_CAPTURE_STREAMTIME */ (const ff_asf_guid){0x14,0x56,0x1A,0x0C,0xCD,0x30,0x40,0x4F,0xBC,0xBF,0xD0,0x3E,0x52,0x30,0x62,0x07}) ||
+ !ff_guidcmp(g, /* DSATTRIB_PicSampleSeq */ (const ff_asf_guid){0x02,0xAE,0x5B,0x2F,0x8F,0x7B,0x60,0x4F,0x82,0xD6,0xE4,0xEA,0x2F,0x1F,0x4C,0x99}) ||
+ !ff_guidcmp(g, /* DSATTRIB_TRANSPORT_PROPERTIES */ ff_DSATTRIB_TRANSPORT_PROPERTIES) ||
+ !ff_guidcmp(g, /* dvr_ms_vid_frame_rep_data */ (const ff_asf_guid){0xCC,0x32,0x64,0xDD,0x29,0xE2,0xDB,0x40,0x80,0xF6,0xD2,0x63,0x28,0xD2,0x76,0x1F}) ||
+ !ff_guidcmp(g, /* EVENTID_ChannelChangeSpanningEvent */ (const ff_asf_guid){0xE5,0xC5,0x67,0x90,0x5C,0x4C,0x05,0x42,0x86,0xC8,0x7A,0xFE,0x20,0xFE,0x1E,0xFA}) ||
+ !ff_guidcmp(g, /* EVENTID_ChannelInfoSpanningEvent */ (const ff_asf_guid){0x80,0x6D,0xF3,0x41,0x32,0x41,0xC2,0x4C,0xB1,0x21,0x01,0xA4,0x32,0x19,0xD8,0x1B}) ||
+ !ff_guidcmp(g, /* EVENTID_ChannelTypeSpanningEvent */ (const ff_asf_guid){0x51,0x1D,0xAB,0x72,0xD2,0x87,0x9B,0x48,0xBA,0x11,0x0E,0x08,0xDC,0x21,0x02,0x43}) ||
+ !ff_guidcmp(g, /* EVENTID_PIDListSpanningEvent */ (const ff_asf_guid){0x65,0x8F,0xFC,0x47,0xBB,0xE2,0x34,0x46,0x9C,0xEF,0xFD,0xBF,0xE6,0x26,0x1D,0x5C}) ||
+ !ff_guidcmp(g, /* EVENTID_SignalAndServiceStatusSpanningEvent */ (const ff_asf_guid){0xCB,0xC5,0x68,0x80,0x04,0x3C,0x2B,0x49,0xB4,0x7D,0x03,0x08,0x82,0x0D,0xCE,0x51}) ||
+ !ff_guidcmp(g, /* EVENTID_StreamTypeSpanningEvent */ (const ff_asf_guid){0xBC,0x2E,0xAF,0x82,0xA6,0x30,0x64,0x42,0xA8,0x0B,0xAD,0x2E,0x13,0x72,0xAC,0x60}) ||
+ !ff_guidcmp(g, (const ff_asf_guid){0x1E,0xBE,0xC3,0xC5,0x43,0x92,0xDC,0x11,0x85,0xE5,0x00,0x12,0x3F,0x6F,0x73,0xB9}) ||
+ !ff_guidcmp(g, (const ff_asf_guid){0x3B,0x86,0xA2,0xB1,0xEB,0x1E,0xC3,0x44,0x8C,0x88,0x1C,0xA3,0xFF,0xE3,0xE7,0x6A}) ||
+ !ff_guidcmp(g, (const ff_asf_guid){0x4E,0x7F,0x4C,0x5B,0xC4,0xD0,0x38,0x4B,0xA8,0x3E,0x21,0x7F,0x7B,0xBF,0x52,0xE7}) ||
+ !ff_guidcmp(g, (const ff_asf_guid){0x63,0x36,0xEB,0xFE,0xA1,0x7E,0xD9,0x11,0x83,0x08,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
+ !ff_guidcmp(g, (const ff_asf_guid){0x70,0xE9,0xF1,0xF8,0x89,0xA4,0x4C,0x4D,0x83,0x73,0xB8,0x12,0xE0,0xD5,0xF8,0x1E}) ||
+ !ff_guidcmp(g, (const ff_asf_guid){0x96,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
+ !ff_guidcmp(g, (const ff_asf_guid){0x97,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
+ !ff_guidcmp(g, (const ff_asf_guid){0xA1,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D})) {
+ //ignore known guids
+ } else
+ av_log(s, AV_LOG_WARNING, "unsupported chunk:"FF_PRI_GUID"\n", FF_ARG_GUID(g));
+
+ avio_skip(pb, WTV_PAD8(len) - consumed);
+ }
+ return AVERROR_EOF;
+}
+
+static int read_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+ WtvContext *wtv = s->priv_data;
+ int root_sector, root_size;
+ uint8_t root[WTV_SECTOR_SIZE];
+ AVIOContext *pb;
+ int64_t timeline_pos;
+ int ret;
+
+ wtv->epoch =
+ wtv->pts =
+ wtv->last_valid_pts = AV_NOPTS_VALUE;
+
+ /* read root directory sector */
+ avio_skip(s->pb, 0x30);
+ root_size = avio_rl32(s->pb);
+ if (root_size > sizeof(root)) {
+ av_log(s, AV_LOG_ERROR, "root directory size exceeds sector size\n");
+ return AVERROR_INVALIDDATA;
+ }
+ avio_skip(s->pb, 4);
+ root_sector = avio_rl32(s->pb);
+
+ avio_seek(s->pb, root_sector << WTV_SECTOR_BITS, SEEK_SET);
+ root_size = avio_read(s->pb, root, root_size);
+ if (root_size < 0)
+ return AVERROR_INVALIDDATA;
+
+ /* parse chunks up until first data chunk */
+ wtv->pb = wtvfile_open(s, root, root_size, ff_timeline_le16);
+ if (!wtv->pb) {
+ av_log(s, AV_LOG_ERROR, "timeline data missing\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ ret = parse_chunks(s, SEEK_TO_DATA, 0, 0);
+ if (ret < 0)
+ return ret;
+ avio_seek(wtv->pb, -32, SEEK_CUR);
+
+ timeline_pos = avio_tell(s->pb); // save before opening another file
+
+ /* read metadata */
+ pb = wtvfile_open(s, root, root_size, ff_table_0_entries_legacy_attrib_le16);
+ if (pb) {
+ parse_legacy_attrib(s, pb);
+ wtvfile_close(pb);
+ }
+
+ /* read seek index */
+ if (s->nb_streams) {
+ AVStream *st = s->streams[0];
+ pb = wtvfile_open(s, root, root_size, ff_table_0_entries_time_le16);
+ if (pb) {
+ while(1) {
+ uint64_t timestamp = avio_rl64(pb);
+ uint64_t frame_nb = avio_rl64(pb);
+ if (url_feof(pb))
+ break;
+ ff_add_index_entry(&wtv->index_entries, &wtv->nb_index_entries, &wtv->index_entries_allocated_size,
+ 0, timestamp, frame_nb, 0, AVINDEX_KEYFRAME);
+ }
+ wtvfile_close(pb);
+
+ if (wtv->nb_index_entries) {
+ pb = wtvfile_open(s, root, root_size, ff_timeline_table_0_entries_Events_le16);
+ if (pb) {
+ int i;
+ while (1) {
+ uint64_t frame_nb = avio_rl64(pb);
+ uint64_t position = avio_rl64(pb);
+ if (url_feof(pb))
+ break;
+ for (i = wtv->nb_index_entries - 1; i >= 0; i--) {
+ AVIndexEntry *e = wtv->index_entries + i;
+ if (frame_nb > e->size)
+ break;
+ if (position > e->pos)
+ e->pos = position;
+ }
+ }
+ wtvfile_close(pb);
+ st->duration = wtv->index_entries[wtv->nb_index_entries - 1].timestamp;
+ }
+ }
+ }
+ }
+
+ avio_seek(s->pb, timeline_pos, SEEK_SET);
+ return 0;
+}
+
+static int read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ WtvContext *wtv = s->priv_data;
+ AVIOContext *pb = wtv->pb;
+ int stream_index, len, ret;
+
+ stream_index = parse_chunks(s, SEEK_TO_DATA, 0, &len);
+ if (stream_index < 0)
+ return stream_index;
+
+ ret = av_get_packet(pb, pkt, len - 32);
+ if (ret < 0)
+ return ret;
+ pkt->stream_index = stream_index;
+ pkt->pts = wtv->pts;
+ avio_skip(pb, WTV_PAD8(len) - len);
+ return 0;
+}
+
+static int read_seek(AVFormatContext *s, int stream_index,
+ int64_t ts, int flags)
+{
+ WtvContext *wtv = s->priv_data;
+ AVIOContext *pb = wtv->pb;
+ AVStream *st = s->streams[0];
+ int64_t ts_relative;
+ int i;
+
+ if ((flags & AVSEEK_FLAG_FRAME) || (flags & AVSEEK_FLAG_BYTE))
+ return AVERROR(ENOSYS);
+
+ /* timestamp adjustment is required because wtv->pts values are absolute,
+ * whereas AVIndexEntry->timestamp values are relative to epoch. */
+ ts_relative = ts;
+ if (wtv->epoch != AV_NOPTS_VALUE)
+ ts_relative -= wtv->epoch;
+
+ i = ff_index_search_timestamp(wtv->index_entries, wtv->nb_index_entries, ts_relative, flags);
+ if (i < 0) {
+ if (wtv->last_valid_pts == AV_NOPTS_VALUE || ts < wtv->last_valid_pts) {
+ if (avio_seek(pb, 0, SEEK_SET) < 0)
+ return -1;
+ } else if (st->duration != AV_NOPTS_VALUE && ts_relative > st->duration && wtv->nb_index_entries) {
+ if (avio_seek(pb, wtv->index_entries[wtv->nb_index_entries - 1].pos, SEEK_SET) < 0)
+ return -1;
+ }
+ if (parse_chunks(s, SEEK_TO_PTS, ts, 0) < 0)
+ return AVERROR(ERANGE);
+ return 0;
+ }
+ if (avio_seek(pb, wtv->index_entries[i].pos, SEEK_SET) < 0)
+ return -1;
+ wtv->pts = wtv->index_entries[i].timestamp;
+ if (wtv->epoch != AV_NOPTS_VALUE)
+ wtv->pts += wtv->epoch;
+ wtv->last_valid_pts = wtv->pts;
+ return 0;
+}
+
+static int read_close(AVFormatContext *s)
+{
+ WtvContext *wtv = s->priv_data;
+ wtvfile_close(wtv->pb);
+ return 0;
+}
+
+AVInputFormat ff_wtv_demuxer = {
+ .name = "wtv",
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Television (WTV)"),
+ .priv_data_size = sizeof(WtvContext),
+ .read_probe = read_probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
+ .read_seek = read_seek,
+ .read_close = read_close,
+ .flags = AVFMT_SHOW_IDS,
+};
diff --git a/libavformat/wtvenc.c b/libavformat/wtvenc.c
new file mode 100644
index 0000000000..b571833920
--- /dev/null
+++ b/libavformat/wtvenc.c
@@ -0,0 +1,722 @@
+/*
+ * Windows Television (WTV) muxer
+ * Copyright (c) 2011 Zhentan Feng <spyfeng at gmail dot com>
+ * Copyright (c) 2011 Peter Ross <pross@xvid.org>
+ * 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 "libavutil/intreadwrite.h"
+#include "libavutil/avassert.h"
+#include "avformat.h"
+#include "internal.h"
+#include "wtv.h"
+
+#define WTV_BIGSECTOR_SIZE (1 << WTV_BIGSECTOR_BITS)
+#define INDEX_BASE 0x2
+#define MAX_NB_INDEX 10
+
+/* declare utf16le strings */
+#define _ , 0,
+static const uint8_t timeline_table_0_header_events[] =
+ {'t'_'i'_'m'_'e'_'l'_'i'_'n'_'e'_'.'_'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'h'_'e'_'a'_'d'_'e'_'r'_'.'_'E'_'v'_'e'_'n'_'t'_'s', 0};
+static const uint8_t table_0_header_legacy_attrib[] =
+ {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'h'_'e'_'a'_'d'_'e'_'r'_'.'_'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
+static const uint8_t table_0_redirector_legacy_attrib[] =
+ {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'r'_'e'_'d'_'i'_'r'_'e'_'c'_'t'_'o'_'r'_'.'_'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
+static const uint8_t table_0_header_time[] =
+ {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'h'_'e'_'a'_'d'_'e'_'r'_'.'_'t'_'i'_'m'_'e', 0};
+static const uint8_t legacy_attrib[] =
+ {'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
+#undef _
+
+static const ff_asf_guid sub_wtv_guid =
+ {0x8C,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
+static const ff_asf_guid stream1_guid =
+ {0xA1,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
+static const ff_asf_guid sync_guid =
+ {0x97,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
+static const ff_asf_guid index_guid =
+ {0x96,0xc3,0xd2,0xc2,0x7e,0x9a,0xda,0x11,0x8b,0xf7,0x00,0x07,0xe9,0x5e,0xad,0x8d};
+
+enum WtvFileIndex {
+ WTV_TIMELINE_TABLE_0_HEADER_EVENTS = 0,
+ WTV_TIMELINE_TABLE_0_ENTRIES_EVENTS,
+ WTV_TIMELINE,
+ WTV_TABLE_0_HEADER_LEGACY_ATTRIB,
+ WTV_TABLE_0_ENTRIES_LEGACY_ATTRIB,
+ WTV_TABLE_0_REDIRECTOR_LEGACY_ATTRIB,
+ WTV_TABLE_0_HEADER_TIME,
+ WTV_TABLE_0_ENTRIES_TIME,
+ WTV_FILES
+};
+
+typedef struct {
+ int64_t length;
+ const void *header;
+ int depth;
+ int first_sector;
+} WtvFile;
+
+typedef struct {
+ int64_t pos;
+ int64_t serial;
+ const ff_asf_guid * guid;
+ int stream_id;
+} WtvChunkEntry;
+
+typedef struct {
+ int64_t timeline_start_pos;
+ WtvFile file[WTV_FILES];
+ int64_t serial; /** chunk serial number */
+ int64_t last_chunk_pos; /** last chunk position */
+ int64_t frame_nb;
+
+ WtvChunkEntry index[MAX_NB_INDEX];
+ int nb_index;
+ int first_video_flag;
+ int64_t sync_pos;
+} WtvContext;
+
+typedef int WTVHeaderWriteFunc(AVIOContext *pb);
+
+typedef struct {
+ const uint8_t *header;
+ int header_size;
+ WTVHeaderWriteFunc *write_header;
+}WTVRootEntryTable;
+
+static int write_pad(AVIOContext *pb, int size)
+{
+ for (; size > 0; size--)
+ avio_w8(pb, 0);
+ return 0;
+}
+
+static void put_guid(AVIOContext *s, const ff_asf_guid *g)
+{
+ assert(sizeof(*g) == 16);
+ avio_write(s, *g, sizeof(*g));
+ }
+
+static const ff_asf_guid *get_codec_guid(enum CodecID id, const AVCodecGuid *av_guid)
+{
+ int i;
+ for (i = 0; av_guid[i].id != CODEC_ID_NONE; i++) {
+ if (id == av_guid[i].id)
+ return &(av_guid[i].guid);
+ }
+ return NULL;
+}
+
+/**
+ * Write chunk header. If header chunk (0x80000000 set) then add to list of header chunks
+ */
+static void write_chunk_header(AVFormatContext *s, const ff_asf_guid *guid, int length, int stream_id)
+{
+ WtvContext *wctx = s->priv_data;
+ AVIOContext *pb = s->pb;
+
+ wctx->last_chunk_pos = avio_tell(pb) - wctx->timeline_start_pos;
+ put_guid(pb, guid);
+ avio_wl32(pb, 32 + length);
+ avio_wl32(pb, stream_id);
+ avio_wl64(pb, wctx->serial);
+
+ if ((stream_id & 0x80000000) && guid != &index_guid) {
+ WtvChunkEntry *t = wctx->index + wctx->nb_index;
+ av_assert0(wctx->nb_index < MAX_NB_INDEX);
+ t->pos = wctx->last_chunk_pos;
+ t->serial = wctx->serial;
+ t->guid = guid;
+ t->stream_id = stream_id & 0x3FFFFFFF;
+ wctx->nb_index++;
+ }
+}
+
+static void write_chunk_header2(AVFormatContext *s, const ff_asf_guid *guid, int stream_id)
+{
+ WtvContext *wctx = s->priv_data;
+ AVIOContext *pb = s->pb;
+
+ int64_t last_chunk_pos = wctx->last_chunk_pos;
+ write_chunk_header(s, guid, 0, stream_id); // length updated later
+ avio_wl64(pb, last_chunk_pos);
+}
+
+static void finish_chunk_noindex(AVFormatContext *s)
+{
+ WtvContext *wctx = s->priv_data;
+ AVIOContext *pb = s->pb;
+
+ // update the chunk_len field and pad.
+ int64_t chunk_len = avio_tell(pb) - (wctx->last_chunk_pos + wctx->timeline_start_pos);
+ avio_seek(pb, -(chunk_len - 16), SEEK_CUR);
+ avio_wl32(pb, chunk_len);
+ avio_seek(pb, chunk_len - (16 + 4), SEEK_CUR);
+
+ write_pad(pb, WTV_PAD8(chunk_len) - chunk_len);
+ wctx->serial++;
+}
+
+static void write_index(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ WtvContext *wctx = s->priv_data;
+ int i;
+
+ write_chunk_header2(s, &index_guid, 0x80000000);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+
+ for (i = 0; i < wctx->nb_index; i++) {
+ WtvChunkEntry *t = wctx->index + i;
+ put_guid(pb, t->guid);
+ avio_wl64(pb, t->pos);
+ avio_wl32(pb, t->stream_id);
+ avio_wl32(pb, 0); // checksum?
+ avio_wl64(pb, t->serial);
+ }
+ wctx->nb_index = 0; // reset index
+ finish_chunk_noindex(s);
+}
+
+static void finish_chunk(AVFormatContext *s)
+{
+ WtvContext *wctx = s->priv_data;
+ finish_chunk_noindex(s);
+ if (wctx->nb_index == MAX_NB_INDEX)
+ write_index(s);
+}
+
+static int write_stream_codec_info(AVFormatContext *s, AVStream *st)
+{
+ WtvContext *wctx = s->priv_data;
+ const ff_asf_guid *g, *media_type, *format_type;
+ AVIOContext *pb = s->pb;
+ int64_t hdr_pos_start;
+ int hdr_size = 0;
+
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ g = get_codec_guid(st->codec->codec_id, ff_video_guids);
+ media_type = &ff_mediatype_video;
+ format_type = &ff_format_mpeg2_video;
+ } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ g = get_codec_guid(st->codec->codec_id, ff_codec_wav_guids);
+ media_type = &ff_mediatype_audio;
+ format_type = &ff_format_waveformatex;
+ } else {
+ av_log(s, AV_LOG_ERROR, "unknown codec_type (0x%x)\n", st->codec->codec_type);
+ return -1;
+ }
+
+ if (g == NULL) {
+ av_log(s, AV_LOG_ERROR, "can't get video codec_id (0x%x) guid.\n", st->codec->codec_id);
+ return -1;
+ }
+
+ put_guid(pb, media_type); // mediatype
+ put_guid(pb, &ff_mediasubtype_cpfilters_processed); // subtype
+ write_pad(pb, 12);
+ put_guid(pb,&ff_format_cpfilters_processed); // format type
+ avio_wl32(pb, 0); // size
+
+ hdr_pos_start = avio_tell(pb);
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (wctx->first_video_flag) {
+ write_pad(pb, 216); //The size is sensitive.
+ wctx->first_video_flag = 0;
+ } else {
+ write_pad(pb, 72); // aspect ratio
+ ff_put_bmp_header(pb, st->codec, ff_codec_bmp_tags, 0);
+ }
+ } else {
+ ff_put_wav_header(pb, st->codec);
+ }
+ hdr_size = avio_tell(pb) - hdr_pos_start;
+
+ // seek back write hdr_size
+ avio_seek(pb, -(hdr_size + 4), SEEK_CUR);
+ avio_wl32(pb, hdr_size + 32);
+ avio_seek(pb, hdr_size, SEEK_CUR);
+ put_guid(pb, g); // actual_subtype
+ put_guid(pb, format_type); // actual_formattype
+
+ return 0;
+}
+
+static int write_stream_codec(AVFormatContext *s, AVStream * st)
+{
+ AVIOContext *pb = s->pb;
+ int ret;
+ write_chunk_header2(s, &stream1_guid, 0x80000000 | 0x01);
+
+ avio_wl32(pb, 0x01);
+ write_pad(pb, 4);
+ write_pad(pb, 4);
+
+ ret = write_stream_codec_info(s, st);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "write stream codec info failed codec_type(0x%x)\n", st->codec->codec_type);
+ return -1;
+ }
+
+ finish_chunk(s);
+ return 0;
+}
+
+static void write_sync(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ WtvContext *wctx = s->priv_data;
+ int64_t last_chunk_pos = wctx->last_chunk_pos;
+ wctx->sync_pos = avio_tell(pb) - wctx->timeline_start_pos;;
+
+ write_chunk_header(s, &sync_guid, 0x18, 0);
+ write_pad(pb, 24);
+
+ finish_chunk(s);
+
+ wctx->last_chunk_pos = last_chunk_pos;
+}
+
+static void write_DSATTRIB_TRANSPORT_PROPERTIES_init(AVFormatContext *s, int stream_index)
+{
+ AVIOContext *pb = s->pb;
+ write_chunk_header2(s, &ff_DSATTRIB_TRANSPORT_PROPERTIES, 0x80000000 | stream_index);
+ avio_wl64(pb, stream_index);
+ avio_wl64(pb, -1);
+ avio_wl64(pb, 0);
+ finish_chunk(s);
+}
+
+static int write_stream_data(AVFormatContext *s, AVStream *st, int flag)
+{
+ AVIOContext *pb = s->pb;
+ int ret;
+
+ if (!flag) {
+ write_chunk_header2(s, &ff_stream_guid, 0x80000000 | (st->index + INDEX_BASE));
+ avio_wl32(pb, 0x00000001);
+ avio_wl32(pb, st->index + INDEX_BASE); //stream_id
+ avio_wl32(pb, 0x00000001);
+ write_pad(pb, 8);
+ } else {
+ write_chunk_header2(s, &ff_stream2_guid, 0x80000000 | (st->index + INDEX_BASE));
+ write_pad(pb, 4);
+ }
+
+ ret = write_stream_codec_info(s, st);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "write stream codec info failed codec_type(0x%x)\n", st->codec->codec_type);
+ return -1;
+ }
+ finish_chunk(s);
+
+ av_set_pts_info(st, 64, 1, 10000000);
+
+ return 0;
+}
+
+static int write_header(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ WtvContext *wctx = s->priv_data;
+ int i, pad, ret;
+ AVStream *st;
+
+ put_guid(pb, &ff_wtv_guid);
+ put_guid(pb, &sub_wtv_guid);
+
+ avio_wl32(pb, 0x01);
+ avio_wl32(pb, 0x02);
+ avio_wl32(pb, 1 << WTV_SECTOR_BITS);
+ avio_wl32(pb, 1 << WTV_BIGSECTOR_BITS);
+
+ //write initial root fields
+ avio_wl32(pb, 0); // root_size, update later
+ write_pad(pb, 4);
+ avio_wl32(pb, 0); // root_sector, update it later.
+
+ write_pad(pb, 32);
+ avio_wl32(pb, 0); // file ends pointer, update it later.
+
+ pad = (1 << WTV_SECTOR_BITS) - avio_tell(pb);
+ write_pad(pb, pad);
+ wctx->timeline_start_pos = avio_tell(pb);
+
+ wctx->serial = 1;
+ wctx->last_chunk_pos = -1;
+ wctx->first_video_flag = 1;
+
+ for (i = 0; i < s->nb_streams; i++) {
+ st = s->streams[i];
+ ret = write_stream_codec(s, st);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "write stream codec failed codec_type(0x%x)\n", st->codec->codec_type);
+ return -1;
+ }
+ if (i + 1 < s->nb_streams) {
+ write_sync(s);
+ }
+ }
+
+ for (i = 0; i < s->nb_streams; i++) {
+ st = s->streams[i];
+ ret = write_stream_data(s, st, 0);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "write stream data failed codec_type(0x%x)\n", st->codec->codec_type);
+ return -1;
+ }
+ ret = write_stream_data(s, st, 1);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "write stream2 data failed codec_type(0x%x)\n", st->codec->codec_type);
+ return -1;
+ }
+ }
+
+ for (i = 0; i < s->nb_streams; i++)
+ write_DSATTRIB_TRANSPORT_PROPERTIES_init(s, INDEX_BASE + i);
+
+ if (wctx->nb_index)
+ write_index(s);
+
+ return 0;
+}
+
+static void write_timestamp(AVFormatContext *s, AVPacket *pkt)
+{
+ AVIOContext *pb = s->pb;
+ WtvContext *wctx = s->priv_data;
+ AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
+ int flag = 0;
+ int64_t frame_number = 0;
+
+ if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+ wctx->frame_nb++;
+ frame_number = wctx->frame_nb;
+ flag = pkt->flags & AV_PKT_FLAG_KEY ? 1 : 0;
+ }
+ write_chunk_header(s, &ff_timestamp_guid, 56, 0x40000000 | (INDEX_BASE + pkt->stream_index));
+ write_pad(pb, 8);
+ avio_wl64(pb, pkt->pts == AV_NOPTS_VALUE ? -1 : pkt->pts);
+ avio_wl64(pb, pkt->pts == AV_NOPTS_VALUE ? -1 : pkt->pts);
+
+ avio_wl64(pb, frame_number);
+ avio_wl64(pb, 0);
+ avio_wl64(pb, flag);
+ avio_wl64(pb, 0);
+}
+
+static int write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ AVIOContext *pb = s->pb;
+ WtvContext *wctx = s->priv_data;
+
+ // write timestamp chunk
+ write_timestamp(s, pkt);
+
+ write_chunk_header(s, &ff_data_guid, pkt->size, INDEX_BASE + pkt->stream_index);
+ avio_write(pb, pkt->data, pkt->size);
+ write_pad(pb, WTV_PAD8(pkt->size) - pkt->size);
+
+ wctx->serial++;
+ avio_flush(pb);
+ return 0;
+}
+
+static int write_table0_header_envents(AVIOContext *pb)
+{
+ avio_wl32(pb, 0x10);
+ write_pad(pb, 84);
+ avio_wl64(pb, 0x32);
+ return 96;
+}
+
+static int write_table0_header_legacy_attrib(AVIOContext *pb)
+{
+ int pad = 0;
+ avio_wl32(pb, 0xFFFFFFFF);
+ write_pad(pb, 12);
+ avio_write(pb, legacy_attrib, sizeof(legacy_attrib));
+ pad = WTV_PAD8(sizeof(legacy_attrib)) - sizeof(legacy_attrib);
+ write_pad(pb, pad);
+ write_pad(pb, 32);
+ return 48 + WTV_PAD8(sizeof(legacy_attrib));
+}
+
+static int write_table0_header_time(AVIOContext *pb)
+{
+ avio_wl32(pb, 0x10);
+ write_pad(pb, 76);
+ avio_wl64(pb, 0x40);
+ return 88;
+}
+
+static const WTVRootEntryTable wtv_root_entry_table[] = {
+ { timeline_table_0_header_events, sizeof(timeline_table_0_header_events), write_table0_header_envents},
+ { ff_timeline_table_0_entries_Events_le16, sizeof(ff_timeline_table_0_entries_Events_le16), NULL},
+ { ff_timeline_le16, sizeof(ff_timeline_le16), NULL},
+ { table_0_header_legacy_attrib, sizeof(table_0_header_legacy_attrib), write_table0_header_legacy_attrib},
+ { ff_table_0_entries_legacy_attrib_le16, sizeof(ff_table_0_entries_legacy_attrib_le16), NULL},
+ { table_0_redirector_legacy_attrib, sizeof(table_0_redirector_legacy_attrib), NULL},
+ { table_0_header_time, sizeof(table_0_header_time), write_table0_header_time},
+ { ff_table_0_entries_time_le16, sizeof(ff_table_0_entries_time_le16), NULL},
+};
+
+static int write_root_table(AVFormatContext *s, int64_t sector_pos)
+{
+ AVIOContext *pb = s->pb;
+ WtvContext *wctx = s->priv_data;
+ int size, pad;
+ int i;
+
+ const WTVRootEntryTable *h = wtv_root_entry_table;
+ for (i = 0; i < sizeof(wtv_root_entry_table)/sizeof(WTVRootEntryTable); i++, h++) {
+ WtvFile *w = &wctx->file[i];
+ int filename_padding = WTV_PAD8(h->header_size) - h->header_size;
+ WTVHeaderWriteFunc *write = h->write_header;
+ int len = 0;
+ int64_t len_pos;
+
+ put_guid(pb, &ff_dir_entry_guid);
+ len_pos = avio_tell(pb);
+ avio_wl16(pb, 40 + h->header_size + filename_padding + 8); // maybe updated later
+ write_pad(pb, 6);
+ avio_wl64(pb, write ? 0 : w->length);// maybe update later
+ avio_wl32(pb, (h->header_size + filename_padding) >> 1);
+ write_pad(pb, 4);
+
+ avio_write(pb, h->header, h->header_size);
+ write_pad(pb, filename_padding);
+
+ if (write) {
+ len = write(pb);
+ // update length field
+ avio_seek(pb, len_pos, SEEK_SET);
+ avio_wl64(pb, 40 + h->header_size + filename_padding + len);
+ avio_wl64(pb, len |(1ULL<<62) | (1ULL<<60));
+ avio_seek(pb, 8 + h->header_size + filename_padding + len, SEEK_CUR);
+ } else {
+ avio_wl32(pb, w->first_sector);
+ avio_wl32(pb, w->depth);
+ }
+ }
+
+ // caculate root table size
+ size = avio_tell(pb) - sector_pos;
+ pad = WTV_SECTOR_SIZE- size;
+ write_pad(pb, pad);
+
+ return size;
+}
+
+static void write_fat(AVIOContext *pb, int start_sector, int nb_sectors, int shift)
+{
+ int i;
+ for (i = 0; i < nb_sectors; i++) {
+ avio_wl32(pb, start_sector + (i << shift));
+ }
+ // pad left sector pointer size
+ write_pad(pb, WTV_SECTOR_SIZE - (nb_sectors << 2));
+}
+
+static int write_fat_sector(AVFormatContext *s, int64_t start_pos, int nb_sectors, int sector_bits, int depth)
+{
+ int64_t start_sector = start_pos >> WTV_SECTOR_BITS;
+ int shift = sector_bits - WTV_SECTOR_BITS;
+
+ int64_t fat = avio_tell(s->pb);
+ write_fat(s->pb, start_sector, nb_sectors, shift);
+
+ if (depth == 2) {
+ int64_t start_sector1 = fat >> WTV_SECTOR_BITS;
+ int nb_sectors1 = ((nb_sectors << 2) + WTV_SECTOR_SIZE - 1) / WTV_SECTOR_SIZE;
+ int64_t fat1 = avio_tell(s->pb);
+
+ write_fat(s->pb, start_sector1, nb_sectors1, 0);
+ return fat1;
+ }
+
+ return fat;
+}
+
+static void write_table_entries_events(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ WtvContext *wctx = s->priv_data;
+
+ //FIXME: output frame_nb, position pairs.
+ //We only set the first sync_chunk position here.
+ avio_wl64(pb, 0x2); avio_wl64(pb, wctx->sync_pos);
+}
+
+static void write_tag(AVIOContext *pb, const char *key, const char *value)
+{
+ put_guid(pb, &ff_metadata_guid);
+ avio_wl32(pb, 1);
+ avio_wl32(pb, strlen(value)*2 + 2);
+ avio_put_str16le(pb, key);
+ avio_put_str16le(pb, value);
+}
+
+static void write_table_entries_attrib(AVFormatContext *s)
+{
+ AVDictionaryEntry *tag = 0;
+
+ //FIXME: translate special tags (e.g. WM/Bitrate) to binary representation
+ ff_metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL);
+ while((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
+ write_tag(s->pb, tag->key, tag->value);
+}
+
+static void write_table_redirector_legacy_attrib(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ AVDictionaryEntry *tag = 0;
+ int64_t pos = 0;
+
+ //FIXME: translate special tags to binary representation
+ while((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+ avio_wl64(pb, pos);
+ pos += 16 + 4 + 4 + strlen(tag->key)*2 + 2 + strlen(tag->value)*2 + 2;
+ }
+}
+
+/**
+ * Pad the remainder of a file
+ * Write out fat table
+ * @return <0 on error
+ */
+static int finish_file(AVFormatContext *s, enum WtvFileIndex index, int64_t start_pos)
+{
+ WtvContext *wctx = s->priv_data;
+ AVIOContext *pb = s->pb;
+ WtvFile *w = &wctx->file[index];
+ int64_t end_pos = avio_tell(pb);
+ int sector_bits, nb_sectors, pad;
+
+ av_assert0(index < WTV_FILES);
+
+ w->length = (end_pos - start_pos);
+
+ // determine optimal fat table depth, sector_bits, nb_sectors
+ if (w->length <= WTV_SECTOR_SIZE) {
+ w->depth = 0;
+ sector_bits = WTV_SECTOR_BITS;
+ } else if (w->length <= (WTV_SECTOR_SIZE / 4) * WTV_SECTOR_SIZE) {
+ w->depth = 1;
+ sector_bits = WTV_SECTOR_BITS;
+ } else if (w->length <= (WTV_SECTOR_SIZE / 4) * WTV_BIGSECTOR_SIZE) {
+ w->depth = 1;
+ sector_bits = WTV_BIGSECTOR_BITS;
+ } else if (w->length <= (int64_t)(WTV_SECTOR_SIZE / 4) * (WTV_SECTOR_SIZE / 4) * WTV_SECTOR_SIZE) {
+ w->depth = 2;
+ sector_bits = WTV_SECTOR_BITS;
+ } else if (w->length <= (int64_t)(WTV_SECTOR_SIZE / 4) * (WTV_SECTOR_SIZE / 4) * WTV_BIGSECTOR_SIZE) {
+ w->depth = 2;
+ sector_bits = WTV_BIGSECTOR_BITS;
+ } else {
+ av_log(s, AV_LOG_ERROR, "unsupported file allocation table depth (%"PRIi64" bytes)\n", w->length);
+ return -1;
+ }
+
+ // determine the nb_sectors
+ nb_sectors = (int)(w->length >> sector_bits);
+
+ // pad sector of timeline
+ pad = (1 << sector_bits) - (w->length % (1 << sector_bits));
+ if (pad) {
+ nb_sectors++;
+ write_pad(pb, pad);
+ }
+
+ //write fat table
+ if (w->depth > 0) {
+ w->first_sector = write_fat_sector(s, start_pos, nb_sectors, sector_bits, w->depth);
+ } else {
+ w->first_sector = start_pos;
+ }
+ w->first_sector >>= WTV_SECTOR_BITS;
+
+ w->length |= 1ULL<<60;
+ if (sector_bits == WTV_SECTOR_BITS)
+ w->length |= 1ULL<<63;
+
+ return 0;
+}
+
+static int write_trailer(AVFormatContext *s)
+{
+ WtvContext *wctx = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int root_size;
+ int64_t sector_pos;
+ int64_t start_pos, file_end_pos;
+
+ if (finish_file(s, WTV_TIMELINE, wctx->timeline_start_pos) < 0)
+ return -1;
+
+ start_pos = avio_tell(pb);
+ write_table_entries_events(s);
+ if (finish_file(s, WTV_TIMELINE_TABLE_0_ENTRIES_EVENTS, start_pos) < 0)
+ return -1;
+
+ start_pos = avio_tell(pb);
+ write_table_entries_attrib(s);
+ if (finish_file(s, WTV_TABLE_0_ENTRIES_LEGACY_ATTRIB, start_pos) < 0)
+ return -1;
+
+ start_pos = avio_tell(pb);
+ write_table_redirector_legacy_attrib(s);
+ if (finish_file(s, WTV_TABLE_0_REDIRECTOR_LEGACY_ATTRIB, start_pos) < 0)
+ return -1;
+
+ start_pos = avio_tell(pb);
+ //FIXME: output timestamp, frame_nb pairs here.
+ if (finish_file(s, WTV_TABLE_0_ENTRIES_TIME, start_pos) < 0)
+ return -1;
+
+ // write root table
+ sector_pos = avio_tell(pb);
+ root_size = write_root_table(s, sector_pos);
+
+ file_end_pos = avio_tell(pb);
+ // update root value
+ avio_seek(pb, 0x30, SEEK_SET);
+ avio_wl32(pb, root_size);
+ avio_seek(pb, 4, SEEK_CUR);
+ avio_wl32(pb, sector_pos >> WTV_SECTOR_BITS);
+ avio_seek(pb, 0x5c, SEEK_SET);
+ avio_wl32(pb, file_end_pos >> WTV_SECTOR_BITS);
+
+ avio_flush(pb);
+ return 0;
+}
+
+AVOutputFormat ff_wtv_muxer = {
+ .name = "wtv",
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Television (WTV)"),
+ .extensions = "wtv",
+ .priv_data_size = sizeof(WtvContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = write_header,
+ .write_packet = write_packet,
+ .write_trailer = write_trailer,
+ .codec_tag = (const AVCodecTag* const []){ ff_codec_bmp_tags,
+ ff_codec_wav_tags, 0 },
+};
diff --git a/libavformat/wv.c b/libavformat/wv.c
index d6d7099ba7..72c8df0f24 100644
--- a/libavformat/wv.c
+++ b/libavformat/wv.c
@@ -2,20 +2,20 @@
* WavPack demuxer
* Copyright (c) 2006,2011 Konstantin Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -220,7 +220,7 @@ static int wv_read_header(AVFormatContext *s,
}
/* now we are ready: build format streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -250,14 +250,16 @@ static int wv_read_packet(AVFormatContext *s,
WVContext *wc = s->priv_data;
int ret;
int size, ver, off;
+ int64_t pos;
- if (s->pb->eof_reached)
+ if (url_feof(s->pb))
return AVERROR(EIO);
if(wc->block_parsed){
if(wv_read_block_header(s, s->pb, 0) < 0)
return -1;
}
+ pos = wc->pos;
off = wc->multichannel ? 4 : 0;
if(av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0)
return AVERROR(ENOMEM);
@@ -314,7 +316,7 @@ static int wv_read_packet(AVFormatContext *s,
pkt->stream_index = 0;
wc->block_parsed = 1;
pkt->pts = wc->soff;
- av_add_index_entry(s->streams[0], wc->pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
+ av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
return 0;
}
@@ -328,7 +330,8 @@ static int wv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
int64_t pos, pts;
/* if found, seek there */
- if (index >= 0){
+ if (index >= 0 &&
+ timestamp <= st->index_entries[st->nb_index_entries - 1].timestamp) {
wc->block_parsed = 1;
avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
return 0;
@@ -351,12 +354,11 @@ static int wv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
}
AVInputFormat ff_wv_demuxer = {
- "wv",
- NULL_IF_CONFIG_SMALL("WavPack"),
- sizeof(WVContext),
- wv_probe,
- wv_read_header,
- wv_read_packet,
- NULL,
- wv_read_seek,
+ .name = "wv",
+ .long_name = NULL_IF_CONFIG_SMALL("WavPack"),
+ .priv_data_size = sizeof(WVContext),
+ .read_probe = wv_probe,
+ .read_header = wv_read_header,
+ .read_packet = wv_read_packet,
+ .read_seek = wv_read_seek,
};
diff --git a/libavformat/xa.c b/libavformat/xa.c
index c3421a34e7..dd7811dd91 100644
--- a/libavformat/xa.c
+++ b/libavformat/xa.c
@@ -2,20 +2,20 @@
* Maxis XA (.xa) File Demuxer
* Copyright (c) 2008 Robert Marston
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -70,7 +70,7 @@ static int xa_read_header(AVFormatContext *s,
AVStream *st;
/*Set up the XA Audio Decoder*/
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -119,10 +119,10 @@ static int xa_read_packet(AVFormatContext *s,
}
AVInputFormat ff_xa_demuxer = {
- "xa",
- NULL_IF_CONFIG_SMALL("Maxis XA File Format"),
- sizeof(MaxisXADemuxContext),
- xa_probe,
- xa_read_header,
- xa_read_packet,
+ .name = "xa",
+ .long_name = NULL_IF_CONFIG_SMALL("Maxis XA File Format"),
+ .priv_data_size = sizeof(MaxisXADemuxContext),
+ .read_probe = xa_probe,
+ .read_header = xa_read_header,
+ .read_packet = xa_read_packet,
};
diff --git a/libavformat/xmv.c b/libavformat/xmv.c
new file mode 100644
index 0000000000..aeafcb6904
--- /dev/null
+++ b/libavformat/xmv.c
@@ -0,0 +1,557 @@
+/*
+ * Microsoft XMV demuxer
+ * Copyright (c) 2011 Sven Hesse <drmccoy@drmccoy.de>
+ * Copyright (c) 2011 Matthew Hoops <clone2727@gmail.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
+ */
+
+/**
+ * @file
+ * Microsoft XMV demuxer
+ */
+
+#include <stdint.h>
+
+#include "libavutil/intreadwrite.h"
+
+#include "avformat.h"
+#include "riff.h"
+
+/** The min size of an XMV header. */
+#define XMV_MIN_HEADER_SIZE 36
+
+/** Audio flag: ADPCM'd 5.1 stream, front left / right channels */
+#define XMV_AUDIO_ADPCM51_FRONTLEFTRIGHT 1
+/** Audio flag: ADPCM'd 5.1 stream, front center / low frequency channels */
+#define XMV_AUDIO_ADPCM51_FRONTCENTERLOW 2
+/** Audio flag: ADPCM'd 5.1 stream, rear left / right channels */
+#define XMV_AUDIO_ADPCM51_REARLEFTRIGHT 4
+
+/** Audio flag: Any of the ADPCM'd 5.1 stream flags. */
+#define XMV_AUDIO_ADPCM51 (XMV_AUDIO_ADPCM51_FRONTLEFTRIGHT | \
+ XMV_AUDIO_ADPCM51_FRONTCENTERLOW | \
+ XMV_AUDIO_ADPCM51_REARLEFTRIGHT)
+
+/** A video packet with an XMV file. */
+typedef struct XMVVideoPacket {
+ int stream_index; ///< The decoder stream index for this video packet.
+
+ uint32_t data_size; ///< The size of the remaining video data.
+ uint64_t data_offset; ///< The offset of the video data within the file.
+
+ uint32_t current_frame; ///< The current frame within this video packet.
+ uint32_t frame_count; ///< The amount of frames within this video packet.
+
+ int has_extradata; ///< Does the video packet contain extra data?
+ uint8_t extradata[4]; ///< The extra data
+
+ int64_t last_pts; ///< PTS of the last video frame.
+ int64_t pts; ///< PTS of the most current video frame.
+} XMVVideoPacket;
+
+/** An audio packet with an XMV file. */
+typedef struct XMVAudioPacket {
+ int stream_index; ///< The decoder stream index for this audio packet.
+
+ /* Stream format properties. */
+ uint16_t compression; ///< The type of compression.
+ uint16_t channels; ///< Number of channels.
+ uint32_t sample_rate; ///< Sampling rate.
+ uint16_t bits_per_sample; ///< Bits per compressed sample.
+ uint32_t bit_rate; ///< Bits of compressed data per second.
+ uint16_t flags; ///< Flags
+ uint16_t block_align; ///< Bytes per compressed block.
+ uint16_t block_samples; ///< Decompressed samples per compressed block.
+
+ enum CodecID codec_id; ///< The codec ID of the compression scheme.
+
+ uint32_t data_size; ///< The size of the remaining audio data.
+ uint64_t data_offset; ///< The offset of the audio data within the file.
+
+ uint32_t frame_size; ///< Number of bytes to put into an audio frame.
+
+ uint64_t block_count; ///< Running counter of decompressed audio block.
+} XMVAudioPacket;
+
+/** Context for demuxing an XMV file. */
+typedef struct XMVDemuxContext {
+ uint16_t audio_track_count; ///< Number of audio track in this file.
+
+ uint32_t this_packet_size; ///< Size of the current packet.
+ uint32_t next_packet_size; ///< Size of the next packet.
+
+ uint64_t this_packet_offset; ///< Offset of the current packet.
+ uint64_t next_packet_offset; ///< Offset of the next packet.
+
+ uint16_t current_stream; ///< The index of the stream currently handling.
+ uint16_t stream_count; ///< The number of streams in this file.
+
+ XMVVideoPacket video; ///< The video packet contained in each packet.
+ XMVAudioPacket *audio; ///< The audio packets contained in each packet.
+} XMVDemuxContext;
+
+static int xmv_probe(AVProbeData *p)
+{
+ uint32_t file_version;
+
+ if (p->buf_size < XMV_MIN_HEADER_SIZE)
+ return 0;
+
+ file_version = AV_RL32(p->buf + 16);
+ if ((file_version == 0) || (file_version > 4))
+ return 0;
+
+ if (!memcmp(p->buf + 12, "xobX", 4))
+ return AVPROBE_SCORE_MAX;
+
+ return 0;
+}
+
+static int xmv_read_header(AVFormatContext *s,
+ AVFormatParameters *ap)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+ AVIOContext *pb = s->pb;
+ AVStream *vst = NULL;
+
+ uint32_t file_version;
+ uint32_t this_packet_size;
+ uint16_t audio_track;
+
+ avio_skip(pb, 4); /* Next packet size */
+
+ this_packet_size = avio_rl32(pb);
+
+ avio_skip(pb, 4); /* Max packet size */
+ avio_skip(pb, 4); /* "xobX" */
+
+ file_version = avio_rl32(pb);
+ if ((file_version != 4) && (file_version != 2))
+ av_log_ask_for_sample(s, "Found uncommon version %d\n", file_version);
+
+
+ /* Video track */
+
+ vst = avformat_new_stream(s, NULL);
+ if (!vst)
+ return AVERROR(ENOMEM);
+
+ av_set_pts_info(vst, 32, 1, 1000);
+
+ vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ vst->codec->codec_id = CODEC_ID_WMV2;
+ vst->codec->codec_tag = MKBETAG('W', 'M', 'V', '2');
+ vst->codec->width = avio_rl32(pb);
+ vst->codec->height = avio_rl32(pb);
+
+ vst->duration = avio_rl32(pb);
+
+ xmv->video.stream_index = vst->index;
+
+ /* Audio tracks */
+
+ xmv->audio_track_count = avio_rl16(pb);
+
+ avio_skip(pb, 2); /* Unknown (padding?) */
+
+ xmv->audio = av_malloc(xmv->audio_track_count * sizeof(XMVAudioPacket));
+ if (!xmv->audio)
+ return AVERROR(ENOMEM);
+
+ for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {
+ XMVAudioPacket *packet = &xmv->audio[audio_track];
+ AVStream *ast = NULL;
+
+ packet->compression = avio_rl16(pb);
+ packet->channels = avio_rl16(pb);
+ packet->sample_rate = avio_rl32(pb);
+ packet->bits_per_sample = avio_rl16(pb);
+ packet->flags = avio_rl16(pb);
+
+ packet->bit_rate = packet->bits_per_sample *
+ packet->sample_rate *
+ packet->channels;
+ packet->block_align = 36 * packet->channels;
+ packet->block_samples = 64;
+ packet->codec_id = ff_wav_codec_get_id(packet->compression,
+ packet->bits_per_sample);
+
+ packet->stream_index = -1;
+
+ packet->frame_size = 0;
+ packet->block_count = 0;
+
+ /* TODO: ADPCM'd 5.1 sound is encoded in three separate streams.
+ * Those need to be interleaved to a proper 5.1 stream. */
+ if (packet->flags & XMV_AUDIO_ADPCM51)
+ av_log(s, AV_LOG_WARNING, "Unsupported 5.1 ADPCM audio stream "
+ "(0x%04X)\n", packet->flags);
+
+ ast = avformat_new_stream(s, NULL);
+ if (!ast)
+ return AVERROR(ENOMEM);
+
+ ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ ast->codec->codec_id = packet->codec_id;
+ ast->codec->codec_tag = packet->compression;
+ ast->codec->channels = packet->channels;
+ ast->codec->sample_rate = packet->sample_rate;
+ ast->codec->bits_per_coded_sample = packet->bits_per_sample;
+ ast->codec->bit_rate = packet->bit_rate;
+ ast->codec->block_align = 36 * packet->channels;
+
+ av_set_pts_info(ast, 32, packet->block_samples, packet->sample_rate);
+
+ packet->stream_index = ast->index;
+
+ ast->duration = vst->duration;
+ }
+
+
+ /* Initialize the packet context */
+
+ xmv->next_packet_offset = avio_tell(pb);
+ xmv->next_packet_size = this_packet_size - xmv->next_packet_offset;
+ xmv->stream_count = xmv->audio_track_count + 1;
+
+ return 0;
+}
+
+static void xmv_read_extradata(uint8_t *extradata, AVIOContext *pb)
+{
+ /* Read the XMV extradata */
+
+ uint32_t data = avio_rl32(pb);
+
+ int mspel_bit = !!(data & 0x01);
+ int loop_filter = !!(data & 0x02);
+ int abt_flag = !!(data & 0x04);
+ int j_type_bit = !!(data & 0x08);
+ int top_left_mv_flag = !!(data & 0x10);
+ int per_mb_rl_bit = !!(data & 0x20);
+ int slice_count = (data >> 6) & 7;
+
+ /* Write it back as standard WMV2 extradata */
+
+ data = 0;
+
+ data |= mspel_bit << 15;
+ data |= loop_filter << 14;
+ data |= abt_flag << 13;
+ data |= j_type_bit << 12;
+ data |= top_left_mv_flag << 11;
+ data |= per_mb_rl_bit << 10;
+ data |= slice_count << 7;
+
+ AV_WB32(extradata, data);
+}
+
+static int xmv_process_packet_header(AVFormatContext *s)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+ AVIOContext *pb = s->pb;
+
+ uint8_t data[8];
+ uint16_t audio_track;
+ uint64_t data_offset;
+
+ /* Next packet size */
+ xmv->next_packet_size = avio_rl32(pb);
+
+ /* Packet video header */
+
+ if (avio_read(pb, data, 8) != 8)
+ return AVERROR(EIO);
+
+ xmv->video.data_size = AV_RL32(data) & 0x007FFFFF;
+
+ xmv->video.current_frame = 0;
+ xmv->video.frame_count = (AV_RL32(data) >> 23) & 0xFF;
+
+ xmv->video.has_extradata = (data[3] & 0x80) != 0;
+
+ /* Adding the audio data sizes and the video data size keeps you 4 bytes
+ * short for every audio track. But as playing around with XMV files with
+ * ADPCM audio showed, taking the extra 4 bytes from the audio data gives
+ * you either completely distorted audio or click (when skipping the
+ * remaining 68 bytes of the ADPCM block). Substracting 4 bytes for every
+ * audio track from the video data works at least for the audio. Probably
+ * some alignment thing?
+ * The video data has (always?) lots of padding, so it should work out...
+ */
+ xmv->video.data_size -= xmv->audio_track_count * 4;
+
+ xmv->current_stream = 0;
+ if (!xmv->video.frame_count) {
+ xmv->video.frame_count = 1;
+ xmv->current_stream = 1;
+ }
+
+ /* Packet audio header */
+
+ for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {
+ XMVAudioPacket *packet = &xmv->audio[audio_track];
+
+ if (avio_read(pb, data, 4) != 4)
+ return AVERROR(EIO);
+
+ packet->data_size = AV_RL32(data) & 0x007FFFFF;
+ if ((packet->data_size == 0) && (audio_track != 0))
+ /* This happens when I create an XMV with several identical audio
+ * streams. From the size calculations, duplicating the previous
+ * stream's size works out, but the track data itself is silent.
+ * Maybe this should also redirect the offset to the previous track?
+ */
+ packet->data_size = xmv->audio[audio_track - 1].data_size;
+
+ /* Carve up the audio data in frame_count slices */
+ packet->frame_size = packet->data_size / xmv->video.frame_count;
+ packet->frame_size -= packet->frame_size % packet->block_align;
+ }
+
+ /* Packet data offsets */
+
+ data_offset = avio_tell(pb);
+
+ xmv->video.data_offset = data_offset;
+ data_offset += xmv->video.data_size;
+
+ for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {
+ xmv->audio[audio_track].data_offset = data_offset;
+ data_offset += xmv->audio[audio_track].data_size;
+ }
+
+ /* Video frames header */
+
+ /* Read new video extra data */
+ if (xmv->video.data_size > 0) {
+ if (xmv->video.has_extradata) {
+ xmv_read_extradata(xmv->video.extradata, pb);
+
+ xmv->video.data_size -= 4;
+ xmv->video.data_offset += 4;
+
+ if (xmv->video.stream_index >= 0) {
+ AVStream *vst = s->streams[xmv->video.stream_index];
+
+ assert(xmv->video.stream_index < s->nb_streams);
+
+ if (vst->codec->extradata_size < 4) {
+ av_free(vst->codec->extradata);
+
+ vst->codec->extradata =
+ av_malloc(4 + FF_INPUT_BUFFER_PADDING_SIZE);
+ vst->codec->extradata_size = 4;
+ }
+
+ memcpy(vst->codec->extradata, xmv->video.extradata, 4);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int xmv_fetch_new_packet(AVFormatContext *s)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int result;
+
+ /* Seek to it */
+ xmv->this_packet_offset = xmv->next_packet_offset;
+ if (avio_seek(pb, xmv->this_packet_offset, SEEK_SET) != xmv->this_packet_offset)
+ return AVERROR(EIO);
+
+ /* Update the size */
+ xmv->this_packet_size = xmv->next_packet_size;
+ if (xmv->this_packet_size < (12 + xmv->audio_track_count * 4))
+ return AVERROR(EIO);
+
+ /* Process the header */
+ result = xmv_process_packet_header(s);
+ if (result)
+ return result;
+
+ /* Update the offset */
+ xmv->next_packet_offset = xmv->this_packet_offset + xmv->this_packet_size;
+
+ return 0;
+}
+
+static int xmv_fetch_audio_packet(AVFormatContext *s,
+ AVPacket *pkt, uint32_t stream)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+ AVIOContext *pb = s->pb;
+ XMVAudioPacket *audio = &xmv->audio[stream];
+
+ uint32_t data_size;
+ uint32_t block_count;
+ int result;
+
+ /* Seek to it */
+ if (avio_seek(pb, audio->data_offset, SEEK_SET) != audio->data_offset)
+ return AVERROR(EIO);
+
+ if ((xmv->video.current_frame + 1) < xmv->video.frame_count)
+ /* Not the last frame, get at most frame_size bytes. */
+ data_size = FFMIN(audio->frame_size, audio->data_size);
+ else
+ /* Last frame, get the rest. */
+ data_size = audio->data_size;
+
+ /* Read the packet */
+ result = av_get_packet(pb, pkt, data_size);
+ if (result <= 0)
+ return result;
+
+ pkt->stream_index = audio->stream_index;
+
+ /* Calculate the PTS */
+
+ block_count = data_size / audio->block_align;
+
+ pkt->duration = block_count;
+ pkt->pts = audio->block_count;
+ pkt->dts = AV_NOPTS_VALUE;
+
+ audio->block_count += block_count;
+
+ /* Advance offset */
+ audio->data_size -= data_size;
+ audio->data_offset += data_size;
+
+ return 0;
+}
+
+static int xmv_fetch_video_packet(AVFormatContext *s,
+ AVPacket *pkt)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+ AVIOContext *pb = s->pb;
+ XMVVideoPacket *video = &xmv->video;
+
+ int result;
+ uint32_t frame_header;
+ uint32_t frame_size, frame_timestamp;
+ uint8_t *data, *end;
+
+ /* Seek to it */
+ if (avio_seek(pb, video->data_offset, SEEK_SET) != video->data_offset)
+ return AVERROR(EIO);
+
+ /* Read the frame header */
+ frame_header = avio_rl32(pb);
+
+ frame_size = (frame_header & 0x1FFFF) * 4 + 4;
+ frame_timestamp = (frame_header >> 17);
+
+ if ((frame_size + 4) > video->data_size)
+ return AVERROR(EIO);
+
+ /* Get the packet data */
+ result = av_get_packet(pb, pkt, frame_size);
+ if (result != frame_size)
+ return result;
+
+ /* Contrary to normal WMV2 video, the bit stream in XMV's
+ * WMV2 is little-endian.
+ * TODO: This manual swap is of course suboptimal.
+ */
+ for (data = pkt->data, end = pkt->data + frame_size; data < end; data += 4)
+ AV_WB32(data, AV_RL32(data));
+
+ pkt->stream_index = video->stream_index;
+
+ /* Calculate the PTS */
+
+ video->last_pts = frame_timestamp + video->pts;
+
+ pkt->duration = 0;
+ pkt->pts = video->last_pts;
+ pkt->dts = AV_NOPTS_VALUE;
+
+ video->pts += frame_timestamp;
+
+ /* Keyframe? */
+ pkt->flags = (pkt->data[0] & 0x80) ? 0 : AV_PKT_FLAG_KEY;
+
+ /* Advance offset */
+ video->data_size -= frame_size + 4;
+ video->data_offset += frame_size + 4;
+
+ return 0;
+}
+
+static int xmv_read_packet(AVFormatContext *s,
+ AVPacket *pkt)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+ int result;
+
+ if (xmv->video.current_frame == xmv->video.frame_count) {
+ /* No frames left in this packet, so we fetch a new one */
+
+ result = xmv_fetch_new_packet(s);
+ if (result)
+ return result;
+ }
+
+ if (xmv->current_stream == 0) {
+ /* Fetch a video frame */
+
+ result = xmv_fetch_video_packet(s, pkt);
+ if (result)
+ return result;
+
+ } else {
+ /* Fetch an audio frame */
+
+ result = xmv_fetch_audio_packet(s, pkt, xmv->current_stream - 1);
+ if (result)
+ return result;
+ }
+
+ /* Increase our counters */
+ if (++xmv->current_stream >= xmv->stream_count) {
+ xmv->current_stream = 0;
+ xmv->video.current_frame += 1;
+ }
+
+ return 0;
+}
+
+static int xmv_read_close(AVFormatContext *s)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+
+ av_free(xmv->audio);
+
+ return 0;
+}
+
+AVInputFormat ff_xmv_demuxer = {
+ .name = "xmv",
+ .long_name = NULL_IF_CONFIG_SMALL("Microsoft XMV"),
+ .priv_data_size = sizeof(XMVDemuxContext),
+ .read_probe = xmv_probe,
+ .read_header = xmv_read_header,
+ .read_packet = xmv_read_packet,
+ .read_close = xmv_read_close,
+};
diff --git a/libavformat/xwma.c b/libavformat/xwma.c
index d18ab48795..94208abc47 100644
--- a/libavformat/xwma.c
+++ b/libavformat/xwma.c
@@ -2,20 +2,20 @@
* xWMA demuxer
* Copyright (c) 2011 Max Horn
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -69,7 +69,7 @@ static int xwma_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (tag != MKTAG('f', 'm', 't', ' '))
return -1;
size = avio_rl32(pb);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -252,10 +252,10 @@ static int xwma_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_xwma_demuxer = {
- "xwma",
- NULL_IF_CONFIG_SMALL("Microsoft xWMA"),
- sizeof(XWMAContext),
- xwma_probe,
- xwma_read_header,
- xwma_read_packet,
+ .name = "xwma",
+ .long_name = NULL_IF_CONFIG_SMALL("Microsoft xWMA"),
+ .priv_data_size = sizeof(XWMAContext),
+ .read_probe = xwma_probe,
+ .read_header = xwma_read_header,
+ .read_packet = xwma_read_packet,
};
diff --git a/libavformat/yop.c b/libavformat/yop.c
index e3671874a1..8cadf125a2 100644
--- a/libavformat/yop.c
+++ b/libavformat/yop.c
@@ -1,25 +1,24 @@
-/**
- * @file
+/*
* Psygnosis YOP demuxer
*
* Copyright (C) 2010 Mohamed Naufal Basheer <naufal11@gmail.com>
* derived from the code by
* Copyright (C) 2009 Thomas P. Higdon <thomas.p.higdon@gmail.com>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -57,8 +56,8 @@ static int yop_read_header(AVFormatContext *s, AVFormatParameters *ap)
int frame_rate, ret;
- audio_stream = av_new_stream(s, 0);
- video_stream = av_new_stream(s, 1);
+ audio_stream = avformat_new_stream(s, NULL);
+ video_stream = avformat_new_stream(s, NULL);
// Extra data that will be passed to the decoder
video_stream->codec->extradata_size = 8;
@@ -184,8 +183,6 @@ static int yop_read_seek(AVFormatContext *s, int stream_index,
int64_t frame_pos, pos_min, pos_max;
int frame_count;
- av_free_packet(&yop->video_packet);
-
if (!stream_index)
return -1;
@@ -196,21 +193,25 @@ static int yop_read_seek(AVFormatContext *s, int stream_index,
timestamp = FFMAX(0, FFMIN(frame_count, timestamp));
frame_pos = timestamp * yop->frame_size + pos_min;
+
+ if (avio_seek(s->pb, frame_pos, SEEK_SET) < 0)
+ return -1;
+
+ av_free_packet(&yop->video_packet);
yop->odd_frame = timestamp & 1;
- avio_seek(s->pb, frame_pos, SEEK_SET);
return 0;
}
AVInputFormat ff_yop_demuxer = {
- "yop",
- NULL_IF_CONFIG_SMALL("Psygnosis YOP Format"),
- sizeof(YopDecContext),
- yop_probe,
- yop_read_header,
- yop_read_packet,
- yop_read_close,
- yop_read_seek,
+ .name = "yop",
+ .long_name = NULL_IF_CONFIG_SMALL("Psygnosis YOP Format"),
+ .priv_data_size = sizeof(YopDecContext),
+ .read_probe = yop_probe,
+ .read_header = yop_read_header,
+ .read_packet = yop_read_packet,
+ .read_close = yop_read_close,
+ .read_seek = yop_read_seek,
.extensions = "yop",
.flags = AVFMT_GENERIC_INDEX,
};
diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c
index 9a6a0c8315..97d2261a93 100644
--- a/libavformat/yuv4mpeg.c
+++ b/libavformat/yuv4mpeg.c
@@ -2,20 +2,20 @@
* YUV4MPEG format
* Copyright (c) 2001, 2002, 2003 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
@@ -154,6 +154,12 @@ static int yuv4_write_header(AVFormatContext *s)
if (s->nb_streams != 1)
return AVERROR(EIO);
+ if (s->streams[0]->codec->codec_id != CODEC_ID_RAWVIDEO) {
+ av_log(s, AV_LOG_ERROR,
+ "A non-rawvideo stream was selected, but yuv4mpeg only handles rawvideo streams\n");
+ return AVERROR(EINVAL);
+ }
+
if (s->streams[0]->codec->pix_fmt == PIX_FMT_YUV411P) {
av_log(s, AV_LOG_ERROR, "Warning: generating rarely used 4:1:1 YUV stream, some mjpegtools might not work.\n");
}
@@ -170,15 +176,15 @@ static int yuv4_write_header(AVFormatContext *s)
}
AVOutputFormat ff_yuv4mpegpipe_muxer = {
- "yuv4mpegpipe",
- NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"),
- "",
- "y4m",
- sizeof(int),
- CODEC_ID_NONE,
- CODEC_ID_RAWVIDEO,
- yuv4_write_header,
- yuv4_write_packet,
+ .name = "yuv4mpegpipe",
+ .long_name = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"),
+ .mime_type = "",
+ .extensions = "y4m",
+ .priv_data_size = sizeof(int),
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_header = yuv4_write_header,
+ .write_packet = yuv4_write_packet,
.flags = AVFMT_RAWPICTURE,
};
#endif
@@ -327,7 +333,7 @@ static int yuv4_read_header(AVFormatContext *s, AVFormatParameters *ap)
aspectd = 1;
}
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if(!st)
return AVERROR(ENOMEM);
st->codec->width = width;
@@ -391,12 +397,12 @@ static int yuv4_probe(AVProbeData *pd)
#if CONFIG_YUV4MPEGPIPE_DEMUXER
AVInputFormat ff_yuv4mpegpipe_demuxer = {
- "yuv4mpegpipe",
- NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"),
- sizeof(struct frame_attributes),
- yuv4_probe,
- yuv4_read_header,
- yuv4_read_packet,
+ .name = "yuv4mpegpipe",
+ .long_name = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"),
+ .priv_data_size = sizeof(struct frame_attributes),
+ .read_probe = yuv4_probe,
+ .read_header = yuv4_read_header,
+ .read_packet = yuv4_read_packet,
.extensions = "y4m"
};
#endif