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 /libavformat | |
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>
Diffstat (limited to 'libavformat')
-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 |
18 files changed, 109 insertions, 49 deletions
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); } } |