diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-01-06 05:45:12 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-01-06 05:45:12 +0400 |
commit | 3edff185abfdd089b88ecc5770e5f6a963055a97 (patch) | |
tree | 62407714d095f71c370e07c78c2c019ab01ff324 | |
parent | ee4d43ef7a89626de8eaf02bec5a7ca44d96edbf (diff) | |
parent | f5be84cfbc9c132a867ae8a8c0e0de26ed1a4e88 (diff) |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (21 commits)
ipmovie: do not read audio packets before the codec is known
truemotion2: check size before GetBitContext initialisation
avio: Only do implicit network initialization for network protocols
avio: Add an URLProtocol flag for indicating that a protocol uses network
adpcm: ADPCM Electronic Arts has always two channels
matroskadec: Fix a bug where a pointer was cached to an array that might later move due to a realloc()
fate: Add missing reference file from 9b4767e4.
mov: Support MOV_CH_LAYOUT_USE_DESCRIPTIONS for labeled descriptions.
4xm: Prevent buffer overreads.
mjpegdec: parse RSTn to prevent skipping other data in mjpeg_decode_scan
vp3: add fate test for non-zero last coefficient
vp3: fix streams with non-zero last coefficient
swscale: remove unused U/V arguments from yuv2rgb_write().
timer: K&R formatting cosmetics
lavf: cosmetics, reformat av_read_frame().
lavf: refactor av_read_frame() to make it easier to understand.
Report an error if pitch_lag is zero in AMR-NB decoder.
Revert "4xm: Prevent buffer overreads."
4xm: Prevent buffer overreads.
4xm: pass the correct remaining buffer size to decode_i2_frame().
...
Conflicts:
libavcodec/4xm.c
libavcodec/mjpegdec.c
libavcodec/truemotion2.c
libavformat/ipmovie.c
libavformat/mov_chan.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/4xm.c | 18 | ||||
-rw-r--r-- | libavcodec/adpcm.c | 6 | ||||
-rw-r--r-- | libavcodec/amrnbdec.c | 4 | ||||
-rw-r--r-- | libavcodec/mjpegdec.c | 27 | ||||
-rw-r--r-- | libavcodec/truemotion2.c | 6 | ||||
-rw-r--r-- | libavcodec/vp3.c | 2 | ||||
-rw-r--r-- | libavformat/avio.c | 8 | ||||
-rw-r--r-- | libavformat/avio.h | 1 | ||||
-rw-r--r-- | libavformat/gopher.c | 1 | ||||
-rw-r--r-- | libavformat/http.c | 3 | ||||
-rw-r--r-- | libavformat/ipmovie.c | 5 | ||||
-rw-r--r-- | libavformat/librtmp.c | 5 | ||||
-rw-r--r-- | libavformat/mmsh.c | 1 | ||||
-rw-r--r-- | libavformat/mmst.c | 1 | ||||
-rw-r--r-- | libavformat/mov.c | 22 | ||||
-rw-r--r-- | libavformat/mov_chan.c | 16 | ||||
-rw-r--r-- | libavformat/mov_chan.h | 8 | ||||
-rw-r--r-- | libavformat/rtmpproto.c | 1 | ||||
-rw-r--r-- | libavformat/rtpproto.c | 1 | ||||
-rw-r--r-- | libavformat/tcp.c | 1 | ||||
-rw-r--r-- | libavformat/tls.c | 1 | ||||
-rw-r--r-- | libavformat/udp.c | 1 | ||||
-rw-r--r-- | libavformat/url.h | 1 | ||||
-rw-r--r-- | libavformat/utils.c | 81 | ||||
-rw-r--r-- | libavutil/timer.h | 44 | ||||
-rw-r--r-- | libswscale/swscale.c | 18 | ||||
-rw-r--r-- | tests/fate/vpx.mak | 3 | ||||
-rw-r--r-- | tests/ref/fate/vp3-coeff-level64 | 8 |
28 files changed, 201 insertions, 93 deletions
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index e57ce90df6..d665436844 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -643,9 +643,17 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ int x, y, x2, y2; const int width= f->avctx->width; const int height= f->avctx->height; + const int mbs = (FFALIGN(width, 16) >> 4) * (FFALIGN(height, 16) >> 4); uint16_t *dst= (uint16_t*)f->current_picture.data[0]; const int stride= f->current_picture.linesize[0]>>1; const uint8_t *buf_end = buf + length; + GetByteContext g3; + + if(length < mbs * 8) { + av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n"); + return AVERROR_INVALIDDATA; + } + bytestream2_init(&g3, buf, length); for(y=0; y<height; y+=16){ for(x=0; x<width; x+=16){ @@ -654,8 +662,8 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ return -1; memset(color, 0, sizeof(color)); //warning following is purely guessed ... - color[0]= bytestream_get_le16(&buf); - color[1]= bytestream_get_le16(&buf); + color[0]= bytestream2_get_le16u(&g3); + color[1]= bytestream2_get_le16u(&g3); if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n"); if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n"); @@ -663,7 +671,7 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ color[2]= mix(color[0], color[1]); color[3]= mix(color[1], color[0]); - bits= bytestream_get_le32(&buf); + bits= bytestream2_get_le32u(&g3); for(y2=0; y2<16; y2++){ for(x2=0; x2<16; x2++){ int index= 2*(x2>>2) + 8*(y2>>2); @@ -672,7 +680,7 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ } dst+=16; } - dst += 16*stride - width; + dst += 16 * stride - x; } return 0; @@ -823,7 +831,7 @@ static int decode_frame(AVCodecContext *avctx, if(frame_4cc == AV_RL32("ifr2")){ p->pict_type= AV_PICTURE_TYPE_I; - if(decode_i2_frame(f, buf-4, frame_size+4) < 0){ + if(decode_i2_frame(f, buf-4, frame_size + 4) < 0) { av_log(f->avctx, AV_LOG_ERROR, "decode i2 frame failed\n"); return -1; } diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 688fba430c..c176b5e03d 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -91,9 +91,13 @@ typedef struct ADPCMDecodeContext { static av_cold int adpcm_decode_init(AVCodecContext * avctx) { ADPCMDecodeContext *c = avctx->priv_data; + unsigned int min_channels = 1; unsigned int max_channels = 2; switch(avctx->codec->id) { + case CODEC_ID_ADPCM_EA: + min_channels = 2; + break; case CODEC_ID_ADPCM_EA_R1: case CODEC_ID_ADPCM_EA_R2: case CODEC_ID_ADPCM_EA_R3: @@ -101,7 +105,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) max_channels = 6; break; } - if (avctx->channels <= 0 || avctx->channels > max_channels) { + if (avctx->channels < min_channels || avctx->channels > max_channels) { av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); return AVERROR(EINVAL); } diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c index 57c8ae9ae5..c560d69e88 100644 --- a/libavcodec/amrnbdec.c +++ b/libavcodec/amrnbdec.c @@ -978,6 +978,10 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, pitch_sharpening(p, subframe, p->cur_frame_mode, &fixed_sparse); + if (fixed_sparse.pitch_lag == 0) { + av_log(avctx, AV_LOG_ERROR, "The file is corrupted, pitch_lag = 0 is not allowed\n"); + return AVERROR_INVALIDDATA; + } ff_set_fixed_vector(p->fixed_vector, &fixed_sparse, 1.0, AMR_SUBFRAME_SIZE); diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index b1c3aeda6d..7c27f5d987 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -985,18 +985,21 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, i } } - if (s->restart_interval) --s->restart_count; - i= 8+((-get_bits_count(&s->gb))&7); - if (s->restart_interval && show_bits(&s->gb, i) == (1<<i)-1){ /* skip RSTn */ - int pos= get_bits_count(&s->gb); - align_get_bits(&s->gb); - while(get_bits_count(&s->gb) < s->gb.size_in_bits && show_bits(&s->gb, 8) == 0xFF) - skip_bits(&s->gb, 8); - if(get_bits_count(&s->gb) < s->gb.size_in_bits && (get_bits(&s->gb, 8)&0xF8) == 0xD0){ - for (i=0; i<nb_components; i++) /* reset dc */ - s->last_dc[i] = 1024; - }else{ - skip_bits_long(&s->gb, pos - get_bits_count(&s->gb)); + if (s->restart_interval) { + s->restart_count--; + i = 8 + ((-get_bits_count(&s->gb)) & 7); + /* skip RSTn */ + if (show_bits(&s->gb, i) == (1 << i) - 1) { + int pos = get_bits_count(&s->gb); + align_get_bits(&s->gb); + while (get_bits_left(&s->gb) >= 8 && show_bits(&s->gb, 8) == 0xFF) + skip_bits(&s->gb, 8); + if (get_bits_left(&s->gb) >= 8 && (get_bits(&s->gb, 8) & 0xF8) == 0xD0) { + for (i = 0; i < nb_components; i++) /* reset dc */ + s->last_dc[i] = 1024; + } else { + skip_bits_long(&s->gb, pos - get_bits_count(&s->gb)); + } } } } diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index 95487d9436..567383499a 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -272,6 +272,8 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i len = AV_RB32(buf); buf += 4; cur += 4; } if(len > 0) { + if (skip <= cur) + return -1; init_get_bits(&ctx->gb, buf, (skip - cur) * 8); if(tm2_read_deltas(ctx, stream_id) == -1) return -1; @@ -286,7 +288,7 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i buf += 4; cur += 4; buf += 4; cur += 4; /* unused by decoder */ - if(skip < cur) + if (skip <= cur) return -1; init_get_bits(&ctx->gb, buf, (skip - cur) * 8); if(tm2_build_huff_table(ctx, &codes) == -1) @@ -305,6 +307,8 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i ctx->tok_lens[stream_id] = toks; len = AV_RB32(buf); buf += 4; cur += 4; if(len > 0) { + if (skip <= cur) + return -1; init_get_bits(&ctx->gb, buf, (skip - cur) * 8); for(i = 0; i < toks; i++) { if (get_bits_left(&ctx->gb) <= 0) { diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 80e71303fa..738ae9fd25 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -1378,6 +1378,8 @@ static inline int vp3_dequant(Vp3DecodeContext *s, Vp3Fragment *frag, return i; } } while (i < 64); + // return value is expected to be a valid level + i--; end: // the actual DC+prediction is in the fragment structure block[0] = frag->dc * s->qmat[0][inter][plane][0]; diff --git a/libavformat/avio.c b/libavformat/avio.c index 67005e3eca..418a8a79fc 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -127,7 +127,7 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, int err; #if CONFIG_NETWORK - if (!ff_network_init()) + if (up->flags & URL_PROTOCOL_FLAG_NETWORK && !ff_network_init()) return AVERROR(EIO); #endif uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1); @@ -181,7 +181,8 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, fail: *puc = NULL; #if CONFIG_NETWORK - ff_network_close(); + if (up->flags & URL_PROTOCOL_FLAG_NETWORK) + ff_network_close(); #endif return err; } @@ -409,7 +410,8 @@ int ffurl_close(URLContext *h) if (h->is_connected && h->prot->url_close) ret = h->prot->url_close(h); #if CONFIG_NETWORK - ff_network_close(); + if (h->prot->flags & URL_PROTOCOL_FLAG_NETWORK) + ff_network_close(); #endif if (h->prot->priv_data_size) { if (h->prot->priv_data_class) diff --git a/libavformat/avio.h b/libavformat/avio.h index 16216819f4..9570f0051d 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -152,6 +152,7 @@ typedef struct URLContext { } URLContext; #define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the first part of a nested protocol scheme */ +#define URL_PROTOCOL_FLAG_NETWORK 2 /*< The protocol uses network */ /** * @deprecated This struct is to be made private. Use the higher-level diff --git a/libavformat/gopher.c b/libavformat/gopher.c index e1acf5039c..9dc155ad11 100644 --- a/libavformat/gopher.c +++ b/libavformat/gopher.c @@ -121,4 +121,5 @@ URLProtocol ff_gopher_protocol = { .url_write = gopher_write, .url_close = gopher_close, .priv_data_size = sizeof(GopherContext), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; diff --git a/libavformat/http.c b/libavformat/http.c index 5d19c6e007..8922a74441 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -569,6 +569,7 @@ URLProtocol ff_http_protocol = { .url_get_file_handle = http_get_file_handle, .priv_data_size = sizeof(HTTPContext), .priv_data_class = &http_context_class, + .flags = URL_PROTOCOL_FLAG_NETWORK, }; #endif #if CONFIG_HTTPS_PROTOCOL @@ -582,6 +583,7 @@ URLProtocol ff_https_protocol = { .url_get_file_handle = http_get_file_handle, .priv_data_size = sizeof(HTTPContext), .priv_data_class = &https_context_class, + .flags = URL_PROTOCOL_FLAG_NETWORK, }; #endif @@ -697,5 +699,6 @@ URLProtocol ff_httpproxy_protocol = { .url_close = http_proxy_close, .url_get_file_handle = http_get_file_handle, .priv_data_size = sizeof(HTTPContext), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; #endif diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c index bb42a12e62..6ebafb6647 100644 --- a/libavformat/ipmovie.c +++ b/libavformat/ipmovie.c @@ -116,6 +116,11 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, int chunk_type; if (s->audio_chunk_offset && s->audio_channels && s->audio_bits) { + if (s->audio_type == CODEC_ID_NONE) { + av_log(NULL, AV_LOG_ERROR, "Can not read audio packet before" + "audio codec is known\n"); + return CHUNK_BAD; + } /* adjust for PCM audio by skipping chunk header */ if (s->audio_type != CODEC_ID_INTERPLAY_DPCM) { diff --git a/libavformat/librtmp.c b/libavformat/librtmp.c index 018ea0f4b0..e433860823 100644 --- a/libavformat/librtmp.c +++ b/libavformat/librtmp.c @@ -162,6 +162,7 @@ URLProtocol ff_rtmp_protocol = { .url_read_seek = rtmp_read_seek, .url_get_file_handle = rtmp_get_file_handle, .priv_data_size = sizeof(RTMP), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; URLProtocol ff_rtmpt_protocol = { @@ -174,6 +175,7 @@ URLProtocol ff_rtmpt_protocol = { .url_read_seek = rtmp_read_seek, .url_get_file_handle = rtmp_get_file_handle, .priv_data_size = sizeof(RTMP), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; URLProtocol ff_rtmpe_protocol = { @@ -186,6 +188,7 @@ URLProtocol ff_rtmpe_protocol = { .url_read_seek = rtmp_read_seek, .url_get_file_handle = rtmp_get_file_handle, .priv_data_size = sizeof(RTMP), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; URLProtocol ff_rtmpte_protocol = { @@ -198,6 +201,7 @@ URLProtocol ff_rtmpte_protocol = { .url_read_seek = rtmp_read_seek, .url_get_file_handle = rtmp_get_file_handle, .priv_data_size = sizeof(RTMP), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; URLProtocol ff_rtmps_protocol = { @@ -210,4 +214,5 @@ URLProtocol ff_rtmps_protocol = { .url_read_seek = rtmp_read_seek, .url_get_file_handle = rtmp_get_file_handle, .priv_data_size = sizeof(RTMP), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c index e92b74fc0a..d6e398200f 100644 --- a/libavformat/mmsh.c +++ b/libavformat/mmsh.c @@ -406,4 +406,5 @@ URLProtocol ff_mmsh_protocol = { .url_close = mmsh_close, .url_read_seek = mmsh_read_seek, .priv_data_size = sizeof(MMSHContext), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; diff --git a/libavformat/mmst.c b/libavformat/mmst.c index 8d6f8a3a48..e3515b656a 100644 --- a/libavformat/mmst.c +++ b/libavformat/mmst.c @@ -625,4 +625,5 @@ URLProtocol ff_mmst_protocol = { .url_read = mms_read, .url_close = mms_close, .priv_data_size = sizeof(MMSTContext), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; diff --git a/libavformat/mov.c b/libavformat/mov.c index 6698b6a3a4..05521fd03e 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -576,7 +576,8 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; uint8_t version; - uint32_t flags, layout_tag, bitmap, num_descr; + uint32_t flags, layout_tag, bitmap, num_descr, label_mask; + int i; if (c->fc->nb_streams < 1) return 0; @@ -598,9 +599,7 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_dlog(c->fc, "chan: size=%" PRId64 " version=%u flags=%u layout=%u bitmap=%u num_descr=%u\n", atom.size, version, flags, layout_tag, bitmap, num_descr); -#if 0 - /* TODO: use the channel descriptions if the layout tag is 0 */ - int i; + label_mask = 0; for (i = 0; i < num_descr; i++) { uint32_t label, cflags; float coords[3]; @@ -609,10 +608,19 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) AV_WN32(&coords[0], avio_rl32(pb)); // mCoordinates[0] AV_WN32(&coords[1], avio_rl32(pb)); // mCoordinates[1] AV_WN32(&coords[2], avio_rl32(pb)); // mCoordinates[2] + if (layout_tag == 0) { + uint32_t mask_incr = ff_mov_get_channel_label(label); + if (mask_incr == 0) { + label_mask = 0; + break; + } + label_mask |= mask_incr; + } } -#endif - - st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap); + if (layout_tag == 0) + st->codec->channel_layout = label_mask; + else + st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap); return 0; } diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c index a8e6b94c51..5728ebd898 100644 --- a/libavformat/mov_chan.c +++ b/libavformat/mov_chan.c @@ -428,8 +428,7 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap) int i, channels; const struct MovChannelLayoutMap *layout_map; - /* handle the use of the channel descriptions */ - /* TODO: map MOV channel labels to FFmpeg channels */ + /* use ff_mov_get_channel_label() to build a layout instead */ if (tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS) return 0; @@ -451,6 +450,19 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap) return layout_map[i].layout; } +uint32_t ff_mov_get_channel_label(uint32_t label) +{ + if (label == 0) + return 0; + if (label <= 18) + return 1U << (label - 1); + if (label == 38) + return AV_CH_STEREO_LEFT; + if (label == 39) + return AV_CH_STEREO_RIGHT; + return 0; +} + uint32_t ff_mov_get_channel_layout_tag(enum CodecID codec_id, uint64_t channel_layout, uint32_t *bitmap) diff --git a/libavformat/mov_chan.h b/libavformat/mov_chan.h index 9723340102..abb6916144 100644 --- a/libavformat/mov_chan.h +++ b/libavformat/mov_chan.h @@ -40,6 +40,14 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap); /** + * Get the channel layout for the specified channel layout tag. + * + * @param[in] tag channel label + * @return channel layout mask fragment + */ +uint32_t ff_mov_get_channel_label(uint32_t label); + +/** * Get the channel layout tag for the specified codec id and channel layout. * If the layout tag was not found, use a channel bitmap if possible. * diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 4fe1d33274..a2c7b5da88 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -1000,4 +1000,5 @@ URLProtocol ff_rtmp_protocol = { .url_write = rtmp_write, .url_close = rtmp_close, .priv_data_size = sizeof(RTMPContext), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index b6f2a56146..4ce1d6bbbb 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -331,4 +331,5 @@ URLProtocol ff_rtp_protocol = { .url_close = rtp_close, .url_get_file_handle = rtp_get_file_handle, .priv_data_size = sizeof(RTPContext), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; diff --git a/libavformat/tcp.c b/libavformat/tcp.c index 1aeceb9e02..4eaf0a02b4 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -204,4 +204,5 @@ URLProtocol ff_tcp_protocol = { .url_close = tcp_close, .url_get_file_handle = tcp_get_file_handle, .priv_data_size = sizeof(TCPContext), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; diff --git a/libavformat/tls.c b/libavformat/tls.c index 26f5ee5106..fb84fa82b6 100644 --- a/libavformat/tls.c +++ b/libavformat/tls.c @@ -248,4 +248,5 @@ URLProtocol ff_tls_protocol = { .url_write = tls_write, .url_close = tls_close, .priv_data_size = sizeof(TLSContext), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; diff --git a/libavformat/udp.c b/libavformat/udp.c index 5bf7d82dad..cdcd13617d 100644 --- a/libavformat/udp.c +++ b/libavformat/udp.c @@ -637,4 +637,5 @@ URLProtocol ff_udp_protocol = { .url_close = udp_close, .url_get_file_handle = udp_get_file_handle, .priv_data_size = sizeof(UDPContext), + .flags = URL_PROTOCOL_FLAG_NETWORK, }; diff --git a/libavformat/url.h b/libavformat/url.h index dbcf470d69..3a80f216c7 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -33,6 +33,7 @@ #if !FF_API_OLD_AVIO #define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the first part of a nested protocol scheme */ +#define URL_PROTOCOL_FLAG_NETWORK 2 /*< The protocol uses network */ extern int (*url_interrupt_cb)(void); diff --git a/libavformat/utils.c b/libavformat/utils.c index 84dfd6a8bc..795ecb774c 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -33,6 +33,7 @@ #include "libavutil/pixdesc.h" #include "metadata.h" #include "id3v2.h" +#include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/mathematics.h" #include "libavutil/parseutils.h" @@ -1318,57 +1319,63 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) return 0; } +static int read_from_packet_buffer(AVFormatContext *s, AVPacket *pkt) +{ + AVPacketList *pktl = s->packet_buffer; + av_assert0(pktl); + *pkt = pktl->pkt; + s->packet_buffer = pktl->next; + av_freep(&pktl); + return 0; +} + int av_read_frame(AVFormatContext *s, AVPacket *pkt) { - AVPacketList *pktl; - int eof=0; - const int genpts= s->flags & AVFMT_FLAG_GENPTS; + const int genpts = s->flags & AVFMT_FLAG_GENPTS; + int eof = 0; + + if (!genpts) + return s->packet_buffer ? read_from_packet_buffer(s, pkt) : + read_frame_internal(s, pkt); + + for (;;) { + int ret; + AVPacketList *pktl = s->packet_buffer; - for(;;){ - pktl = s->packet_buffer; if (pktl) { - AVPacket *next_pkt= &pktl->pkt; + AVPacket *next_pkt = &pktl->pkt; - if(genpts && next_pkt->dts != AV_NOPTS_VALUE){ + if (next_pkt->dts != AV_NOPTS_VALUE) { int wrap_bits = s->streams[next_pkt->stream_index]->pts_wrap_bits; - while(pktl && next_pkt->pts == AV_NOPTS_VALUE){ - if( pktl->pkt.stream_index == next_pkt->stream_index - && (0 > av_compare_mod(next_pkt->dts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) - && av_compare_mod(pktl->pkt.pts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) { //not b frame - next_pkt->pts= pktl->pkt.dts; + while (pktl && next_pkt->pts == AV_NOPTS_VALUE) { + if (pktl->pkt.stream_index == next_pkt->stream_index && + (av_compare_mod(next_pkt->dts, pktl->pkt.dts, 2LL << (wrap_bits - 1)) < 0) && + av_compare_mod(pktl->pkt.pts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) { //not b frame + next_pkt->pts = pktl->pkt.dts; } - pktl= pktl->next; + pktl = pktl->next; } pktl = s->packet_buffer; } - if( next_pkt->pts != AV_NOPTS_VALUE - || next_pkt->dts == AV_NOPTS_VALUE - || !genpts || eof){ - /* read packet from packet buffer, if there is data */ - *pkt = *next_pkt; - s->packet_buffer = pktl->next; - av_free(pktl); - return 0; - } + /* read packet from packet buffer, if there is data */ + if (!(next_pkt->pts == AV_NOPTS_VALUE && + next_pkt->dts != AV_NOPTS_VALUE && !eof)) + return read_from_packet_buffer(s, pkt); } - if(genpts){ - int ret= read_frame_internal(s, pkt); - if(ret<0){ - if(pktl && ret != AVERROR(EAGAIN)){ - eof=1; - continue; - }else - return ret; - } - if(av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt, - &s->packet_buffer_end)) < 0) - return AVERROR(ENOMEM); - }else{ - assert(!s->packet_buffer); - return read_frame_internal(s, pkt); + ret = read_frame_internal(s, pkt); + if (ret < 0) { + if (pktl && ret != AVERROR(EAGAIN)) { + eof = 1; + continue; + } else + return ret; } + + if (av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt, + &s->packet_buffer_end)) < 0) + return AVERROR(ENOMEM); } } diff --git a/libavutil/timer.h b/libavutil/timer.h index 63576c95bf..8a5caecd6c 100644 --- a/libavutil/timer.h +++ b/libavutil/timer.h @@ -28,6 +28,7 @@ #include <stdlib.h> #include <stdint.h> + #include "config.h" #if ARCH_ARM @@ -45,29 +46,32 @@ #endif #ifdef AV_READ_TIME -#define START_TIMER \ -uint64_t tend;\ -uint64_t tstart= AV_READ_TIME();\ +#define START_TIMER \ + uint64_t tend; \ + uint64_t tstart = AV_READ_TIME(); \ -#define STOP_TIMER(id) \ -tend= AV_READ_TIME();\ -{\ - static uint64_t tsum=0;\ - static int tcount=0;\ - static int tskip_count=0;\ - if(tcount<2 || tend - tstart < 8*tsum/tcount || tend - tstart < 2000){\ - tsum+= tend - tstart;\ - tcount++;\ - }else\ - tskip_count++;\ - if(((tcount+tskip_count)&(tcount+tskip_count-1))==0){\ - av_log(NULL, AV_LOG_ERROR, "%"PRIu64" decicycles in %s, %d runs, %d skips\n",\ - tsum*10/tcount, id, tcount, tskip_count);\ - }\ -} +#define STOP_TIMER(id) \ + tend = AV_READ_TIME(); \ + { \ + static uint64_t tsum = 0; \ + static int tcount = 0; \ + static int tskip_count = 0; \ + if (tcount < 2 || \ + tend - tstart < 8 * tsum / tcount || \ + tend - tstart < 2000) { \ + tsum+= tend - tstart; \ + tcount++; \ + } else \ + tskip_count++; \ + if (((tcount + tskip_count) & (tcount + tskip_count - 1)) == 0) { \ + av_log(NULL, AV_LOG_ERROR, \ + "%"PRIu64" decicycles in %s, %d runs, %d skips\n", \ + tsum * 10 / tcount, id, tcount, tskip_count); \ + } \ + } #else #define START_TIMER -#define STOP_TIMER(id) {} +#define STOP_TIMER(id) { } #endif #endif /* AVUTIL_TIMER_H */ diff --git a/libswscale/swscale.c b/libswscale/swscale.c index ff0656ee20..dca6b073d0 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -981,9 +981,17 @@ YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48le, PIX_FMT_RGB48LE) YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48be, PIX_FMT_BGR48BE) YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48le, PIX_FMT_BGR48LE) +/* + * Write out 2 RGB pixels in the target pixel format. This function takes a + * R/G/B LUT as generated by ff_yuv2rgb_c_init_tables(), which takes care of + * things like endianness conversion and shifting. The caller takes care of + * setting the correct offset in these tables from the chroma (U/V) values. + * This function then uses the luminance (Y1/Y2) values to write out the + * correct RGB values into the destination buffer. + */ static av_always_inline void yuv2rgb_write(uint8_t *_dest, int i, unsigned Y1, unsigned Y2, - unsigned U, unsigned V, unsigned A1, unsigned A2, + unsigned A1, unsigned A2, const void *_r, const void *_g, const void *_b, int y, enum PixelFormat target, int hasAlpha) { @@ -1151,7 +1159,7 @@ yuv2rgb_X_c_template(SwsContext *c, const int16_t *lumFilter, g = (c->table_gU[U] + c->table_gV[V]); b = c->table_bU[U]; - yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0, + yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0, r, g, b, y, target, hasAlpha); } } @@ -1187,7 +1195,7 @@ yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2], A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 19; } - yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0, + yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0, r, g, b, y, target, hasAlpha); } } @@ -1219,7 +1227,7 @@ yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0, A2 = abuf0[i * 2 + 1] >> 7; } - yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0, + yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0, r, g, b, y, target, hasAlpha); } } else { @@ -1238,7 +1246,7 @@ yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0, A2 = abuf0[i * 2 + 1] >> 7; } - yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0, + yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0, r, g, b, y, target, hasAlpha); } } diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak index 85749f0c80..2d1c8fd619 100644 --- a/tests/fate/vpx.mak +++ b/tests/fate/vpx.mak @@ -7,6 +7,9 @@ fate-ea-vp61: CMD = framecrc -i $(SAMPLES)/ea-vp6/MovieSkirmishGondor.vp6 -t 4 FATE_TESTS += fate-vp3 fate-vp3: CMD = framecrc -i $(SAMPLES)/vp3/vp31.avi +FATE_TESTS += fate-vp3-coeff-level64 +fate-vp3-coeff-level64: CMD = framecrc -i $(SAMPLES)/vp3/coeff_level64.mkv + FATE_TESTS += fate-vp5 fate-vp5: CMD = framecrc -i $(SAMPLES)/vp5/potter512-400-partial.avi -an diff --git a/tests/ref/fate/vp3-coeff-level64 b/tests/ref/fate/vp3-coeff-level64 new file mode 100644 index 0000000000..31a49aa1a9 --- /dev/null +++ b/tests/ref/fate/vp3-coeff-level64 @@ -0,0 +1,8 @@ +0, 0, 4617600, 0x4ba6df50 +0, 6000, 4617600, 0x419fdeaf +0, 12000, 4617600, 0xeb2edced +0, 18000, 4617600, 0xa2bb3a1a +0, 24000, 4617600, 0x411cfb36 +0, 30000, 4617600, 0xb2dc22ed +0, 36000, 4617600, 0x236d23b5 +0, 42000, 4617600, 0x7fef275e |