Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/4xm.c4
-rw-r--r--libavformat/Makefile6
-rw-r--r--libavformat/aacdec.c2
-rw-r--r--libavformat/aiffdec.c3
-rw-r--r--libavformat/aiffenc.c7
-rw-r--r--libavformat/ape.c60
-rw-r--r--libavformat/apetag.c9
-rw-r--r--libavformat/applehttp.c3
-rw-r--r--libavformat/asfdec.c57
-rw-r--r--libavformat/asfenc.c18
-rw-r--r--libavformat/avformat.h161
-rw-r--r--libavformat/avidec.c48
-rw-r--r--libavformat/avienc.c7
-rw-r--r--libavformat/avio.c10
-rw-r--r--libavformat/avio.h1
-rw-r--r--libavformat/avio_internal.h2
-rw-r--r--libavformat/aviobuf.c2
-rw-r--r--libavformat/cafdec.c3
-rw-r--r--libavformat/cafenc.c6
-rw-r--r--libavformat/cavsvideodec.c11
-rw-r--r--libavformat/crypto.c4
-rw-r--r--libavformat/diracdec.c11
-rw-r--r--libavformat/dnxhddec.c11
-rw-r--r--libavformat/ffmdec.c14
-rw-r--r--libavformat/ffmeta.h6
-rw-r--r--libavformat/ffmetadec.c7
-rw-r--r--libavformat/ffmetaenc.c7
-rw-r--r--libavformat/flacenc.c3
-rw-r--r--libavformat/flvdec.c11
-rw-r--r--libavformat/flvenc.c7
-rw-r--r--libavformat/gif.c4
-rw-r--r--libavformat/h261dec.c12
-rw-r--r--libavformat/h263dec.c12
-rw-r--r--libavformat/h264dec.c12
-rw-r--r--libavformat/id3v1.c7
-rw-r--r--libavformat/id3v2.c48
-rw-r--r--libavformat/iff.c87
-rw-r--r--libavformat/img2.c71
-rw-r--r--libavformat/ingenientdec.c3
-rw-r--r--libavformat/internal.h10
-rw-r--r--libavformat/ipmovie.c104
-rw-r--r--libavformat/isom.c20
-rw-r--r--libavformat/isom.h3
-rw-r--r--libavformat/m4vdec.c12
-rw-r--r--libavformat/matroska.c24
-rw-r--r--libavformat/matroska.h34
-rw-r--r--libavformat/matroskadec.c97
-rw-r--r--libavformat/matroskaenc.c59
-rw-r--r--libavformat/metadata.c105
-rw-r--r--libavformat/metadata.h8
-rw-r--r--libavformat/mmf.c6
-rw-r--r--libavformat/mms.h3
-rw-r--r--libavformat/mmsh.c4
-rw-r--r--libavformat/mmst.c2
-rw-r--r--libavformat/mov.c86
-rw-r--r--libavformat/movenc.c112
-rw-r--r--libavformat/movenc.h6
-rw-r--r--libavformat/mp3dec.c3
-rw-r--r--libavformat/mp3enc.c18
-rw-r--r--libavformat/mpc.c3
-rw-r--r--libavformat/mpeg.c21
-rw-r--r--libavformat/mpegenc.c7
-rw-r--r--libavformat/mpegts.c76
-rw-r--r--libavformat/mpegtsenc.c12
-rw-r--r--libavformat/mpegvideodec.c11
-rw-r--r--libavformat/mxfdec.c8
-rw-r--r--libavformat/network.h6
-rw-r--r--libavformat/nsvdec.c38
-rw-r--r--libavformat/nutdec.c9
-rw-r--r--libavformat/nutenc.c9
-rw-r--r--libavformat/oggdec.c71
-rw-r--r--libavformat/oggdec.h2
-rw-r--r--libavformat/oggenc.c6
-rw-r--r--libavformat/oggparsecelt.c4
-rw-r--r--libavformat/oggparseogm.c4
-rw-r--r--libavformat/oggparsevorbis.c13
-rw-r--r--libavformat/oma.c2
-rw-r--r--libavformat/options.c7
-rw-r--r--libavformat/output-example.c538
-rw-r--r--libavformat/pcmdec.c3
-rw-r--r--libavformat/r3d.c27
-rw-r--r--libavformat/rawdec.c161
-rw-r--r--libavformat/rawdec.h31
-rw-r--r--libavformat/rawvideodec.c3
-rw-r--r--libavformat/riff.c2
-rw-r--r--libavformat/rl2.c6
-rw-r--r--libavformat/rmdec.c7
-rw-r--r--libavformat/rmenc.c7
-rw-r--r--libavformat/rpl.c11
-rw-r--r--libavformat/rtmppkt.c8
-rw-r--r--libavformat/rtmpproto.c2
-rw-r--r--libavformat/rtpdec.c2
-rw-r--r--libavformat/rtpdec_asf.c2
-rw-r--r--libavformat/rtpdec_latm.c5
-rw-r--r--libavformat/rtpenc.c19
-rw-r--r--libavformat/rtpenc.h10
-rw-r--r--libavformat/rtpenc_chain.c9
-rw-r--r--libavformat/rtpenc_h264.c32
-rw-r--r--libavformat/rtpenc_latm.c61
-rw-r--r--libavformat/rtsp.c8
-rw-r--r--libavformat/rtsp.h13
-rw-r--r--libavformat/rtspdec.c28
-rw-r--r--libavformat/rtspenc.c15
-rw-r--r--libavformat/sauce.c9
-rw-r--r--libavformat/sdp.c124
-rw-r--r--libavformat/smacker.c2
-rw-r--r--libavformat/sol.c3
-rw-r--r--libavformat/soxdec.c5
-rw-r--r--libavformat/soxenc.c5
-rw-r--r--libavformat/spdif.h5
-rw-r--r--libavformat/tcp.c32
-rw-r--r--libavformat/tta.c3
-rw-r--r--libavformat/tty.c70
-rw-r--r--libavformat/udp.c13
-rw-r--r--libavformat/url.h2
-rw-r--r--libavformat/utils.c133
-rw-r--r--libavformat/version.h13
-rw-r--r--libavformat/vorbiscomment.c13
-rw-r--r--libavformat/vorbiscomment.h6
-rw-r--r--libavformat/vqf.c3
-rw-r--r--libavformat/wav.c212
-rw-r--r--libavformat/wc3movie.c5
-rw-r--r--libavformat/wtvdec.c6
-rw-r--r--libavformat/wv.c3
-rw-r--r--libavformat/yuv4mpeg.c10
125 files changed, 1846 insertions, 1623 deletions
diff --git a/libavformat/4xm.c b/libavformat/4xm.c
index 699277248d..0b79c761a5 100644
--- a/libavformat/4xm.c
+++ b/libavformat/4xm.c
@@ -246,7 +246,7 @@ static int fourxm_read_packet(AVFormatContext *s,
FourxmDemuxContext *fourxm = s->priv_data;
AVIOContext *pb = s->pb;
unsigned int fourcc_tag;
- unsigned int size, out_size;
+ unsigned int size;
int ret = 0;
unsigned int track_number;
int packet_read = 0;
@@ -295,7 +295,7 @@ static int fourxm_read_packet(AVFormatContext *s,
case snd__TAG:
track_number = avio_rl32(pb);
- out_size= avio_rl32(pb);
+ avio_skip(pb, 4);
size-=8;
if (track_number < fourxm->track_count && fourxm->tracks[track_number].channels>0) {
diff --git a/libavformat/Makefile b/libavformat/Makefile
index cbaa4d6840..05f524690b 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -25,7 +25,7 @@ OBJS-$(CONFIG_AC3_MUXER) += rawenc.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 isom.o
-OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o riff.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
@@ -234,6 +234,7 @@ OBJS-$(CONFIG_RSO_MUXER) += rsoenc.o rso.o
OBJS-$(CONFIG_RPL_DEMUXER) += rpl.o
OBJS-$(CONFIG_RTP_MUXER) += rtp.o \
rtpenc_aac.o \
+ rtpenc_latm.o \
rtpenc_amr.o \
rtpenc_h263.o \
rtpenc_mpv.o \
@@ -340,9 +341,6 @@ OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o
# libavdevice dependencies
OBJS-$(CONFIG_JACK_INDEV) += timefilter.o
-EXAMPLES = output
TESTPROGS = timefilter
include $(SUBDIR)../subdir.mak
-
-$(SUBDIR)output-example$(EXESUF): ELIBS = -lswscale
diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c
index 47e9bf3a18..4ac2cadb8f 100644
--- a/libavformat/aacdec.c
+++ b/libavformat/aacdec.c
@@ -44,7 +44,7 @@ static int adts_aac_probe(AVProbeData *p)
uint32_t header = AV_RB16(buf2);
if((header&0xFFF6) != 0xFFF0)
break;
- fsize = (AV_RB32(buf2+3)>>13) & 0x8FFF;
+ fsize = (AV_RB32(buf2 + 3) >> 13) & 0x1FFF;
if(fsize < 7)
break;
buf2 += fsize;
diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c
index e691bba29d..9608910340 100644
--- a/libavformat/aiffdec.c
+++ b/libavformat/aiffdec.c
@@ -20,6 +20,7 @@
*/
#include "libavutil/intfloat_readwrite.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "pcm.h"
#include "aiff.h"
@@ -77,7 +78,7 @@ static void get_meta(AVFormatContext *s, const char *key, int size)
}
size += (size&1)-res;
str[res] = 0;
- av_metadata_set2(&s->metadata, key, str, AV_METADATA_DONT_STRDUP_VAL);
+ av_dict_set(&s->metadata, key, str, AV_METADATA_DONT_STRDUP_VAL);
}else
size+= size&1;
diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
index cc3cbc4762..34ab0cc246 100644
--- a/libavformat/aiffenc.c
+++ b/libavformat/aiffenc.c
@@ -22,6 +22,7 @@
#include "avformat.h"
#include "aiff.h"
#include "avio_internal.h"
+#include "isom.h"
typedef struct {
int64_t form;
@@ -61,6 +62,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 */
diff --git a/libavformat/ape.c b/libavformat/ape.c
index 4b37c7972d..bda6b32b1d 100644
--- a/libavformat/ape.c
+++ b/libavformat/ape.c
@@ -26,8 +26,6 @@
#include "avformat.h"
#include "apetag.h"
-#define ENABLE_DEBUG 0
-
/* The earliest and latest file formats supported by this library */
#define APE_MIN_VERSION 3950
#define APE_MAX_VERSION 3990
@@ -96,19 +94,19 @@ static int ape_probe(AVProbeData * p)
static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx)
{
-#if ENABLE_DEBUG
+#ifdef DEBUG
int i;
av_log(s, AV_LOG_DEBUG, "Descriptor Block:\n\n");
av_log(s, AV_LOG_DEBUG, "magic = \"%c%c%c%c\"\n", ape_ctx->magic[0], ape_ctx->magic[1], ape_ctx->magic[2], ape_ctx->magic[3]);
- av_log(s, AV_LOG_DEBUG, "fileversion = %d\n", ape_ctx->fileversion);
- av_log(s, AV_LOG_DEBUG, "descriptorlength = %d\n", ape_ctx->descriptorlength);
- av_log(s, AV_LOG_DEBUG, "headerlength = %d\n", ape_ctx->headerlength);
- av_log(s, AV_LOG_DEBUG, "seektablelength = %d\n", ape_ctx->seektablelength);
- av_log(s, AV_LOG_DEBUG, "wavheaderlength = %d\n", ape_ctx->wavheaderlength);
- av_log(s, AV_LOG_DEBUG, "audiodatalength = %d\n", ape_ctx->audiodatalength);
- av_log(s, AV_LOG_DEBUG, "audiodatalength_high = %d\n", ape_ctx->audiodatalength_high);
- av_log(s, AV_LOG_DEBUG, "wavtaillength = %d\n", ape_ctx->wavtaillength);
+ av_log(s, AV_LOG_DEBUG, "fileversion = %"PRId16"\n", ape_ctx->fileversion);
+ av_log(s, AV_LOG_DEBUG, "descriptorlength = %"PRIu32"\n", ape_ctx->descriptorlength);
+ av_log(s, AV_LOG_DEBUG, "headerlength = %"PRIu32"\n", ape_ctx->headerlength);
+ av_log(s, AV_LOG_DEBUG, "seektablelength = %"PRIu32"\n", ape_ctx->seektablelength);
+ av_log(s, AV_LOG_DEBUG, "wavheaderlength = %"PRIu32"\n", ape_ctx->wavheaderlength);
+ av_log(s, AV_LOG_DEBUG, "audiodatalength = %"PRIu32"\n", ape_ctx->audiodatalength);
+ av_log(s, AV_LOG_DEBUG, "audiodatalength_high = %"PRIu32"\n", ape_ctx->audiodatalength_high);
+ av_log(s, AV_LOG_DEBUG, "wavtaillength = %"PRIu32"\n", ape_ctx->wavtaillength);
av_log(s, AV_LOG_DEBUG, "md5 = ");
for (i = 0; i < 16; i++)
av_log(s, AV_LOG_DEBUG, "%02x", ape_ctx->md5[i]);
@@ -116,14 +114,14 @@ static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx)
av_log(s, AV_LOG_DEBUG, "\nHeader Block:\n\n");
- av_log(s, AV_LOG_DEBUG, "compressiontype = %d\n", ape_ctx->compressiontype);
- av_log(s, AV_LOG_DEBUG, "formatflags = %d\n", ape_ctx->formatflags);
- av_log(s, AV_LOG_DEBUG, "blocksperframe = %d\n", ape_ctx->blocksperframe);
- av_log(s, AV_LOG_DEBUG, "finalframeblocks = %d\n", ape_ctx->finalframeblocks);
- av_log(s, AV_LOG_DEBUG, "totalframes = %d\n", ape_ctx->totalframes);
- av_log(s, AV_LOG_DEBUG, "bps = %d\n", ape_ctx->bps);
- av_log(s, AV_LOG_DEBUG, "channels = %d\n", ape_ctx->channels);
- av_log(s, AV_LOG_DEBUG, "samplerate = %d\n", ape_ctx->samplerate);
+ av_log(s, AV_LOG_DEBUG, "compressiontype = %"PRIu16"\n", ape_ctx->compressiontype);
+ av_log(s, AV_LOG_DEBUG, "formatflags = %"PRIu16"\n", ape_ctx->formatflags);
+ av_log(s, AV_LOG_DEBUG, "blocksperframe = %"PRIu32"\n", ape_ctx->blocksperframe);
+ av_log(s, AV_LOG_DEBUG, "finalframeblocks = %"PRIu32"\n", ape_ctx->finalframeblocks);
+ av_log(s, AV_LOG_DEBUG, "totalframes = %"PRIu32"\n", ape_ctx->totalframes);
+ av_log(s, AV_LOG_DEBUG, "bps = %"PRIu16"\n", ape_ctx->bps);
+ av_log(s, AV_LOG_DEBUG, "channels = %"PRIu16"\n", ape_ctx->channels);
+ av_log(s, AV_LOG_DEBUG, "samplerate = %"PRIu32"\n", ape_ctx->samplerate);
av_log(s, AV_LOG_DEBUG, "\nSeektable\n\n");
if ((ape_ctx->seektablelength / sizeof(uint32_t)) != ape_ctx->totalframes) {
@@ -140,12 +138,14 @@ static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx)
av_log(s, AV_LOG_DEBUG, "\nFrames\n\n");
for (i = 0; i < ape_ctx->totalframes; i++)
- av_log(s, AV_LOG_DEBUG, "%8d %8lld %8d (%d samples)\n", i, ape_ctx->frames[i].pos, ape_ctx->frames[i].size, ape_ctx->frames[i].nblocks);
+ av_log(s, AV_LOG_DEBUG, "%8d %8"PRId64" %8d (%d samples)\n", i,
+ ape_ctx->frames[i].pos, ape_ctx->frames[i].size,
+ ape_ctx->frames[i].nblocks);
av_log(s, AV_LOG_DEBUG, "\nCalculated information:\n\n");
- av_log(s, AV_LOG_DEBUG, "junklength = %d\n", ape_ctx->junklength);
- av_log(s, AV_LOG_DEBUG, "firstframe = %d\n", ape_ctx->firstframe);
- av_log(s, AV_LOG_DEBUG, "totalsamples = %d\n", ape_ctx->totalsamples);
+ av_log(s, AV_LOG_DEBUG, "junklength = %"PRIu32"\n", ape_ctx->junklength);
+ av_log(s, AV_LOG_DEBUG, "firstframe = %"PRIu32"\n", ape_ctx->firstframe);
+ av_log(s, AV_LOG_DEBUG, "totalsamples = %"PRIu32"\n", ape_ctx->totalsamples);
#endif
}
@@ -169,7 +169,8 @@ 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 - %d.%02d\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10);
+ av_log(s, AV_LOG_ERROR, "Unsupported file version - %"PRId16".%02"PRId16"\n",
+ ape->fileversion / 1000, (ape->fileversion % 1000) / 10);
return -1;
}
@@ -247,11 +248,12 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
return AVERROR(EINVAL);
}
if(ape->totalframes > UINT_MAX / sizeof(APEFrame)){
- av_log(s, AV_LOG_ERROR, "Too many frames: %d\n", ape->totalframes);
+ av_log(s, AV_LOG_ERROR, "Too many frames: %"PRIu32"\n",
+ ape->totalframes);
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: %zd vs. %d\n",
+ av_log(s, AV_LOG_ERROR, "Number of seek entries is less than number of frames: %ld vs. %"PRIu32"\n",
ape->seektablelength / sizeof(*ape->seektable), ape->totalframes);
return AVERROR_INVALIDDATA;
}
@@ -276,7 +278,7 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
ape->frames[0].nblocks = ape->blocksperframe;
ape->frames[0].skip = 0;
for (i = 1; i < ape->totalframes; i++) {
- ape->frames[i].pos = ape->seektable[i] + ape->junklength; //ape->frames[i-1].pos + ape->blocksperframe;
+ ape->frames[i].pos = ape->seektable[i] + ape->junklength;
ape->frames[i].nblocks = ape->blocksperframe;
ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos;
ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3;
@@ -301,7 +303,9 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
avio_seek(pb, 0, SEEK_SET);
}
- av_log(s, AV_LOG_DEBUG, "Decoding file - v%d.%02d, compression level %d\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10, ape->compressiontype);
+ av_log(s, AV_LOG_DEBUG, "Decoding file - v%d.%02d, compression level %"PRIu16"\n",
+ ape->fileversion / 1000, (ape->fileversion % 1000) / 10,
+ ape->compressiontype);
/* now we are ready: build format streams */
st = av_new_stream(s, 0);
diff --git a/libavformat/apetag.c b/libavformat/apetag.c
index fb46d2bac2..8d53e4cdf7 100644
--- a/libavformat/apetag.c
+++ b/libavformat/apetag.c
@@ -21,11 +21,10 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "apetag.h"
-#define ENABLE_DEBUG 0
-
#define APE_TAG_VERSION 2000
#define APE_TAG_FOOTER_BYTES 32
#define APE_TAG_FLAG_CONTAINS_HEADER (1 << 31)
@@ -35,11 +34,11 @@ static int ape_tag_read_field(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
uint8_t key[1024], *value;
- uint32_t size, flags;
+ uint32_t size;
int i, c;
size = avio_rl32(pb); /* field size */
- flags = avio_rl32(pb); /* field flags */
+ avio_skip(pb, 4); /* field flags */
for (i = 0; i < sizeof(key) - 1; i++) {
c = avio_r8(pb);
if (c < 0x20 || c > 0x7E)
@@ -59,7 +58,7 @@ static int ape_tag_read_field(AVFormatContext *s)
return AVERROR(ENOMEM);
avio_read(pb, value, size);
value[size] = 0;
- av_metadata_set2(&s->metadata, key, value, AV_METADATA_DONT_STRDUP_VAL);
+ av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
return 0;
}
diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c
index d0de6bbc3e..dec77f80e6 100644
--- a/libavformat/applehttp.c
+++ b/libavformat/applehttp.c
@@ -28,6 +28,7 @@
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/opt.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "internal.h"
#include <unistd.h>
@@ -507,7 +508,7 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);
if (v->bandwidth)
- av_metadata_set2(&st->metadata, "variant_bitrate", bitrate_str,
+ av_dict_set(&st->metadata, "variant_bitrate", bitrate_str,
0);
}
stream_offset += v->ctx->nb_streams;
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index 4a4f1d927c..725e013b17 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -21,8 +21,10 @@
//#define DEBUG
+#include "libavutil/bswap.h"
#include "libavutil/common.h"
#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
#include "libavcodec/mpegaudio.h"
#include "avformat.h"
#include "avio_internal.h"
@@ -171,7 +173,8 @@ static void get_tag(AVFormatContext *s, const char *key, int type, int len)
av_log(s, AV_LOG_DEBUG, "Unsupported value type %d in tag %s.\n", type, key);
goto finish;
}
- av_metadata_set2(&s->metadata, key, value, 0);
+ if (*value)
+ av_dict_set(&s->metadata, key, value, 0);
finish:
av_freep(&value);
avio_seek(s->pb, off + len, SEEK_SET);
@@ -208,7 +211,6 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
ff_asf_guid g;
enum AVMediaType type;
int type_specific_size, sizeX;
- uint64_t total_size;
unsigned int tag1;
int64_t pos1, pos2, start_time;
int test_for_ext_stream_audio, is_dvr_ms_audio=0;
@@ -255,7 +257,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
return -1;
}
ff_get_guid(pb, &g);
- total_size = avio_rl64(pb);
+ avio_skip(pb, 8); /* total_size */
type_specific_size = avio_rl32(pb);
avio_rl32(pb);
st->id = avio_rl16(pb) & 0x7f; /* stream id */
@@ -393,7 +395,7 @@ static int asf_read_ext_stream_properties(AVFormatContext *s, int64_t size)
AVIOContext *pb = s->pb;
ff_asf_guid g;
int ext_len, payload_ext_ct, stream_ct, i;
- uint32_t ext_d, leak_rate, stream_num;
+ uint32_t leak_rate, stream_num;
unsigned int stream_languageid_index;
avio_rl64(pb); // starttime
@@ -427,7 +429,7 @@ static int asf_read_ext_stream_properties(AVFormatContext *s, int64_t size)
for (i=0; i<payload_ext_ct; i++){
ff_get_guid(pb, &g);
- ext_d=avio_rl16(pb);
+ avio_skip(pb, 2);
ext_len=avio_rl32(pb);
avio_skip(pb, ext_len);
}
@@ -511,7 +513,7 @@ static int asf_read_metadata(AVFormatContext *s, int64_t size)
{
AVIOContext *pb = s->pb;
ASFContext *asf = s->priv_data;
- int n, stream_num, name_len, value_len, value_type, value_num;
+ int n, stream_num, name_len, value_len, value_num;
int ret, i;
n = avio_rl16(pb);
@@ -521,7 +523,7 @@ static int asf_read_metadata(AVFormatContext *s, int64_t size)
avio_rl16(pb); //lang_list_index
stream_num= avio_rl16(pb);
name_len= avio_rl16(pb);
- value_type= avio_rl16(pb);
+ avio_skip(pb, 2); /* value_type */
value_len= avio_rl32(pb);
if ((ret = avio_get_str16le(pb, name_len, name, sizeof(name))) < name_len)
@@ -626,10 +628,8 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
// if so the next iteration will pick it up
continue;
} else if (!ff_guidcmp(&g, &ff_asf_head1_guid)) {
- int v1, v2;
ff_get_guid(pb, &g);
- v1 = avio_rl32(pb);
- v2 = avio_rl16(pb);
+ avio_skip(pb, 6);
continue;
} else if (!ff_guidcmp(&g, &ff_asf_marker_header)) {
asf_read_marker(s, gsize);
@@ -684,7 +684,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' }; // ignore country code if any
const char *iso6392 = av_convert_lang_to(primary_tag, AV_LANG_ISO639_2_BIBL);
if (iso6392)
- av_metadata_set2(&st->metadata, "language", iso6392, 0);
+ av_dict_set(&st->metadata, "language", iso6392, 0);
}
}
}
@@ -799,7 +799,7 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
ASFContext *asf = s->priv_data;
int rsize = 1;
int num = avio_r8(pb);
- int64_t ts0, ts1;
+ int64_t ts0;
asf->packet_segments--;
asf->packet_key_frame = num >> 7;
@@ -822,7 +822,7 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
// av_log(s, AV_LOG_DEBUG, "\n");
avio_skip(pb, 10);
ts0= avio_rl64(pb);
- ts1= avio_rl64(pb);
+ avio_skip(pb, 8);;
avio_skip(pb, 12);
avio_rl32(pb);
avio_skip(pb, asf->packet_replic_size - 8 - 38 - 4);
@@ -849,7 +849,10 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
}
if (asf->packet_flags & 0x01) {
DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal
- if(asf->packet_frag_size > asf->packet_size_left - rsize){
+ if (rsize > asf->packet_size_left) {
+ av_log(s, AV_LOG_ERROR, "packet_replic_size is invalid\n");
+ return -1;
+ } else if(asf->packet_frag_size > asf->packet_size_left - rsize){
if (asf->packet_frag_size > asf->packet_size_left - rsize + asf->packet_padsize) {
av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid (%d-%d)\n", asf->packet_size_left, rsize);
return -1;
@@ -1257,21 +1260,22 @@ 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(av_seek_frame_binary(s, stream_index, pts, flags)<0)
- return -1;
- }else{
+ if((asf->index_read && st->index_entries)){
index= av_index_search_timestamp(st, pts, flags);
- if(index<0)
- return -1;
+ if(index >= 0) {
+ /* find the position */
+ pos = st->index_entries[index].pos;
- /* find the position */
- pos = st->index_entries[index].pos;
-
- /* do the seek */
- av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos);
- avio_seek(s->pb, pos, SEEK_SET);
+ /* do the seek */
+ av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos);
+ avio_seek(s->pb, pos, SEEK_SET);
+ asf_reset_header(s);
+ return 0;
+ }
}
+ /* no index or seeking by index failed */
+ if(av_seek_frame_binary(s, stream_index, pts, flags)<0)
+ return -1;
asf_reset_header(s);
return 0;
}
@@ -1286,4 +1290,5 @@ AVInputFormat ff_asf_demuxer = {
asf_read_close,
asf_read_seek,
asf_read_pts,
+ .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH,
};
diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c
index fe5a67ce4b..5c929f4547 100644
--- a/libavformat/asfenc.c
+++ b/libavformat/asfenc.c
@@ -19,10 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
-#include "metadata.h"
#include "riff.h"
#include "asf.h"
#include "avio_internal.h"
+#include "libavutil/dict.h"
#undef NDEBUG
#include <assert.h>
@@ -296,7 +296,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
{
ASFContext *asf = s->priv_data;
AVIOContext *pb = s->pb;
- AVMetadataTag *tags[5];
+ AVDictionaryEntry *tags[5];
int header_size, n, extra_size, extra_size2, wav_extra_size, file_time;
int has_title;
int metadata_count;
@@ -307,11 +307,11 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
ff_metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL);
- tags[0] = av_metadata_get(s->metadata, "title" , NULL, 0);
- tags[1] = av_metadata_get(s->metadata, "author" , NULL, 0);
- tags[2] = av_metadata_get(s->metadata, "copyright", NULL, 0);
- tags[3] = av_metadata_get(s->metadata, "comment" , NULL, 0);
- tags[4] = av_metadata_get(s->metadata, "rating" , NULL, 0);
+ tags[0] = av_dict_get(s->metadata, "title" , NULL, 0);
+ tags[1] = av_dict_get(s->metadata, "author" , NULL, 0);
+ tags[2] = av_dict_get(s->metadata, "copyright", NULL, 0);
+ tags[3] = av_dict_get(s->metadata, "comment" , NULL, 0);
+ tags[4] = av_dict_get(s->metadata, "rating" , NULL, 0);
duration = asf->duration + PREROLL_TIME * 10000;
has_title = tags[0] || tags[1] || tags[2] || tags[3] || tags[4];
@@ -381,10 +381,10 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
end_header(pb, hpos);
}
if (metadata_count) {
- AVMetadataTag *tag = NULL;
+ AVDictionaryEntry *tag = NULL;
hpos = put_header(pb, &ff_asf_extended_content_header);
avio_wl16(pb, metadata_count);
- while ((tag = av_metadata_get(s->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX))) {
+ while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
put_str16(pb, tag->key);
avio_wl16(pb, 0);
put_str16(pb, tag->value);
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index e558096cf2..05cbf0a6b1 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -23,8 +23,7 @@
/**
- * I return the LIBAVFORMAT_VERSION_INT constant. You got
- * a fucking problem with that, douchebag?
+ * Return the LIBAVFORMAT_VERSION_INT constant.
*/
unsigned avformat_version(void);
@@ -41,6 +40,7 @@ const char *avformat_license(void);
#include <time.h>
#include <stdio.h> /* FILE */
#include "libavcodec/avcodec.h"
+#include "libavutil/dict.h"
#include "avio.h"
#include "libavformat/version.h"
@@ -107,21 +107,24 @@ struct AVFormatContext;
* variant_bitrate -- the total bitrate of the bitrate variant that the current stream is part of
*/
-#define AV_METADATA_MATCH_CASE 1
-#define AV_METADATA_IGNORE_SUFFIX 2
-#define AV_METADATA_DONT_STRDUP_KEY 4
-#define AV_METADATA_DONT_STRDUP_VAL 8
-#define AV_METADATA_DONT_OVERWRITE 16 ///< Don't overwrite existing tags.
+#if FF_API_OLD_METADATA2
+/**
+ * @defgroup old_metadata Old metadata API
+ * The following functions are deprecated, use
+ * their equivalents from libavutil/dict.h instead.
+ * @{
+ */
-typedef struct {
- char *key;
- char *value;
-}AVMetadataTag;
+#define AV_METADATA_MATCH_CASE AV_DICT_MATCH_CASE
+#define AV_METADATA_IGNORE_SUFFIX AV_DICT_IGNORE_SUFFIX
+#define AV_METADATA_DONT_STRDUP_KEY AV_DICT_DONT_STRDUP_KEY
+#define AV_METADATA_DONT_STRDUP_VAL AV_DICT_DONT_STRDUP_VAL
+#define AV_METADATA_DONT_OVERWRITE AV_DICT_DONT_OVERWRITE
+
+typedef attribute_deprecated AVDictionary AVMetadata;
+typedef attribute_deprecated AVDictionaryEntry AVMetadataTag;
-typedef struct AVMetadata AVMetadata;
-#if FF_API_OLD_METADATA2
typedef struct AVMetadataConv AVMetadataConv;
-#endif
/**
* Get a metadata element with matching key.
@@ -131,8 +134,8 @@ typedef struct AVMetadataConv AVMetadataConv;
* @param flags Allows case as well as suffix-insensitive comparisons.
* @return Found tag or NULL, changing key or value leads to undefined behavior.
*/
-AVMetadataTag *
-av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags);
+attribute_deprecated AVDictionaryEntry *
+av_metadata_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags);
#if FF_API_OLD_METADATA
/**
@@ -158,30 +161,32 @@ attribute_deprecated int av_metadata_set(AVMetadata **pm, const char *key, const
* Passing a NULL value will cause an existing tag to be deleted.
* @return >= 0 on success otherwise an error code <0
*/
-int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags);
+attribute_deprecated int av_metadata_set2(AVDictionary **pm, const char *key, const char *value, int flags);
-#if FF_API_OLD_METADATA2
/**
* This function is provided for compatibility reason and currently does nothing.
*/
attribute_deprecated void av_metadata_conv(struct AVFormatContext *ctx, const AVMetadataConv *d_conv,
const AVMetadataConv *s_conv);
-#endif
/**
- * Copy metadata from one AVMetadata struct into another.
- * @param dst pointer to a pointer to a AVMetadata struct. If *dst is NULL,
+ * Copy metadata from one AVDictionary struct into another.
+ * @param dst pointer to a pointer to a AVDictionary struct. If *dst is NULL,
* this function will allocate a struct for you and put it in *dst
- * @param src pointer to source AVMetadata struct
+ * @param src pointer to source AVDictionary struct
* @param flags flags to use when setting metadata in *dst
- * @note metadata is read using the AV_METADATA_IGNORE_SUFFIX flag
+ * @note metadata is read using the AV_DICT_IGNORE_SUFFIX flag
*/
-void av_metadata_copy(AVMetadata **dst, AVMetadata *src, int flags);
+attribute_deprecated void av_metadata_copy(AVDictionary **dst, AVDictionary *src, int flags);
/**
- * Free all the memory allocated for an AVMetadata struct.
+ * Free all the memory allocated for an AVDictionary struct.
+ */
+attribute_deprecated void av_metadata_free(AVDictionary **m);
+/**
+ * @}
*/
-void av_metadata_free(AVMetadata **m);
+#endif
/* packet functions */
@@ -242,20 +247,21 @@ typedef struct AVProbeData {
#define AVPROBE_PADDING_SIZE 32 ///< extra allocated bytes at the end of the probe buffer
typedef struct AVFormatParameters {
- AVRational time_base;
- int sample_rate;
- int channels;
- int width;
- int height;
- enum PixelFormat pix_fmt;
- int channel; /**< Used to select DV channel. */
- const char *standard; /**< TV standard, NTSC, PAL, SECAM */
- unsigned int mpeg2ts_raw:1; /**< Force raw MPEG-2 transport stream output, if possible. */
- unsigned int mpeg2ts_compute_pcr:1; /**< Compute exact PCR for each transport
- stream packet (only meaningful if
- mpeg2ts_raw is TRUE). */
- unsigned int initial_pause:1; /**< Do not begin to play the stream
- immediately (RTSP only). */
+#if FF_API_FORMAT_PARAMETERS
+ attribute_deprecated AVRational time_base;
+ attribute_deprecated int sample_rate;
+ attribute_deprecated int channels;
+ attribute_deprecated int width;
+ attribute_deprecated int height;
+ attribute_deprecated enum PixelFormat pix_fmt;
+ attribute_deprecated int channel; /**< Used to select DV channel. */
+ attribute_deprecated const char *standard; /**< deprecated, use demuxer-specific options instead. */
+ attribute_deprecated unsigned int mpeg2ts_raw:1; /**< deprecated, use mpegtsraw demuxer */
+ /**< deprecated, use mpegtsraw demuxer-specific options instead */
+ attribute_deprecated unsigned int mpeg2ts_compute_pcr:1;
+ attribute_deprecated unsigned int initial_pause:1; /**< Do not begin to play the stream
+ immediately (RTSP only). */
+#endif
unsigned int prealloced_context:1;
#if FF_API_PARAMETERS_CODEC_ID
attribute_deprecated enum CodecID video_codec_id;
@@ -276,6 +282,11 @@ typedef struct AVFormatParameters {
#define AVFMT_VARIABLE_FPS 0x0400 /**< Format allows variable fps. */
#define AVFMT_NODIMENSIONS 0x0800 /**< Format does not need width/height */
#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_TS_NONSTRICT 0x8000 /**< Format does not require strictly
+ increasing timestamps, but they must
+ still be monotonic */
typedef struct AVOutputFormat {
const char *name;
@@ -588,7 +599,7 @@ typedef struct AVStream {
*/
AVRational sample_aspect_ratio;
- AVMetadata *metadata;
+ AVDictionary *metadata;
/* Intended mostly for av_read_frame() support. Not supposed to be used by */
/* external applications; try to use something else if at all possible. */
@@ -630,6 +641,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)
@@ -666,7 +684,11 @@ typedef struct AVProgram {
enum AVDiscard discard; ///< selects which program to discard and which to feed to the caller
unsigned int *stream_index;
unsigned int nb_stream_indexes;
- AVMetadata *metadata;
+ AVDictionary *metadata;
+
+ int program_num;
+ int pmt_pid;
+ int pcr_pid;
} AVProgram;
#define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present
@@ -679,7 +701,7 @@ typedef struct AVChapter {
#if FF_API_OLD_METADATA
attribute_deprecated char *title; ///< chapter title
#endif
- AVMetadata *metadata;
+ AVDictionary *metadata;
} AVChapter;
#if FF_API_MAX_STREAMS
@@ -789,10 +811,13 @@ typedef struct AVFormatContext {
#define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS
#define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container
#define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled
-#define AVFMT_FLAG_RTP_HINT 0x0040 ///< Add RTP hinting to the output file
+#if FF_API_FLAG_RTP_HINT
+#define AVFMT_FLAG_RTP_HINT 0x0040 ///< Deprecated, use the -movflags rtphint muxer specific AVOption instead
+#endif
+#define AVFMT_FLAG_MP4A_LATM 0x0080 ///< 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;
/**
@@ -868,7 +893,7 @@ typedef struct AVFormatContext {
struct AVPacketList *packet_buffer_end;
- AVMetadata *metadata;
+ AVDictionary *metadata;
/**
* Remaining size available for raw_packet_buffer, in bytes.
@@ -885,6 +910,17 @@ typedef struct AVFormatContext {
* - decoding: Unused.
*/
int64_t start_time_realtime;
+
+ /**
+ * decoding: number of frames used to probe fps
+ */
+ int fps_probe_size;
+
+ /**
+ * Transport stream id.
+ * This will be moved into demuxer private options. Thus no API/ABI compatibility
+ */
+ int ts_id;
} AVFormatContext;
typedef struct AVPacketList {
@@ -1138,12 +1174,34 @@ int av_demuxer_open(AVFormatContext *ic, AVFormatParameters *ap);
*/
AVFormatContext *avformat_alloc_context(void);
+#if FF_API_ALLOC_OUTPUT_CONTEXT
/**
- * Allocate an AVFormatContext.
- * avformat_free_context() can be used to free the context and everything
- * allocated by the framework within it.
+ * @deprecated deprecated in favor of avformat_alloc_output_context2()
*/
-AVFormatContext *avformat_alloc_output_context(const char *format, AVOutputFormat *oformat, const char *filename);
+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);
/**
* Read packets of a media file to get stream information. This
@@ -1493,6 +1551,9 @@ int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
int av_write_trailer(AVFormatContext *s);
#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,
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index 39686491e2..d3ae8bee73 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -19,13 +19,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-//#define DEBUG
-//#define DEBUG_SEEK
-
#include <strings.h>
#include "libavutil/intreadwrite.h"
#include "libavutil/bswap.h"
#include "libavutil/opt.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "avi.h"
#include "dv.h"
@@ -159,10 +157,8 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
int64_t last_pos= -1;
int64_t filesize= avio_size(s->pb);
-#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_ERROR, "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);
-#endif
+ 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);
if(stream_id >= s->nb_streams || stream_id < 0)
return -1;
@@ -280,8 +276,8 @@ static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t
AV_WL32(key, tag);
- return av_metadata_set2(st ? &st->metadata : &s->metadata, key, value,
- AV_METADATA_DONT_STRDUP_VAL);
+ return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
+ AV_DICT_DONT_STRDUP_VAL);
}
static void avi_read_info(AVFormatContext *s, uint64_t end)
@@ -296,7 +292,7 @@ static void avi_read_info(AVFormatContext *s, uint64_t end)
static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-static void avi_metadata_creation_time(AVMetadata **metadata, char *date)
+static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
{
char month[4], time[9], buffer[64];
int i, day, year;
@@ -307,11 +303,11 @@ static void avi_metadata_creation_time(AVMetadata **metadata, char *date)
if (!strcasecmp(month, months[i])) {
snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
year, i+1, day, time);
- av_metadata_set2(metadata, "creation_time", buffer, 0);
+ av_dict_set(metadata, "creation_time", buffer, 0);
}
} else if (date[4] == '/' && date[7] == '/') {
date[4] = date[7] = '-';
- av_metadata_set2(metadata, "creation_time", date, 0);
+ av_dict_set(metadata, "creation_time", date, 0);
}
}
@@ -339,7 +335,7 @@ static void avi_read_nikon(AVFormatContext *s, uint64_t end)
break;
}
if (name)
- av_metadata_set2(&s->metadata, name, buffer, 0);
+ av_dict_set(&s->metadata, name, buffer, 0);
avio_skip(s->pb, size);
}
break;
@@ -792,7 +788,7 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));
avio_skip(pb, desc_len - ret);
if (*desc)
- av_metadata_set2(&st->metadata, "title", desc, 0);
+ av_dict_set(&st->metadata, "title", desc, 0);
avio_rl16(pb); /* flags? */
avio_rl32(pb); /* data size */
@@ -1178,10 +1174,8 @@ static int avi_read_idx1(AVFormatContext *s, int size)
flags = avio_rl32(pb);
pos = avio_rl32(pb);
len = avio_rl32(pb);
-#if defined(DEBUG_SEEK)
- av_log(s, AV_LOG_DEBUG, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
- i, tag, flags, pos, len);
-#endif
+ av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
+ i, tag, flags, pos, len);
if(i==0 && pos > avi->movi_list)
avi->movi_list= 0; //FIXME better check
pos += avi->movi_list;
@@ -1250,22 +1244,18 @@ static int avi_load_index(AVFormatContext *s)
if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
goto the_end; // maybe truncated file
-#ifdef DEBUG_SEEK
- printf("movi_end=0x%"PRIx64"\n", avi->movi_end);
-#endif
+ av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end);
for(;;) {
if (url_feof(pb))
break;
tag = avio_rl32(pb);
size = avio_rl32(pb);
-#ifdef DEBUG_SEEK
- printf("tag=%c%c%c%c size=0x%x\n",
- tag & 0xff,
- (tag >> 8) & 0xff,
- (tag >> 16) & 0xff,
- (tag >> 24) & 0xff,
- size);
-#endif
+ av_dlog(s, "tag=%c%c%c%c size=0x%x\n",
+ tag & 0xff,
+ (tag >> 8) & 0xff,
+ (tag >> 16) & 0xff,
+ (tag >> 24) & 0xff,
+ size);
switch(tag) {
case MKTAG('i', 'd', 'x', '1'):
if (avi_read_idx1(s, size) < 0)
diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index 9f488d9600..8a53bb53d3 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -23,6 +23,7 @@
#include "avio_internal.h"
#include "riff.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
/*
* TODO:
@@ -157,7 +158,7 @@ static int avi_write_header(AVFormatContext *s)
int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale;
AVCodecContext *stream, *video_enc;
int64_t list1, list2, strh, strf;
- AVMetadataTag *t = NULL;
+ AVDictionaryEntry *t = NULL;
if (s->nb_streams > AVI_MAX_STREAM_COUNT) {
av_log(s, AV_LOG_ERROR, "AVI does not support >%d streams\n",
@@ -297,7 +298,7 @@ static int avi_write_header(AVFormatContext *s)
return -1;
}
ff_end_tag(pb, strf);
- if ((t = av_metadata_get(s->streams[i]->metadata, "title", NULL, 0))) {
+ if ((t = av_dict_get(s->streams[i]->metadata, "title", NULL, 0))) {
avi_write_info_tag(s->pb, "strn", t->value);
t = NULL;
}
@@ -379,7 +380,7 @@ static int avi_write_header(AVFormatContext *s)
ffio_wfourcc(pb, "INFO");
ff_metadata_conv(&s->metadata, ff_avi_metadata_conv, NULL);
for (i = 0; *ff_avi_tags[i]; i++) {
- if ((t = av_metadata_get(s->metadata, ff_avi_tags[i], NULL, AV_METADATA_MATCH_CASE)))
+ if ((t = av_dict_get(s->metadata, ff_avi_tags[i], NULL, AV_DICT_MATCH_CASE)))
avi_write_info_tag(s->pb, t->key, t->value);
}
ff_end_tag(pb, list2);
diff --git a/libavformat/avio.c b/libavformat/avio.c
index 16f8c2f2dd..80644795d5 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -62,11 +62,11 @@ URLProtocol *av_protocol_next(URLProtocol *p)
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);
}
diff --git a/libavformat/avio.h b/libavformat/avio.h
index 9d805822d4..5885349ca7 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -391,6 +391,7 @@ attribute_deprecated int av_register_protocol(URLProtocol *protocol);
* freed with av_free().
*
* @param buffer Memory block for input/output operations via AVIOContext.
+ * The buffer must be allocated with av_malloc() and friends.
* @param buffer_size The buffer size is very important for performance.
* For protocols with fixed blocksize it should be set to this blocksize.
* For others a typical size is a cache page, e.g. 4kb.
diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h
index 92528f2d18..4c80163d31 100644
--- a/libavformat/avio_internal.h
+++ b/libavformat/avio_internal.h
@@ -98,4 +98,4 @@ int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size);
*/
int ffio_fdopen(AVIOContext **s, URLContext *h);
-#endif // AVFORMAT_AVIO_INTERNAL_H
+#endif /* AVFORMAT_AVIO_INTERNAL_H */
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 456205bc76..c6cea6adfb 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -115,6 +115,8 @@ AVIOContext *avio_alloc_context(
int64_t (*seek)(void *opaque, int64_t offset, int whence))
{
AVIOContext *s = av_mallocz(sizeof(AVIOContext));
+ if (!s)
+ return NULL;
ffio_init_context(s, buffer, buffer_size, write_flag, opaque,
read_packet, write_packet, seek);
return s;
diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c
index ea9a3c17ae..b24ff1d023 100644
--- a/libavformat/cafdec.c
+++ b/libavformat/cafdec.c
@@ -29,6 +29,7 @@
#include "riff.h"
#include "isom.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
#include "caf.h"
typedef struct {
@@ -187,7 +188,7 @@ static void read_info_chunk(AVFormatContext *s, int64_t size)
char value[1024];
get_strz(pb, key, sizeof(key));
get_strz(pb, value, sizeof(value));
- av_metadata_set2(&s->metadata, key, value, 0);
+ av_dict_set(&s->metadata, key, value, 0);
}
}
diff --git a/libavformat/cafenc.c b/libavformat/cafenc.c
index 0f33c6b592..13636f30ee 100644
--- a/libavformat/cafenc.c
+++ b/libavformat/cafenc.c
@@ -134,7 +134,11 @@ static int caf_write_header(AVFormatContext *s)
avio_wb32(pb, enc->channels); //< mChannelsPerFrame
avio_wb32(pb, enc->bits_per_coded_sample); //< mBitsPerChannel
- ff_mov_write_chan(s, enc->channel_layout, "chan");
+ if (enc->channel_layout) {
+ ffio_wfourcc(pb, "chan");
+ avio_wb64(pb, 12);
+ ff_mov_write_chan(pb, enc->channel_layout);
+ }
ffio_wfourcc(pb, "data"); //< Audio Data chunk
caf->data = avio_tell(pb);
diff --git a/libavformat/cavsvideodec.c b/libavformat/cavsvideodec.c
index 6db9ad9fcf..4a399a26d1 100644
--- a/libavformat/cavsvideodec.c
+++ b/libavformat/cavsvideodec.c
@@ -65,13 +65,4 @@ static int cavsvideo_probe(AVProbeData *p)
return 0;
}
-AVInputFormat ff_cavsvideo_demuxer = {
- "cavsvideo",
- NULL_IF_CONFIG_SMALL("raw Chinese AVS video"),
- 0,
- cavsvideo_probe,
- ff_raw_video_read_header,
- ff_raw_read_partial_packet,
- .flags= AVFMT_GENERIC_INDEX,
- .value = CODEC_ID_CAVS,
-};
+FF_DEF_RAWVIDEO_DEMUXER(cavsvideo, "raw Chinese AVS video", cavsvideo_probe, NULL, CODEC_ID_CAVS)
diff --git a/libavformat/crypto.c b/libavformat/crypto.c
index c83bf92895..d52a503e38 100644
--- a/libavformat/crypto.c
+++ b/libavformat/crypto.c
@@ -97,8 +97,8 @@ static int crypto_open(URLContext *h, const char *uri, int flags)
return 0;
err:
- av_free(c->key);
- av_free(c->iv);
+ av_freep(&c->key);
+ av_freep(&c->iv);
return ret;
}
diff --git a/libavformat/diracdec.c b/libavformat/diracdec.c
index 6c6896163b..6afda533dc 100644
--- a/libavformat/diracdec.c
+++ b/libavformat/diracdec.c
@@ -31,13 +31,4 @@ static int dirac_probe(AVProbeData *p)
return 0;
}
-AVInputFormat ff_dirac_demuxer = {
- "dirac",
- NULL_IF_CONFIG_SMALL("raw Dirac"),
- 0,
- dirac_probe,
- ff_raw_video_read_header,
- ff_raw_read_partial_packet,
- .flags= AVFMT_GENERIC_INDEX,
- .value = CODEC_ID_DIRAC,
-};
+FF_DEF_RAWVIDEO_DEMUXER(dirac, "raw Dirac", dirac_probe, NULL, CODEC_ID_DIRAC)
diff --git a/libavformat/dnxhddec.c b/libavformat/dnxhddec.c
index 035e1c4b30..f89782a880 100644
--- a/libavformat/dnxhddec.c
+++ b/libavformat/dnxhddec.c
@@ -42,13 +42,4 @@ static int dnxhd_probe(AVProbeData *p)
return AVPROBE_SCORE_MAX;
}
-AVInputFormat ff_dnxhd_demuxer = {
- "dnxhd",
- NULL_IF_CONFIG_SMALL("raw DNxHD (SMPTE VC-3)"),
- 0,
- dnxhd_probe,
- ff_raw_video_read_header,
- ff_raw_read_partial_packet,
- .flags= AVFMT_GENERIC_INDEX,
- .value = CODEC_ID_DNXHD,
-};
+FF_DEF_RAWVIDEO_DEMUXER(dnxhd, "raw DNxHD (SMPTE VC-3)", dnxhd_probe, NULL, CODEC_ID_DNXHD)
diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c
index 604e75183c..e776d0c384 100644
--- a/libavformat/ffmdec.c
+++ b/libavformat/ffmdec.c
@@ -163,8 +163,6 @@ static int ffm_read_data(AVFormatContext *s,
return size1 - size;
}
-//#define DEBUG_SEEK
-
/* ensure that acutal seeking happens between FFM_PACKET_SIZE
and file_size - FFM_PACKET_SIZE */
static void ffm_seek1(AVFormatContext *s, int64_t pos1)
@@ -175,9 +173,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);
-#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_DEBUG, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos);
-#endif
+ av_dlog(s, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos);
avio_seek(pb, pos, SEEK_SET);
}
@@ -189,9 +185,7 @@ static int64_t get_dts(AVFormatContext *s, int64_t pos)
ffm_seek1(s, pos);
avio_skip(pb, 4);
dts = avio_rb64(pb);
-#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_DEBUG, "dts=%0.6f\n", dts / 1000000.0);
-#endif
+ av_dlog(s, "dts=%0.6f\n", dts / 1000000.0);
return dts;
}
@@ -464,9 +458,7 @@ static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, in
int64_t pts_min, pts_max, pts;
double pos1;
-#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_DEBUG, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0);
-#endif
+ 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;
diff --git a/libavformat/ffmeta.h b/libavformat/ffmeta.h
index f96dbb2efb..ae8778d614 100644
--- a/libavformat/ffmeta.h
+++ b/libavformat/ffmeta.h
@@ -19,11 +19,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef AVFORMAT_META_H
-#define AVFORMAT_META_H
+#ifndef AVFORMAT_FFMETA_H
+#define AVFORMAT_FFMETA_H
#define ID_STRING ";FFMETADATA"
#define ID_CHAPTER "[CHAPTER]"
#define ID_STREAM "[STREAM]"
-#endif /* AVFORMAT_META_H */
+#endif /* AVFORMAT_FFMETA_H */
diff --git a/libavformat/ffmetadec.c b/libavformat/ffmetadec.c
index a8bffa09af..0063e6eafa 100644
--- a/libavformat/ffmetadec.c
+++ b/libavformat/ffmetadec.c
@@ -22,6 +22,7 @@
#include "avformat.h"
#include "ffmeta.h"
#include "internal.h"
+#include "libavutil/dict.h"
static int probe(AVProbeData *p)
{
@@ -93,7 +94,7 @@ static uint8_t *unescape(uint8_t *buf, int size)
return ret;
}
-static int read_tag(uint8_t *line, AVMetadata **m)
+static int read_tag(uint8_t *line, AVDictionary **m)
{
uint8_t *key, *value, *p = line;
@@ -117,13 +118,13 @@ static int read_tag(uint8_t *line, AVMetadata **m)
return AVERROR(ENOMEM);
}
- av_metadata_set2(m, key, value, AV_METADATA_DONT_STRDUP_KEY | AV_METADATA_DONT_STRDUP_VAL);
+ av_dict_set(m, key, value, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
return 0;
}
static int read_header(AVFormatContext *s, AVFormatParameters *ap)
{
- AVMetadata **m = &s->metadata;
+ AVDictionary **m = &s->metadata;
uint8_t line[1024];
while(!url_feof(s->pb)) {
diff --git a/libavformat/ffmetaenc.c b/libavformat/ffmetaenc.c
index 596185b70c..200c9940a4 100644
--- a/libavformat/ffmetaenc.c
+++ b/libavformat/ffmetaenc.c
@@ -23,6 +23,7 @@
#include "avformat.h"
#include "ffmeta.h"
+#include "libavutil/dict.h"
static void write_escape_str(AVIOContext *s, const uint8_t *str)
@@ -37,10 +38,10 @@ static void write_escape_str(AVIOContext *s, const uint8_t *str)
}
}
-static void write_tags(AVIOContext *s, AVMetadata *m)
+static void write_tags(AVIOContext *s, AVDictionary *m)
{
- AVMetadataTag *t = NULL;
- while ((t = av_metadata_get(m, "", t, AV_METADATA_IGNORE_SUFFIX))) {
+ AVDictionaryEntry *t = NULL;
+ while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) {
write_escape_str(s, t->key);
avio_w8(s, '=');
write_escape_str(s, t->value);
diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
index 1674527816..24e0287ef8 100644
--- a/libavformat/flacenc.c
+++ b/libavformat/flacenc.c
@@ -22,7 +22,6 @@
#include "libavcodec/flac.h"
#include "avformat.h"
#include "flacenc.h"
-#include "metadata.h"
#include "vorbiscomment.h"
#include "libavcodec/bytestream.h"
@@ -39,7 +38,7 @@ static int flac_write_block_padding(AVIOContext *pb, unsigned int n_padding_byte
return 0;
}
-static int flac_write_block_comment(AVIOContext *pb, AVMetadata **m,
+static int flac_write_block_comment(AVIOContext *pb, AVDictionary **m,
int last_block, int bitexact)
{
const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 44d21683ba..4fb562f4e2 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -25,6 +25,7 @@
*/
#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
#include "libavcodec/bytestream.h"
#include "libavcodec/mpeg4audio.h"
#include "avformat.h"
@@ -259,17 +260,17 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
if(amf_type == AMF_DATA_TYPE_BOOL) {
av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val));
- av_metadata_set2(&s->metadata, key, str_val, 0);
+ 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_metadata_set2(&s->metadata, key, str_val, 0);
+ 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_STRING)
- av_metadata_set2(&s->metadata, key, str_val, 0);
+ av_dict_set(&s->metadata, key, str_val, 0);
}
return 0;
@@ -375,7 +376,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
size = avio_rb24(s->pb);
dts = avio_rb24(s->pb);
dts |= avio_r8(s->pb) << 24;
-// av_log(s, AV_LOG_DEBUG, "type:%d, size:%d, dts:%d\n", type, size, dts);
+ av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts);
if (url_feof(s->pb))
return AVERROR_EOF;
avio_skip(s->pb, 3); /* stream id, always 0 */
@@ -421,7 +422,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
st= create_stream(s, is_audio);
s->ctx_flags &= ~AVFMTCTX_NOHEADER;
}
-// av_log(s, AV_LOG_DEBUG, "%d %X %d \n", is_audio, flags, st->discard);
+ 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))
|| st->discard >= AVDISCARD_ALL
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 3e933ce922..cea0d02e3c 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -25,6 +25,7 @@
#include "internal.h"
#include "avc.h"
#include "metadata.h"
+#include "libavutil/dict.h"
#undef NDEBUG
#include <assert.h>
@@ -179,7 +180,7 @@ static int flv_write_header(AVFormatContext *s)
int i;
double framerate = 0.0;
int metadata_size_pos, data_size;
- AVMetadataTag *tag = NULL;
+ AVDictionaryEntry *tag = NULL;
for(i=0; i<s->nb_streams; i++){
AVCodecContext *enc = s->streams[i]->codec;
@@ -276,7 +277,7 @@ static int flv_write_header(AVFormatContext *s)
put_amf_double(pb, audio_enc->codec_tag);
}
- while ((tag = av_metadata_get(s->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX))) {
+ while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
put_amf_string(pb, tag->key);
avio_w8(pb, AMF_DATA_TYPE_STRING);
put_amf_string(pb, tag->value);
@@ -440,7 +441,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
av_free(data);
- return 0;
+ return pb->error;
}
AVOutputFormat ff_flv_muxer = {
diff --git a/libavformat/gif.c b/libavformat/gif.c
index f5f8147e4f..0960705cf3 100644
--- a/libavformat/gif.c
+++ b/libavformat/gif.c
@@ -295,9 +295,7 @@ static int gif_write_video(AVFormatContext *s,
AVCodecContext *enc, const uint8_t *buf, int size)
{
AVIOContext *pb = s->pb;
- GIFContext *gif = s->priv_data;
int jiffies;
- int64_t delay;
/* graphic control extension block */
avio_w8(pb, 0x21);
@@ -307,8 +305,6 @@ static int gif_write_video(AVFormatContext *s,
/* 1 jiffy is 1/70 s */
/* the delay_time field indicates the number of jiffies - 1 */
- delay = gif->file_time - gif->time;
-
/* XXX: should use delay, in order to be more accurate */
/* instead of using the same rounded value each time */
/* XXX: don't even remember if I really use it for now */
diff --git a/libavformat/h261dec.c b/libavformat/h261dec.c
index 1478ed663f..354a7c78c1 100644
--- a/libavformat/h261dec.c
+++ b/libavformat/h261dec.c
@@ -62,14 +62,4 @@ static int h261_probe(AVProbeData *p)
return 0;
}
-AVInputFormat ff_h261_demuxer = {
- "h261",
- NULL_IF_CONFIG_SMALL("raw H.261"),
- 0,
- h261_probe,
- ff_raw_video_read_header,
- ff_raw_read_partial_packet,
- .flags= AVFMT_GENERIC_INDEX,
- .extensions = "h261",
- .value = CODEC_ID_H261,
-};
+FF_DEF_RAWVIDEO_DEMUXER(h261, "raw H.261", h261_probe, "h261", CODEC_ID_H261)
diff --git a/libavformat/h263dec.c b/libavformat/h263dec.c
index 634923d885..b07e9782b8 100644
--- a/libavformat/h263dec.c
+++ b/libavformat/h263dec.c
@@ -64,14 +64,4 @@ static int h263_probe(AVProbeData *p)
return 0;
}
-AVInputFormat ff_h263_demuxer = {
- "h263",
- NULL_IF_CONFIG_SMALL("raw H.263"),
- 0,
- h263_probe,
- ff_raw_video_read_header,
- ff_raw_read_partial_packet,
- .flags= AVFMT_GENERIC_INDEX,
-// .extensions = "h263", //FIXME remove after writing mpeg4_probe
- .value = CODEC_ID_H263,
-};
+FF_DEF_RAWVIDEO_DEMUXER(h263, "raw H.263", h263_probe, NULL, CODEC_ID_H263)
diff --git a/libavformat/h264dec.c b/libavformat/h264dec.c
index cec8f85275..e7c6d70deb 100644
--- a/libavformat/h264dec.c
+++ b/libavformat/h264dec.c
@@ -67,14 +67,4 @@ static int h264_probe(AVProbeData *p)
return 0;
}
-AVInputFormat ff_h264_demuxer = {
- "h264",
- NULL_IF_CONFIG_SMALL("raw H.264 video format"),
- 0,
- h264_probe,
- ff_raw_video_read_header,
- ff_raw_read_partial_packet,
- .flags= AVFMT_GENERIC_INDEX,
- .extensions = "h26l,h264,264", //FIXME remove after writing mpeg4_probe
- .value = CODEC_ID_H264,
-};
+FF_DEF_RAWVIDEO_DEMUXER(h264 , "raw H.264 video format", h264_probe, "h26l,h264,264", CODEC_ID_H264)
diff --git a/libavformat/id3v1.c b/libavformat/id3v1.c
index 37d46956ef..2d1e806920 100644
--- a/libavformat/id3v1.c
+++ b/libavformat/id3v1.c
@@ -21,6 +21,7 @@
#include "id3v1.h"
#include "libavcodec/avcodec.h"
+#include "libavutil/dict.h"
const char * const ff_id3v1_genre_str[ID3v1_GENRE_MAX + 1] = {
[0] = "Blues",
@@ -191,7 +192,7 @@ static void get_string(AVFormatContext *s, const char *key,
*q = '\0';
if (*str)
- av_metadata_set2(&s->metadata, key, str, 0);
+ av_dict_set(&s->metadata, key, str, 0);
}
/**
@@ -215,11 +216,11 @@ static int parse_tag(AVFormatContext *s, const uint8_t *buf)
get_string(s, "comment", buf + 97, 30);
if (buf[125] == 0 && buf[126] != 0) {
snprintf(str, sizeof(str), "%d", buf[126]);
- av_metadata_set2(&s->metadata, "track", str, 0);
+ av_dict_set(&s->metadata, "track", str, 0);
}
genre = buf[127];
if (genre <= ID3v1_GENRE_MAX)
- av_metadata_set2(&s->metadata, "genre", ff_id3v1_genre_str[genre], 0);
+ av_dict_set(&s->metadata, "genre", ff_id3v1_genre_str[genre], 0);
return 0;
}
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 95353276b5..930ab5c870 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -1,5 +1,4 @@
/*
- * ID3v2 header parser
* Copyright (c) 2003 Fabrice Bellard
*
* This file is part of FFmpeg.
@@ -19,11 +18,19 @@
* 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"
#include "libavutil/intreadwrite.h"
-#include "metadata.h"
+#include "libavutil/dict.h"
#include "avio_internal.h"
int ff_id3v2_match(const uint8_t *buf, const char * magic)
@@ -133,7 +140,7 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const cha
val = dst;
if (val)
- av_metadata_set2(&s->metadata, key, val, AV_METADATA_DONT_OVERWRITE);
+ av_dict_set(&s->metadata, key, val, AV_DICT_DONT_OVERWRITE);
}
static int is_number(const char *str)
@@ -142,44 +149,44 @@ static int is_number(const char *str)
return !*str;
}
-static AVMetadataTag* get_date_tag(AVMetadata *m, const char *tag)
+static AVDictionaryEntry* get_date_tag(AVDictionary *m, const char *tag)
{
- AVMetadataTag *t;
- if ((t = av_metadata_get(m, tag, NULL, AV_METADATA_MATCH_CASE)) &&
+ AVDictionaryEntry *t;
+ if ((t = av_dict_get(m, tag, NULL, AV_DICT_MATCH_CASE)) &&
strlen(t->value) == 4 && is_number(t->value))
return t;
return NULL;
}
-static void merge_date(AVMetadata **m)
+static void merge_date(AVDictionary **m)
{
- AVMetadataTag *t;
+ AVDictionaryEntry *t;
char date[17] = {0}; // YYYY-MM-DD hh:mm
if (!(t = get_date_tag(*m, "TYER")) &&
!(t = get_date_tag(*m, "TYE")))
return;
av_strlcpy(date, t->value, 5);
- av_metadata_set2(m, "TYER", NULL, 0);
- av_metadata_set2(m, "TYE", NULL, 0);
+ av_dict_set(m, "TYER", NULL, 0);
+ av_dict_set(m, "TYE", NULL, 0);
if (!(t = get_date_tag(*m, "TDAT")) &&
!(t = get_date_tag(*m, "TDA")))
goto finish;
snprintf(date + 4, sizeof(date) - 4, "-%.2s-%.2s", t->value + 2, t->value);
- av_metadata_set2(m, "TDAT", NULL, 0);
- av_metadata_set2(m, "TDA", NULL, 0);
+ av_dict_set(m, "TDAT", NULL, 0);
+ av_dict_set(m, "TDA", NULL, 0);
if (!(t = get_date_tag(*m, "TIME")) &&
!(t = get_date_tag(*m, "TIM")))
goto finish;
snprintf(date + 10, sizeof(date) - 10, " %.2s:%.2s", t->value, t->value + 2);
- av_metadata_set2(m, "TIME", NULL, 0);
- av_metadata_set2(m, "TIM", NULL, 0);
+ av_dict_set(m, "TIME", NULL, 0);
+ av_dict_set(m, "TIM", NULL, 0);
finish:
if (date[0])
- av_metadata_set2(m, "date", date, 0);
+ av_dict_set(m, "date", date, 0);
}
static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags)
@@ -221,7 +228,7 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
avio_skip(s->pb, get_size(s->pb, 4));
while (len >= taghdrlen) {
- unsigned int tflags;
+ unsigned int tflags = 0;
int tunsync = 0;
if (isv34) {
@@ -238,7 +245,7 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
tag[3] = 0;
tlen = avio_rb24(s->pb);
}
- if (tlen > (1<<28))
+ if (tlen > (1<<28) || !tlen)
break;
len -= taghdrlen + tlen;
@@ -248,6 +255,8 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
next = avio_tell(s->pb) + tlen;
if (tflags & ID3v2_FLAG_DATALEN) {
+ if (tlen < 4)
+ break;
avio_rb32(s->pb);
tlen -= 4;
}
@@ -259,6 +268,10 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
if (unsync || tunsync) {
int i, j;
av_fast_malloc(&buffer, &buffer_size, tlen);
+ if (!buffer) {
+ av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", tlen);
+ goto seek;
+ }
for (i = 0, j = 0; i < tlen; i++, j++) {
buffer[j] = avio_r8(s->pb);
if (j > 0 && !buffer[j] && buffer[j - 1] == 0xff) {
@@ -279,6 +292,7 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
break;
}
/* Skip to end of tag */
+seek:
avio_seek(s->pb, next, SEEK_SET);
}
diff --git a/libavformat/iff.c b/libavformat/iff.c
index da4e858501..db988a6ecd 100644
--- a/libavformat/iff.c
+++ b/libavformat/iff.c
@@ -1,5 +1,4 @@
/*
- * 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>
@@ -31,6 +30,7 @@
#include "libavcodec/bytestream.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#define ID_8SVX MKTAG('8','S','V','X')
@@ -60,8 +60,6 @@
#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
@@ -88,7 +86,8 @@ typedef struct {
uint32_t body_size;
uint32_t sent_bytes;
uint32_t audio_frame_count;
- unsigned compression; ///< delta compression method used
+ 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
@@ -96,19 +95,6 @@ typedef struct {
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,
@@ -124,7 +110,7 @@ static int get_metadata(AVFormatContext *s,
return AVERROR(EIO);
}
buf[data_size] = 0;
- av_metadata_set2(&s->metadata, tag, buf, AV_METADATA_DONT_STRDUP_VAL);
+ av_dict_set(&s->metadata, tag, buf, AV_DICT_DONT_STRDUP_VAL);
return 0;
}
@@ -146,7 +132,6 @@ static int iff_read_header(AVFormatContext *s,
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
@@ -178,7 +163,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;
@@ -209,6 +194,7 @@ static int iff_read_header(AVFormatContext *s,
break;
case ID_BMHD:
+ iff->bitmap_compression = -1;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
if (data_size <= 8)
return AVERROR_INVALIDDATA;
@@ -219,7 +205,7 @@ static int iff_read_header(AVFormatContext *s,
if (data_size >= 10)
masking = avio_r8(pb);
if (data_size >= 11)
- compression = avio_r8(pb);
+ iff->bitmap_compression = avio_r8(pb);
if (data_size >= 14) {
avio_skip(pb, 1); // padding
transparency = avio_rb16(pb);
@@ -231,21 +217,10 @@ static int iff_read_header(AVFormatContext *s,
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) {
@@ -263,9 +238,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;
@@ -274,17 +249,17 @@ 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:
- iff->compression = 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;
@@ -302,14 +277,14 @@ static int iff_read_header(AVFormatContext *s,
}
buf = st->codec->extradata;
bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE);
- bytestream_put_byte(&buf, iff->compression);
+ 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 (compression) {
+ switch (iff->bitmap_compression) {
case BITMAP_RAW:
st->codec->codec_id = CODEC_ID_IFF_ILBM;
break;
@@ -317,7 +292,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;
@@ -339,15 +315,8 @@ static int iff_read_packet(AVFormatContext *s,
if(iff->sent_bytes >= iff->body_size)
return AVERROR(EIO);
- if(st->codec->channels == 2) {
- uint8_t sample_buffer[PACKET_SIZE];
-
- 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");
- return AVERROR(ENOMEM);
- }
- interleave_stereo(sample_buffer, pkt->data, 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;
@@ -359,22 +328,14 @@ static int iff_read_packet(AVFormatContext *s,
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;
}
diff --git a/libavformat/img2.c b/libavformat/img2.c
index 19292c39ec..11ebf12d43 100644
--- a/libavformat/img2.c
+++ b/libavformat/img2.c
@@ -22,12 +22,17 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/parseutils.h"
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
#include <strings.h>
typedef struct {
+ const AVClass *class; /**< Class for private options. */
int img_first;
int img_last;
int img_number;
@@ -35,6 +40,9 @@ typedef struct {
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. */
} VideoData;
typedef struct {
@@ -77,6 +85,7 @@ static const IdStrMap img_tags[] = {
{ CODEC_ID_SUNRAST , "sunras"},
{ CODEC_ID_JPEG2000 , "j2k"},
{ CODEC_ID_JPEG2000 , "jp2"},
+ { CODEC_ID_JPEG2000 , "jpc"},
{ CODEC_ID_DPX , "dpx"},
{ CODEC_ID_PICTOR , "pic"},
{ CODEC_ID_NONE , NULL}
@@ -201,8 +210,11 @@ enum CodecID av_guess_image2_codec(const char *filename){
static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
{
VideoData *s = s1->priv_data;
- int first_index, last_index;
+ int first_index, last_index, ret = 0;
+ int width = 0, height = 0;
AVStream *st;
+ enum PixelFormat pix_fmt = PIX_FMT_NONE;
+ AVRational framerate;
s1->ctx_flags |= AVFMTCTX_NOHEADER;
@@ -211,6 +223,29 @@ static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
return AVERROR(ENOMEM);
}
+ if (s->pixel_format && (pix_fmt = av_get_pix_fmt(s->pixel_format)) == PIX_FMT_NONE) {
+ av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", s->pixel_format);
+ return AVERROR(EINVAL);
+ }
+ if (s->video_size && (ret = av_parse_video_size(&width, &height, s->video_size)) < 0) {
+ av_log(s, AV_LOG_ERROR, "Could not parse video size: %s.\n", s->video_size);
+ return ret;
+ }
+ if ((ret = av_parse_video_rate(&framerate, s->framerate)) < 0) {
+ 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};
+#endif
+
av_strlcpy(s->path, s1->filename, sizeof(s->path));
s->img_number = 0;
s->img_count = 0;
@@ -223,15 +258,11 @@ static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
st->need_parsing = AVSTREAM_PARSE_FULL;
}
- 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);
- }
+ av_set_pts_info(st, 60, framerate.den, framerate.num);
- if(ap->width && ap->height){
- st->codec->width = ap->width;
- st->codec->height= ap->height;
+ if (width && height) {
+ st->codec->width = width;
+ st->codec->height = height;
}
if (!s->is_pipe) {
@@ -257,8 +288,8 @@ static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = av_str2id(img_tags, s->path);
}
- if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ap->pix_fmt != PIX_FMT_NONE)
- st->codec->pix_fmt = ap->pix_fmt;
+ if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO && pix_fmt != PIX_FMT_NONE)
+ st->codec->pix_fmt = pix_fmt;
return 0;
}
@@ -429,6 +460,22 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
#endif /* CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER */
+#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 },
+ { NULL },
+};
+
+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 = {
@@ -439,6 +486,7 @@ AVInputFormat ff_image2_demuxer = {
.read_header = read_header,
.read_packet = read_packet,
.flags = AVFMT_NOFILE,
+ .priv_class = &img2_class,
};
#endif
#if CONFIG_IMAGE2PIPE_DEMUXER
@@ -448,6 +496,7 @@ AVInputFormat ff_image2pipe_demuxer = {
.priv_data_size = sizeof(VideoData),
.read_header = read_header,
.read_packet = read_packet,
+ .priv_class = &img2_class,
};
#endif
diff --git a/libavformat/ingenientdec.c b/libavformat/ingenientdec.c
index eb1e6f6521..4a7ff09dbe 100644
--- a/libavformat/ingenientdec.c
+++ b/libavformat/ingenientdec.c
@@ -61,11 +61,12 @@ static int ingenient_read_packet(AVFormatContext *s, AVPacket *pkt)
AVInputFormat ff_ingenient_demuxer = {
"ingenient",
NULL_IF_CONFIG_SMALL("raw Ingenient MJPEG"),
- 0,
+ sizeof(FFRawVideoDemuxerContext),
NULL,
ff_raw_video_read_header,
ingenient_read_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "cgi", // FIXME
.value = CODEC_ID_MJPEG,
+ .priv_class = &ff_rawvideo_demuxer_class,
};
diff --git a/libavformat/internal.h b/libavformat/internal.h
index d75e0676e5..64992dadfa 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -26,6 +26,12 @@
#define MAX_URL_SIZE 4096
+#ifdef DEBUG
+# define hex_dump_debug(class, buf, size) av_hex_dump_log(class, AV_LOG_DEBUG, buf, size)
+#else
+# define hex_dump_debug(class, buf, size)
+#endif
+
typedef struct AVCodecTag {
enum CodecID id;
unsigned int tag;
@@ -128,10 +134,12 @@ int ff_url_join(char *str, int size, const char *proto,
* @param dest_type the destination address type, may be NULL
* @param port the destination port of the media stream, 0 if unknown
* @param ttl the time to live of the stream, 0 if not multicast
+ * @param fmt the AVFormatContext, which might contain options modifying
+ * the generated SDP
*/
void ff_sdp_write_media(char *buff, int size, AVCodecContext *c,
const char *dest_addr, const char *dest_type,
- int port, int ttl);
+ int port, int ttl, AVFormatContext *fmt);
/**
* Write a packet to another muxer than the one the user originally
diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c
index 8ea59a3b08..471d6a4bc0 100644
--- a/libavformat/ipmovie.c
+++ b/libavformat/ipmovie.c
@@ -35,17 +35,6 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
-/* debugging support: #define DEBUG_IPMOVIE as non-zero to see extremely
- * verbose information about the demux process */
-#define DEBUG_IPMOVIE 0
-
-#if DEBUG_IPMOVIE
-#undef printf
-#define debug_ipmovie printf
-#else
-static inline void debug_ipmovie(const char *format, ...) { }
-#endif
-
#define CHUNK_PREAMBLE_SIZE 4
#define OPCODE_PREAMBLE_SIZE 4
@@ -150,8 +139,8 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb,
s->audio_frame_count +=
(s->audio_chunk_size - 6) / s->audio_channels;
- debug_ipmovie("sending audio frame with pts %"PRId64" (%d audio frames)\n",
- pkt->pts, s->audio_frame_count);
+ av_dlog(NULL, "sending audio frame with pts %"PRId64" (%d audio frames)\n",
+ pkt->pts, s->audio_frame_count);
chunk_type = CHUNK_VIDEO;
@@ -184,8 +173,7 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb,
pkt->stream_index = s->video_stream_index;
pkt->pts = s->video_pts;
- debug_ipmovie("sending video frame with pts %"PRId64"\n",
- pkt->pts);
+ av_dlog(NULL, "sending video frame with pts %"PRId64"\n", pkt->pts);
s->video_pts += s->frame_pts_inc;
@@ -233,36 +221,36 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
chunk_size = AV_RL16(&chunk_preamble[0]);
chunk_type = AV_RL16(&chunk_preamble[2]);
- debug_ipmovie("chunk type 0x%04X, 0x%04X bytes: ", chunk_type, chunk_size);
+ av_dlog(NULL, "chunk type 0x%04X, 0x%04X bytes: ", chunk_type, chunk_size);
switch (chunk_type) {
case CHUNK_INIT_AUDIO:
- debug_ipmovie("initialize audio\n");
+ av_dlog(NULL, "initialize audio\n");
break;
case CHUNK_AUDIO_ONLY:
- debug_ipmovie("audio only\n");
+ av_dlog(NULL, "audio only\n");
break;
case CHUNK_INIT_VIDEO:
- debug_ipmovie("initialize video\n");
+ av_dlog(NULL, "initialize video\n");
break;
case CHUNK_VIDEO:
- debug_ipmovie("video (and audio)\n");
+ av_dlog(NULL, "video (and audio)\n");
break;
case CHUNK_SHUTDOWN:
- debug_ipmovie("shutdown\n");
+ av_dlog(NULL, "shutdown\n");
break;
case CHUNK_END:
- debug_ipmovie("end\n");
+ av_dlog(NULL, "end\n");
break;
default:
- debug_ipmovie("invalid chunk\n");
+ av_dlog(NULL, "invalid chunk\n");
chunk_type = CHUNK_BAD;
break;
@@ -288,29 +276,29 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
chunk_size -= OPCODE_PREAMBLE_SIZE;
chunk_size -= opcode_size;
if (chunk_size < 0) {
- debug_ipmovie("chunk_size countdown just went negative\n");
+ av_dlog(NULL, "chunk_size countdown just went negative\n");
chunk_type = CHUNK_BAD;
break;
}
- debug_ipmovie(" opcode type %02X, version %d, 0x%04X bytes: ",
- opcode_type, opcode_version, opcode_size);
+ av_dlog(NULL, " opcode type %02X, version %d, 0x%04X bytes: ",
+ opcode_type, opcode_version, opcode_size);
switch (opcode_type) {
case OPCODE_END_OF_STREAM:
- debug_ipmovie("end of stream\n");
+ av_dlog(NULL, "end of stream\n");
avio_skip(pb, opcode_size);
break;
case OPCODE_END_OF_CHUNK:
- debug_ipmovie("end of chunk\n");
+ av_dlog(NULL, "end of chunk\n");
avio_skip(pb, opcode_size);
break;
case OPCODE_CREATE_TIMER:
- debug_ipmovie("create timer\n");
+ av_dlog(NULL, "create timer\n");
if ((opcode_version > 0) || (opcode_size > 6)) {
- debug_ipmovie("bad create_timer opcode\n");
+ av_dlog(NULL, "bad create_timer opcode\n");
chunk_type = CHUNK_BAD;
break;
}
@@ -320,14 +308,15 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
break;
}
s->frame_pts_inc = ((uint64_t)AV_RL32(&scratch[0])) * AV_RL16(&scratch[4]);
- debug_ipmovie(" %.2f frames/second (timer div = %d, subdiv = %d)\n",
- 1000000.0/s->frame_pts_inc, AV_RL32(&scratch[0]), AV_RL16(&scratch[4]));
+ av_dlog(NULL, " %.2f frames/second (timer div = %d, subdiv = %d)\n",
+ 1000000.0 / s->frame_pts_inc, AV_RL32(&scratch[0]),
+ AV_RL16(&scratch[4]));
break;
case OPCODE_INIT_AUDIO_BUFFERS:
- debug_ipmovie("initialize audio buffers\n");
+ av_dlog(NULL, "initialize audio buffers\n");
if ((opcode_version > 1) || (opcode_size > 10)) {
- debug_ipmovie("bad init_audio_buffers opcode\n");
+ av_dlog(NULL, "bad init_audio_buffers opcode\n");
chunk_type = CHUNK_BAD;
break;
}
@@ -349,23 +338,22 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
s->audio_type = CODEC_ID_PCM_S16LE;
else
s->audio_type = CODEC_ID_PCM_U8;
- debug_ipmovie("audio: %d bits, %d Hz, %s, %s format\n",
- s->audio_bits,
- s->audio_sample_rate,
- (s->audio_channels == 2) ? "stereo" : "mono",
- (s->audio_type == CODEC_ID_INTERPLAY_DPCM) ?
- "Interplay audio" : "PCM");
+ av_dlog(NULL, "audio: %d bits, %d Hz, %s, %s format\n",
+ s->audio_bits, s->audio_sample_rate,
+ (s->audio_channels == 2) ? "stereo" : "mono",
+ (s->audio_type == CODEC_ID_INTERPLAY_DPCM) ?
+ "Interplay audio" : "PCM");
break;
case OPCODE_START_STOP_AUDIO:
- debug_ipmovie("start/stop audio\n");
+ av_dlog(NULL, "start/stop audio\n");
avio_skip(pb, opcode_size);
break;
case OPCODE_INIT_VIDEO_BUFFERS:
- debug_ipmovie("initialize video buffers\n");
+ av_dlog(NULL, "initialize video buffers\n");
if ((opcode_version > 2) || (opcode_size > 8)) {
- debug_ipmovie("bad init_video_buffers opcode\n");
+ av_dlog(NULL, "bad init_video_buffers opcode\n");
chunk_type = CHUNK_BAD;
break;
}
@@ -381,8 +369,8 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
} else {
s->video_bpp = 16;
}
- debug_ipmovie("video resolution: %d x %d\n",
- s->video_width, s->video_height);
+ av_dlog(NULL, "video resolution: %d x %d\n",
+ s->video_width, s->video_height);
break;
case OPCODE_UNKNOWN_06:
@@ -392,17 +380,17 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
case OPCODE_UNKNOWN_13:
case OPCODE_UNKNOWN_14:
case OPCODE_UNKNOWN_15:
- debug_ipmovie("unknown (but documented) opcode %02X\n", opcode_type);
+ av_dlog(NULL, "unknown (but documented) opcode %02X\n", opcode_type);
avio_skip(pb, opcode_size);
break;
case OPCODE_SEND_BUFFER:
- debug_ipmovie("send buffer\n");
+ av_dlog(NULL, "send buffer\n");
avio_skip(pb, opcode_size);
break;
case OPCODE_AUDIO_FRAME:
- debug_ipmovie("audio frame\n");
+ av_dlog(NULL, "audio frame\n");
/* log position and move on for now */
s->audio_chunk_offset = avio_tell(pb);
@@ -411,26 +399,26 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
break;
case OPCODE_SILENCE_FRAME:
- debug_ipmovie("silence frame\n");
+ av_dlog(NULL, "silence frame\n");
avio_skip(pb, opcode_size);
break;
case OPCODE_INIT_VIDEO_MODE:
- debug_ipmovie("initialize video mode\n");
+ av_dlog(NULL, "initialize video mode\n");
avio_skip(pb, opcode_size);
break;
case OPCODE_CREATE_GRADIENT:
- debug_ipmovie("create gradient\n");
+ av_dlog(NULL, "create gradient\n");
avio_skip(pb, opcode_size);
break;
case OPCODE_SET_PALETTE:
- debug_ipmovie("set palette\n");
+ av_dlog(NULL, "set palette\n");
/* check for the logical maximum palette size
* (3 * 256 + 4 bytes) */
if (opcode_size > 0x304) {
- debug_ipmovie("demux_ipmovie: set_palette opcode too large\n");
+ av_dlog(NULL, "demux_ipmovie: set_palette opcode too large\n");
chunk_type = CHUNK_BAD;
break;
}
@@ -444,7 +432,7 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
last_color = first_color + AV_RL16(&scratch[2]) - 1;
/* sanity check (since they are 16 bit values) */
if ((first_color > 0xFF) || (last_color > 0xFF)) {
- debug_ipmovie("demux_ipmovie: set_palette indexes out of range (%d -> %d)\n",
+ av_dlog(NULL, "demux_ipmovie: set_palette indexes out of range (%d -> %d)\n",
first_color, last_color);
chunk_type = CHUNK_BAD;
break;
@@ -463,12 +451,12 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
break;
case OPCODE_SET_PALETTE_COMPRESSED:
- debug_ipmovie("set palette compressed\n");
+ av_dlog(NULL, "set palette compressed\n");
avio_skip(pb, opcode_size);
break;
case OPCODE_SET_DECODING_MAP:
- debug_ipmovie("set decoding map\n");
+ av_dlog(NULL, "set decoding map\n");
/* log position and move on for now */
s->decode_map_chunk_offset = avio_tell(pb);
@@ -477,7 +465,7 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
break;
case OPCODE_VIDEO_DATA:
- debug_ipmovie("set video data\n");
+ av_dlog(NULL, "set video data\n");
/* log position and move on for now */
s->video_chunk_offset = avio_tell(pb);
@@ -486,7 +474,7 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
break;
default:
- debug_ipmovie("*** unknown opcode type\n");
+ av_dlog(NULL, "*** unknown opcode type\n");
chunk_type = CHUNK_BAD;
break;
diff --git a/libavformat/isom.c b/libavformat/isom.c
index 3259128d3a..dcc3b74af3 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -27,7 +27,6 @@
#include "internal.h"
#include "isom.h"
#include "riff.h"
-#include "avio_internal.h"
#include "libavcodec/mpeg4audio.h"
#include "libavcodec/mpegaudiodata.h"
@@ -460,16 +459,18 @@ 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;
- if (size != 12) {
+ 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;
}
- layout_tag = avio_rb32(pb);
if (layout_tag == 0x10000) { //< kCAFChannelLayoutTag_UseChannelBitmap
codec->channel_layout = avio_rb32(pb);
- avio_skip(pb, 4);
+ size -= 4;
+ avio_skip(pb, size);
return;
}
while (layouts->channel_layout) {
@@ -481,27 +482,20 @@ void ff_mov_read_chan(AVFormatContext *s, int64_t size, AVCodecContext *codec)
}
if (!codec->channel_layout)
av_log(s, AV_LOG_WARNING, "Unknown container channel layout.\n");
- avio_skip(pb, 8);
+ avio_skip(pb, size);
}
-void ff_mov_write_chan(AVFormatContext *s, int64_t channel_layout,
- const char *chunk_type)
+void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout)
{
- AVIOContext *pb = s->pb;
const MovChannelLayout *layouts;
uint32_t layout_tag = 0;
- if (!channel_layout)
- return;
-
for (layouts = mov_channel_layout; layouts->channel_layout; layouts++)
if (channel_layout == layouts->channel_layout) {
layout_tag = layouts->layout_tag;
break;
}
- ffio_wfourcc(pb, chunk_type);
- avio_wb64(pb, 12); //< mChunkSize
if (layout_tag) {
avio_wb32(pb, layout_tag); //< mChannelLayoutTag
avio_wb32(pb, 0); //< mChannelBitmap
diff --git a/libavformat/isom.h b/libavformat/isom.h
index 6e42a1f841..43fa477a7d 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -155,7 +155,6 @@ 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(AVFormatContext *s, int64_t channel_layout,
- const char *chunk_type);
+void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout);
#endif /* AVFORMAT_ISOM_H */
diff --git a/libavformat/m4vdec.c b/libavformat/m4vdec.c
index f830c7afcf..88f838022e 100644
--- a/libavformat/m4vdec.c
+++ b/libavformat/m4vdec.c
@@ -49,14 +49,4 @@ static int mpeg4video_probe(AVProbeData *probe_packet)
return 0;
}
-AVInputFormat ff_m4v_demuxer = {
- "m4v",
- NULL_IF_CONFIG_SMALL("raw MPEG-4 video format"),
- 0,
- mpeg4video_probe, /** probing for MPEG-4 data */
- ff_raw_video_read_header,
- ff_raw_read_partial_packet,
- .flags= AVFMT_GENERIC_INDEX,
- .extensions = "m4v",
- .value = CODEC_ID_MPEG4,
-};
+FF_DEF_RAWVIDEO_DEMUXER(m4v, "raw MPEG-4 video format", mpeg4video_probe, "m4v", CODEC_ID_MPEG4)
diff --git a/libavformat/matroska.c b/libavformat/matroska.c
index c7e9663316..52481d7556 100644
--- a/libavformat/matroska.c
+++ b/libavformat/matroska.c
@@ -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 0d0d0bcff4..ab7e3269fa 100644
--- a/libavformat/matroska.h
+++ b/libavformat/matroska.h
@@ -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
@@ -111,7 +116,7 @@
#define MATROSKA_ID_VIDEOPIXELCROPR 0x54DD
#define MATROSKA_ID_VIDEODISPLAYUNIT 0x54B2
#define MATROSKA_ID_VIDEOFLAGINTERLACED 0x9A
-#define MATROSKA_ID_VIDEOSTEREOMODE 0x53B9
+#define MATROSKA_ID_VIDEOSTEREOMODE 0x53B8
#define MATROSKA_ID_VIDEOASPECTRATIO 0x54B3
#define MATROSKA_ID_VIDEOCOLORSPACE 0x2EB524
@@ -218,6 +223,24 @@ typedef enum {
MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP = 3,
} MatroskaTrackEncodingCompAlgo;
+typedef enum {
+ MATROSKA_VIDEO_STEREOMODE_TYPE_MONO = 0,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT = 1,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_BOTTOM_TOP = 2,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM = 3,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_RL = 4,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_LR = 5,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_RL = 6,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_LR = 7,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_RL = 8,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_LR = 9,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_ANAGLYPH_CYAN_RED = 10,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT = 11,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_ANAGLYPH_GREEN_MAG = 12,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR = 13,
+ MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_RL = 14,
+} MatroskaVideoStereoModeType;
+
/*
* Matroska Codec IDs, strings
*/
@@ -235,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 ab67e110c2..efb80a017d 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -42,6 +42,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
#include "libavutil/lzo.h"
+#include "libavutil/dict.h"
#if CONFIG_ZLIB
#include <zlib.h>
#endif
@@ -111,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 {
@@ -132,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;
@@ -145,6 +156,7 @@ typedef struct {
uint64_t flag_forced;
MatroskaTrackVideo video;
MatroskaTrackAudio audio;
+ MatroskaTrackOperation operation;
EbmlList encodings;
AVStream *stream;
@@ -290,14 +302,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 }
};
@@ -329,6 +341,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) },
@@ -343,6 +371,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 },
@@ -1009,7 +1038,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;
@@ -1044,7 +1074,7 @@ static void matroska_merge_packets(AVPacket *out, AVPacket *in)
}
static void matroska_convert_tag(AVFormatContext *s, EbmlList *list,
- AVMetadata **metadata, char *prefix)
+ AVDictionary **metadata, char *prefix)
{
MatroskaTag *tags = list->elem;
char key[1024];
@@ -1060,14 +1090,14 @@ static void matroska_convert_tag(AVFormatContext *s, EbmlList *list,
if (prefix) snprintf(key, sizeof(key), "%s/%s", prefix, tags[i].name);
else av_strlcpy(key, tags[i].name, sizeof(key));
if (tags[i].def || !lang) {
- av_metadata_set2(metadata, key, tags[i].string, 0);
+ av_dict_set(metadata, key, tags[i].string, 0);
if (tags[i].sub.nb_elem)
matroska_convert_tag(s, &tags[i].sub, metadata, key);
}
if (lang) {
av_strlcat(key, "-", sizeof(key));
av_strlcat(key, lang, sizeof(key));
- av_metadata_set2(metadata, key, tags[i].string, 0);
+ av_dict_set(metadata, key, tags[i].string, 0);
if (tags[i].sub.nb_elem)
matroska_convert_tag(s, &tags[i].sub, metadata, key);
}
@@ -1202,20 +1232,25 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
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]))
@@ -1235,7 +1270,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (matroska->duration)
matroska->ctx->duration = matroska->duration * matroska->time_scale
* 1000 / AV_TIME_BASE;
- av_metadata_set2(&s->metadata, "title", matroska->title, 0);
+ av_dict_set(&s->metadata, "title", matroska->title, 0);
tracks = matroska->tracks.elem;
for (i=0; i < matroska->tracks.nb_elem; i++) {
@@ -1246,6 +1281,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
uint8_t *extradata = NULL;
int extradata_size = 0;
int extradata_offset = 0;
+ uint32_t fourcc = 0;
AVIOContext b;
/* Apply some sanity checks. */
@@ -1267,6 +1303,8 @@ 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;
@@ -1326,8 +1364,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
@@ -1343,8 +1381,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;
@@ -1433,8 +1471,8 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->codec_id = codec_id;
st->start_time = 0;
if (strcmp(track->language, "und"))
- av_metadata_set2(&st->metadata, "language", track->language, 0);
- av_metadata_set2(&st->metadata, "title", track->name, 0);
+ av_dict_set(&st->metadata, "language", track->language, 0);
+ av_dict_set(&st->metadata, "title", track->name, 0);
if (track->flag_default)
st->disposition |= AV_DISPOSITION_DEFAULT;
@@ -1462,8 +1500,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,
@@ -1475,6 +1515,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;
@@ -1495,7 +1554,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
AVStream *st = av_new_stream(s, 0);
if (st == NULL)
break;
- av_metadata_set2(&st->metadata, "filename",attachements[j].filename, 0);
+ av_dict_set(&st->metadata, "filename",attachements[j].filename, 0);
st->codec->codec_id = CODEC_ID_NONE;
st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
st->codec->extradata = av_malloc(attachements[j].bin.size);
@@ -1523,7 +1582,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
ff_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000},
chapters[i].start, chapters[i].end,
chapters[i].title);
- av_metadata_set2(&chapters[i].chapter->metadata,
+ av_dict_set(&chapters[i].chapter->metadata,
"title", chapters[i].title, 0);
max_start = chapters[i].start;
}
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 387cead8cd..9e42019415 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -30,6 +30,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/random_seed.h"
#include "libavutil/lfg.h"
+#include "libavutil/dict.h"
#include "libavcodec/xiph.h"
#include "libavcodec/mpeg4audio.h"
#include <strings.h>
@@ -523,7 +524,7 @@ static int mkv_write_tracks(AVFormatContext *s)
int bit_depth = av_get_bits_per_sample(codec->codec_id);
int sample_rate = codec->sample_rate;
int output_sample_rate = 0;
- AVMetadataTag *tag;
+ AVDictionaryEntry *tag;
if (!bit_depth)
bit_depth = av_get_bits_per_sample_fmt(codec->sample_fmt);
@@ -536,9 +537,9 @@ static int mkv_write_tracks(AVFormatContext *s)
put_ebml_uint (pb, MATROSKA_ID_TRACKUID , i + 1);
put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0); // no lacing (yet)
- if ((tag = av_metadata_get(st->metadata, "title", NULL, 0)))
+ if ((tag = av_dict_get(st->metadata, "title", NULL, 0)))
put_ebml_string(pb, MATROSKA_ID_TRACKNAME, tag->value);
- tag = av_metadata_get(st->metadata, "language", NULL, 0);
+ tag = av_dict_get(st->metadata, "language", NULL, 0);
put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und");
if (st->disposition)
@@ -586,12 +587,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(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;
@@ -656,7 +683,7 @@ static int mkv_write_chapters(AVFormatContext *s)
for (i = 0; i < s->nb_chapters; i++) {
ebml_master chapteratom, chapterdisplay;
AVChapter *c = s->chapters[i];
- AVMetadataTag *t = NULL;
+ AVDictionaryEntry *t = NULL;
chapteratom = start_ebml_master(pb, MATROSKA_ID_CHAPTERATOM, 0);
put_ebml_uint(pb, MATROSKA_ID_CHAPTERUID, c->id);
@@ -666,7 +693,7 @@ static int mkv_write_chapters(AVFormatContext *s)
av_rescale_q(c->end, c->time_base, scale));
put_ebml_uint(pb, MATROSKA_ID_CHAPTERFLAGHIDDEN , 0);
put_ebml_uint(pb, MATROSKA_ID_CHAPTERFLAGENABLED, 1);
- if ((t = av_metadata_get(c->metadata, "title", NULL, 0))) {
+ if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
chapterdisplay = start_ebml_master(pb, MATROSKA_ID_CHAPTERDISPLAY, 0);
put_ebml_string(pb, MATROSKA_ID_CHAPSTRING, t->value);
put_ebml_string(pb, MATROSKA_ID_CHAPLANG , "und");
@@ -679,7 +706,7 @@ static int mkv_write_chapters(AVFormatContext *s)
return 0;
}
-static void mkv_write_simpletag(AVIOContext *pb, AVMetadataTag *t)
+static void mkv_write_simpletag(AVIOContext *pb, AVDictionaryEntry *t)
{
uint8_t *key = av_strdup(t->key);
uint8_t *p = key;
@@ -709,12 +736,12 @@ static void mkv_write_simpletag(AVIOContext *pb, AVMetadataTag *t)
av_freep(&key);
}
-static int mkv_write_tag(AVFormatContext *s, AVMetadata *m, unsigned int elementid,
+static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int elementid,
unsigned int uid, ebml_master *tags)
{
MatroskaMuxContext *mkv = s->priv_data;
ebml_master tag, targets;
- AVMetadataTag *t = NULL;
+ AVDictionaryEntry *t = NULL;
int ret;
if (!tags->pos) {
@@ -730,8 +757,8 @@ static int mkv_write_tag(AVFormatContext *s, AVMetadata *m, unsigned int element
put_ebml_uint(s->pb, elementid, uid);
end_ebml_master(s->pb, targets);
- while ((t = av_metadata_get(m, "", t, AV_METADATA_IGNORE_SUFFIX)))
- if (strcasecmp(t->key, "title"))
+ while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX)))
+ if (strcasecmp(t->key, "title") && strcasecmp(t->key, "stereo_mode"))
mkv_write_simpletag(s->pb, t);
end_ebml_master(s->pb, tag);
@@ -745,7 +772,7 @@ static int mkv_write_tags(AVFormatContext *s)
ff_metadata_conv_ctx(s, ff_mkv_metadata_conv, NULL);
- if (av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) {
+ if (av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) {
ret = mkv_write_tag(s, s->metadata, 0, 0, &tags);
if (ret < 0) return ret;
}
@@ -753,7 +780,7 @@ static int mkv_write_tags(AVFormatContext *s)
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
- if (!av_metadata_get(st->metadata, "", 0, AV_METADATA_IGNORE_SUFFIX))
+ if (!av_dict_get(st->metadata, "", 0, AV_DICT_IGNORE_SUFFIX))
continue;
ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &tags);
@@ -763,7 +790,7 @@ static int mkv_write_tags(AVFormatContext *s)
for (i = 0; i < s->nb_chapters; i++) {
AVChapter *ch = s->chapters[i];
- if (!av_metadata_get(ch->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
+ if (!av_dict_get(ch->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
continue;
ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id, &tags);
@@ -780,7 +807,7 @@ static int mkv_write_header(AVFormatContext *s)
MatroskaMuxContext *mkv = s->priv_data;
AVIOContext *pb = s->pb;
ebml_master ebml_header, segment_info;
- AVMetadataTag *tag;
+ AVDictionaryEntry *tag;
int ret, i;
if (!strcmp(s->oformat->name, "webm")) mkv->mode = MODE_WEBM;
@@ -817,7 +844,7 @@ static int mkv_write_header(AVFormatContext *s)
segment_info = start_ebml_master(pb, MATROSKA_ID_INFO, 0);
put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000);
- if ((tag = av_metadata_get(s->metadata, "title", NULL, 0)))
+ if ((tag = av_dict_get(s->metadata, "title", NULL, 0)))
put_ebml_string(pb, MATROSKA_ID_TITLE, tag->value);
if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
uint32_t segment_uid[4];
@@ -1199,7 +1226,7 @@ AVOutputFormat ff_webm_muxer = {
mkv_write_header,
mkv_write_packet,
mkv_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
};
#endif
diff --git a/libavformat/metadata.c b/libavformat/metadata.c
index 68d42fd257..8caeffa316 100644
--- a/libavformat/metadata.c
+++ b/libavformat/metadata.c
@@ -21,71 +21,20 @@
#include <strings.h>
#include "avformat.h"
#include "metadata.h"
+#include "libavutil/dict.h"
-AVMetadataTag *
-av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags)
+#if FF_API_OLD_METADATA2
+AVDictionaryEntry *
+av_metadata_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
{
- unsigned int i, j;
-
- if(!m)
- return NULL;
-
- if(prev) i= prev - m->elems + 1;
- else i= 0;
-
- for(; i<m->count; i++){
- const char *s= m->elems[i].key;
- if(flags & AV_METADATA_MATCH_CASE) for(j=0; s[j] == key[j] && key[j]; j++);
- else for(j=0; toupper(s[j]) == toupper(key[j]) && key[j]; j++);
- if(key[j])
- continue;
- if(s[j] && !(flags & AV_METADATA_IGNORE_SUFFIX))
- continue;
- return &m->elems[i];
- }
- return NULL;
+ return av_dict_get(m, key, prev, flags);
}
-int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags)
+int av_metadata_set2(AVDictionary **pm, const char *key, const char *value, int flags)
{
- AVMetadata *m= *pm;
- AVMetadataTag *tag= av_metadata_get(m, key, NULL, flags);
-
- if(!m)
- m=*pm= av_mallocz(sizeof(*m));
-
- if(tag){
- if (flags & AV_METADATA_DONT_OVERWRITE)
- return 0;
- av_free(tag->value);
- av_free(tag->key);
- *tag= m->elems[--m->count];
- }else{
- AVMetadataTag *tmp= av_realloc(m->elems, (m->count+1) * sizeof(*m->elems));
- if(tmp){
- m->elems= tmp;
- }else
- return AVERROR(ENOMEM);
- }
- if(value){
- if(flags & AV_METADATA_DONT_STRDUP_KEY){
- m->elems[m->count].key = key;
- }else
- m->elems[m->count].key = av_strdup(key );
- if(flags & AV_METADATA_DONT_STRDUP_VAL){
- m->elems[m->count].value= value;
- }else
- m->elems[m->count].value= av_strdup(value);
- m->count++;
- }
- if(!m->count) {
- av_free(m->elems);
- av_freep(pm);
- }
-
- return 0;
+ return av_dict_set(pm, key, value, flags);
}
-
+#endif
#if FF_API_OLD_METADATA
int av_metadata_set(AVMetadata **pm, const char *key, const char *value)
{
@@ -94,41 +43,38 @@ int av_metadata_set(AVMetadata **pm, const char *key, const char *value)
#endif
#if FF_API_OLD_METADATA2
+
void av_metadata_conv(AVFormatContext *ctx, const AVMetadataConv *d_conv,
const AVMetadataConv *s_conv)
{
return;
}
-#endif
-void av_metadata_free(AVMetadata **pm)
+void av_metadata_free(AVDictionary **pm)
{
- AVMetadata *m= *pm;
+ av_dict_free(pm);
+}
- if(m){
- while(m->count--){
- av_free(m->elems[m->count].key);
- av_free(m->elems[m->count].value);
- }
- av_free(m->elems);
- }
- av_freep(pm);
+void av_metadata_copy(AVDictionary **dst, AVDictionary *src, int flags)
+{
+ av_dict_copy(dst, src, flags);
}
+#endif
-void ff_metadata_conv(AVMetadata **pm, const AVMetadataConv *d_conv,
+void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv,
const AVMetadataConv *s_conv)
{
/* TODO: use binary search to look up the two conversion tables
if the tables are getting big enough that it would matter speed wise */
const AVMetadataConv *sc, *dc;
- AVMetadataTag *mtag = NULL;
- AVMetadata *dst = NULL;
+ AVDictionaryEntry *mtag = NULL;
+ AVDictionary *dst = NULL;
const char *key;
if (d_conv == s_conv)
return;
- while((mtag=av_metadata_get(*pm, "", mtag, AV_METADATA_IGNORE_SUFFIX))) {
+ while ((mtag = av_dict_get(*pm, "", mtag, AV_DICT_IGNORE_SUFFIX))) {
key = mtag->key;
if (s_conv)
for (sc=s_conv; sc->native; sc++)
@@ -142,9 +88,9 @@ void ff_metadata_conv(AVMetadata **pm, const AVMetadataConv *d_conv,
key = dc->native;
break;
}
- av_metadata_set2(&dst, key, mtag->value, 0);
+ av_dict_set(&dst, key, mtag->value, 0);
}
- av_metadata_free(pm);
+ av_dict_free(pm);
*pm = dst;
}
@@ -161,10 +107,3 @@ void ff_metadata_conv_ctx(AVFormatContext *ctx, const AVMetadataConv *d_conv,
ff_metadata_conv(&ctx->programs[i]->metadata, d_conv, s_conv);
}
-void av_metadata_copy(AVMetadata **dst, AVMetadata *src, int flags)
-{
- AVMetadataTag *t = NULL;
-
- while ((t = av_metadata_get(src, "", t, AV_METADATA_IGNORE_SUFFIX)))
- av_metadata_set2(dst, t->key, t->value, flags);
-}
diff --git a/libavformat/metadata.h b/libavformat/metadata.h
index dd9b69005c..aa96118f80 100644
--- a/libavformat/metadata.h
+++ b/libavformat/metadata.h
@@ -29,11 +29,7 @@
#include "avformat.h"
-
-struct AVMetadata{
- int count;
- AVMetadataTag *elems;
-};
+#include "libavutil/dict.h"
struct AVMetadataConv{
const char *native;
@@ -48,7 +44,7 @@ void ff_metadata_demux_compat(AVFormatContext *s);
void ff_metadata_mux_compat(AVFormatContext *s);
#endif
-void ff_metadata_conv(AVMetadata **pm, const AVMetadataConv *d_conv,
+void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv,
const AVMetadataConv *s_conv);
void ff_metadata_conv_ctx(AVFormatContext *ctx, const AVMetadataConv *d_conv,
const AVMetadataConv *s_conv);
diff --git a/libavformat/mmf.c b/libavformat/mmf.c
index fc6fcc3caa..89e33b4ce2 100644
--- a/libavformat/mmf.c
+++ b/libavformat/mmf.c
@@ -186,13 +186,13 @@ static int mmf_read_header(AVFormatContext *s,
unsigned int tag;
AVIOContext *pb = s->pb;
AVStream *st;
- int64_t file_size, size;
+ int64_t size;
int rate, params;
tag = avio_rl32(pb);
if (tag != MKTAG('M', 'M', 'M', 'D'))
return -1;
- file_size = avio_rb32(pb);
+ avio_skip(pb, 4); /* file_size */
/* Skip some unused chunks that may or may not be present */
for(;; avio_skip(pb, size)) {
@@ -263,12 +263,10 @@ static int mmf_read_packet(AVFormatContext *s,
AVPacket *pkt)
{
MMFContext *mmf = s->priv_data;
- AVStream *st;
int ret, size;
if (url_feof(s->pb))
return AVERROR(EIO);
- st = s->streams[0];
size = MAX_SIZE;
if(size > mmf->data_size)
diff --git a/libavformat/mms.h b/libavformat/mms.h
index 788851e24f..0117089d24 100644
--- a/libavformat/mms.h
+++ b/libavformat/mms.h
@@ -60,4 +60,5 @@ typedef struct {
int ff_mms_asf_header_parser(MMSContext * mms);
int ff_mms_read_data(MMSContext *mms, uint8_t *buf, const int size);
int ff_mms_read_header(MMSContext * mms, uint8_t * buf, const int size);
-#endif
+
+#endif /* AVFORMAT_MMS_H */
diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c
index 70664b9776..105e53c82b 100644
--- a/libavformat/mmsh.c
+++ b/libavformat/mmsh.c
@@ -28,7 +28,7 @@
#include <string.h>
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
-#include "libavformat/internal.h"
+#include "internal.h"
#include "mms.h"
#include "asf.h"
#include "http.h"
@@ -231,7 +231,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags)
host, sizeof(host), &port, path, sizeof(path), location);
if (port<0)
port = 80; // default mmsh protocol port
- ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, path);
+ ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, "%s", path);
if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_RDONLY) < 0) {
return AVERROR(EIO);
diff --git a/libavformat/mmst.c b/libavformat/mmst.c
index 775ab7ea7f..7c1041ec85 100644
--- a/libavformat/mmst.c
+++ b/libavformat/mmst.c
@@ -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 c16add7713..302ab18857 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -23,11 +23,11 @@
#include <limits.h>
//#define DEBUG
-//#define DEBUG_METADATA
//#define MOV_EXPORT_ALL_METADATA
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "avio_internal.h"
#include "riff.h"
@@ -79,15 +79,15 @@ 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 *type)
{
char buf[16];
avio_rb16(pb); // unknown
snprintf(buf, sizeof(buf), "%d", avio_rb16(pb));
- av_metadata_set2(&c->fc->metadata, "track", buf, 0);
+ av_dict_set(&c->fc->metadata, type, buf, 0);
- avio_rb16(pb); // total tracks
+ avio_rb16(pb); // total tracks/discs
return 0;
}
@@ -138,7 +138,7 @@ 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;
@@ -164,7 +164,9 @@ 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;
}
if (c->itunes_metadata && atom.size > 8) {
@@ -199,7 +201,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));
@@ -207,17 +209,15 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_read(pb, str, str_size);
str[str_size] = 0;
}
- av_metadata_set2(&c->fc->metadata, key, str, 0);
+ av_dict_set(&c->fc->metadata, key, str, 0);
if (*language && strcmp(language, "und")) {
snprintf(key2, sizeof(key2), "%s-%s", key, language);
- av_metadata_set2(&c->fc->metadata, key2, str, 0);
+ av_dict_set(&c->fc->metadata, key2, str, 0);
}
}
-#ifdef DEBUG_METADATA
- av_log(c->fc, AV_LOG_DEBUG, "lang \"%3s\" ", language);
- av_log(c->fc, AV_LOG_DEBUG, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %lld\n",
- key, str, (char*)&atom.type, str_size, atom.size);
-#endif
+ av_dlog(c->fc, "lang \"%3s\" ", language);
+ av_dlog(c->fc, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %"PRId64"\n",
+ key, str, (char*)&atom.type, str_size, atom.size);
return 0;
}
@@ -431,7 +431,7 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
uint32_t type;
- uint32_t ctype;
+ uint32_t av_unused ctype;
if (c->fc->nb_streams < 1) // meta before first trak
return 0;
@@ -467,21 +467,21 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
- int tag, len;
+ int tag;
if (fc->nb_streams < 1)
return 0;
st = fc->streams[fc->nb_streams-1];
avio_rb32(pb); /* version + flags */
- len = ff_mp4_read_descr(fc, pb, &tag);
+ ff_mp4_read_descr(fc, pb, &tag);
if (tag == MP4ESDescrTag) {
avio_rb16(pb); /* ID */
avio_r8(pb); /* priority */
} else
avio_rb16(pb); /* ID */
- len = ff_mp4_read_descr(fc, pb, &tag);
+ ff_mp4_read_descr(fc, pb, &tag);
if (tag == MP4DecConfigDescrTag)
ff_mp4_read_dec_config_descr(fc, st, pb);
return 0;
@@ -513,6 +513,19 @@ static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
+static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ AVStream *st;
+
+ if (c->fc->nb_streams < 1)
+ return 0;
+ st = c->fc->streams[c->fc->nb_streams-1];
+
+ ff_get_wav_header(pb, st->codec, atom.size);
+
+ return 0;
+}
+
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
const int num = avio_rb32(pb);
@@ -558,10 +571,10 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (strcmp(type, "qt "))
c->isom = 1;
av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
- av_metadata_set2(&c->fc->metadata, "major_brand", type, 0);
+ av_dict_set(&c->fc->metadata, "major_brand", type, 0);
minor_ver = avio_rb32(pb); /* minor version */
snprintf(minor_ver_str, sizeof(minor_ver_str), "%d", minor_ver);
- av_metadata_set2(&c->fc->metadata, "minor_version", minor_ver_str, 0);
+ av_dict_set(&c->fc->metadata, "minor_version", minor_ver_str, 0);
comp_brand_size = atom.size - 8;
if (comp_brand_size < 0)
@@ -571,7 +584,7 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return AVERROR(ENOMEM);
avio_read(pb, comp_brands_str, comp_brand_size);
comp_brands_str[comp_brand_size] = 0;
- av_metadata_set2(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
+ av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
av_freep(&comp_brands_str);
return 0;
@@ -595,7 +608,7 @@ static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return mov_read_default(c, pb, atom);
}
-static void mov_metadata_creation_time(AVMetadata **metadata, time_t time)
+static void mov_metadata_creation_time(AVDictionary **metadata, time_t time)
{
char buffer[32];
if (time) {
@@ -604,7 +617,7 @@ static void mov_metadata_creation_time(AVMetadata **metadata, time_t time)
ptm = gmtime(&time);
if (!ptm) return;
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm);
- av_metadata_set2(metadata, "creation_time", buffer, 0);
+ av_dict_set(metadata, "creation_time", buffer, 0);
}
}
@@ -641,7 +654,7 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
lang = avio_rb16(pb); /* language */
if (ff_mov_lang_to_iso639(lang, language))
- av_metadata_set2(&st->metadata, "language", language, 0);
+ av_dict_set(&st->metadata, "language", language, 0);
avio_rb16(pb); /* quality */
return 0;
@@ -718,7 +731,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) {
@@ -1525,10 +1538,11 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
/* adjust first dts according to edit list */
if (sc->time_offset && mov->time_scale > 0) {
- int rescaled = sc->time_offset < 0 ? av_rescale(sc->time_offset, sc->time_scale, mov->time_scale) : sc->time_offset;
- current_dts = -rescaled;
+ if (sc->time_offset < 0)
+ 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;
@@ -1690,13 +1704,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 */
@@ -1914,6 +1928,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
@@ -2056,7 +2074,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (flags & 0x001) data_offset = avio_rb32(pb);
if (flags & 0x004) first_sample_flags = avio_rb32(pb);
- dts = st->duration;
+ dts = st->duration - sc->time_offset;
offset = frag->base_data_offset + data_offset;
distance = 0;
av_dlog(c->fc, "first sample flags 0x%x\n", first_sample_flags);
@@ -2085,7 +2103,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
offset += sample_size;
}
frag->moof_offset = offset;
- st->duration = dts;
+ st->duration = dts + sc->time_offset;
return 0;
}
@@ -2149,9 +2167,6 @@ static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
goto free_and_return;
atom.type = MKTAG('m','o','o','v');
atom.size = moov_len;
-#ifdef DEBUG
-// { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
-#endif
ret = mov_read_default(c, &ctx, atom);
free_and_return:
av_free(moov_data);
@@ -2265,6 +2280,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('e','s','d','s'), mov_read_esds },
{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
{ 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 }
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 1b61706da3..ebfcacb107 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -32,10 +32,27 @@
#include "libavcodec/put_bits.h"
#include "internal.h"
#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "libavutil/dict.h"
+#include "rtpenc.h"
#undef NDEBUG
#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" },
+ 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,
+};
+
//FIXME support 64 bit variant with wide placeholders
static int64_t updateSize(AVIOContext *pb, int64_t pos)
{
@@ -1274,20 +1291,49 @@ static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
// This box seems important for the psp playback ... without it the movie seems to hang
static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track)
{
- avio_wb32(pb, 0x24); /* size */
+ int64_t duration = av_rescale_rnd(track->trackDuration, MOV_TIMESCALE,
+ track->timescale, AV_ROUND_UP);
+ int version = duration < INT32_MAX ? 0 : 1;
+ int entry_size, entry_count, size;
+ int64_t delay, start_ct = track->cluster[0].cts;
+ delay = av_rescale_rnd(track->cluster[0].dts + start_ct, MOV_TIMESCALE,
+ track->timescale, AV_ROUND_DOWN);
+ version |= delay < INT32_MAX ? 0 : 1;
+
+ entry_size = (version == 1) ? 20 : 12;
+ entry_count = 1 + (delay > 0);
+ size = 24 + entry_count * entry_size;
+
+ /* write the atom data */
+ avio_wb32(pb, size);
ffio_wfourcc(pb, "edts");
- avio_wb32(pb, 0x1c); /* size */
+ avio_wb32(pb, size - 8);
ffio_wfourcc(pb, "elst");
- avio_wb32(pb, 0x0);
- avio_wb32(pb, 0x1);
+ avio_w8(pb, version);
+ avio_wb24(pb, 0); /* flags */
- /* duration ... doesn't seem to effect psp */
- avio_wb32(pb, av_rescale_rnd(track->trackDuration, MOV_TIMESCALE,
- track->timescale, AV_ROUND_UP));
+ avio_wb32(pb, entry_count);
+ if (delay > 0) { /* add an empty edit to delay presentation */
+ if (version == 1) {
+ avio_wb64(pb, delay);
+ avio_wb64(pb, -1);
+ } else {
+ avio_wb32(pb, delay);
+ avio_wb32(pb, -1);
+ }
+ avio_wb32(pb, 0x00010000);
+ }
- avio_wb32(pb, track->cluster[0].cts); /* first pts is cts since dts is 0 */
+ /* duration */
+ if (version == 1) {
+ avio_wb64(pb, duration);
+ avio_wb64(pb, start_ct);
+ } else {
+ avio_wb32(pb, duration);
+ avio_wb32(pb, start_ct);
+ }
avio_wb32(pb, 0x00010000);
- return 0x24;
+ return size;
}
static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
@@ -1319,12 +1365,12 @@ static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
return 0x34;
}
-static int mov_write_udta_sdp(AVIOContext *pb, AVCodecContext *ctx, int index)
+static int mov_write_udta_sdp(AVIOContext *pb, AVFormatContext *ctx, int index)
{
char buf[1000] = "";
int len;
- ff_sdp_write_media(buf, sizeof(buf), ctx, NULL, NULL, 0, 0);
+ ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0]->codec, NULL, NULL, 0, 0, ctx);
av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", index);
len = strlen(buf);
@@ -1344,7 +1390,7 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
avio_wb32(pb, 0); /* size */
ffio_wfourcc(pb, "trak");
mov_write_tkhd_tag(pb, track, st);
- if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS)
+ if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS || track->cluster[0].dts)
mov_write_edts_tag(pb, track); // PSP Movies require edts box
if (track->tref_tag)
mov_write_tref_tag(pb, track);
@@ -1352,7 +1398,7 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
if (track->mode == MODE_PSP)
mov_write_uuid_tag_psp(pb,track); // PSP Movies require this uuid box
if (track->tag == MKTAG('r','t','p',' '))
- mov_write_udta_sdp(pb, track->rtp_ctx->streams[0]->codec, track->trackID);
+ mov_write_udta_sdp(pb, track->rtp_ctx, track->trackID);
if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && track->mode == MODE_MOV) {
double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
if (0.0 != sample_aspect_ratio && 1.0 != sample_aspect_ratio)
@@ -1491,15 +1537,15 @@ static int mov_write_string_metadata(AVFormatContext *s, AVIOContext *pb,
int long_style)
{
int l, lang = 0, len, len2;
- AVMetadataTag *t, *t2 = NULL;
+ AVDictionaryEntry *t, *t2 = NULL;
char tag2[16];
- if (!(t = av_metadata_get(s->metadata, tag, NULL, 0)))
+ if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
return 0;
len = strlen(t->key);
snprintf(tag2, sizeof(tag2), "%s-", tag);
- while ((t2 = av_metadata_get(s->metadata, tag2, t2, AV_METADATA_IGNORE_SUFFIX))) {
+ while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
len2 = strlen(t2->key);
if (len2 == len+4 && !strcmp(t->value, t2->value)
&& (l=ff_mov_iso639_to_lang(&t2->key[len2-3], 1)) >= 0) {
@@ -1514,7 +1560,7 @@ static int mov_write_string_metadata(AVFormatContext *s, AVIOContext *pb,
static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov,
AVFormatContext *s)
{
- AVMetadataTag *t = av_metadata_get(s->metadata, "track", NULL, 0);
+ AVDictionaryEntry *t = av_dict_get(s->metadata, "track", NULL, 0);
int size = 0, track = t ? atoi(t->value) : 0;
if (track) {
avio_wb32(pb, 32); /* size */
@@ -1606,7 +1652,7 @@ static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s,
const char *tag, const char *str)
{
int64_t pos = avio_tell(pb);
- AVMetadataTag *t = av_metadata_get(s->metadata, str, NULL, 0);
+ AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
if (!t || !utf8len(t->value))
return 0;
avio_wb32(pb, 0); /* size */
@@ -1618,7 +1664,7 @@ static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s,
avio_wb16(pb, language_code("eng")); /* language */
avio_write(pb, t->value, strlen(t->value)+1); /* UTF8 string value */
if (!strcmp(tag, "albm") &&
- (t = av_metadata_get(s->metadata, "track", NULL, 0)))
+ (t = av_dict_get(s->metadata, "track", NULL, 0)))
avio_w8(pb, atoi(t->value));
}
return updateSize(pb, pos);
@@ -1637,10 +1683,10 @@ static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s)
for (i = 0; i < nb_chapters; i++) {
AVChapter *c = s->chapters[i];
- AVMetadataTag *t;
+ AVDictionaryEntry *t;
avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
- if ((t = av_metadata_get(c->metadata, "title", NULL, 0))) {
+ if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
int len = FFMIN(strlen(t->value), 255);
avio_w8(pb, len);
avio_write(pb, t->value, len);
@@ -1718,7 +1764,7 @@ static void mov_write_psp_udta_tag(AVIOContext *pb,
static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s)
{
- AVMetadataTag *title = av_metadata_get(s->metadata, "title", NULL, 0);
+ AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
int64_t pos, pos2;
if (title) {
@@ -2072,13 +2118,13 @@ static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
for (i = 0; i < s->nb_chapters; i++) {
AVChapter *c = s->chapters[i];
- AVMetadataTag *t;
+ AVDictionaryEntry *t;
int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,MOV_TIMESCALE});
pkt.pts = pkt.dts = av_rescale_q(c->start, c->time_base, (AVRational){1,MOV_TIMESCALE});
pkt.duration = end - pkt.dts;
- if ((t = av_metadata_get(c->metadata, "title", NULL, 0))) {
+ if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
len = strlen(t->value);
pkt.size = len+2;
pkt.data = av_malloc(pkt.size);
@@ -2125,7 +2171,15 @@ static int mov_write_header(AVFormatContext *s)
if (mov->mode & (MODE_MOV|MODE_IPOD) && s->nb_chapters)
mov->chapter_track = mov->nb_streams++;
+#if FF_API_FLAG_RTP_HINT
if (s->flags & AVFMT_FLAG_RTP_HINT) {
+ av_log(s, AV_LOG_WARNING, "The RTP_HINT flag is deprecated, enable it "
+ "via the -movflags rtphint muxer option "
+ "instead.\n");
+ mov->flags |= FF_MOV_FLAG_RTP_HINT;
+ }
+#endif
+ if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
/* Add hint tracks for each audio and video stream */
hint_track = mov->nb_streams;
for (i = 0; i < s->nb_streams; i++) {
@@ -2144,7 +2198,7 @@ static int mov_write_header(AVFormatContext *s)
for(i=0; i<s->nb_streams; i++){
AVStream *st= s->streams[i];
MOVTrack *track= &mov->tracks[i];
- AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL,0);
+ AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
track->enc = st->codec;
track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
@@ -2221,7 +2275,7 @@ static int mov_write_header(AVFormatContext *s)
if (mov->chapter_track)
mov_create_chapter_track(s, mov->chapter_track);
- if (s->flags & AVFMT_FLAG_RTP_HINT) {
+ if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
/* Initialize the hint tracks for each audio and video stream */
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
@@ -2298,6 +2352,7 @@ AVOutputFormat ff_mov_muxer = {
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
@@ -2314,6 +2369,7 @@ AVOutputFormat ff_tgp_muxer = {
mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
+ .priv_class = &mov_muxer_class,
};
#endif
#if CONFIG_MP4_MUXER
@@ -2330,6 +2386,7 @@ AVOutputFormat ff_mp4_muxer = {
mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
+ .priv_class = &mov_muxer_class,
};
#endif
#if CONFIG_PSP_MUXER
@@ -2346,6 +2403,7 @@ AVOutputFormat ff_psp_muxer = {
mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
+ .priv_class = &mov_muxer_class,
};
#endif
#if CONFIG_TG2_MUXER
@@ -2362,6 +2420,7 @@ AVOutputFormat ff_tg2_muxer = {
mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
+ .priv_class = &mov_muxer_class,
};
#endif
#if CONFIG_IPOD_MUXER
@@ -2378,5 +2437,6 @@ AVOutputFormat ff_ipod_muxer = {
mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){codec_ipod_tags, 0},
+ .priv_class = &mov_muxer_class,
};
#endif
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 182c5edc8c..610683fa6a 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -101,6 +101,7 @@ typedef struct MOVIndex {
} MOVTrack;
typedef struct MOVMuxContext {
+ const AVClass *av_class;
int mode;
int64_t time;
int nb_streams;
@@ -108,8 +109,13 @@ typedef struct MOVMuxContext {
int64_t mdat_pos;
uint64_t mdat_size;
MOVTrack *tracks;
+
+ int flags;
+ int rtp_flags;
} MOVMuxContext;
+#define FF_MOV_FLAG_RTP_HINT 1
+
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index);
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index 1306888b46..64f6ea8c0e 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -21,6 +21,7 @@
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "id3v2.h"
#include "id3v1.h"
@@ -149,7 +150,7 @@ static int mp3_read_header(AVFormatContext *s,
off = avio_tell(s->pb);
- if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
+ if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
ff_id3v1_read(s);
if (mp3_parse_vbr_tags(s, st, off) < 0)
diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
index 082450779f..50342bb950 100644
--- a/libavformat/mp3enc.c
+++ b/libavformat/mp3enc.c
@@ -27,22 +27,24 @@
#include "libavutil/avstring.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,
uint8_t *buf, int buf_size)
{
- AVMetadataTag *tag;
- if ((tag = av_metadata_get(s->metadata, key, NULL, 0)))
+ AVDictionaryEntry *tag;
+ if ((tag = av_dict_get(s->metadata, key, NULL, 0)))
av_strlcpy(buf, tag->value, buf_size);
return !!tag;
}
static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
{
- AVMetadataTag *tag;
+ AVDictionaryEntry *tag;
int i, count = 0;
memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */
@@ -54,13 +56,13 @@ static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
count += id3v1_set_string(s, "TALB", buf + 63, 30); //album
count += id3v1_set_string(s, "TDRL", buf + 93, 4); //date
count += id3v1_set_string(s, "comment", buf + 97, 30);
- if ((tag = av_metadata_get(s->metadata, "TRCK", NULL, 0))) { //track
+ if ((tag = av_dict_get(s->metadata, "TRCK", NULL, 0))) { //track
buf[125] = 0;
buf[126] = atoi(tag->value);
count++;
}
buf[127] = 0xFF; /* default to unknown genre */
- if ((tag = av_metadata_get(s->metadata, "TCON", NULL, 0))) { //genre
+ if ((tag = av_dict_get(s->metadata, "TCON", NULL, 0))) { //genre
for(i = 0; i <= ID3v1_GENRE_MAX; i++) {
if (!strcasecmp(tag->value, ff_id3v1_genre_str[i])) {
buf[127] = i;
@@ -185,7 +187,7 @@ static const AVClass mp3_muxer_class = {
.version = LIBAVUTIL_VERSION_INT,
};
-static int id3v2_check_write_tag(AVFormatContext *s, AVMetadataTag *t, const char table[][4],
+static int id3v2_check_write_tag(AVFormatContext *s, AVDictionaryEntry *t, const char table[][4],
enum ID3v2Encoding enc)
{
uint32_t tag;
@@ -344,7 +346,7 @@ static void mp3_fix_xing(AVFormatContext *s)
static int mp3_write_header(struct AVFormatContext *s)
{
MP3Context *mp3 = s->priv_data;
- AVMetadataTag *t = NULL;
+ AVDictionaryEntry *t = NULL;
int totlen = 0, enc = mp3->id3v2_version == 3 ? ID3v2_ENCODING_UTF16BOM :
ID3v2_ENCODING_UTF8;
int64_t size_pos, cur_pos;
@@ -361,7 +363,7 @@ static int mp3_write_header(struct AVFormatContext *s)
if (mp3->id3v2_version == 4)
ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL);
- while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) {
+ while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
int ret;
if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_tags, enc)) > 0) {
diff --git a/libavformat/mpc.c b/libavformat/mpc.c
index 3544cf11cf..4d6854f13f 100644
--- a/libavformat/mpc.c
+++ b/libavformat/mpc.c
@@ -23,6 +23,7 @@
#include "avformat.h"
#include "apetag.h"
#include "id3v1.h"
+#include "libavutil/dict.h"
#define MPC_FRAMESIZE 1152
#define DELAY_FRAMES 32
@@ -96,7 +97,7 @@ static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (s->pb->seekable) {
int64_t pos = avio_tell(s->pb);
ff_ape_parse_tag(s);
- if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
+ if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
ff_id3v1_read(s);
avio_seek(s->pb, pos, SEEK_SET);
}
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index f9f818951f..1bc4480cd8 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -23,8 +23,6 @@
#include "internal.h"
#include "mpeg.h"
-//#define DEBUG_SEEK
-
#undef NDEBUG
#include <assert.h>
@@ -572,10 +570,9 @@ static int mpegps_read_packet(AVFormatContext *s,
pkt->dts = dts;
pkt->pos = dummy_pos;
pkt->stream_index = st->index;
-#if 0
- av_log(s, AV_LOG_DEBUG, "%d: pts=%0.3f dts=%0.3f size=%d\n",
- pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0, pkt->size);
-#endif
+ av_dlog(s, "%d: pts=%0.3f dts=%0.3f size=%d\n",
+ pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0,
+ pkt->size);
return 0;
}
@@ -587,18 +584,13 @@ static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
int64_t pos, pts, dts;
pos = *ppos;
-#ifdef DEBUG_SEEK
- printf("read_dts: pos=0x%"PRIx64" next=%d -> ", pos, find_next);
-#endif
if (avio_seek(s->pb, pos, SEEK_SET) < 0)
return AV_NOPTS_VALUE;
for(;;) {
len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts);
if (len < 0) {
-#ifdef DEBUG_SEEK
- printf("none (ret=%d)\n", len);
-#endif
+ av_dlog(s, "none (ret=%d)\n", len);
return AV_NOPTS_VALUE;
}
if (startcode == s->streams[stream_index]->id &&
@@ -607,9 +599,8 @@ static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
}
avio_skip(s->pb, len);
}
-#ifdef DEBUG_SEEK
- printf("pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", pos, dts, dts / 90000.0);
-#endif
+ av_dlog(s, "pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n",
+ pos, dts, dts / 90000.0);
*ppos = pos;
return dts;
}
diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
index e42fac4ceb..9c808d0f1e 100644
--- a/libavformat/mpegenc.c
+++ b/libavformat/mpegenc.c
@@ -25,7 +25,6 @@
#include "mpeg.h"
#define MAX_PAYLOAD_SIZE 4096
-//#define DEBUG_SEEK
#undef NDEBUG
#include <assert.h>
@@ -1078,10 +1077,8 @@ retry:
best_dts= pkt_desc->dts;
}
-#if 0
- av_log(ctx, AV_LOG_DEBUG, "bumping scr, scr:%f, dts:%f\n",
- scr/90000.0, best_dts/90000.0);
-#endif
+ av_dlog(ctx, "bumping scr, scr:%f, dts:%f\n",
+ scr / 90000.0, best_dts / 90000.0);
if(best_dts == INT64_MAX)
return 0;
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 6452861e38..89109c0689 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -19,12 +19,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-//#define DEBUG
-//#define DEBUG_SEEK
//#define USE_SYNCPOINT_SEARCH
#include "libavutil/crc.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/log.h"
+#include "libavutil/dict.h"
+#include "libavutil/opt.h"
#include "libavcodec/bytestream.h"
#include "avformat.h"
#include "mpegts.h"
@@ -86,6 +87,7 @@ struct Program {
};
struct MpegTSContext {
+ const AVClass *class;
/* user data */
AVFormatContext *stream;
/** raw packet size, including FEC if present */
@@ -122,6 +124,19 @@ struct MpegTSContext {
MpegTSFilter *pids[NB_PID_MAX];
};
+static const AVOption options[] = {
+ {"compute_pcr", "Compute exact PCR for each transport stream packet.", offsetof(MpegTSContext, mpeg2ts_compute_pcr), FF_OPT_TYPE_INT,
+ {.dbl = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
+ { NULL },
+};
+
+static const AVClass mpegtsraw_class = {
+ .class_name = "mpegtsraw demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
/* TS stream handling */
enum MpegTSState {
@@ -205,6 +220,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
@@ -928,7 +954,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
language[1] = get8(pp, desc_end);
language[2] = get8(pp, desc_end);
language[3] = 0;
- av_metadata_set2(&st->metadata, "language", language, 0);
+ av_dict_set(&st->metadata, "language", language, 0);
break;
case 0x59: /* subtitling descriptor */
language[0] = get8(pp, desc_end);
@@ -957,7 +983,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
}
}
*pp += 4;
- av_metadata_set2(&st->metadata, "language", language, 0);
+ av_dict_set(&st->metadata, "language", language, 0);
break;
case 0x0a: /* ISO 639 language descriptor */
for (i = 0; i + 4 <= desc_len; i += 4) {
@@ -973,7 +999,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
}
if (i) {
language[i - 1] = 0;
- av_metadata_set2(&st->metadata, "language", language, 0);
+ av_dict_set(&st->metadata, "language", language, 0);
}
break;
case 0x05: /* registration descriptor */
@@ -983,6 +1009,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;
}
@@ -1004,10 +1033,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
int mp4_dec_config_descr_len = 0;
int mp4_es_id = 0;
-#ifdef DEBUG
av_dlog(ts->stream, "PMT: len %i\n", section_len);
- av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
-#endif
+ hex_dump_debug(ts->stream, (uint8_t *)section, section_len);
p_end = section + section_len - 4;
p = section;
@@ -1025,6 +1052,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);
@@ -1123,11 +1151,11 @@ 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;
-#ifdef DEBUG
av_dlog(ts->stream, "PAT:\n");
- av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
-#endif
+ hex_dump_debug(ts->stream, (uint8_t *)section, section_len);
+
p_end = section + section_len - 4;
p = section;
if (parse_section_header(h, &p, p_end) < 0)
@@ -1135,6 +1163,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);
@@ -1149,7 +1179,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);
@@ -1168,10 +1200,8 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type;
char *name, *provider_name;
-#ifdef DEBUG
av_dlog(ts->stream, "SDT:\n");
- av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
-#endif
+ hex_dump_debug(ts->stream, (uint8_t *)section, section_len);
p_end = section + section_len - 4;
p = section;
@@ -1222,8 +1252,8 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
if (name) {
AVProgram *program = av_new_program(ts->stream, sid);
if(program) {
- av_metadata_set2(&program->metadata, "service_name", name, 0);
- av_metadata_set2(&program->metadata, "service_provider", provider_name, 0);
+ av_dict_set(&program->metadata, "service_name", name, 0);
+ av_dict_set(&program->metadata, "service_provider", provider_name, 0);
}
}
av_free(name);
@@ -1460,13 +1490,16 @@ static int mpegts_read_header(AVFormatContext *s,
int len;
int64_t pos;
+#if FF_API_FORMAT_PARAMETERS
if (ap) {
- ts->mpeg2ts_compute_pcr = ap->mpeg2ts_compute_pcr;
+ 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 */
pos = avio_tell(pb);
@@ -1544,10 +1577,8 @@ static int mpegts_read_header(AVFormatContext *s,
s->bit_rate = (TS_PACKET_SIZE * 8) * 27e6 / ts->pcr_incr;
st->codec->bit_rate = s->bit_rate;
st->start_time = ts->cur_pcr;
-#if 0
- av_log(ts->stream, AV_LOG_DEBUG, "start=%0.3f pcr=%0.3f incr=%d\n",
- st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr);
-#endif
+ av_dlog(ts->stream, "start=%0.3f pcr=%0.3f incr=%d\n",
+ st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr);
}
avio_seek(pb, pos, SEEK_SET);
@@ -1888,4 +1919,5 @@ AVInputFormat ff_mpegtsraw_demuxer = {
#ifdef USE_SYNCPOINT_SEARCH
.read_seek2 = read_seek2,
#endif
+ .priv_class = &mpegtsraw_class,
};
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index e7d70015aa..7e9647257f 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -21,6 +21,7 @@
#include "libavutil/bswap.h"
#include "libavutil/crc.h"
+#include "libavutil/dict.h"
#include "libavutil/opt.h"
#include "libavcodec/mpegvideo.h"
#include "avformat.h"
@@ -53,6 +54,7 @@ typedef struct MpegTSService {
} MpegTSService;
typedef struct MpegTSWrite {
+ const AVClass *av_class;
MpegTSSection pat; /* MPEG2 pat table */
MpegTSSection sdt; /* MPEG2 sdt table context */
MpegTSService **services;
@@ -243,7 +245,7 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
for(i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
MpegTSWriteStream *ts_st = st->priv_data;
- AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL,0);
+ AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
switch(st->codec->codec_id) {
case CODEC_ID_MPEG1VIDEO:
case CODEC_ID_MPEG2VIDEO:
@@ -442,7 +444,7 @@ static int mpegts_write_header(AVFormatContext *s)
MpegTSWriteStream *ts_st;
MpegTSService *service;
AVStream *st, *pcr_st = NULL;
- AVMetadataTag *title, *provider;
+ AVDictionaryEntry *title, *provider;
int i, j;
const char *service_name;
const char *provider_name;
@@ -451,11 +453,11 @@ static int mpegts_write_header(AVFormatContext *s)
ts->tsid = ts->transport_stream_id;
ts->onid = ts->original_network_id;
/* allocate a single DVB service */
- title = av_metadata_get(s->metadata, "service_name", NULL, 0);
+ title = av_dict_get(s->metadata, "service_name", NULL, 0);
if (!title)
- title = av_metadata_get(s->metadata, "title", NULL, 0);
+ title = av_dict_get(s->metadata, "title", NULL, 0);
service_name = title ? title->value : DEFAULT_SERVICE_NAME;
- provider = av_metadata_get(s->metadata, "service_provider", NULL, 0);
+ provider = av_dict_get(s->metadata, "service_provider", NULL, 0);
provider_name = provider ? provider->value : DEFAULT_PROVIDER_NAME;
service = mpegts_add_service(ts, ts->service_id, provider_name, service_name);
service->pmt.write_packet = section_write_packet;
diff --git a/libavformat/mpegvideodec.c b/libavformat/mpegvideodec.c
index d1ba1f8c2c..d38d6955e4 100644
--- a/libavformat/mpegvideodec.c
+++ b/libavformat/mpegvideodec.c
@@ -55,13 +55,4 @@ static int mpegvideo_probe(AVProbeData *p)
return 0;
}
-AVInputFormat ff_mpegvideo_demuxer = {
- "mpegvideo",
- NULL_IF_CONFIG_SMALL("raw MPEG video"),
- 0,
- mpegvideo_probe,
- ff_raw_video_read_header,
- ff_raw_read_partial_packet,
- .flags= AVFMT_GENERIC_INDEX,
- .value = CODEC_ID_MPEG1VIDEO,
-};
+FF_DEF_RAWVIDEO_DEMUXER(mpegvideo, "raw MPEG video", mpegvideo_probe, NULL, CODEC_ID_MPEG1VIDEO)
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 6b44b8f3e3..8548c792f6 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -309,7 +309,7 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
if (klv_read_packet(&klv, s->pb) < 0)
return -1;
PRINT_KEY(s, "read packet", klv.key);
- av_dlog(s, "size %lld offset %#llx\n", klv.length, klv.offset);
+ av_dlog(s, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);
if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
int res = mxf_decrypt_triplet(s, pkt, &klv);
if (res < 0) {
@@ -522,8 +522,8 @@ static int mxf_read_index_table_segment(void *arg, AVIOContext *pb, int tag, int
case 0x3F06: av_dlog(NULL, "IndexSID %d\n", avio_rb32(pb)); break;
case 0x3F07: av_dlog(NULL, "BodySID %d\n", avio_rb32(pb)); break;
case 0x3F0B: av_dlog(NULL, "IndexEditRate %d/%d\n", avio_rb32(pb), avio_rb32(pb)); break;
- case 0x3F0C: av_dlog(NULL, "IndexStartPosition %lld\n", avio_rb64(pb)); break;
- case 0x3F0D: av_dlog(NULL, "IndexDuration %lld\n", avio_rb64(pb)); break;
+ case 0x3F0C: av_dlog(NULL, "IndexStartPosition %"PRIu64"\n", avio_rb64(pb)); break;
+ case 0x3F0D: av_dlog(NULL, "IndexDuration %"PRIu64"\n", avio_rb64(pb)); break;
}
return 0;
}
@@ -920,7 +920,7 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (klv_read_packet(&klv, s->pb) < 0)
return -1;
PRINT_KEY(s, "read header", klv.key);
- av_dlog(s, "size %lld offset %#llx\n", klv.length, klv.offset);
+ av_dlog(s, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);
if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) ||
IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
/* FIXME avoid seek */
diff --git a/libavformat/network.h b/libavformat/network.h
index f2a0c97d77..f7e19b196e 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -21,7 +21,10 @@
#ifndef AVFORMAT_NETWORK_H
#define AVFORMAT_NETWORK_H
+#include <errno.h>
+
#include "config.h"
+#include "libavutil/error.h"
#include "os_support.h"
#if HAVE_WINSOCK2_H
@@ -33,7 +36,8 @@
#define ECONNREFUSED WSAECONNREFUSED
#define EINPROGRESS WSAEINPROGRESS
-static inline int ff_neterrno() {
+static inline int ff_neterrno(void)
+{
int err = WSAGetLastError();
switch (err) {
case WSAEWOULDBLOCK:
diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c
index 300a8fd7f8..4898187f3a 100644
--- a/libavformat/nsvdec.c
+++ b/libavformat/nsvdec.c
@@ -20,10 +20,10 @@
*/
#include "avformat.h"
#include "riff.h"
+#include "libavutil/dict.h"
+#include "libavutil/intreadwrite.h"
-//#define DEBUG
//#define DEBUG_DUMP_INDEX // XXX dumbdriving-271.nsv breaks with it commented!!
-//#define DEBUG_SEEK
#define CHECK_SUBSEQUENT_NSVS
//#define DISABLE_AUDIO
@@ -267,7 +267,8 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap)
{
NSVContext *nsv = s->priv_data;
AVIOContext *pb = s->pb;
- unsigned int file_size, size;
+ unsigned int av_unused file_size;
+ unsigned int size;
int64_t duration;
int strings_size;
int table_entries;
@@ -327,7 +328,7 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap)
break;
*p++ = '\0';
av_dlog(s, "NSV NSVf INFO: %s='%s'\n", token, value);
- av_metadata_set2(&s->metadata, token, value, 0);
+ av_dict_set(&s->metadata, token, value, 0);
}
av_free(strings);
}
@@ -531,7 +532,7 @@ static int nsv_read_header(AVFormatContext *s, AVFormatParameters *ap)
err = nsv_read_chunk(s, 1);
av_dlog(s, "parsed header\n");
- return 0;
+ return err;
}
static int nsv_read_chunk(AVFormatContext *s, int fill_header)
@@ -546,7 +547,7 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header)
uint32_t vsize;
uint16_t asize;
uint16_t auxsize;
- uint32_t auxtag;
+ uint32_t av_unused auxtag;
av_dlog(s, "%s(%d)\n", __FUNCTION__, fill_header);
@@ -736,10 +737,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 */
@@ -751,19 +750,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... */
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index 2957a2b173..8af0c48bfc 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -23,6 +23,7 @@
#include <strings.h>
#include "libavutil/avstring.h"
#include "libavutil/bswap.h"
+#include "libavutil/dict.h"
#include "libavutil/tree.h"
#include "avio_internal.h"
#include "nut.h"
@@ -194,7 +195,6 @@ static int decode_main_header(NUTContext *nut){
uint64_t tmp, end;
unsigned int stream_count;
int i, j, tmp_stream, tmp_mul, tmp_pts, tmp_size, count, tmp_res, tmp_head_idx;
- int64_t tmp_match;
end= get_packetheader(nut, bc, 1, MAIN_STARTCODE);
end += avio_tell(bc);
@@ -222,7 +222,6 @@ static int decode_main_header(NUTContext *nut){
tmp_pts=0;
tmp_mul=1;
tmp_stream=0;
- tmp_match= 1-(1LL<<62);
tmp_head_idx= 0;
for(i=0; i<256;){
int tmp_flags = ffio_read_varlen(bc);
@@ -236,7 +235,7 @@ static int decode_main_header(NUTContext *nut){
else tmp_res = 0;
if(tmp_fields>5) count = ffio_read_varlen(bc);
else count = tmp_mul - tmp_size;
- if(tmp_fields>6) tmp_match = get_s(bc);
+ if(tmp_fields>6) get_s(bc);
if(tmp_fields>7) tmp_head_idx= ffio_read_varlen(bc);
while(tmp_fields-- > 8)
@@ -407,7 +406,7 @@ static int decode_info_header(NUTContext *nut){
const char *type;
AVChapter *chapter= NULL;
AVStream *st= NULL;
- AVMetadata **metadata = NULL;
+ AVDictionary **metadata = NULL;
end= get_packetheader(nut, bc, 1, INFO_STARTCODE);
end += avio_tell(bc);
@@ -465,7 +464,7 @@ static int decode_info_header(NUTContext *nut){
}
if(metadata && strcasecmp(name,"Uses")
&& strcasecmp(name,"Depends") && strcasecmp(name,"Replaces"))
- av_metadata_set2(metadata, name, str_value, 0);
+ av_dict_set(metadata, name, str_value, 0);
}
}
diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c
index 4756ca2a1a..6ec9bcd8fd 100644
--- a/libavformat/nutenc.c
+++ b/libavformat/nutenc.c
@@ -21,6 +21,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/tree.h"
+#include "libavutil/dict.h"
#include "libavcodec/mpegaudiodata.h"
#include "nut.h"
#include "internal.h"
@@ -432,7 +433,7 @@ static int add_info(AVIOContext *bc, const char *type, const char *value){
static int write_globalinfo(NUTContext *nut, AVIOContext *bc){
AVFormatContext *s= nut->avf;
- AVMetadataTag *t = NULL;
+ AVDictionaryEntry *t = NULL;
AVIOContext *dyn_bc;
uint8_t *dyn_buf=NULL;
int count=0, dyn_size;
@@ -440,7 +441,7 @@ static int write_globalinfo(NUTContext *nut, AVIOContext *bc){
if(ret < 0)
return ret;
- while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX)))
+ while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX)))
count += add_info(dyn_bc, t->key, t->value);
ff_put_v(bc, 0); //stream_if_plus1
@@ -491,7 +492,7 @@ static int write_chapter(NUTContext *nut, AVIOContext *bc, int id)
{
AVIOContext *dyn_bc;
uint8_t *dyn_buf = NULL;
- AVMetadataTag *t = NULL;
+ AVDictionaryEntry *t = NULL;
AVChapter *ch = nut->avf->chapters[id];
int ret, dyn_size, count = 0;
@@ -504,7 +505,7 @@ static int write_chapter(NUTContext *nut, AVIOContext *bc, int id)
put_tt(nut, nut->chapter[id].time_base, bc, ch->start); // chapter_start
ff_put_v(bc, ch->end - ch->start); // chapter_len
- while ((t = av_metadata_get(ch->metadata, "", t, AV_METADATA_IGNORE_SUFFIX)))
+ while ((t = av_dict_get(ch->metadata, "", t, AV_DICT_IGNORE_SUFFIX)))
count += add_info(dyn_bc, t->key, t->value);
ff_put_v(bc, count);
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index c799ce5205..655da35dd4 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -193,18 +193,17 @@ static int ogg_read_page(AVFormatContext *s, int *str)
AVIOContext *bc = s->pb;
struct ogg *ogg = s->priv_data;
struct ogg_stream *os;
- int i = 0;
+ int ret, i = 0;
int flags, nsegs;
uint64_t gp;
uint32_t serial;
- uint32_t seq;
- uint32_t crc;
int size, idx;
uint8_t sync[4];
int sp = 0;
- if (avio_read (bc, sync, 4) < 4)
- return -1;
+ ret = avio_read (bc, sync, 4);
+ if (ret < 4)
+ return ret < 0 ? ret : AVERROR_EOF;
do{
int c;
@@ -216,23 +215,22 @@ static int ogg_read_page(AVFormatContext *s, int *str)
c = avio_r8(bc);
if (url_feof(bc))
- return -1;
+ return AVERROR_EOF;
sync[sp++ & 3] = c;
}while (i++ < MAX_PAGE_SIZE);
if (i >= MAX_PAGE_SIZE){
av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (avio_r8(bc) != 0) /* version */
- return -1;
+ return AVERROR_INVALIDDATA;
flags = avio_r8(bc);
gp = avio_rl64 (bc);
serial = avio_rl32 (bc);
- seq = avio_rl32 (bc);
- crc = avio_rl32 (bc);
+ avio_skip(bc, 8); /* seq, crc */
nsegs = avio_r8(bc);
idx = ogg_find_stream (ogg, serial);
@@ -251,7 +249,7 @@ static int ogg_read_page(AVFormatContext *s, int *str)
idx = ogg_new_stream(s, serial, 1);
}
if (idx < 0)
- return -1;
+ return idx;
}
os = ogg->streams + idx;
@@ -260,8 +258,9 @@ static int ogg_read_page(AVFormatContext *s, int *str)
if(os->psize > 0)
ogg_new_buf(ogg, idx);
- if (avio_read (bc, os->segments, nsegs) < nsegs)
- return -1;
+ ret = avio_read (bc, os->segments, nsegs);
+ if (ret < nsegs)
+ return ret < 0 ? ret : AVERROR_EOF;
os->nsegs = nsegs;
os->segp = 0;
@@ -292,8 +291,9 @@ static int ogg_read_page(AVFormatContext *s, int *str)
os->buf = nb;
}
- if (avio_read (bc, os->buf + os->bufpos, size) < size)
- return -1;
+ ret = avio_read (bc, os->buf + os->bufpos, size);
+ if (ret < size)
+ return ret < 0 ? ret : AVERROR_EOF;
os->bufpos += size;
os->granule = gp;
@@ -309,35 +309,32 @@ static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
int64_t *fpos)
{
struct ogg *ogg = s->priv_data;
- int idx, i;
+ int idx, i, ret;
struct ogg_stream *os;
int complete = 0;
int segp = 0, psize = 0;
-#if 0
- av_log (s, AV_LOG_DEBUG, "ogg_packet: curidx=%i\n", ogg->curidx);
-#endif
+ av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
do{
idx = ogg->curidx;
while (idx < 0){
- if (ogg_read_page (s, &idx) < 0)
- return -1;
+ ret = ogg_read_page (s, &idx);
+ if (ret < 0)
+ return ret;
}
os = ogg->streams + idx;
-#if 0
- av_log (s, AV_LOG_DEBUG,
- "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
+ av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
idx, os->pstart, os->psize, os->segp, os->nsegs);
-#endif
if (!os->codec){
if (os->header < 0){
os->codec = ogg_find_codec (os->buf, os->bufpos);
if (!os->codec){
+ av_log(s, AV_LOG_WARNING, "Codec not found\n");
os->header = 0;
return 0;
}
@@ -364,11 +361,6 @@ static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
}
}while (!complete);
-#if 0
- av_log (s, AV_LOG_DEBUG,
- "ogg_packet: idx %i, frame size %i, start %i\n",
- idx, os->psize, os->pstart);
-#endif
if (os->granule == -1)
av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
@@ -418,6 +410,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;
}
@@ -439,15 +433,15 @@ static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
static int ogg_get_headers(AVFormatContext *s)
{
struct ogg *ogg = s->priv_data;
+ int ret;
do{
- if (ogg_packet (s, NULL, NULL, NULL, NULL) < 0)
- return -1;
+ ret = ogg_packet (s, NULL, NULL, NULL, NULL);
+ if (ret < 0)
+ return ret;
}while (!ogg->headers);
-#if 0
- av_log (s, AV_LOG_DEBUG, "found headers\n");
-#endif
+ av_dlog(s, "found headers\n");
return 0;
}
@@ -503,11 +497,12 @@ static int ogg_get_length(AVFormatContext *s)
static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
struct ogg *ogg = s->priv_data;
- int i;
+ int ret, i;
ogg->curidx = -1;
//linear headers seek from start
- if (ogg_get_headers (s) < 0){
- return -1;
+ ret = ogg_get_headers (s);
+ if (ret < 0){
+ return ret;
}
for (i = 0; i < ogg->nstreams; i++)
diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h
index 82efd97aec..184a628622 100644
--- a/libavformat/oggdec.h
+++ b/libavformat/oggdec.h
@@ -112,7 +112,7 @@ extern const struct ogg_codec ff_speex_codec;
extern const struct ogg_codec ff_theora_codec;
extern const struct ogg_codec ff_vorbis_codec;
-int ff_vorbis_comment(AVFormatContext *ms, AVMetadata **m, const uint8_t *buf, int size);
+int ff_vorbis_comment(AVFormatContext *ms, AVDictionary **m, const uint8_t *buf, int size);
static inline int
ogg_find_stream (struct ogg * ogg, int serial)
diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c
index 45e677fb08..04f536f157 100644
--- a/libavformat/oggenc.c
+++ b/libavformat/oggenc.c
@@ -241,7 +241,7 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st,
}
static uint8_t *ogg_write_vorbiscomment(int offset, int bitexact,
- int *header_len, AVMetadata **m, int framing_bit)
+ int *header_len, AVDictionary **m, int framing_bit)
{
const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
int size;
@@ -267,7 +267,7 @@ static uint8_t *ogg_write_vorbiscomment(int offset, int bitexact,
static int ogg_build_flac_headers(AVCodecContext *avctx,
OGGStreamContext *oggstream, int bitexact,
- AVMetadata **m)
+ AVDictionary **m)
{
enum FLACExtradataFormat format;
uint8_t *streaminfo;
@@ -307,7 +307,7 @@ static int ogg_build_flac_headers(AVCodecContext *avctx,
static int ogg_build_speex_headers(AVCodecContext *avctx,
OGGStreamContext *oggstream, int bitexact,
- AVMetadata **m)
+ AVDictionary **m)
{
uint8_t *p;
diff --git a/libavformat/oggparsecelt.c b/libavformat/oggparsecelt.c
index bbb695f438..2adc06046a 100644
--- a/libavformat/oggparsecelt.c
+++ b/libavformat/oggparsecelt.c
@@ -41,8 +41,8 @@ static int celt_header(AVFormatContext *s, int idx)
/* Main header */
- uint32_t version, header_size, sample_rate, nb_channels, frame_size;
- uint32_t overlap, bytes_per_packet, extra_headers;
+ uint32_t version, header_size av_unused, sample_rate, nb_channels, frame_size;
+ uint32_t overlap, bytes_per_packet av_unused, extra_headers;
uint8_t *extradata;
extradata = av_malloc(2 * sizeof(uint32_t) +
diff --git a/libavformat/oggparseogm.c b/libavformat/oggparseogm.c
index dda5be601a..9526c3acc1 100644
--- a/libavformat/oggparseogm.c
+++ b/libavformat/oggparseogm.c
@@ -39,7 +39,6 @@ ogm_header(AVFormatContext *s, int idx)
const uint8_t *p = os->buf + os->pstart;
uint64_t time_unit;
uint64_t spu;
- uint32_t default_len;
if(!(*p & 1))
return 0;
@@ -74,8 +73,7 @@ ogm_header(AVFormatContext *s, int idx)
time_unit = bytestream_get_le64(&p);
spu = bytestream_get_le64(&p);
- default_len = bytestream_get_le32(&p);
-
+ p += 4; /* default_len */
p += 8; /* buffersize + bits_per_sample */
if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index 830f0bca37..86951f3e2f 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include "libavutil/avstring.h"
#include "libavutil/bswap.h"
+#include "libavutil/dict.h"
#include "libavcodec/get_bits.h"
#include "libavcodec/bytestream.h"
#include "avformat.h"
@@ -57,8 +58,8 @@ static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
if (!chapter)
return 0;
- av_metadata_set2(&chapter->metadata, "title", val,
- AV_METADATA_DONT_STRDUP_VAL);
+ av_dict_set(&chapter->metadata, "title", val,
+ AV_DICT_DONT_STRDUP_VAL);
} else
return 0;
@@ -67,7 +68,7 @@ static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
}
int
-ff_vorbis_comment(AVFormatContext * as, AVMetadata **m, const uint8_t *buf, int size)
+ff_vorbis_comment(AVFormatContext * as, AVDictionary **m, const uint8_t *buf, int size)
{
const uint8_t *p = buf;
const uint8_t *end = buf + size;
@@ -127,9 +128,9 @@ ff_vorbis_comment(AVFormatContext * as, AVMetadata **m, const uint8_t *buf, int
ct[vl] = 0;
if (!ogm_chapter(as, tt, ct))
- av_metadata_set2(m, tt, ct,
- AV_METADATA_DONT_STRDUP_KEY |
- AV_METADATA_DONT_STRDUP_VAL);
+ av_dict_set(m, tt, ct,
+ AV_DICT_DONT_STRDUP_KEY |
+ AV_DICT_DONT_STRDUP_VAL);
}
}
diff --git a/libavformat/oma.c b/libavformat/oma.c
index f29b16a4d6..aac96d14e5 100644
--- a/libavformat/oma.c
+++ b/libavformat/oma.c
@@ -80,6 +80,8 @@ static int oma_read_header(AVFormatContext *s,
ff_id3v2_read(s, ID3v2_EA3_MAGIC);
ret = avio_read(s->pb, buf, EA3_HEADER_SIZE);
+ if (ret < EA3_HEADER_SIZE)
+ return -1;
if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
diff --git a/libavformat/options.c b/libavformat/options.c
index a6f78817f4..ffd82ba207 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -49,8 +49,12 @@ static const AVOption options[]={
{"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"},
-{"rtphint", "add rtp hinting", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_RTP_HINT }, INT_MIN, INT_MAX, E, "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"},
+#endif
{"sortdts", "try to interleave outputted packets by dts", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_SORT_DTS }, INT_MIN, INT_MAX, D, "fflags"},
+{"keepside", "dont merge side data", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_KEEP_SIDE_DATA }, INT_MIN, INT_MAX, D, "fflags"},
+{"latm", "enable RTP MP4A-LATM payload", 0, FF_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), 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},
@@ -58,6 +62,7 @@ static const AVOption options[]={
{"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},
{NULL},
};
diff --git a/libavformat/output-example.c b/libavformat/output-example.c
deleted file mode 100644
index 1a429638d1..0000000000
--- a/libavformat/output-example.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Libavformat API example: Output a media file in any supported
- * libavformat format. The default codecs are used.
- *
- * 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.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.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];
-
- /* allocate the output media context */
- oc = avformat_alloc_output_context(NULL, NULL, filename);
- if (!oc) {
- printf("Could not deduce output format from file extension: using MPEG.\n");
- oc = avformat_alloc_output_context("mpeg", NULL, filename);
- }
- if (!oc) {
- exit(1);
- }
- fmt= oc->oformat;
-
- /* add the audio and video streams using the default format codecs
- and initialize the codecs */
- video_st = NULL;
- audio_st = NULL;
- if (fmt->video_codec != 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);
- }
-
- 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_WRONLY) < 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/pcmdec.c b/libavformat/pcmdec.c
index 6441d89c5c..ab3b739ccb 100644
--- a/libavformat/pcmdec.c
+++ b/libavformat/pcmdec.c
@@ -50,7 +50,7 @@ static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
AVInputFormat ff_pcm_ ## name ## _demuxer = {\
#name,\
NULL_IF_CONFIG_SMALL(long_name),\
- 0,\
+ sizeof(RawAudioDemuxerContext),\
NULL,\
ff_raw_read_header,\
raw_read_packet,\
@@ -59,6 +59,7 @@ AVInputFormat ff_pcm_ ## name ## _demuxer = {\
.flags= AVFMT_GENERIC_INDEX,\
.extensions = ext,\
.value = codec,\
+ .priv_class = &ff_rawaudio_demuxer_class,\
};
PCMDEF(f64be, "PCM 64 bit floating-point big-endian format",
diff --git a/libavformat/r3d.c b/libavformat/r3d.c
index 5e027d158b..af74a9ee56 100644
--- a/libavformat/r3d.c
+++ b/libavformat/r3d.c
@@ -22,6 +22,7 @@
//#define DEBUG
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
#include "avformat.h"
typedef struct {
@@ -43,7 +44,7 @@ static int read_atom(AVFormatContext *s, Atom *atom)
if (atom->size < 8)
return -1;
atom->tag = avio_rl32(s->pb);
- av_dlog(s, "atom %d %.4s offset %#llx\n",
+ av_dlog(s, "atom %u %.4s offset %#"PRIx64"\n",
atom->size, (char*)&atom->tag, atom->offset);
return atom->size;
}
@@ -52,7 +53,8 @@ static int r3d_read_red1(AVFormatContext *s)
{
AVStream *st = av_new_stream(s, 0);
char filename[258];
- int tmp, tmp2;
+ int tmp;
+ int av_unused tmp2;
if (!st)
return AVERROR(ENOMEM);
@@ -97,7 +99,7 @@ static int r3d_read_red1(AVFormatContext *s)
avio_read(s->pb, filename, 257);
filename[sizeof(filename)-1] = 0;
- av_metadata_set2(&st->metadata, "filename", filename, 0);
+ av_dict_set(&st->metadata, "filename", filename, 0);
av_dlog(s, "filename %s\n", filename);
av_dlog(s, "resolution %dx%d\n", st->codec->width, st->codec->height);
@@ -131,7 +133,7 @@ static int r3d_read_rdvo(AVFormatContext *s, Atom *atom)
if (st->codec->time_base.den)
st->duration = (uint64_t)r3d->video_offsets_count*
st->time_base.den*st->codec->time_base.num/st->codec->time_base.den;
- av_dlog(s, "duration %lld\n", st->duration);
+ av_dlog(s, "duration %"PRId64"\n", st->duration);
return 0;
}
@@ -139,7 +141,7 @@ static int r3d_read_rdvo(AVFormatContext *s, Atom *atom)
static void r3d_read_reos(AVFormatContext *s)
{
R3DContext *r3d = s->priv_data;
- int tmp;
+ int av_unused tmp;
r3d->rdvo_offset = avio_rb32(s->pb);
avio_rb32(s->pb); // rdvs offset
@@ -176,7 +178,7 @@ static int r3d_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
s->data_offset = avio_tell(s->pb);
- av_dlog(s, "data offset %#llx\n", s->data_offset);
+ av_dlog(s, "data offset %#"PRIx64"\n", s->data_offset);
if (!s->pb->seekable)
return 0;
// find REOB/REOF/REOS to load index
@@ -209,7 +211,8 @@ static int r3d_read_header(AVFormatContext *s, AVFormatParameters *ap)
static int r3d_read_redv(AVFormatContext *s, AVPacket *pkt, Atom *atom)
{
AVStream *st = s->streams[0];
- int tmp, tmp2;
+ int tmp;
+ int av_unused tmp2;
uint64_t pos = avio_tell(s->pb);
unsigned dts;
int ret;
@@ -255,7 +258,7 @@ static int r3d_read_redv(AVFormatContext *s, AVPacket *pkt, Atom *atom)
if (st->codec->time_base.den)
pkt->duration = (uint64_t)st->time_base.den*
st->codec->time_base.num/st->codec->time_base.den;
- av_dlog(s, "pkt dts %lld duration %d\n", pkt->dts, pkt->duration);
+ av_dlog(s, "pkt dts %"PRId64" duration %d\n", pkt->dts, pkt->duration);
return 0;
}
@@ -263,7 +266,8 @@ static int r3d_read_redv(AVFormatContext *s, AVPacket *pkt, Atom *atom)
static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom)
{
AVStream *st = s->streams[1];
- int tmp, tmp2, samples, size;
+ int av_unused tmp, tmp2;
+ int samples, size;
uint64_t pos = avio_tell(s->pb);
unsigned dts;
int ret;
@@ -299,7 +303,7 @@ static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom)
pkt->stream_index = 1;
pkt->dts = dts;
pkt->duration = av_rescale(samples, st->time_base.den, st->codec->sample_rate);
- av_dlog(s, "pkt dts %lld duration %d samples %d sample rate %d\n",
+ av_dlog(s, "pkt dts %"PRId64" duration %d samples %d sample rate %d\n",
pkt->dts, pkt->duration, samples, st->codec->sample_rate);
return 0;
@@ -356,7 +360,8 @@ static int r3d_seek(AVFormatContext *s, int stream_index, int64_t sample_time, i
frame_num = sample_time*st->codec->time_base.den/
((int64_t)st->codec->time_base.num*st->time_base.den);
- av_dlog(s, "seek frame num %d timestamp %lld\n", frame_num, sample_time);
+ av_dlog(s, "seek frame num %d timestamp %"PRId64"\n",
+ frame_num, sample_time);
if (frame_num < r3d->video_offsets_count) {
avio_seek(s->pb, r3d->video_offsets_count, SEEK_SET);
diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c
index 0387e3d266..a4e009b7e0 100644
--- a/libavformat/rawdec.c
+++ b/libavformat/rawdec.c
@@ -23,6 +23,9 @@
#include "avformat.h"
#include "avio_internal.h"
#include "rawdec.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
/* raw input */
int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap)
@@ -43,26 +46,64 @@ int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->codec_id = id;
switch(st->codec->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- st->codec->sample_rate = ap->sample_rate;
- if(ap->channels) st->codec->channels = ap->channels;
- else st->codec->channels = 1;
+ 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
+
+ if (s1->sample_rate)
+ st->codec->sample_rate = s1->sample_rate;
+ if (s1->channels)
+ st->codec->channels = s1->channels;
+
st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
assert(st->codec->bits_per_coded_sample > 0);
st->codec->block_align = st->codec->bits_per_coded_sample*st->codec->channels/8;
av_set_pts_info(st, 64, 1, st->codec->sample_rate);
break;
- case AVMEDIA_TYPE_VIDEO:
- if(ap->time_base.num)
- av_set_pts_info(st, 64, ap->time_base.num, ap->time_base.den);
- else
- av_set_pts_info(st, 64, 1, 25);
- st->codec->width = ap->width;
- st->codec->height = ap->height;
- st->codec->pix_fmt = ap->pix_fmt;
- if(st->codec->pix_fmt == PIX_FMT_NONE)
- st->codec->pix_fmt= PIX_FMT_YUV420P;
- break;
+ }
+ case AVMEDIA_TYPE_VIDEO: {
+ FFRawVideoDemuxerContext *s1 = s->priv_data;
+ int width = 0, height = 0, ret = 0;
+ enum PixelFormat pix_fmt;
+ AVRational framerate;
+
+ if (s1->video_size && (ret = av_parse_video_size(&width, &height, s1->video_size)) < 0) {
+ av_log(s, AV_LOG_ERROR, "Couldn't parse video size.\n");
+ goto fail;
+ }
+ if ((pix_fmt = av_get_pix_fmt(s1->pixel_format)) == PIX_FMT_NONE) {
+ av_log(s, AV_LOG_ERROR, "No such pixel format: %s.\n", s1->pixel_format);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ if ((ret = av_parse_video_rate(&framerate, s1->framerate)) < 0) {
+ 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;
+ st->codec->pix_fmt = pix_fmt;
+fail:
+ return ret;
+ }
default:
return -1;
}
@@ -111,45 +152,82 @@ int ff_raw_video_read_header(AVFormatContext *s,
AVFormatParameters *ap)
{
AVStream *st;
+ FFRawVideoDemuxerContext *s1 = s->priv_data;
+ AVRational framerate;
+ int ret = 0;
+
st = av_new_stream(s, 0);
- if (!st)
- return AVERROR(ENOMEM);
+ if (!st) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = s->iformat->value;
st->need_parsing = AVSTREAM_PARSE_FULL;
- /* for MJPEG, specify frame rate */
- /* for MPEG-4 specify it, too (most MPEG-4 streams do not have the fixed_vop_rate set ...)*/
- if (ap->time_base.num) {
- st->codec->time_base= ap->time_base;
- } else if ( st->codec->codec_id == CODEC_ID_MJPEG ||
- st->codec->codec_id == CODEC_ID_MPEG4 ||
- st->codec->codec_id == CODEC_ID_DIRAC ||
- st->codec->codec_id == CODEC_ID_DNXHD ||
- st->codec->codec_id == CODEC_ID_VC1 ||
- st->codec->codec_id == CODEC_ID_H264) {
- st->codec->time_base= (AVRational){1,25};
+ if ((ret = av_parse_video_rate(&framerate, s1->framerate)) < 0) {
+ 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);
- return 0;
+fail:
+ return ret;
}
/* 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 },
+ { 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"),
- 0,
+ sizeof(RawAudioDemuxerContext),
NULL,
ff_raw_read_header,
ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "g722,722",
.value = CODEC_ID_ADPCM_G722,
+ .priv_class = &ff_rawaudio_demuxer_class,
};
#endif
@@ -168,17 +246,7 @@ AVInputFormat ff_gsm_demuxer = {
#endif
#if CONFIG_MJPEG_DEMUXER
-AVInputFormat ff_mjpeg_demuxer = {
- "mjpeg",
- NULL_IF_CONFIG_SMALL("raw MJPEG video"),
- 0,
- NULL,
- ff_raw_video_read_header,
- ff_raw_read_partial_packet,
- .flags= AVFMT_GENERIC_INDEX,
- .extensions = "mjpg,mjpeg",
- .value = CODEC_ID_MJPEG,
-};
+FF_DEF_RAWVIDEO_DEMUXER(mjpeg, "raw MJPEG video", NULL, "mjpg,mjpeg", CODEC_ID_MJPEG)
#endif
#if CONFIG_MLP_DEMUXER
@@ -224,14 +292,5 @@ AVInputFormat ff_shorten_demuxer = {
#endif
#if CONFIG_VC1_DEMUXER
-AVInputFormat ff_vc1_demuxer = {
- "vc1",
- NULL_IF_CONFIG_SMALL("raw VC-1"),
- 0,
- NULL /* vc1_probe */,
- ff_raw_video_read_header,
- ff_raw_read_partial_packet,
- .extensions = "vc1",
- .value = CODEC_ID_VC1,
-};
+FF_DEF_RAWVIDEO_DEMUXER(vc1, "raw VC-1", NULL, "vc1", CODEC_ID_VC1)
#endif
diff --git a/libavformat/rawdec.h b/libavformat/rawdec.h
index 0b0cf1beef..6cb5af2b0a 100644
--- a/libavformat/rawdec.h
+++ b/libavformat/rawdec.h
@@ -23,6 +23,23 @@
#define AVFORMAT_RAWDEC_H
#include "avformat.h"
+#include "libavutil/log.h"
+
+typedef struct RawAudioDemuxerContext {
+ AVClass *class;
+ int sample_rate;
+ int channels;
+} RawAudioDemuxerContext;
+
+typedef struct FFRawVideoDemuxerContext {
+ const AVClass *class; /**< Class for private options. */
+ char *video_size; /**< String describing video size, set by a private option. */
+ char *pixel_format; /**< Set by a private option. */
+ 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;
int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap);
@@ -32,4 +49,18 @@ int ff_raw_audio_read_header(AVFormatContext *s, AVFormatParameters *ap);
int ff_raw_video_read_header(AVFormatContext *s, AVFormatParameters *ap);
+#define FF_DEF_RAWVIDEO_DEMUXER(shortname, longname, probe, ext, id)\
+AVInputFormat ff_ ## shortname ## _demuxer = {\
+ .name = #shortname,\
+ .long_name = NULL_IF_CONFIG_SMALL(longname),\
+ .read_probe = probe,\
+ .read_header = ff_raw_video_read_header,\
+ .read_packet = ff_raw_read_partial_packet,\
+ .extensions = ext,\
+ .flags = AVFMT_GENERIC_INDEX,\
+ .value = id,\
+ .priv_data_size = sizeof(FFRawVideoDemuxerContext),\
+ .priv_class = &ff_rawvideo_demuxer_class,\
+};
+
#endif /* AVFORMAT_RAWDEC_H */
diff --git a/libavformat/rawvideodec.c b/libavformat/rawvideodec.c
index 127119f18a..36f5d954ae 100644
--- a/libavformat/rawvideodec.c
+++ b/libavformat/rawvideodec.c
@@ -47,11 +47,12 @@ static int rawvideo_read_packet(AVFormatContext *s, AVPacket *pkt)
AVInputFormat ff_rawvideo_demuxer = {
"rawvideo",
NULL_IF_CONFIG_SMALL("raw video format"),
- 0,
+ sizeof(FFRawVideoDemuxerContext),
NULL,
ff_raw_read_header,
rawvideo_read_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "yuv,cif,qcif,rgb",
.value = CODEC_ID_RAWVIDEO,
+ .priv_class = &ff_rawvideo_demuxer_class,
};
diff --git a/libavformat/riff.c b/libavformat/riff.c
index 833a6bf9e8..544c29f116 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -250,6 +250,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_ZMBV, MKTAG('Z', 'M', 'B', 'V') },
{ CODEC_ID_KMVC, MKTAG('K', 'M', 'V', 'C') },
{ 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_VMNC, MKTAG('V', 'M', 'n', 'c') },
{ CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') },
@@ -536,6 +537,7 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size)
}
codec->extradata_size = cbSize;
if (cbSize > 0) {
+ av_free(codec->extradata);
codec->extradata = av_mallocz(codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!codec->extradata)
return AVERROR(ENOMEM);
diff --git a/libavformat/rl2.c b/libavformat/rl2.c
index 93d4c34459..e41406791e 100644
--- a/libavformat/rl2.c
+++ b/libavformat/rl2.c
@@ -80,8 +80,6 @@ static av_cold int rl2_read_header(AVFormatContext *s,
unsigned int audio_frame_counter = 0;
unsigned int video_frame_counter = 0;
unsigned int back_size;
- int data_size;
- unsigned short encoding_method;
unsigned short sound_rate;
unsigned short rate;
unsigned short channels;
@@ -98,14 +96,14 @@ static av_cold int rl2_read_header(AVFormatContext *s,
avio_skip(pb,4); /* skip FORM tag */
back_size = avio_rl32(pb); /**< get size of the background frame */
signature = avio_rb32(pb);
- data_size = avio_rb32(pb);
+ avio_skip(pb, 4); /* data size */
frame_count = avio_rl32(pb);
/* disallow back_sizes and frame_counts that may lead to overflows later */
if(back_size > INT_MAX/2 || frame_count > INT_MAX / sizeof(uint32_t))
return AVERROR_INVALIDDATA;
- encoding_method = avio_rl16(pb);
+ avio_skip(pb, 2); /* encoding mentod */
sound_rate = avio_rl16(pb);
rate = avio_rl16(pb);
channels = avio_rl16(pb);
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index 6fb362473e..c2eee815c2 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -21,6 +21,7 @@
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "riff.h"
#include "rm.h"
@@ -104,7 +105,7 @@ static void rm_read_metadata(AVFormatContext *s, int wide)
for (i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) {
int len = wide ? avio_rb16(s->pb) : avio_r8(s->pb);
get_strl(s->pb, buf, sizeof(buf), len);
- av_metadata_set2(&s->metadata, ff_rm_metadata[i], buf, 0);
+ av_dict_set(&s->metadata, ff_rm_metadata[i], buf, 0);
}
}
@@ -280,7 +281,7 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb,
if (rm_read_audio_stream_info(s, pb, st, rst, 0))
return -1;
} else {
- int fps, fps2;
+ int fps;
if (avio_rl32(pb) != MKTAG('V', 'I', 'D', 'O')) {
fail1:
av_log(st->codec, AV_LOG_ERROR, "Unsupported video codec\n");
@@ -298,7 +299,7 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb,
fps= avio_rb16(pb);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
avio_rb32(pb);
- fps2= avio_rb16(pb);
+ avio_skip(pb, 2);
avio_rb16(pb);
if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (avio_tell(pb) - codec_pos))) < 0)
diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c
index e08b677987..575d895a6a 100644
--- a/libavformat/rmenc.c
+++ b/libavformat/rmenc.c
@@ -21,6 +21,7 @@
#include "avformat.h"
#include "avio_internal.h"
#include "rm.h"
+#include "libavutil/dict.h"
typedef struct {
int nb_packets;
@@ -71,7 +72,7 @@ static int rv10_write_header(AVFormatContext *ctx,
const char *desc, *mimetype;
int nb_packets, packet_total_size, packet_max_size, size, packet_avg_size, i;
int bit_rate, v, duration, flags, data_pos;
- AVMetadataTag *tag;
+ AVDictionaryEntry *tag;
start_ptr = s->buf_ptr;
@@ -127,13 +128,13 @@ static int rv10_write_header(AVFormatContext *ctx,
ffio_wfourcc(s,"CONT");
size = 4 * 2 + 10;
for(i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) {
- tag = av_metadata_get(ctx->metadata, ff_rm_metadata[i], NULL, 0);
+ tag = av_dict_get(ctx->metadata, ff_rm_metadata[i], NULL, 0);
if(tag) size += strlen(tag->value);
}
avio_wb32(s,size);
avio_wb16(s,0);
for(i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) {
- tag = av_metadata_get(ctx->metadata, ff_rm_metadata[i], NULL, 0);
+ tag = av_dict_get(ctx->metadata, ff_rm_metadata[i], NULL, 0);
put_str(s, tag ? tag->value : "");
}
diff --git a/libavformat/rpl.c b/libavformat/rpl.c
index 9702fc7035..151893cdd7 100644
--- a/libavformat/rpl.c
+++ b/libavformat/rpl.c
@@ -20,6 +20,7 @@
*/
#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include <stdlib.h>
@@ -131,11 +132,11 @@ static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap)
// for the text in a few cases; samples needed.)
error |= read_line(pb, line, sizeof(line)); // ARMovie
error |= read_line(pb, line, sizeof(line)); // movie name
- av_metadata_set2(&s->metadata, "title" , line, 0);
+ av_dict_set(&s->metadata, "title" , line, 0);
error |= read_line(pb, line, sizeof(line)); // date/copyright
- av_metadata_set2(&s->metadata, "copyright", line, 0);
+ av_dict_set(&s->metadata, "copyright", line, 0);
error |= read_line(pb, line, sizeof(line)); // author and other
- av_metadata_set2(&s->metadata, "author" , line, 0);
+ av_dict_set(&s->metadata, "author" , line, 0);
// video headers
vst = av_new_stream(s, 0);
@@ -299,9 +300,9 @@ static int rpl_read_packet(AVFormatContext *s, AVPacket *pkt)
stream->codec->codec_tag == 124) {
// We have to split Escape 124 frames because there are
// multiple frames per chunk in Escape 124 samples.
- uint32_t frame_size, frame_flags;
+ uint32_t frame_size;
- frame_flags = avio_rl32(pb);
+ avio_skip(pb, 4); /* flags */
frame_size = avio_rl32(pb);
if (avio_seek(pb, -8, SEEK_CUR) < 0)
return AVERROR(EIO);
diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 53c6a5fe19..4b6d549f74 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -233,9 +233,11 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type,
int timestamp, int size)
{
- pkt->data = av_malloc(size);
- if (!pkt->data)
- return AVERROR(ENOMEM);
+ if (size) {
+ pkt->data = av_malloc(size);
+ if (!pkt->data)
+ return AVERROR(ENOMEM);
+ }
pkt->data_size = size;
pkt->channel_id = channel_id;
pkt->type = type;
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 94361ca80d..3701a77176 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -690,7 +690,7 @@ static int get_packet(URLContext *s, int for_header)
return AVERROR_EOF;
for (;;) {
- RTMPPacket rpkt;
+ RTMPPacket rpkt = { 0 };
if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
rt->chunk_size, rt->prev_pkt[0])) <= 0) {
if (ret == 0) {
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 0a9a8bc8d6..9fc30d7b66 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -321,7 +321,7 @@ int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
avio_flush(pb);
len = avio_close_dyn_buf(pb, &buf);
if ((len > 0) && buf) {
- int result;
+ int av_unused result;
av_dlog(s->ic, "sending %d bytes of RR\n", len);
result= ffurl_write(s->rtp_ctx, buf, len);
av_dlog(s->ic, "result from ffurl_write: %d\n", result);
diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c
index b2ac2b7ac0..58c9068a87 100644
--- a/libavformat/rtpdec_asf.c
+++ b/libavformat/rtpdec_asf.c
@@ -113,7 +113,7 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p)
ret = av_open_input_stream(&rt->asf_ctx, &pb, "", &ff_asf_demuxer, NULL);
if (ret < 0)
return ret;
- av_metadata_copy(&s->metadata, rt->asf_ctx->metadata, 0);
+ av_dict_copy(&s->metadata, rt->asf_ctx->metadata, 0);
rt->asf_pb_pos = avio_tell(&pb);
av_free(buf);
rt->asf_ctx->pb = NULL;
diff --git a/libavformat/rtpdec_latm.c b/libavformat/rtpdec_latm.c
index 2b366a0dc2..4bf2c3fb23 100644
--- a/libavformat/rtpdec_latm.c
+++ b/libavformat/rtpdec_latm.c
@@ -108,8 +108,7 @@ static int parse_fmtp_config(AVStream *st, char *value)
int len = ff_hex_to_data(NULL, value), i, ret = 0;
GetBitContext gb;
uint8_t *config;
- int audio_mux_version, same_time_framing, num_sub_frames,
- num_programs, num_layers;
+ int audio_mux_version, same_time_framing, num_programs, num_layers;
/* Pad this buffer, too, to avoid out of bounds reads with get_bits below */
config = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
@@ -119,7 +118,7 @@ static int parse_fmtp_config(AVStream *st, char *value)
init_get_bits(&gb, config, len*8);
audio_mux_version = get_bits(&gb, 1);
same_time_framing = get_bits(&gb, 1);
- num_sub_frames = get_bits(&gb, 6);
+ skip_bits(&gb, 6); /* num_sub_frames */
num_programs = get_bits(&gb, 4);
num_layers = get_bits(&gb, 3);
if (audio_mux_version != 0 || same_time_framing != 1 || num_programs != 0 ||
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index 71ccdabf4a..60629b098b 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -23,11 +23,24 @@
#include "mpegts.h"
#include "internal.h"
#include "libavutil/random_seed.h"
+#include "libavutil/opt.h"
#include "rtpenc.h"
//#define DEBUG
+static const AVOption options[] = {
+ FF_RTP_FLAG_OPTS(RTPMuxContext, flags),
+ { NULL },
+};
+
+static const AVClass rtp_muxer_class = {
+ .class_name = "RTP muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
#define RTCP_SR_SIZE 28
static int is_supported(enum CodecID id)
@@ -404,7 +417,10 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
ff_rtp_send_mpegvideo(s1, pkt->data, size);
break;
case CODEC_ID_AAC:
- ff_rtp_send_aac(s1, pkt->data, size);
+ if (s->flags & FF_RTP_FLAG_MP4A_LATM)
+ ff_rtp_send_latm(s1, pkt->data, size);
+ else
+ ff_rtp_send_aac(s1, pkt->data, size);
break;
case CODEC_ID_AMR_NB:
case CODEC_ID_AMR_WB:
@@ -455,4 +471,5 @@ AVOutputFormat ff_rtp_muxer = {
rtp_write_header,
rtp_write_packet,
rtp_write_trailer,
+ .priv_class = &rtp_muxer_class,
};
diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h
index b9663c55b0..cba0d02d91 100644
--- a/libavformat/rtpenc.h
+++ b/libavformat/rtpenc.h
@@ -25,6 +25,7 @@
#include "rtp.h"
struct RTPMuxContext {
+ const AVClass *av_class;
AVFormatContext *ic;
AVStream *st;
int payload_type;
@@ -56,15 +57,24 @@ struct RTPMuxContext {
* (1, 2 or 4)
*/
int nal_length_size;
+
+ int flags;
};
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" } \
+
void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m);
void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size);
void ff_rtp_send_h263(AVFormatContext *s1, const uint8_t *buf1, int size);
void ff_rtp_send_aac(AVFormatContext *s1, const uint8_t *buff, int size);
+void ff_rtp_send_latm(AVFormatContext *s1, const uint8_t *buff, int size);
void ff_rtp_send_amr(AVFormatContext *s1, const uint8_t *buff, int size);
void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size);
void ff_rtp_send_xiph(AVFormatContext *s1, const uint8_t *buff, int size);
diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c
index bd3d1a875d..7f1a8868eb 100644
--- a/libavformat/rtpenc_chain.c
+++ b/libavformat/rtpenc_chain.c
@@ -23,6 +23,7 @@
#include "avio_internal.h"
#include "rtpenc_chain.h"
#include "avio_internal.h"
+#include "libavutil/opt.h"
AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
URLContext *handle, int packet_size)
@@ -48,6 +49,14 @@ 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));
/* Set the synchronized start time. */
rtpctx->start_time_realtime = s->start_time_realtime;
diff --git a/libavformat/rtpenc_h264.c b/libavformat/rtpenc_h264.c
index 697def61c2..11074d0d51 100644
--- a/libavformat/rtpenc_h264.c
+++ b/libavformat/rtpenc_h264.c
@@ -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
new file mode 100644
index 0000000000..4430c44afe
--- /dev/null
+++ b/libavformat/rtpenc_latm.c
@@ -0,0 +1,61 @@
+/*
+ * RTP Packetization of MPEG-4 Audio (RFC 3016)
+ * Copyright (c) 2011 Juan Carlos Rodriguez <ing.juancarlosrodriguez@hotmail.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
+ */
+
+#include "avformat.h"
+#include "rtpenc.h"
+
+void ff_rtp_send_latm(AVFormatContext *s1, const uint8_t *buff, int size)
+{
+ /* MP4A-LATM
+ * The RTP payload format specification is described in RFC 3016
+ * The encoding specifications are provided in ISO/IEC 14496-3 */
+
+ RTPMuxContext *s = s1->priv_data;
+ int header_size;
+ int offset = 0;
+ int len = 0;
+
+ /* skip ADTS header, if present */
+ if ((s1->streams[0]->codec->extradata_size) == 0) {
+ size -= 7;
+ buff += 7;
+ }
+
+ /* PayloadLengthInfo() */
+ header_size = size/0xFF + 1;
+ memset(s->buf, 0xFF, header_size - 1);
+ s->buf[header_size - 1] = size % 0xFF;
+
+ s->timestamp = s->cur_timestamp;
+
+ /* PayloadMux() */
+ while (size > 0) {
+ len = FFMIN(size, s->max_payload_size - (!offset ? header_size : 0));
+ size -= len;
+ if (!offset) {
+ memcpy(s->buf + header_size, buff, len);
+ ff_rtp_send_data(s1, s->buf, header_size + len, !size);
+ } else {
+ ff_rtp_send_data(s1, buff + offset, len, !size);
+ }
+ offset += len;
+ }
+}
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 74e4b31f43..f5a638423f 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -24,6 +24,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/parseutils.h"
#include "libavutil/random_seed.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "avio_internal.h"
@@ -45,7 +46,6 @@
#include "url.h"
//#define DEBUG
-//#define DEBUG_RTP_TCP
/* Timeout values for socket poll, in ms,
* and read_packet(), in seconds */
@@ -282,11 +282,11 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
}
break;
case 's':
- av_metadata_set2(&s->metadata, "title", p, 0);
+ av_dict_set(&s->metadata, "title", p, 0);
break;
case 'i':
if (s->nb_streams == 0) {
- av_metadata_set2(&s->metadata, "comment", p, 0);
+ av_dict_set(&s->metadata, "comment", p, 0);
break;
}
break;
@@ -860,9 +860,7 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
q = buf;
for (;;) {
ret = ffurl_read_complete(rt->rtsp_hd, &ch, 1);
-#ifdef DEBUG_RTP_TCP
av_dlog(s, "ret=%d c=%02x [%c]\n", ret, ch, ch);
-#endif
if (ret != 1)
return AVERROR_EOF;
if (ch == '\n')
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 56160cefc2..6b060923e4 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -28,6 +28,8 @@
#include "network.h"
#include "httpauth.h"
+#include "libavutil/log.h"
+
/**
* Network layer over which RTP/etc packet data will be transported.
*/
@@ -196,6 +198,7 @@ enum RTSPServerType {
* @todo Use AVIOContext instead of URLContext
*/
typedef struct RTSPState {
+ const AVClass *class; /**< Class for private options. */
URLContext *rtsp_hd; /* RTSP TCP connection handle */
/** number of items in the 'rtsp_streams' variable */
@@ -336,6 +339,16 @@ typedef struct RTSPState {
* Whether the server supports the GET_PARAMETER method.
*/
int get_parameter_supported;
+
+ /**
+ * Do not begin to play the stream immediately.
+ */
+ int initial_pause;
+
+ /**
+ * Option flags for the chained RTP muxer.
+ */
+ int rtp_muxer_flags;
} RTSPState;
/**
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 454a31c3f9..cf95915110 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -21,6 +21,7 @@
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
#include "avformat.h"
#include "internal.h"
@@ -30,9 +31,6 @@
#include "rdt.h"
#include "url.h"
-//#define DEBUG
-//#define DEBUG_RTP_TCP
-
static int rtsp_read_play(AVFormatContext *s)
{
RTSPState *rt = s->priv_data;
@@ -165,7 +163,12 @@ static int rtsp_read_header(AVFormatContext *s,
return AVERROR(ENOMEM);
rt->real_setup = rt->real_setup_cache + s->nb_streams;
- if (ap->initial_pause) {
+#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 {
if (rtsp_read_play(s) < 0) {
@@ -185,9 +188,7 @@ int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
int id, len, i, ret;
RTSPStream *rtsp_st;
-#ifdef DEBUG_RTP_TCP
av_dlog(s, "tcp_read_packet:\n");
-#endif
redo:
for (;;) {
RTSPMessageHeader reply;
@@ -206,9 +207,7 @@ redo:
return -1;
id = buf[0];
len = AV_RB16(buf + 1);
-#ifdef DEBUG_RTP_TCP
av_dlog(s, "id=%d len=%d\n", id, len);
-#endif
if (len > buf_size || len < 12)
goto redo;
/* get the data */
@@ -399,6 +398,18 @@ 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,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_rtsp_demuxer = {
"rtsp",
NULL_IF_CONFIG_SMALL("RTSP input format"),
@@ -411,4 +422,5 @@ AVInputFormat ff_rtsp_demuxer = {
.flags = AVFMT_NOFILE,
.read_play = rtsp_read_play,
.read_pause = rtsp_read_pause,
+ .priv_class = &rtsp_demuxer_class,
};
diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c
index 1cbcb49750..9120d187b4 100644
--- a/libavformat/rtspenc.c
+++ b/libavformat/rtspenc.c
@@ -33,9 +33,23 @@
#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,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
int ff_rtsp_setup_output_streams(AVFormatContext *s, const char *addr)
{
RTSPState *rt = s->priv_data;
@@ -238,5 +252,6 @@ AVOutputFormat ff_rtsp_muxer = {
rtsp_write_packet,
rtsp_write_close,
.flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER,
+ .priv_class = &rtsp_muxer_class,
};
diff --git a/libavformat/sauce.c b/libavformat/sauce.c
index 41e991e3e7..21cc95bccb 100644
--- a/libavformat/sauce.c
+++ b/libavformat/sauce.c
@@ -25,6 +25,7 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "sauce.h"
@@ -32,7 +33,7 @@ int ff_sauce_read(AVFormatContext *avctx, uint64_t *fsize, int *got_width, int g
{
AVIOContext *pb = avctx->pb;
char buf[36];
- int datatype, filetype, t1, t2, nb_comments, flags;
+ int datatype, filetype, t1, t2, nb_comments;
uint64_t start_pos = avio_size(pb) - 128;
avio_seek(pb, start_pos, SEEK_SET);
@@ -44,7 +45,7 @@ int ff_sauce_read(AVFormatContext *avctx, uint64_t *fsize, int *got_width, int g
#define GET_SAUCE_META(name,size) \
if (avio_read(pb, buf, size) == size && buf[0]) { \
buf[size] = 0; \
- av_metadata_set2(&avctx->metadata, name, buf, 0); \
+ av_dict_set(&avctx->metadata, name, buf, 0); \
}
GET_SAUCE_META("title", 35)
@@ -57,7 +58,7 @@ int ff_sauce_read(AVFormatContext *avctx, uint64_t *fsize, int *got_width, int g
t1 = avio_rl16(pb);
t2 = avio_rl16(pb);
nb_comments = avio_r8(pb);
- flags = avio_r8(pb);
+ avio_skip(pb, 1); /* flags */
avio_skip(pb, 4);
GET_SAUCE_META("encoder", 22);
@@ -95,7 +96,7 @@ int ff_sauce_read(AVFormatContext *avctx, uint64_t *fsize, int *got_width, int g
str[65*i + 64] = '\n';
}
str[65*i] = 0;
- av_metadata_set2(&avctx->metadata, "comment", str, AV_METADATA_DONT_STRDUP_VAL);
+ av_dict_set(&avctx->metadata, "comment", str, AV_DICT_DONT_STRDUP_VAL);
}
}
diff --git a/libavformat/sdp.c b/libavformat/sdp.c
index 923c57fbcd..32cef49916 100644
--- a/libavformat/sdp.c
+++ b/libavformat/sdp.c
@@ -21,8 +21,11 @@
#include <string.h>
#include "libavutil/avstring.h"
#include "libavutil/base64.h"
+#include "libavutil/dict.h"
#include "libavutil/parseutils.h"
+#include "libavutil/opt.h"
#include "libavcodec/xiph.h"
+#include "libavcodec/mpeg4audio.h"
#include "avformat.h"
#include "internal.h"
#include "avc.h"
@@ -299,7 +302,72 @@ xiph_fail:
return NULL;
}
-static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type)
+static int latm_context2profilelevel(AVCodecContext *c)
+{
+ /* MP4A-LATM
+ * The RTP payload format specification is described in RFC 3016
+ * The encoding specifications are provided in ISO/IEC 14496-3 */
+
+ int profile_level = 0x2B;
+
+ /* TODO: AAC Profile only supports AAC LC Object Type.
+ * Different Object Types should implement different Profile Levels */
+
+ if (c->sample_rate <= 24000) {
+ if (c->channels <= 2)
+ profile_level = 0x28; // AAC Profile, Level 1
+ } else if (c->sample_rate <= 48000) {
+ if (c->channels <= 2) {
+ profile_level = 0x29; // AAC Profile, Level 2
+ } else if (c->channels <= 5) {
+ profile_level = 0x2A; // AAC Profile, Level 4
+ }
+ } else if (c->sample_rate <= 96000) {
+ if (c->channels <= 5) {
+ profile_level = 0x2B; // AAC Profile, Level 5
+ }
+ }
+
+ return profile_level;
+}
+
+static char *latm_context2config(AVCodecContext *c)
+{
+ /* MP4A-LATM
+ * The RTP payload format specification is described in RFC 3016
+ * The encoding specifications are provided in ISO/IEC 14496-3 */
+
+ uint8_t config_byte[6];
+ int rate_index;
+ char *config;
+
+ for (rate_index = 0; rate_index < 16; rate_index++)
+ if (ff_mpeg4audio_sample_rates[rate_index] == c->sample_rate)
+ break;
+ if (rate_index == 16) {
+ av_log(c, AV_LOG_ERROR, "Unsupported sample rate\n");
+ return NULL;
+ }
+
+ config_byte[0] = 0x40;
+ config_byte[1] = 0;
+ config_byte[2] = 0x20 | rate_index;
+ config_byte[3] = c->channels << 4;
+ config_byte[4] = 0x3f;
+ config_byte[5] = 0xc0;
+
+ config = av_malloc(6*2+1);
+ if (!config) {
+ av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the config info.\n");
+ return NULL;
+ }
+ ff_data_to_hex(config, config_byte, 6, 1);
+ config[12] = 0;
+
+ return config;
+}
+
+static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type, AVFormatContext *fmt)
{
char *config = NULL;
@@ -334,24 +402,35 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
payload_type, config ? config : "");
break;
case CODEC_ID_AAC:
- if (c->extradata_size) {
- config = extradata2config(c);
+ if (fmt && fmt->oformat->priv_class &&
+ av_opt_flag_is_set(fmt->priv_data, "rtpflags", "latm")) {
+ config = latm_context2config(c);
+ if (!config)
+ return NULL;
+ av_strlcatf(buff, size, "a=rtpmap:%d MP4A-LATM/%d/%d\r\n"
+ "a=fmtp:%d profile-level-id=%d;cpresent=0;config=%s\r\n",
+ payload_type, c->sample_rate, c->channels,
+ payload_type, latm_context2profilelevel(c), config);
} else {
- /* FIXME: maybe we can forge config information based on the
- * codec parameters...
- */
- av_log(c, AV_LOG_ERROR, "AAC with no global headers is currently not supported.\n");
- return NULL;
+ if (c->extradata_size) {
+ config = extradata2config(c);
+ } else {
+ /* FIXME: maybe we can forge config information based on the
+ * codec parameters...
+ */
+ av_log(c, AV_LOG_ERROR, "AAC with no global headers is currently not supported.\n");
+ return NULL;
+ }
+ if (config == NULL) {
+ return NULL;
+ }
+ av_strlcatf(buff, size, "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n"
+ "a=fmtp:%d profile-level-id=1;"
+ "mode=AAC-hbr;sizelength=13;indexlength=3;"
+ "indexdeltalength=3%s\r\n",
+ payload_type, c->sample_rate, c->channels,
+ payload_type, config);
}
- if (config == NULL) {
- return NULL;
- }
- av_strlcatf(buff, size, "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n"
- "a=fmtp:%d profile-level-id=1;"
- "mode=AAC-hbr;sizelength=13;indexlength=3;"
- "indexdeltalength=3%s\r\n",
- payload_type, c->sample_rate, c->channels,
- payload_type, config);
break;
case CODEC_ID_PCM_S16BE:
if (payload_type >= RTP_PT_PRIVATE)
@@ -448,7 +527,7 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
return buff;
}
-void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl)
+void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt)
{
const char *type;
int payload_type;
@@ -471,12 +550,12 @@ void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *des
av_strlcatf(buff, size, "b=AS:%d\r\n", c->bit_rate / 1000);
}
- sdp_write_media_attributes(buff, size, c, payload_type);
+ sdp_write_media_attributes(buff, size, c, payload_type, fmt);
}
int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
{
- AVMetadataTag *title = av_metadata_get(ac[0]->metadata, "title", NULL, 0);
+ AVDictionaryEntry *title = av_dict_get(ac[0]->metadata, "title", NULL, 0);
struct sdp_session_level s;
int i, j, port, ttl, is_multicast;
char dst[32], dst_type[5];
@@ -520,7 +599,8 @@ int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
for (j = 0; j < ac[i]->nb_streams; j++) {
ff_sdp_write_media(buf, size,
ac[i]->streams[j]->codec, dst[0] ? dst : NULL,
- dst_type, (port > 0) ? port + j * 2 : 0, ttl);
+ dst_type, (port > 0) ? port + j * 2 : 0, ttl,
+ ac[i]);
if (port <= 0) {
av_strlcatf(buf, size,
"a=control:streamid=%d\r\n", i + j);
@@ -536,7 +616,7 @@ int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
return AVERROR(ENOSYS);
}
-void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl)
+void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt)
{
}
#endif
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index 2603a4d71c..29a66e79fa 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -233,7 +233,6 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
int i;
int frame_size = 0;
int palchange = 0;
- int pos;
if (url_feof(s->pb) || smk->cur_frame >= smk->frames)
return AVERROR_EOF;
@@ -244,7 +243,6 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
frame_size = smk->frm_size[smk->cur_frame] & (~3);
flags = smk->frm_flags[smk->cur_frame];
/* handle palette change event */
- pos = avio_tell(s->pb);
if(flags & SMACKER_PAL){
int size, sz, t, off, j, pos;
uint8_t *pal = smk->pal;
diff --git a/libavformat/sol.c b/libavformat/sol.c
index 7ad894e304..c0d2c5d5a2 100644
--- a/libavformat/sol.c
+++ b/libavformat/sol.c
@@ -85,7 +85,6 @@ static int sol_channels(int magic, int type)
static int sol_read_header(AVFormatContext *s,
AVFormatParameters *ap)
{
- int size;
unsigned int magic,tag;
AVIOContext *pb = s->pb;
unsigned int id, channels, rate, type;
@@ -99,7 +98,7 @@ static int sol_read_header(AVFormatContext *s,
return -1;
rate = avio_rl16(pb);
type = avio_r8(pb);
- size = avio_rl32(pb);
+ avio_skip(pb, 4); /* size */
if (magic != 0x0B8D)
avio_r8(pb); /* newer SOLs contain padding byte */
diff --git a/libavformat/soxdec.c b/libavformat/soxdec.c
index 5e1e220f76..16d26ab4a7 100644
--- a/libavformat/soxdec.c
+++ b/libavformat/soxdec.c
@@ -30,6 +30,7 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "pcm.h"
#include "sox.h"
@@ -101,8 +102,8 @@ static int sox_read_header(AVFormatContext *s,
}
comment[comment_size] = 0;
- av_metadata_set2(&s->metadata, "comment", comment,
- AV_METADATA_DONT_STRDUP_VAL);
+ av_dict_set(&s->metadata, "comment", comment,
+ AV_DICT_DONT_STRDUP_VAL);
}
avio_skip(pb, header_size - SOX_FIXED_HDR - comment_size);
diff --git a/libavformat/soxenc.c b/libavformat/soxenc.c
index c93869c691..a07a2068c3 100644
--- a/libavformat/soxenc.c
+++ b/libavformat/soxenc.c
@@ -30,6 +30,7 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "avio_internal.h"
#include "sox.h"
@@ -43,10 +44,10 @@ static int sox_write_header(AVFormatContext *s)
SoXContext *sox = s->priv_data;
AVIOContext *pb = s->pb;
AVCodecContext *enc = s->streams[0]->codec;
- AVMetadataTag *comment;
+ AVDictionaryEntry *comment;
size_t comment_len = 0, comment_size;
- comment = av_metadata_get(s->metadata, "comment", NULL, 0);
+ comment = av_dict_get(s->metadata, "comment", NULL, 0);
if (comment)
comment_len = strlen(comment->value);
comment_size = (comment_len + 7) & ~7;
diff --git a/libavformat/spdif.h b/libavformat/spdif.h
index ac5be7c31a..4b11de20d1 100644
--- a/libavformat/spdif.h
+++ b/libavformat/spdif.h
@@ -19,6 +19,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifndef AVFORMAT_SPDIF_H
+#define AVFORMAT_SPDIF_H
+
#include <stdint.h>
#define SYNCWORD1 0xF872
@@ -55,3 +58,5 @@ static const uint16_t spdif_mpeg_pkt_offset[2][3] = {
};
void ff_spdif_bswap_buf16(uint16_t *dst, const uint16_t *src, int w);
+
+#endif /* AVFORMAT_SPDIF_H */
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index 57be430c23..9b344ab98f 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -45,6 +45,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
char buf[256];
int ret;
socklen_t optlen;
+ int timeout = 50;
char hostname[1024],proto[1024],path[1024];
char portstr[10];
@@ -57,6 +58,9 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
if (p) {
if (av_find_info_tag(buf, sizeof(buf), "listen", p))
listen_socket = 1;
+ if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
+ timeout = strtol(buf, NULL, 10);
+ }
}
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
@@ -73,6 +77,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
cur_ai = ai;
restart:
+ ret = AVERROR(EIO);
fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
if (fd < 0)
goto fail;
@@ -84,29 +89,29 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
fd1 = accept(fd, NULL, NULL);
closesocket(fd);
fd = fd1;
+ ff_socket_nonblock(fd, 1);
} else {
redo:
+ ff_socket_nonblock(fd, 1);
ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
}
- ff_socket_nonblock(fd, 1);
-
if (ret < 0) {
- int timeout=50;
struct pollfd p = {fd, POLLOUT, 0};
- if (ff_neterrno() == AVERROR(EINTR)) {
+ ret = ff_neterrno();
+ if (ret == AVERROR(EINTR)) {
if (url_interrupt_cb()) {
ret = AVERROR_EXIT;
goto fail1;
}
goto redo;
}
- if (ff_neterrno() != AVERROR(EINPROGRESS) &&
- ff_neterrno() != AVERROR(EAGAIN))
+ if (ret != AVERROR(EINPROGRESS) &&
+ ret != AVERROR(EAGAIN))
goto fail;
/* wait until we are connected or until abort */
- for(;;) {
+ while(timeout--) {
if (url_interrupt_cb()) {
ret = AVERROR_EXIT;
goto fail1;
@@ -114,14 +119,11 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
ret = poll(&p, 1, 100);
if (ret > 0)
break;
- if(!--timeout){
- av_log(NULL, AV_LOG_ERROR,
- "TCP open %s:%d timeout\n",
- hostname, port);
- goto fail;
- }
}
-
+ if (ret <= 0) {
+ ret = AVERROR(ETIMEDOUT);
+ goto fail;
+ }
/* test error */
optlen = sizeof(ret);
getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen);
@@ -129,6 +131,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
av_log(NULL, AV_LOG_ERROR,
"TCP connection to %s:%d failed: %s\n",
hostname, port, strerror(ret));
+ ret = AVERROR(ret);
goto fail;
}
}
@@ -151,7 +154,6 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
closesocket(fd);
goto restart;
}
- ret = AVERROR(EIO);
fail1:
if (fd >= 0)
closesocket(fd);
diff --git a/libavformat/tta.c b/libavformat/tta.c
index d5f8e1ed61..c37039d0da 100644
--- a/libavformat/tta.c
+++ b/libavformat/tta.c
@@ -22,6 +22,7 @@
#include "libavcodec/get_bits.h"
#include "avformat.h"
#include "id3v1.h"
+#include "libavutil/dict.h"
typedef struct {
int totalframes, currentframe;
@@ -43,7 +44,7 @@ static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap)
int i, channels, bps, samplerate, datalen, framelen;
uint64_t framepos, start_offset;
- if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
+ if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
ff_id3v1_read(s);
start_offset = avio_tell(s->pb);
diff --git a/libavformat/tty.c b/libavformat/tty.c
index b288d15393..ddf283d8a3 100644
--- a/libavformat/tty.c
+++ b/libavformat/tty.c
@@ -26,14 +26,19 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
+#include "libavutil/log.h"
+#include "libavutil/dict.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
#include "avformat.h"
#include "sauce.h"
-#define LINE_RATE 6000 /* characters per second */
-
typedef struct {
+ AVClass *class;
int chars_per_frame;
uint64_t fsize; /**< file size less metadata buffer */
+ char *video_size;/**< A string describing video size, set by a private option. */
+ char *framerate; /**< Set by a private option. */
} TtyDemuxContext;
/**
@@ -56,7 +61,7 @@ static int efi_read(AVFormatContext *avctx, uint64_t start_pos)
return -1; \
if (avio_read(pb, buf, size) == size) { \
buf[len] = 0; \
- av_metadata_set2(&avctx->metadata, name, buf, 0); \
+ av_dict_set(&avctx->metadata, name, buf, 0); \
}
GET_EFI_META("filename", 12)
@@ -70,23 +75,44 @@ static int read_header(AVFormatContext *avctx,
AVFormatParameters *ap)
{
TtyDemuxContext *s = avctx->priv_data;
+ int width = 0, height = 0, ret = 0;
AVStream *st = av_new_stream(avctx, 0);
- if (!st)
- return AVERROR(ENOMEM);
+ AVRational framerate;
+
+ if (!st) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
st->codec->codec_tag = 0;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_ANSI;
- if (ap->width) st->codec->width = ap->width;
- if (ap->height) st->codec->height = ap->height;
- 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);
+ if (s->video_size && (ret = av_parse_video_size(&width, &height, s->video_size)) < 0) {
+ av_log (avctx, AV_LOG_ERROR, "Couldn't parse video size.\n");
+ goto fail;
}
+ if ((ret = av_parse_video_rate(&framerate, s->framerate)) < 0) {
+ 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 */
- s->chars_per_frame = FFMAX(av_q2d(st->time_base) * (ap->sample_rate ? ap->sample_rate : LINE_RATE), 1);
+#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) {
s->fsize = avio_size(avctx->pb);
@@ -98,7 +124,8 @@ static int read_header(AVFormatContext *avctx,
avio_seek(avctx->pb, 0, SEEK_SET);
}
- return 0;
+fail:
+ return ret;
}
static int read_packet(AVFormatContext *avctx, AVPacket *pkt)
@@ -124,6 +151,22 @@ static int read_packet(AVFormatContext *avctx, AVPacket *pkt)
return 0;
}
+#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 },
+ { NULL },
+};
+
+static const AVClass tty_demuxer_class = {
+ .class_name = "TTY demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_tty_demuxer = {
.name = "tty",
.long_name = NULL_IF_CONFIG_SMALL("Tele-typewriter"),
@@ -131,4 +174,5 @@ AVInputFormat ff_tty_demuxer = {
.read_header = read_header,
.read_packet = read_packet,
.extensions = "ans,art,asc,diz,ice,nfo,txt,vt",
+ .priv_class = &tty_demuxer_class,
};
diff --git a/libavformat/udp.c b/libavformat/udp.c
index 021f529d64..78077e6595 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -35,7 +35,11 @@
#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
@@ -57,9 +61,10 @@ typedef struct {
/* Circular Buffer variables for use in UDP receive code */
int circular_buffer_size;
AVFifoBuffer *fifo;
- int circular_buffer_available_max;
int circular_buffer_error;
+#if HAVE_PTHREADS
pthread_t circular_buffer_thread;
+#endif
} UDPContext;
#define UDP_TX_BUF_SIZE 32768
@@ -509,6 +514,7 @@ 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);
@@ -517,12 +523,13 @@ static int udp_open(URLContext *h, const char *uri, int flags)
goto fail;
}
}
+#endif
return 0;
fail:
if (udp_fd >= 0)
closesocket(udp_fd);
- av_fifo_free(s->fifo);
+ av_fifo_free(s->fifo);
av_free(s);
return AVERROR(EIO);
}
@@ -532,7 +539,6 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
UDPContext *s = h->priv_data;
int ret;
int avail;
- int left;
fd_set rfds;
struct timeval tv;
@@ -597,7 +603,6 @@ static int udp_close(URLContext *h)
if (s->is_multicast && !(h->flags & AVIO_WRONLY))
udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr);
closesocket(s->udp_fd);
- av_log( h, AV_LOG_INFO, "circular_buffer_info max:%d%%\r\n", (s->circular_buffer_available_max*100)/s->circular_buffer_size);
av_fifo_free(s->fifo);
av_free(s);
return 0;
diff --git a/libavformat/url.h b/libavformat/url.h
index 56366644aa..5ef6a21d7b 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -173,4 +173,4 @@ int ffurl_register_protocol(URLProtocol *protocol, int size);
int ff_udp_set_remote_url(URLContext *h, const char *uri);
int ff_udp_get_local_port(URLContext *h);
-#endif //AVFORMAT_URL_H
+#endif /* AVFORMAT_URL_H */
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 16297af16a..454cd5843a 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -27,6 +27,7 @@
#include "libavcodec/internal.h"
#include "libavcodec/raw.h"
#include "libavutil/opt.h"
+#include "libavutil/dict.h"
#include "metadata.h"
#include "id3v2.h"
#include "libavutil/avstring.h"
@@ -743,6 +744,7 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
s->streams[i]->request_probe = -1;
continue;
}
+
st= s->streams[pkt->stream_index];
switch(st->codec->codec_type){
@@ -1516,8 +1518,6 @@ int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp,
wanted_timestamp, flags);
}
-#define DEBUG_SEEK
-
int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
AVInputFormat *avif= s->iformat;
int64_t av_uninit(pos_min), av_uninit(pos_max), pos, pos_limit;
@@ -1529,9 +1529,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
if (stream_index < 0)
return -1;
-#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_DEBUG, "read_seek: %d %"PRId64"\n", stream_index, target_ts);
-#endif
+ av_dlog(s, "read_seek: %d %"PRId64"\n", stream_index, target_ts);
ts_max=
ts_min= AV_NOPTS_VALUE;
@@ -1548,10 +1546,8 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
if(e->timestamp <= target_ts || e->pos == e->min_distance){
pos_min= e->pos;
ts_min= e->timestamp;
-#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_DEBUG, "using cached pos_min=0x%"PRIx64" dts_min=%"PRId64"\n",
- pos_min,ts_min);
-#endif
+ av_dlog(s, "using cached pos_min=0x%"PRIx64" dts_min=%"PRId64"\n",
+ pos_min,ts_min);
}else{
assert(index==0);
}
@@ -1564,10 +1560,8 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
pos_max= e->pos;
ts_max= e->timestamp;
pos_limit= pos_max - e->min_distance;
-#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_DEBUG, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64" dts_max=%"PRId64"\n",
- pos_max,pos_limit, ts_max);
-#endif
+ av_dlog(s, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64" dts_max=%"PRId64"\n",
+ pos_max,pos_limit, ts_max);
}
}
@@ -1589,9 +1583,7 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i
int64_t start_pos, filesize;
int no_change;
-#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_DEBUG, "gen_seek: %d %"PRId64"\n", stream_index, target_ts);
-#endif
+ av_dlog(s, "gen_seek: %d %"PRId64"\n", stream_index, target_ts);
if(ts_min == AV_NOPTS_VALUE){
pos_min = s->data_offset;
@@ -1633,11 +1625,8 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i
no_change=0;
while (pos_min < pos_limit) {
-#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_DEBUG, "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%"PRId64" dts_max=%"PRId64"\n",
- pos_min, pos_max,
- ts_min, ts_max);
-#endif
+ av_dlog(s, "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%"PRId64" dts_max=%"PRId64"\n",
+ pos_min, pos_max, ts_min, ts_max);
assert(pos_limit <= pos_max);
if(no_change==0){
@@ -1664,11 +1653,9 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i
no_change++;
else
no_change=0;
-#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_DEBUG, "%"PRId64" %"PRId64" %"PRId64" / %"PRId64" %"PRId64" %"PRId64" target:%"PRId64" limit:%"PRId64" start:%"PRId64" noc:%d\n",
- pos_min, pos, pos_max, ts_min, ts, ts_max, target_ts, pos_limit,
- start_pos, no_change);
-#endif
+ av_dlog(s, "%"PRId64" %"PRId64" %"PRId64" / %"PRId64" %"PRId64" %"PRId64" target:%"PRId64" limit:%"PRId64" start:%"PRId64" noc:%d\n",
+ pos_min, pos, pos_max, ts_min, ts, ts_max, target_ts,
+ pos_limit, start_pos, no_change);
if(ts == AV_NOPTS_VALUE){
av_log(s, AV_LOG_ERROR, "read_timestamp() failed in the middle\n");
return -1;
@@ -1687,14 +1674,12 @@ 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;
-#ifdef DEBUG_SEEK
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_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n",
- pos, ts_min, target_ts, ts_max);
-#endif
+ av_dlog(s, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n",
+ pos, ts_min, target_ts, ts_max);
*ts_ret= ts;
return pos;
}
@@ -1813,10 +1798,12 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int f
return 0;
}
- if(s->iformat->read_timestamp)
+ if(s->iformat->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH))
return av_seek_frame_binary(s, stream_index, timestamp, flags);
- else
+ else if (!(s->iformat->flags & AVFMT_NOGENSEARCH))
return av_seek_frame_generic(s, stream_index, timestamp, flags);
+ else
+ return -1;
}
int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
@@ -2085,7 +2072,7 @@ static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset)
#if 0
{
int i;
- AVStream *st;
+ AVStream av_unused *st;
for(i = 0;i < ic->nb_streams; i++) {
st = ic->streams[i];
printf("%d: start_time: %0.3f duration: %0.3f\n",
@@ -2219,7 +2206,7 @@ enum CodecID av_codec_get_id(const AVCodecTag * const *tags, unsigned int tag)
static void compute_chapters_end(AVFormatContext *s)
{
unsigned int i, j;
- int64_t max_time = s->duration + (s->start_time == AV_NOPTS_VALUE) ? 0 : s->start_time;
+ int64_t max_time = s->duration + ((s->start_time == AV_NOPTS_VALUE) ? 0 : s->start_time);
for (i = 0; i < s->nb_chapters; i++)
if (s->chapters[i]->end == AV_NOPTS_VALUE) {
@@ -2338,6 +2325,8 @@ int av_find_stream_info(AVFormatContext *ic)
the correct fps */
if (av_q2d(st->time_base) > 0.0005)
fps_analyze_framecount *= 2;
+ if (ic->fps_probe_size >= 0)
+ fps_analyze_framecount = ic->fps_probe_size;
/* variable fps and no guess at the real fps */
if( tb_unreliable(st->codec) && !(st->r_frame_rate.num && st->avg_frame_rate.num)
&& st->info->duration_count < fps_analyze_framecount
@@ -2396,8 +2385,9 @@ 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;
@@ -2655,6 +2645,10 @@ void avformat_free_context(AVFormatContext *s)
int i;
AVStream *st;
+ av_opt_free(s);
+ if (s->iformat && s->iformat->priv_class && s->priv_data)
+ av_opt_free(s->priv_data);
+
for(i=0;i<s->nb_streams;i++) {
/* free all data in a stream component */
st = s->streams[i];
@@ -2662,7 +2656,7 @@ void avformat_free_context(AVFormatContext *s)
av_parser_close(st->parser);
av_free_packet(&st->cur_pkt);
}
- av_metadata_free(&st->metadata);
+ av_dict_free(&st->metadata);
av_free(st->index_entries);
av_free(st->codec->extradata);
av_free(st->codec->subtitle_header);
@@ -2689,12 +2683,12 @@ void avformat_free_context(AVFormatContext *s)
#if FF_API_OLD_METADATA
av_free(s->chapters[s->nb_chapters]->title);
#endif
- av_metadata_free(&s->chapters[s->nb_chapters]->metadata);
+ av_dict_free(&s->chapters[s->nb_chapters]->metadata);
av_free(s->chapters[s->nb_chapters]);
}
av_freep(&s->chapters);
av_metadata_free(&s->metadata);
- av_freep(&s->key);
+// av_freep(&s->key);
av_free(s);
}
@@ -2770,9 +2764,7 @@ AVProgram *av_new_program(AVFormatContext *ac, int id)
AVProgram *program=NULL;
int i;
-#ifdef DEBUG_SI
- av_log(ac, AV_LOG_DEBUG, "new_program: id=0x%04x\n", id);
-#endif
+ av_dlog(ac, "new_program: id=0x%04x\n", id);
for(i=0; i<ac->nb_programs; i++)
if(ac->programs[i]->id == id)
@@ -2808,7 +2800,7 @@ AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, int6
#if FF_API_OLD_METADATA
av_free(chapter->title);
#endif
- av_metadata_set2(&chapter->metadata, "title", title, 0);
+ av_dict_set(&chapter->metadata, "title", title, 0);
chapter->id = id;
chapter->time_base= time_base;
chapter->start = start;
@@ -2836,29 +2828,36 @@ int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
return 0;
}
-AVFormatContext *avformat_alloc_output_context(const char *format, AVOutputFormat *oformat, const char *filename){
- AVFormatContext *s= avformat_alloc_context();
- if(!s)
+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 (!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);
+ filename);
goto error;
}
}
}
- s->oformat= oformat;
+ s->oformat = oformat;
if (s->oformat->priv_data_size > 0) {
s->priv_data = av_mallocz(s->oformat->priv_data_size);
if (!s->priv_data)
@@ -2870,15 +2869,27 @@ AVFormatContext *avformat_alloc_output_context(const char *format, AVOutputForma
} else
s->priv_data = NULL;
- if(filename)
+ if (filename)
av_strlcpy(s->filename, filename, sizeof(s->filename));
- return s;
+ *avctx = s;
+ return 0;
nomem:
av_log(s, AV_LOG_ERROR, "Out of memory\n");
+ ret = AVERROR(ENOMEM);
error:
avformat_free_context(s);
- return NULL;
+ 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
static int validate_codec_tag(AVFormatContext *s, AVStream *st)
{
@@ -2988,7 +2999,7 @@ int av_write_header(AVFormatContext *s)
/* set muxer identification string */
if (s->nb_streams && !(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
- av_metadata_set2(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
+ av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
}
if(s->oformat->write_header){
@@ -3061,7 +3072,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);
@@ -3269,6 +3280,8 @@ fail:
av_freep(&s->streams[i]->priv_data);
av_freep(&s->streams[i]->index_entries);
}
+ if (s->iformat && s->iformat->priv_class)
+ av_opt_free(s->priv_data);
av_freep(&s->priv_data);
return ret;
}
@@ -3308,13 +3321,13 @@ static void print_fps(double d, const char *postfix){
else av_log(NULL, AV_LOG_INFO, ", %1.0fk %s", d/1000, postfix);
}
-static void dump_metadata(void *ctx, AVMetadata *m, const char *indent)
+static void dump_metadata(void *ctx, AVDictionary *m, const char *indent)
{
- if(m && !(m->count == 1 && av_metadata_get(m, "language", NULL, 0))){
- AVMetadataTag *tag=NULL;
+ if(m && !(m->count == 1 && av_dict_get(m, "language", NULL, 0))){
+ AVDictionaryEntry *tag=NULL;
av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent);
- while((tag=av_metadata_get(m, "", tag, AV_METADATA_IGNORE_SUFFIX))) {
+ 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);
}
@@ -3328,7 +3341,7 @@ static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_out
int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
AVStream *st = ic->streams[i];
int g = av_gcd(st->time_base.num, st->time_base.den);
- AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL, 0);
+ 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);
/* the pid is an important information, so we display it */
@@ -3452,7 +3465,7 @@ void av_dump_format(AVFormatContext *ic,
if(ic->nb_programs) {
int j, k, total = 0;
for(j=0; j<ic->nb_programs; j++) {
- AVMetadataTag *name = av_metadata_get(ic->programs[j]->metadata,
+ AVDictionaryEntry *name = av_dict_get(ic->programs[j]->metadata,
"name", NULL, 0);
av_log(NULL, AV_LOG_INFO, " Program %d %s\n", ic->programs[j]->id,
name ? name->value : "");
diff --git a/libavformat/version.h b/libavformat/version.h
index eec52b2363..7292007610 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -24,7 +24,7 @@
#include "libavutil/avutil.h"
#define LIBAVFORMAT_VERSION_MAJOR 52
-#define LIBAVFORMAT_VERSION_MINOR 108
+#define LIBAVFORMAT_VERSION_MINOR 109
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
@@ -113,5 +113,14 @@
#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
-#endif //AVFORMAT_VERSION_H
+#endif /* AVFORMAT_VERSION_H */
diff --git a/libavformat/vorbiscomment.c b/libavformat/vorbiscomment.c
index 59a403f209..9b38e6a791 100644
--- a/libavformat/vorbiscomment.c
+++ b/libavformat/vorbiscomment.c
@@ -23,6 +23,7 @@
#include "metadata.h"
#include "vorbiscomment.h"
#include "libavcodec/bytestream.h"
+#include "libavutil/dict.h"
/**
* VorbisComment metadata conversion mapping.
@@ -36,15 +37,15 @@ const AVMetadataConv ff_vorbiscomment_metadata_conv[] = {
{ 0 }
};
-int ff_vorbiscomment_length(AVMetadata *m, const char *vendor_string,
+int ff_vorbiscomment_length(AVDictionary *m, const char *vendor_string,
unsigned *count)
{
int len = 8;
len += strlen(vendor_string);
*count = 0;
if (m) {
- AVMetadataTag *tag = NULL;
- while ((tag = av_metadata_get(m, "", tag, AV_METADATA_IGNORE_SUFFIX))) {
+ AVDictionaryEntry *tag = NULL;
+ while ((tag = av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX))) {
len += 4 +strlen(tag->key) + 1 + strlen(tag->value);
(*count)++;
}
@@ -52,15 +53,15 @@ int ff_vorbiscomment_length(AVMetadata *m, const char *vendor_string,
return len;
}
-int ff_vorbiscomment_write(uint8_t **p, AVMetadata **m,
+int ff_vorbiscomment_write(uint8_t **p, AVDictionary **m,
const char *vendor_string, const unsigned count)
{
bytestream_put_le32(p, strlen(vendor_string));
bytestream_put_buffer(p, vendor_string, strlen(vendor_string));
if (*m) {
- AVMetadataTag *tag = NULL;
+ AVDictionaryEntry *tag = NULL;
bytestream_put_le32(p, count);
- while ((tag = av_metadata_get(*m, "", tag, AV_METADATA_IGNORE_SUFFIX))) {
+ while ((tag = av_dict_get(*m, "", tag, AV_DICT_IGNORE_SUFFIX))) {
unsigned int len1 = strlen(tag->key);
unsigned int len2 = strlen(tag->value);
bytestream_put_le32(p, len1+1+len2);
diff --git a/libavformat/vorbiscomment.h b/libavformat/vorbiscomment.h
index 3dfe9d226b..b147092071 100644
--- a/libavformat/vorbiscomment.h
+++ b/libavformat/vorbiscomment.h
@@ -35,13 +35,13 @@
* @param count Pointer to store the number of tags in m because m->count is "not allowed"
* @return The length in bytes.
*/
-int ff_vorbiscomment_length(AVMetadata *m, const char *vendor_string,
+int ff_vorbiscomment_length(AVDictionary *m, const char *vendor_string,
unsigned *count);
/**
* Writes a VorbisComment into a buffer. The buffer, p, must have enough
* data to hold the whole VorbisComment. The minimum size required can be
- * obtained by passing the same AVMetadata and vendor_string to
+ * obtained by passing the same AVDictionary and vendor_string to
* ff_vorbiscomment_length()
*
* @param p The buffer in which to write.
@@ -49,7 +49,7 @@ int ff_vorbiscomment_length(AVMetadata *m, const char *vendor_string,
* @param vendor_string The vendor string to write.
* @param count The number of tags in m because m->count is "not allowed"
*/
-int ff_vorbiscomment_write(uint8_t **p, AVMetadata **m,
+int ff_vorbiscomment_write(uint8_t **p, AVDictionary **m,
const char *vendor_string, const unsigned count);
extern const AVMetadataConv ff_vorbiscomment_metadata_conv[];
diff --git a/libavformat/vqf.c b/libavformat/vqf.c
index 94ba543ba5..e06f39349b 100644
--- a/libavformat/vqf.c
+++ b/libavformat/vqf.c
@@ -21,6 +21,7 @@
#include "avformat.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
typedef struct VqfContext {
int frame_bit_len;
@@ -56,7 +57,7 @@ static void add_metadata(AVFormatContext *s, const char *tag,
return;
avio_read(s->pb, buf, len);
buf[len] = 0;
- av_metadata_set2(&s->metadata, tag, buf, AV_METADATA_DONT_STRDUP_VAL);
+ av_dict_set(&s->metadata, tag, buf, AV_DICT_DONT_STRDUP_VAL);
}
static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap)
diff --git a/libavformat/wav.c b/libavformat/wav.c
index 588aff512b..c5dbd631b4 100644
--- a/libavformat/wav.c
+++ b/libavformat/wav.c
@@ -26,6 +26,7 @@
#include "avio_internal.h"
#include "pcm.h"
#include "riff.h"
+#include "metadata.h"
typedef struct {
int64_t data;
@@ -184,6 +185,115 @@ 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 = av_new_stream(s, 0);
+ 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;
+
+ 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_METADATA_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,7 +305,8 @@ static int wav_read_header(AVFormatContext *s,
AVIOContext *pb = s->pb;
AVStream *st;
WAVContext *wav = s->priv_data;
- int ret;
+ int ret, got_fmt = 0;
+ int64_t next_tag_ofs, data_ofs = -1;
/* check RIFF header */
tag = avio_rl32(pb);
@@ -212,54 +323,89 @@ 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 (;;) {
+ 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 (url_feof(pb))
- 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;
+ }
+
+ /* 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;
}
diff --git a/libavformat/wc3movie.c b/libavformat/wc3movie.c
index 0f2e077859..eb2eae1c9c 100644
--- a/libavformat/wc3movie.c
+++ b/libavformat/wc3movie.c
@@ -28,6 +28,7 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#define FORM_TAG MKTAG('F', 'O', 'R', 'M')
@@ -130,8 +131,8 @@ static int wc3_read_header(AVFormatContext *s,
if ((ret = avio_read(pb, buffer, size)) != size)
return AVERROR(EIO);
buffer[size] = 0;
- av_metadata_set2(&s->metadata, "title", buffer,
- AV_METADATA_DONT_STRDUP_VAL);
+ av_dict_set(&s->metadata, "title", buffer,
+ AV_DICT_DONT_STRDUP_VAL);
break;
case SIZE_TAG:
diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c
index 5cbec0576a..5fe7e9fe12 100644
--- a/libavformat/wtvdec.c
+++ b/libavformat/wtvdec.c
@@ -431,7 +431,7 @@ static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length)
st = av_new_stream(s, 0);
if (!st)
goto done;
- av_metadata_set2(&st->metadata, "title", description, 0);
+ 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);
@@ -494,7 +494,7 @@ static void get_tag(AVFormatContext *s, AVIOContext *pb, const char *key, int ty
return;
}
- av_metadata_set2(&s->metadata, key, buf, 0);
+ av_dict_set(&s->metadata, key, buf, 0);
av_freep(&buf);
}
@@ -818,7 +818,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p
avio_read(pb, language, 3);
if (language[0]) {
language[3] = 0;
- av_metadata_set2(&st->metadata, "language", language, 0);
+ av_dict_set(&st->metadata, "language", language, 0);
if (!strcmp(language, "nar") || !strcmp(language, "NAR"))
st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
}
diff --git a/libavformat/wv.c b/libavformat/wv.c
index 52ec9264a0..9da416e580 100644
--- a/libavformat/wv.c
+++ b/libavformat/wv.c
@@ -21,6 +21,7 @@
#include "libavutil/audioconvert.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "apetag.h"
#include "id3v1.h"
@@ -226,7 +227,7 @@ static int wv_read_header(AVFormatContext *s,
if(s->pb->seekable) {
int64_t cur = avio_tell(s->pb);
ff_ape_parse_tag(s);
- if(!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
+ if(!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
ff_id3v1_read(s);
avio_seek(s->pb, cur, SEEK_SET);
}
diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c
index a852568a64..90b222d1d4 100644
--- a/libavformat/yuv4mpeg.c
+++ b/libavformat/yuv4mpeg.c
@@ -94,7 +94,7 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
AVPicture *picture;
int* first_pkt = s->priv_data;
int width, height, h_chroma_shift, v_chroma_shift;
- int i, m;
+ int i;
char buf2[Y4M_LINE_MAX+1];
char buf1[20];
uint8_t *ptr, *ptr1, *ptr2;
@@ -114,7 +114,7 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
/* construct frame header */
- m = snprintf(buf1, sizeof(buf1), "%s\n", Y4M_FRAME_MAGIC);
+ snprintf(buf1, sizeof(buf1), "%s\n", Y4M_FRAME_MAGIC);
avio_write(pb, buf1, strlen(buf1));
width = st->codec->width;
@@ -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");
}