]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/asfdec.c
Currently, the replacement which is used if inet_aton isn't available,
[ffmpeg] / libavformat / asfdec.c
index 4869e55302915c6794d78179e2b9f0abd4ff2be1..ef7c2d309f972b1102ba7341a144792e6e23d0cd 100644 (file)
@@ -152,19 +152,27 @@ static int get_value(ByteIOContext *pb, int type){
 
 static void get_tag(AVFormatContext *s, const char *key, int type, int len)
 {
-    char value[1024];
+    char *value;
+
+    if ((unsigned)len >= UINT_MAX)
+        return;
+
+    value = av_malloc(len+1);
+    if (!value)
+        return;
+
     if (type <= 1) {         // unicode or byte
-        get_str16_nolen(s->pb, len, value, sizeof(value));
+        get_str16_nolen(s->pb, len, value, len);
     } else if (type <= 5) {  // boolean or DWORD or QWORD or WORD
         uint64_t num = get_value(s->pb, type);
-        snprintf(value, sizeof(value), "%"PRIu64, num);
+        snprintf(value, len, "%"PRIu64, num);
     } else {
         url_fskip(s->pb, len);
         return;
     }
     if (!strncmp(key, "WM/", 3))
         key += 3;
-    av_metadata_set(&s->metadata, key, value);
+    av_metadata_set2(&s->metadata, key, value, AV_METADATA_DONT_STRDUP_VAL);
 }
 
 static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
@@ -245,7 +253,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
             asf_st->stream_language_index = 128; // invalid stream index means no language info
 
             if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming...
-                st->duration = asf->hdr.send_time /
+                st->duration = asf->hdr.play_time /
                     (10000000 / 1000) - start_time;
             }
             get_guid(pb, &g);
@@ -364,7 +372,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
                 /* This is true for all paletted codecs implemented in ffmpeg */
                 if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
                     st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl));
-#ifdef WORDS_BIGENDIAN
+#if HAVE_BIGENDIAN
                     for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++)
                         st->codec->palctrl->palette[i] = bswap_32(((uint32_t*)st->codec->extradata)[i]);
 #else
@@ -532,6 +540,15 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
         } else if (url_feof(pb)) {
             return -1;
         } else {
+            if (!s->keylen) {
+                if (!guidcmp(&g, &ff_asf_content_encryption)) {
+                    av_log(s, AV_LOG_WARNING, "DRM protected stream detected, decoding will likely fail!\n");
+                } else if (!guidcmp(&g, &ff_asf_ext_content_encryption)) {
+                    av_log(s, AV_LOG_WARNING, "Ext DRM protected stream detected, decoding will likely fail!\n");
+                } else if (!guidcmp(&g, &ff_asf_digital_signature)) {
+                    av_log(s, AV_LOG_WARNING, "Digital signature detected, decoding will likely fail!\n");
+                }
+            }
             url_fseek(pb, gsize - 24, SEEK_CUR);
         }
     }
@@ -598,7 +615,7 @@ static int ff_asf_get_packet(AVFormatContext *s, ByteIOContext *pb)
     // if we do not know packet size, allow skipping up to 32 kB
     off= 32768;
     if (s->packet_size > 0)
-    off= (url_ftell(pb) - s->data_offset) % s->packet_size + 3;
+        off= (url_ftell(pb) - s->data_offset) % s->packet_size + 3;
 
     c=d=e=-1;
     while(off-- > 0){
@@ -609,6 +626,14 @@ static int ff_asf_get_packet(AVFormatContext *s, ByteIOContext *pb)
     }
 
     if (c != 0x82) {
+        /**
+         * This code allows handling of -EAGAIN at packet boundaries (i.e.
+         * if the packet sync code above triggers -EAGAIN). This does not
+         * imply complete -EAGAIN handling support at random positions in
+         * the stream.
+         */
+        if (url_ferror(pb) == AVERROR(EAGAIN))
+            return AVERROR(EAGAIN);
         if (!url_feof(pb))
             av_log(s, AV_LOG_ERROR, "ff asf bad header %x  at:%"PRId64"\n", c, url_ftell(pb));
     }
@@ -633,7 +658,7 @@ static int ff_asf_get_packet(AVFormatContext *s, ByteIOContext *pb)
     DO_2BITS(asf->packet_flags >> 3, padsize, 0); // padding length
 
     //the following checks prevent overflows and infinite loops
-    if(packet_length >= (1U<<29)){
+    if(!packet_length || packet_length >= (1U<<29)){
         av_log(s, AV_LOG_ERROR, "invalid packet_length %d at:%"PRId64"\n", packet_length, url_ftell(pb));
         return -1;
     }
@@ -993,7 +1018,7 @@ 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;
+        pos= (pos+s->packet_size-1-s->data_offset)/s->packet_size*s->packet_size+ s->data_offset;
     *ppos= pos;
     url_fseek(s->pb, pos, SEEK_SET);
 
@@ -1040,7 +1065,7 @@ static void asf_build_simple_index(AVFormatContext *s, int stream_index)
     url_fseek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET);
     get_guid(s->pb, &g);
     if (!guidcmp(&g, &index_guid)) {
-        int64_t itime;
+        int64_t itime, last_pos=-1;
         int pct, ict;
         int64_t av_unused gsize= get_le64(s->pb);
         get_guid(s->pb, &g);
@@ -1055,8 +1080,11 @@ static void asf_build_simple_index(AVFormatContext *s, int stream_index)
             int64_t pos      = s->data_offset + s->packet_size*(int64_t)pktnum;
             int64_t index_pts= av_rescale(itime, i, 10000);
 
+            if(pos != last_pos){
             av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d\n", pktnum, pktct);
             av_add_index_entry(s->streams[stream_index], pos, index_pts, s->packet_size, 0, AVINDEX_KEYFRAME);
+            last_pos=pos;
+            }
         }
         asf->index_read= 1;
     }