diff --git a/doc/APIchanges b/doc/APIchanges index 94a598798d..eba7f8416b 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-08-02 - 9d39cbf - lavc 53.7.1 + Add AV_PKT_FLAG_CORRUPT AVPacket flag. + 2011-07-16 - xxxxxx - lavfi 2.27.0 Add audio packing negotiation fields and helper functions. diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index 7fce228193..927d4314fa 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -1791,12 +1791,10 @@ static void windowing_and_mdct_ltp(AACContext *ac, float *out, } else { memset(in, 0, 448 * sizeof(float)); ac->dsp.vector_fmul(in + 448, in + 448, swindow_prev, 128); - memcpy(in + 576, in + 576, 448 * sizeof(float)); } if (ics->window_sequence[0] != LONG_START_SEQUENCE) { ac->dsp.vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024); } else { - memcpy(in + 1024, in + 1024, 448 * sizeof(float)); ac->dsp.vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128); memset(in + 1024 + 576, 0, 448 * sizeof(float)); } diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 0bb86690bc..2a438ccc13 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -800,6 +800,9 @@ typedef struct AVPacket { uint8_t *data; int size; int stream_index; + /** + * A combination of AV_PKT_FLAG values + */ int flags; /** * Additional packet data that can be provided by the container. @@ -840,7 +843,8 @@ typedef struct AVPacket { */ int64_t convergence_duration; } AVPacket; -#define AV_PKT_FLAG_KEY 0x0001 +#define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe +#define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted /** * Audio Video Frame. diff --git a/libavcodec/bink.c b/libavcodec/bink.c index 6b58f7716b..e137312693 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -624,7 +624,6 @@ static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t * coef_list[--list_start] = ccoef; mode_list[ list_start] = 3; } else { - int t; if (!bits) { t = 1 - (get_bits1(gb) << 1); } else { diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index 2be01041fe..ee9dd7db6b 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -737,8 +737,8 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type, my = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24); lx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) % 3; ly = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) % 3; - chroma_mx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + 1) >> 1; - chroma_my = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + 1) >> 1; + chroma_mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2; + chroma_my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2; umx = (chroma_mx + (3 << 24)) / 3 - (1 << 24); umy = (chroma_my + (3 << 24)) / 3 - (1 << 24); uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3]; diff --git a/libavcodec/version.h b/libavcodec/version.h index 69040a5195..b19e8946d8 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -22,7 +22,7 @@ #define LIBAVCODEC_VERSION_MAJOR 53 #define LIBAVCODEC_VERSION_MINOR 9 -#define LIBAVCODEC_VERSION_MICRO 0 +#define LIBAVCODEC_VERSION_MICRO 1 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavcodec/x86/dct32_sse.asm b/libavcodec/x86/dct32_sse.asm index 7f5f815591..9a2a6ea88c 100644 --- a/libavcodec/x86/dct32_sse.asm +++ b/libavcodec/x86/dct32_sse.asm @@ -63,6 +63,13 @@ ps_p1p1m1m1: dd 0, 0, 0x80000000, 0x80000000, 0, 0, 0x80000000, 0x80000000 mulps %1, %3 %endmacro +%macro BUTTERFLY0_SSE2 5 + pshufd %4, %1, %5 + xorps %1, %2 + addps %1, %4 + mulps %1, %3 +%endmacro + %macro BUTTERFLY0_AVX 5 vshufps %4, %1, %1, %5 vxorps %1, %1, %2 @@ -405,18 +412,17 @@ INIT_XMM INIT_XMM +%macro DCT32_FUNC 1 ; void ff_dct32_float_sse(FFTSample *out, const FFTSample *in) -cglobal dct32_float_sse, 2,3,16, out, in, tmp +cglobal dct32_float_%1, 2,3,16, out, in, tmp ; pass 1 movaps m0, [inq+0] - movaps m1, [inq+112] - shufps m1, m1, 0x1b + LOAD_INV m1, [inq+112] BUTTERFLY m0, m1, [ps_cos_vec], m3 movaps m7, [inq+64] - movaps m4, [inq+48] - shufps m4, m4, 0x1b + LOAD_INV m4, [inq+48] BUTTERFLY m7, m4, [ps_cos_vec+32], m3 ; pass 2 @@ -427,13 +433,11 @@ cglobal dct32_float_sse, 2,3,16, out, in, tmp ; pass 1 movaps m1, [inq+16] - movaps m6, [inq+96] - shufps m6, m6, 0x1b + LOAD_INV m6, [inq+96] BUTTERFLY m1, m6, [ps_cos_vec+16], m3 movaps m4, [inq+80] - movaps m5, [inq+32] - shufps m5, m5, 0x1b + LOAD_INV m5, [inq+32] BUTTERFLY m4, m5, [ps_cos_vec+48], m3 ; pass 2 @@ -492,3 +496,20 @@ cglobal dct32_float_sse, 2,3,16, out, in, tmp PASS5 PASS6 RET +%endmacro + +%macro LOAD_INV_SSE 2 + movaps %1, %2 + shufps %1, %1, 0x1b +%endmacro + +%define LOAD_INV LOAD_INV_SSE +DCT32_FUNC sse + +%macro LOAD_INV_SSE2 2 + pshufd %1, %2, 0x1b +%endmacro + +%define LOAD_INV LOAD_INV_SSE2 +%define BUTTERFLY0 BUTTERFLY0_SSE2 +DCT32_FUNC sse2 diff --git a/libavcodec/x86/fft.c b/libavcodec/x86/fft.c index 18964d88ca..d2d157c2d3 100644 --- a/libavcodec/x86/fft.c +++ b/libavcodec/x86/fft.c @@ -60,6 +60,8 @@ av_cold void ff_dct_init_mmx(DCTContext *s) int has_vectors = av_get_cpu_flags(); if (has_vectors & AV_CPU_FLAG_AVX && HAVE_AVX) s->dct32 = ff_dct32_float_avx; + else if (has_vectors & AV_CPU_FLAG_SSE2 && HAVE_SSE) + s->dct32 = ff_dct32_float_sse2; else if (has_vectors & AV_CPU_FLAG_SSE && HAVE_SSE) s->dct32 = ff_dct32_float_sse; #endif diff --git a/libavcodec/x86/fft.h b/libavcodec/x86/fft.h index 79064c27cd..7fdc858a50 100644 --- a/libavcodec/x86/fft.h +++ b/libavcodec/x86/fft.h @@ -35,6 +35,7 @@ void ff_imdct_calc_sse(FFTContext *s, FFTSample *output, const FFTSample *input) void ff_imdct_half_sse(FFTContext *s, FFTSample *output, const FFTSample *input); void ff_imdct_half_avx(FFTContext *s, FFTSample *output, const FFTSample *input); void ff_dct32_float_sse(FFTSample *out, const FFTSample *in); +void ff_dct32_float_sse2(FFTSample *out, const FFTSample *in); void ff_dct32_float_avx(FFTSample *out, const FFTSample *in); #endif /* AVCODEC_X86_FFT_H */ 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){ diff --git a/tests/ref/fate/rv30 b/tests/ref/fate/rv30 index 5b43588bb4..6c99871eb6 100644 --- a/tests/ref/fate/rv30 +++ b/tests/ref/fate/rv30 @@ -16,31 +16,31 @@ 0, 112500, 126720, 0xe572dfc9 0, 120000, 126720, 0xbc3cc34f 0, 127500, 126720, 0xcf8cb0e2 -0, 135000, 126720, 0x6d1c630d -0, 142500, 126720, 0x4338e469 -0, 150000, 126720, 0x9d82ea38 -0, 157500, 126720, 0x55e0b559 -0, 165000, 126720, 0x5eefb5ef -0, 172500, 126720, 0x4b10b746 -0, 180000, 126720, 0x8b07a1db -0, 187500, 126720, 0x8c639b34 -0, 195000, 126720, 0x63eb0b9f -0, 202500, 126720, 0x31c80c83 -0, 210000, 126720, 0x78495352 -0, 217500, 126720, 0x63d609c4 -0, 225000, 126720, 0xcd2a62d8 -0, 232500, 126720, 0x4aea732d -0, 240000, 126720, 0xe3bb352c -0, 247500, 126720, 0x4b9036ad -0, 255000, 126720, 0x88b66e2d -0, 262500, 126720, 0x4a8a1b16 -0, 270000, 126720, 0x2e014eac -0, 277500, 126720, 0x83212c67 -0, 285000, 126720, 0x4937e897 -0, 292500, 126720, 0x2d38babe -0, 300000, 126720, 0xbcb43c09 -0, 307500, 126720, 0x955ffaf4 -0, 315000, 126720, 0x3337d4a2 -0, 322500, 126720, 0xe8f58c33 -0, 330000, 126720, 0x3a7f771f -0, 337500, 126720, 0xb67c39b9 +0, 135000, 126720, 0x75ae61b6 +0, 142500, 126720, 0x554fe3e4 +0, 150000, 126720, 0x72ecea95 +0, 157500, 126720, 0x5d00b5fe +0, 165000, 126720, 0xe39bba0d +0, 172500, 126720, 0x9c21bad8 +0, 180000, 126720, 0x72f2a47d +0, 187500, 126720, 0x4f639ebe +0, 195000, 126720, 0x534a10cc +0, 202500, 126720, 0xfdca11d3 +0, 210000, 126720, 0x0c735615 +0, 217500, 126720, 0x0eaf0c1b +0, 225000, 126720, 0xce5e6794 +0, 232500, 126720, 0x14cf7974 +0, 240000, 126720, 0xbc513f2a +0, 247500, 126720, 0xbc303fae +0, 255000, 126720, 0xd9f67585 +0, 262500, 126720, 0x3378251f +0, 270000, 126720, 0xb3ed5911 +0, 277500, 126720, 0xc15a3577 +0, 285000, 126720, 0x0a24f256 +0, 292500, 126720, 0xfab9c45d +0, 300000, 126720, 0x45464610 +0, 307500, 126720, 0xfe2e057d +0, 315000, 126720, 0x23efdc35 +0, 322500, 126720, 0x4d888b2e +0, 330000, 126720, 0xdd0d74df +0, 337500, 126720, 0x08382b8e