aboutsummaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorMichael Niedermayer2012-02-19 01:36:23 +0100
committerMichael Niedermayer2012-02-19 01:47:10 +0100
commit4a519b6e036bb593d868c2a424da43512215c571 (patch)
treebbbd734383e7b2bfd005a1c19fe64d36d493b576 /libavformat
parent57182b9f0fa15ebedbf5229e17bc77a70cc68d9d (diff)
parent5be805d38cb43e6f0b85941f75946d09bc8cc13f (diff)
Merge remote-tracking branch 'qatar/master'
* qatar/master: mov: Use defines for sample flags in fragments mov: Use defines for trun flags mov: Use defines for tfhd flags proresenc: force bitrate not to exceed given limit vc1parse: call vc1_init_common(). wma: don't return 0 on invalid packets. asf: prevent packet_size_left from going negative if hdrlen > pktlen. mjpegb: don't return 0 at the end of frame decoding. rtpdec: Identify incorrectly signalled H263 vp8dsp: split long line. aiff: don't skip block_align==0 check on COMM-after-SSND files. dpcm: ignore extra unpaired bytes in stereo streams. mp3on4: require a minimum framesize. mpc7: assign an error level + context to av_log() msg. huffyuv: error out on bit overrun. dct-test: Add the missing ff_ prefix to the altivec functions dct-test: Remove a stray declaration of a nonexistent function movenc: Write the unknown duration as 64 bit fields in ismv movenc: Write track durations with all bits set if duration is unknown Conflicts: libavcodec/dct-test.c libavcodec/wmadec.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/aiffdec.c4
-rw-r--r--libavformat/asfdec.c7
-rw-r--r--libavformat/isom.h24
-rw-r--r--libavformat/mov.c33
-rw-r--r--libavformat/movenc.c64
-rw-r--r--libavformat/rtpdec_formats.h4
-rw-r--r--libavformat/rtpdec_h263.c14
-rw-r--r--libavformat/rtpdec_h263_rfc2190.c24
8 files changed, 122 insertions, 52 deletions
diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c
index fbbf6a41e7..239fca3452 100644
--- a/libavformat/aiffdec.c
+++ b/libavformat/aiffdec.c
@@ -270,12 +270,12 @@ static int aiff_read_header(AVFormatContext *s)
}
}
+got_sound:
if (!st->codec->block_align) {
- av_log(s, AV_LOG_ERROR, "could not find COMM tag\n");
+ av_log(s, AV_LOG_ERROR, "could not find COMM tag or invalid block_align value\n");
return -1;
}
-got_sound:
/* Now positioned, get the sound data start and end */
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
st->start_time = 0;
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index e2f46dc005..b37cbb04d3 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -797,6 +797,13 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
asf->packet_segments = 1;
asf->packet_segsizetype = 0x80;
}
+ if (rsize > packet_length - padsize) {
+ asf->packet_size_left = 0;
+ av_log(s, AV_LOG_ERROR,
+ "invalid packet header length %d for pktlen %d-%d at %"PRId64"\n",
+ rsize, packet_length, padsize, avio_tell(pb));
+ return -1;
+ }
asf->packet_size_left = packet_length - padsize - rsize;
if (packet_length < asf->hdr.min_pktsize)
padsize += asf->hdr.min_pktsize - packet_length;
diff --git a/libavformat/isom.h b/libavformat/isom.h
index 776b265099..32c81b7445 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -162,6 +162,30 @@ void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id);
#define MP4DecSpecificDescrTag 0x05
#define MP4SLDescrTag 0x06
+#define MOV_TFHD_BASE_DATA_OFFSET 0x01
+#define MOV_TFHD_STSD_ID 0x02
+#define MOV_TFHD_DEFAULT_DURATION 0x08
+#define MOV_TFHD_DEFAULT_SIZE 0x10
+#define MOV_TFHD_DEFAULT_FLAGS 0x20
+#define MOV_TFHD_DURATION_IS_EMPTY 0x010000
+
+#define MOV_TRUN_DATA_OFFSET 0x01
+#define MOV_TRUN_FIRST_SAMPLE_FLAGS 0x04
+#define MOV_TRUN_SAMPLE_DURATION 0x100
+#define MOV_TRUN_SAMPLE_SIZE 0x200
+#define MOV_TRUN_SAMPLE_FLAGS 0x400
+#define MOV_TRUN_SAMPLE_CTS 0x800
+
+#define MOV_FRAG_SAMPLE_FLAG_DEGRADATION_PRIORITY_MASK 0x0000ffff
+#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC 0x00010000
+#define MOV_FRAG_SAMPLE_FLAG_PADDING_MASK 0x000e0000
+#define MOV_FRAG_SAMPLE_FLAG_REDUNDANCY_MASK 0x00300000
+#define MOV_FRAG_SAMPLE_FLAG_DEPENDED_MASK 0x00c00000
+#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_MASK 0x03000000
+
+#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO 0x02000000
+#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES 0x01000000
+
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom);
enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 71b96c192f..c6680274d5 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2257,14 +2257,16 @@ static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return AVERROR_INVALIDDATA;
}
- if (flags & 0x01) frag->base_data_offset = avio_rb64(pb);
- else frag->base_data_offset = frag->moof_offset;
- if (flags & 0x02) frag->stsd_id = avio_rb32(pb);
- else frag->stsd_id = trex->stsd_id;
-
- frag->duration = flags & 0x08 ? avio_rb32(pb) : trex->duration;
- frag->size = flags & 0x10 ? avio_rb32(pb) : trex->size;
- frag->flags = flags & 0x20 ? avio_rb32(pb) : trex->flags;
+ frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
+ avio_rb64(pb) : frag->moof_offset;
+ frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
+
+ frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
+ avio_rb32(pb) : trex->duration;
+ frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
+ avio_rb32(pb) : trex->size;
+ frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
+ avio_rb32(pb) : trex->flags;
av_dlog(c->fc, "frag flags 0x%x\n", frag->flags);
return 0;
}
@@ -2353,8 +2355,8 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return AVERROR(ENOMEM);
sc->ctts_data = ctts_data;
- if (flags & 0x001) data_offset = avio_rb32(pb);
- if (flags & 0x004) first_sample_flags = avio_rb32(pb);
+ if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
+ if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
dts = sc->track_end - sc->time_offset;
offset = frag->base_data_offset + data_offset;
distance = 0;
@@ -2365,14 +2367,15 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
unsigned sample_duration = frag->duration;
int keyframe;
- if (flags & 0x100) sample_duration = avio_rb32(pb);
- if (flags & 0x200) sample_size = avio_rb32(pb);
- if (flags & 0x400) sample_flags = avio_rb32(pb);
+ if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
+ if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
+ if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
sc->ctts_data[sc->ctts_count].count = 1;
- sc->ctts_data[sc->ctts_count].duration = (flags & 0x800) ? avio_rb32(pb) : 0;
+ sc->ctts_data[sc->ctts_count].duration = (flags & MOV_TRUN_SAMPLE_CTS) ?
+ avio_rb32(pb) : 0;
sc->ctts_count++;
if ((keyframe = st->codec->codec_type == AVMEDIA_TYPE_AUDIO ||
- (flags & 0x004 && !i && !(sample_flags & 0xffff0000)) || sample_flags & 0x2000000))
+ (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS && !i && !(sample_flags & ~MOV_FRAG_SAMPLE_FLAG_DEGRADATION_PRIORITY_MASK)) || sample_flags & MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO))
distance = 0;
av_add_index_entry(st, offset, dts, sample_size, distance,
keyframe ? AVINDEX_KEYFRAME : 0);
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 72a66db84f..b5e8770353 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1342,6 +1342,9 @@ static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track)
{
int version = track->track_duration < INT32_MAX ? 0 : 1;
+ if (track->mode == MODE_ISM)
+ version = 1;
+
(version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
ffio_wfourcc(pb, "mdhd");
avio_w8(pb, version);
@@ -1354,7 +1357,10 @@ static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track)
avio_wb32(pb, track->time); /* modification time */
}
avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
- (version == 1) ? avio_wb64(pb, track->track_duration) : avio_wb32(pb, track->track_duration); /* duration */
+ if (!track->entry)
+ (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
+ else
+ (version == 1) ? avio_wb64(pb, track->track_duration) : avio_wb32(pb, track->track_duration); /* duration */
avio_wb16(pb, track->language); /* language */
avio_wb16(pb, 0); /* reserved (quality) */
@@ -1385,6 +1391,9 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
track->timescale, AV_ROUND_UP);
int version = duration < INT32_MAX ? 0 : 1;
+ if (track->mode == MODE_ISM)
+ version = 1;
+
(version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
ffio_wfourcc(pb, "tkhd");
avio_w8(pb, version);
@@ -1398,7 +1407,10 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
}
avio_wb32(pb, track->track_id); /* track-id */
avio_wb32(pb, 0); /* reserved */
- (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
+ if (!track->entry)
+ (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
+ else
+ (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
avio_wb32(pb, 0); /* reserved */
avio_wb32(pb, 0); /* reserved */
@@ -2225,19 +2237,19 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track,
int64_t moof_offset)
{
int64_t pos = avio_tell(pb);
- /* default-sample-size + default-sample-duration + base-data-offset */
- uint32_t flags = 0x19;
+ uint32_t flags = MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
+ MOV_TFHD_BASE_DATA_OFFSET;
if (!track->entry) {
- flags |= 0x010000; /* duration-is-empty */
+ flags |= MOV_TFHD_DURATION_IS_EMPTY;
} else {
- flags |= 0x20; /* default-sample-flags-present */
+ flags |= MOV_TFHD_DEFAULT_FLAGS;
}
/* Don't set a default sample size, the silverlight player refuses
* to play files with that set. Don't set a default sample duration,
* WMP freaks out if it is set. */
if (track->mode == MODE_ISM)
- flags &= ~0x18;
+ flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION);
avio_wb32(pb, 0); /* size placeholder */
ffio_wfourcc(pb, "tfhd");
@@ -2245,22 +2257,23 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track,
avio_wb24(pb, flags);
avio_wb32(pb, track->track_id); /* track-id */
- if (flags & 0x01)
+ if (flags & MOV_TFHD_BASE_DATA_OFFSET)
avio_wb64(pb, moof_offset);
- if (flags & 0x08) {
+ if (flags & MOV_TFHD_DEFAULT_DURATION) {
track->default_duration = track->audio_vbr ? track->enc->frame_size : 1;
avio_wb32(pb, track->default_duration);
}
- if (flags & 0x10) {
+ if (flags & MOV_TFHD_DEFAULT_SIZE) {
track->default_size = track->entry ? track->cluster[0].size : 1;
avio_wb32(pb, track->default_size);
} else
track->default_size = -1;
- if (flags & 0x20) {
+ if (flags & MOV_TFHD_DEFAULT_FLAGS) {
track->default_sample_flags =
track->enc->codec_type == AVMEDIA_TYPE_VIDEO ?
- 0x01010000 : 0x02000000;
+ (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC) :
+ MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO;
avio_wb32(pb, track->default_sample_flags);
}
@@ -2269,13 +2282,14 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track,
static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
{
- return entry->flags & MOV_SYNC_SAMPLE ? 0x02000000 : 0x01010000;
+ return entry->flags & MOV_SYNC_SAMPLE ? MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO :
+ (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC);
}
static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
{
int64_t pos = avio_tell(pb);
- uint32_t flags = 1; /* data-offset-present */
+ uint32_t flags = MOV_TRUN_DATA_OFFSET;
int i;
for (i = 0; i < track->entry; i++) {
@@ -2283,16 +2297,16 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
track->track_duration - track->cluster[i].dts + track->start_dts :
track->cluster[i + 1].dts - track->cluster[i].dts;
if (duration != track->default_duration)
- flags |= 0x100; /* sample-duration-present */
+ flags |= MOV_TRUN_SAMPLE_DURATION;
if (track->cluster[i].size != track->default_size)
- flags |= 0x200; /* sample-size-present */
+ flags |= MOV_TRUN_SAMPLE_SIZE;
if (i > 0 && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
- flags |= 0x400; /* sample-flags-present */
+ flags |= MOV_TRUN_SAMPLE_FLAGS;
}
- if (!(flags & 0x400))
- flags |= 0x4; /* first-sample-flags-present */
+ if (!(flags & MOV_TRUN_SAMPLE_FLAGS))
+ flags |= MOV_TRUN_FIRST_SAMPLE_FLAGS;
if (track->flags & MOV_TRACK_CTTS)
- flags |= 0x800; /* sample-composition-time-offsets-present */
+ flags |= MOV_TRUN_SAMPLE_CTS;
avio_wb32(pb, 0); /* size placeholder */
ffio_wfourcc(pb, "trun");
@@ -2302,20 +2316,20 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
avio_wb32(pb, track->entry); /* sample count */
track->moof_size_offset = avio_tell(pb);
avio_wb32(pb, 0); /* data offset */
- if (flags & 0x4) /* first sample flags */
+ if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS)
avio_wb32(pb, get_sample_flags(track, &track->cluster[0]));
for (i = 0; i < track->entry; i++) {
int64_t duration = i + 1 == track->entry ?
track->track_duration - track->cluster[i].dts + track->start_dts :
track->cluster[i + 1].dts - track->cluster[i].dts;
- if (flags & 0x100)
+ if (flags & MOV_TRUN_SAMPLE_DURATION)
avio_wb32(pb, duration);
- if (flags & 0x200)
+ if (flags & MOV_TRUN_SAMPLE_SIZE)
avio_wb32(pb, track->cluster[i].size);
- if (flags & 0x400)
+ if (flags & MOV_TRUN_SAMPLE_FLAGS)
avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
- if (flags & 0x800)
+ if (flags & MOV_TRUN_SAMPLE_CTS)
avio_wb32(pb, track->cluster[i].cts);
}
diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h
index 41d9590016..73ffe1f49e 100644
--- a/libavformat/rtpdec_formats.h
+++ b/libavformat/rtpdec_formats.h
@@ -31,6 +31,10 @@
*/
int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p);
+int ff_h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
+ AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+ const uint8_t *buf, int len, int flags);
+
extern RTPDynamicProtocolHandler ff_amr_nb_dynamic_handler;
extern RTPDynamicProtocolHandler ff_amr_wb_dynamic_handler;
extern RTPDynamicProtocolHandler ff_g726_16_dynamic_handler;
diff --git a/libavformat/rtpdec_h263.c b/libavformat/rtpdec_h263.c
index 27173f013b..6c22a24715 100644
--- a/libavformat/rtpdec_h263.c
+++ b/libavformat/rtpdec_h263.c
@@ -23,13 +23,9 @@
#include "rtpdec_formats.h"
#include "libavutil/intreadwrite.h"
-static int h263_handle_packet(AVFormatContext *ctx,
- PayloadContext *data,
- AVStream *st,
- AVPacket * pkt,
- uint32_t * timestamp,
- const uint8_t * buf,
- int len, int flags)
+int ff_h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
+ AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+ const uint8_t *buf, int len, int flags)
{
uint8_t *ptr;
uint16_t header;
@@ -96,12 +92,12 @@ RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler = {
.enc_name = "H263-1998",
.codec_type = AVMEDIA_TYPE_VIDEO,
.codec_id = CODEC_ID_H263,
- .parse_packet = h263_handle_packet,
+ .parse_packet = ff_h263_handle_packet,
};
RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler = {
.enc_name = "H263-2000",
.codec_type = AVMEDIA_TYPE_VIDEO,
.codec_id = CODEC_ID_H263,
- .parse_packet = h263_handle_packet,
+ .parse_packet = ff_h263_handle_packet,
};
diff --git a/libavformat/rtpdec_h263_rfc2190.c b/libavformat/rtpdec_h263_rfc2190.c
index baec6a427c..a3a4825719 100644
--- a/libavformat/rtpdec_h263_rfc2190.c
+++ b/libavformat/rtpdec_h263_rfc2190.c
@@ -35,6 +35,7 @@ struct PayloadContext {
uint8_t endbyte;
int endbyte_bits;
uint32_t timestamp;
+ int newformat;
};
static PayloadContext *h263_new_context(void)
@@ -58,9 +59,14 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
AVStream *st, AVPacket *pkt, uint32_t *timestamp,
const uint8_t *buf, int len, int flags)
{
- int f, p, i, sbit, ebit; /* Corresponding to header fields in the RFC */
+ /* Corresponding to header fields in the RFC */
+ int f, p, i, sbit, ebit, src, r;
int header_size;
+ if (data->newformat)
+ return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf, len,
+ flags);
+
if (data->buf && data->timestamp != *timestamp) {
/* Dropping old buffered, unfinished data */
uint8_t *p;
@@ -80,6 +86,7 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
/* Mode A */
header_size = 4;
i = buf[1] & 0x10;
+ r = ((buf[1] & 0x01) << 3) | ((buf[2] & 0xe0) >> 5);
} else if (!p) {
/* Mode B */
header_size = 8;
@@ -89,6 +96,7 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
len, header_size);
return AVERROR_INVALIDDATA;
}
+ r = buf[3] & 0x03;
i = buf[4] & 0x80;
} else {
/* Mode C */
@@ -99,10 +107,24 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
len, header_size);
return AVERROR_INVALIDDATA;
}
+ r = buf[3] & 0x03;
i = buf[4] & 0x80;
}
sbit = (buf[0] >> 3) & 0x7;
ebit = buf[0] & 0x7;
+ src = (buf[1] & 0xe0) >> 5;
+ if (!(buf[0] & 0xf8)) { /* Reserved bits in RFC 2429/4629 are zero */
+ if ((src == 0 || src >= 6) && r) {
+ /* Invalid src for this format, and bits that should be zero
+ * according to RFC 2190 aren't zero. */
+ av_log(ctx, AV_LOG_WARNING,
+ "Interpreting H263 RTP data as RFC 2429/4629 even though "
+ "signalled with a static payload type.\n");
+ data->newformat = 1;
+ return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf,
+ len, flags);
+ }
+ }
buf += header_size;
len -= header_size;