diff options
Diffstat (limited to 'libavformat/asfdec.c')
-rw-r--r-- | libavformat/asfdec.c | 69 |
1 files changed, 42 insertions, 27 deletions
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index a35290b041..2054a32065 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -2,20 +2,20 @@ * ASF compatible demuxer * Copyright (c) 2000, 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -132,12 +132,6 @@ static void print_guid(const ff_asf_guid *g) #define print_guid(g) #endif -void ff_get_guid(AVIOContext *s, ff_asf_guid *g) -{ - assert(sizeof(*g) == 16); - avio_read(s, *g, sizeof(*g)); -} - static int asf_probe(AVProbeData *pd) { /* check file header */ @@ -171,6 +165,9 @@ static void get_tag(AVFormatContext *s, const char *key, int type, int len) if (type == 0) { // UTF16-LE avio_get_str16le(s->pb, len, value, 2*len + 1); + } else if (type == -1) { // ASCII + get_buffer(s->pb, value, len); + value[len]=0; } else if (type > 1 && type <= 5) { // boolean or DWORD or QWORD or WORD uint64_t num = get_value(s->pb, type); snprintf(value, len, "%"PRIu64, num); @@ -235,7 +232,6 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) if (!asf_st) return AVERROR(ENOMEM); st->priv_data = asf_st; - st->start_time = 0; start_time = asf->hdr.preroll; asf_st->stream_language_index = 128; // invalid stream index means no language info @@ -294,7 +290,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) if (is_dvr_ms_audio) { // codec_id and codec_tag are unreliable in dvr_ms // files. Set them later by probing stream. - st->codec->codec_id = CODEC_ID_PROBE; + st->request_probe= 1; st->codec->codec_tag = 0; } if (st->codec->codec_id == CODEC_ID_AAC) { @@ -638,16 +634,28 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) continue; } else if (!ff_guidcmp(&g, &ff_asf_marker_header)) { asf_read_marker(s, gsize); - } else if (pb->eof_reached) { + } else if (url_feof(pb)) { return -1; } else { if (!s->keylen) { if (!ff_guidcmp(&g, &ff_asf_content_encryption)) { + unsigned int len; + AVPacket pkt; av_log(s, AV_LOG_WARNING, "DRM protected stream detected, decoding will likely fail!\n"); + len= avio_rl32(pb); + av_log(s, AV_LOG_DEBUG, "Secret data:\n"); + av_get_packet(pb, &pkt, len); av_hex_dump_log(s, AV_LOG_DEBUG, pkt.data, pkt.size); av_free_packet(&pkt); + len= avio_rl32(pb); + get_tag(s, "ASF_Protection_Type", -1, len); + len= avio_rl32(pb); + get_tag(s, "ASF_Key_ID", -1, len); + len= avio_rl32(pb); + get_tag(s, "ASF_License_URL", -1, len); } else if (!ff_guidcmp(&g, &ff_asf_ext_content_encryption)) { av_log(s, AV_LOG_WARNING, "Ext DRM protected stream detected, decoding will likely fail!\n"); + av_dict_set(&s->metadata, "encryption", "ASF Extended Content Encryption", 0); } else if (!ff_guidcmp(&g, &ff_asf_digital_signature)) { - av_log(s, AV_LOG_WARNING, "Digital signature detected, decoding will likely fail!\n"); + av_log(s, AV_LOG_INFO, "Digital signature detected!\n"); } } } @@ -659,7 +667,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) avio_rl64(pb); avio_r8(pb); avio_r8(pb); - if (pb->eof_reached) + if (url_feof(pb)) return -1; asf->data_offset = avio_tell(pb); asf->packet_size_left = 0; @@ -744,12 +752,12 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb) */ if (pb->error == AVERROR(EAGAIN)) return AVERROR(EAGAIN); - if (!pb->eof_reached) + if (!url_feof(pb)) av_log(s, AV_LOG_ERROR, "ff asf bad header %x at:%"PRId64"\n", c, avio_tell(pb)); } if ((c & 0x8f) == 0x82) { if (d || e) { - if (!pb->eof_reached) + if (!url_feof(pb)) av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n"); return -1; } @@ -848,6 +856,10 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){ av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", asf->packet_replic_size); return -1; } + if (rsize > asf->packet_size_left) { + av_log(s, AV_LOG_ERROR, "packet_replic_size is invalid\n"); + return -1; + } if (asf->packet_flags & 0x01) { DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal if (rsize > asf->packet_size_left) { @@ -865,10 +877,6 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){ } //printf("Fragsize %d\n", asf->packet_frag_size); } else { - if (rsize > asf->packet_size_left) { - av_log(s, AV_LOG_ERROR, "packet_replic_size is invalid\n"); - return -1; - } asf->packet_frag_size = asf->packet_size_left - rsize; //printf("Using rest %d %d %d\n", asf->packet_frag_size, asf->packet_size_left, rsize); } @@ -898,7 +906,7 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk ASFStream *asf_st = 0; for (;;) { int ret; - if(pb->eof_reached) + if(url_feof(pb)) return AVERROR_EOF; if (asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1) { @@ -1162,7 +1170,8 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, if (s->packet_size > 0) pos= (pos+s->packet_size-1-s->data_offset)/s->packet_size*s->packet_size+ s->data_offset; *ppos= pos; - avio_seek(s->pb, pos, SEEK_SET); + if (avio_seek(s->pb, pos, SEEK_SET) < 0) + return AV_NOPTS_VALUE; //printf("asf_read_pts\n"); asf_reset_header(s); @@ -1204,15 +1213,20 @@ static void asf_build_simple_index(AVFormatContext *s, int stream_index) int64_t current_pos= avio_tell(s->pb); int i; - avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET); + if(avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET) < 0) { + asf->index_read= -1; + return; + } + ff_get_guid(s->pb, &g); /* the data object can be followed by other top-level objects, skip them until the simple index object is reached */ while (ff_guidcmp(&g, &index_guid)) { int64_t gsize= avio_rl64(s->pb); - if (gsize < 24 || s->pb->eof_reached) { + if (gsize < 24 || url_feof(s->pb)) { avio_seek(s->pb, current_pos, SEEK_SET); + asf->index_read= -1; return; } avio_skip(s->pb, gsize-24); @@ -1268,7 +1282,7 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int if (!asf->index_read) asf_build_simple_index(s, stream_index); - if((asf->index_read && st->index_entries)){ + if((asf->index_read > 0 && st->index_entries)){ index= av_index_search_timestamp(st, pts, flags); if(index >= 0) { /* find the position */ @@ -1276,7 +1290,8 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int /* do the seek */ av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos); - avio_seek(s->pb, pos, SEEK_SET); + if(avio_seek(s->pb, pos, SEEK_SET) < 0) + return -1; asf_reset_header(s); return 0; } |