aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-08-02 22:07:51 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-08-02 22:12:18 +0200
commit1d186e9e120d777cc9f5e68d2974d48bfbdd528e (patch)
tree571e05f6a9ba06c10729f67ccd29353c2b31aa19 /libavformat
parent03cbe6c8bc42626107e75b001180b81781619ed7 (diff)
parent62ee0e6a977e1990c9853630c7dea1415b38bb28 (diff)
downloadffmpeg-1d186e9e120d777cc9f5e68d2974d48bfbdd528e.tar.gz
Merge remote-tracking branch 'qatar/master'
* qatar/master: Revert "swscale: use 15-bit intermediates for 9/10-bit scaling." swscale: use 15-bit intermediates for 9/10-bit scaling. dct32: Add SSE2 ASM optimizations Correct chroma vector calculation for RealVideo 3. lavf: Add an option to discard corrupted frames mpegts: Mark wrongly-sized packets as corrupted mpegts: Move scan test to handle_packets mpegts: Mark corrupted packets mpegts: Reset continuity counter on seek mpegts: Fix for continuity counter mpegts: Silence "can't seek" warning on unseekable apichange: add an entry for AV_PKT_FLAG_CORRUPT avpacket: signal possibly corrupted packets mpeg4videodec: remove dead code that would have detected erroneous encoding aac: Remove some suspicious illegal memcpy()s from LTP. bink: Eliminate unnecessary shadow declaration. Conflicts: doc/APIchanges libavcodec/version.h libavformat/avformat.h libavformat/options.c libavformat/utils.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/avformat.h1
-rw-r--r--libavformat/mpegts.c86
-rw-r--r--libavformat/options.c1
-rw-r--r--libavformat/utils.c9
4 files changed, 68 insertions, 29 deletions
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 029479152a..59a4240bd3 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -774,6 +774,7 @@ typedef struct AVFormatContext {
#define AVFMT_FLAG_RTP_HINT 0x0040 ///< Deprecated, use the -movflags rtphint muxer specific AVOption instead
#endif
#define AVFMT_FLAG_CUSTOM_IO 0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
+#define AVFMT_FLAG_DISCARD_CORRUPT 0x0100 ///< Discard frames marked corrupted
#define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Enable RTP MP4A-LATM payload
#define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down)
#define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted)
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 630a42ab00..5daffbb521 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -164,6 +164,7 @@ typedef struct PESContext {
enum MpegTSState state;
/* used to get the format */
int data_index;
+ int flags; /**< copied to the AVPacket flags */
int total_size;
int pes_header_size;
int extended_stream_id;
@@ -636,6 +637,12 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
pkt->destruct = av_destruct_packet;
pkt->data = pes->buffer;
pkt->size = pes->data_index;
+
+ if(pes->total_size != MAX_PES_PAYLOAD &&
+ pes->pes_header_size + pes->data_index != pes->total_size + 6) {
+ av_log(pes->ts, AV_LOG_WARNING, "PES packet size mismatch\n");
+ pes->flags |= AV_PKT_FLAG_CORRUPT;
+ }
memset(pkt->data+pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
// Separate out the AC3 substream from an HDMV combined TrueHD/AC3 PID
@@ -647,12 +654,14 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
pkt->dts = pes->dts;
/* store position of first TS packet of this PES packet */
pkt->pos = pes->ts_packet_pos;
+ pkt->flags = pes->flags;
/* reset pts values */
pes->pts = AV_NOPTS_VALUE;
pes->dts = AV_NOPTS_VALUE;
pes->buffer = NULL;
pes->data_index = 0;
+ pes->flags = 0;
}
/* return non zero if a packet could be constructed */
@@ -1269,7 +1278,8 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
{
AVFormatContext *s = ts->stream;
MpegTSFilter *tss;
- int len, pid, cc, expected_cc, cc_ok, afc, is_start;
+ int len, pid, cc, expected_cc, cc_ok, afc, is_start, is_discontinuity,
+ has_adaptation, has_payload;
const uint8_t *p, *p_end;
int64_t pos;
@@ -1285,20 +1295,36 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
if (!tss)
return 0;
+ afc = (packet[3] >> 4) & 3;
+ if (afc == 0) /* reserved value */
+ return 0;
+ has_adaptation = afc & 2;
+ has_payload = afc & 1;
+ is_discontinuity = has_adaptation
+ && packet[4] != 0 /* with length > 0 */
+ && (packet[5] & 0x80); /* and discontinuity indicated */
+
/* continuity check (currently not used) */
cc = (packet[3] & 0xf);
- expected_cc = (packet[3] & 0x10) ? (tss->last_cc + 1) & 0x0f : tss->last_cc;
- cc_ok = (tss->last_cc < 0) || (expected_cc == cc);
+ expected_cc = has_payload ? (tss->last_cc + 1) & 0x0f : tss->last_cc;
+ cc_ok = pid == 0x1FFF // null packet PID
+ || is_discontinuity
+ || tss->last_cc < 0
+ || expected_cc == cc;
+
tss->last_cc = cc;
+ if (!cc_ok) {
+ av_log(ts, AV_LOG_WARNING, "Continuity Check Failed\n");
+ if(tss->type == MPEGTS_PES) {
+ PESContext *pc = tss->u.pes_filter.opaque;
+ pc->flags |= AV_PKT_FLAG_CORRUPT;
+ }
+ }
- /* skip adaptation field */
- afc = (packet[3] >> 4) & 3;
- p = packet + 4;
- if (afc == 0) /* reserved value */
+ if (!has_payload)
return 0;
- if (afc == 2) /* adaptation field only */
- return 0;
- if (afc == 3) {
+ p = packet + 4;
+ if (has_adaptation) {
/* skip adapation field */
p += p[0] + 1;
}
@@ -1399,7 +1425,22 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
{
AVFormatContext *s = ts->stream;
uint8_t packet[TS_PACKET_SIZE];
- int packet_num, ret;
+ int packet_num, ret = 0;
+
+ if (avio_tell(s->pb) != ts->last_pos) {
+ int i;
+// av_dlog("Skipping after seek\n");
+ /* seek detected, flush pes buffer */
+ for (i = 0; i < NB_PID_MAX; i++) {
+ if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) {
+ PESContext *pes = ts->pids[i]->u.pes_filter.opaque;
+ av_freep(&pes->buffer);
+ ts->pids[i]->last_cc = -1;
+ pes->data_index = 0;
+ pes->state = MPEGTS_SKIP; /* skip until pes header */
+ }
+ }
+ }
ts->stop_parse = 0;
packet_num = 0;
@@ -1411,12 +1452,13 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
break;
ret = read_packet(s, packet, ts->raw_packet_size);
if (ret != 0)
- return ret;
+ break;
ret = handle_packet(ts, packet);
if (ret != 0)
- return ret;
+ break;
}
- return 0;
+ ts->last_pos = avio_tell(s->pb);
+ return ret;
}
static int mpegts_probe(AVProbeData *p)
@@ -1511,7 +1553,7 @@ static int mpegts_read_header(AVFormatContext *s,
/* normal demux */
/* first do a scaning to get all the services */
- if (avio_seek(pb, pos, SEEK_SET) < 0)
+ if (pb->seekable && avio_seek(pb, pos, SEEK_SET) < 0)
av_log(s, AV_LOG_ERROR, "Unable to seek back to the start\n");
mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);
@@ -1632,18 +1674,6 @@ static int mpegts_read_packet(AVFormatContext *s,
MpegTSContext *ts = s->priv_data;
int ret, i;
- if (avio_tell(s->pb) != ts->last_pos) {
- /* seek detected, flush pes buffer */
- for (i = 0; i < NB_PID_MAX; i++) {
- if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) {
- PESContext *pes = ts->pids[i]->u.pes_filter.opaque;
- av_freep(&pes->buffer);
- pes->data_index = 0;
- pes->state = MPEGTS_SKIP; /* skip until pes header */
- }
- }
- }
-
ts->pkt = pkt;
ret = handle_packets(ts, 0);
if (ret < 0) {
@@ -1661,8 +1691,6 @@ static int mpegts_read_packet(AVFormatContext *s,
}
}
- ts->last_pos = avio_tell(s->pb);
-
return ret;
}
diff --git a/libavformat/options.c b/libavformat/options.c
index e09fc97a25..fda325c7c7 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -79,6 +79,7 @@ static const AVOption options[]={
#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
+{"discardcorrupt", "discard corrupted frames", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_DISCARD_CORRUPT }, INT_MIN, INT_MAX, D, "fflags"},
{"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"},
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 81577c9158..aa1220dbbc 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -738,8 +738,17 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
continue;
}
+ if ((s->flags & AVFMT_FLAG_DISCARD_CORRUPT) &&
+ (pkt->flags & AV_PKT_FLAG_CORRUPT)) {
+ av_log(s, AV_LOG_WARNING,
+ "Dropped corrupted packet (stream = %d)\n",
+ pkt->stream_index);
+ continue;
+ }
+
if(!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA))
av_packet_merge_side_data(pkt);
+
st= s->streams[pkt->stream_index];
switch(st->codec->codec_type){