]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/asf.c
Rename yuv2rgb2.c --> yuv2rgb.c.
[ffmpeg] / libavformat / asf.c
index faa0d6916afbe4843934cf3a92b1d076cace9391..bcaf2a1c165ea69fd9bcae03866a254aa8f0ca84 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ASF compatible demuxer
- * Copyright (c) 2000, 2001 Fabrice Bellard.
+ * Copyright (c) 2000, 2001 Fabrice Bellard
  *
  * This file is part of FFmpeg.
  *
@@ -26,7 +26,7 @@
 #include "asf.h"
 #include "asfcrypt.h"
 
-extern void ff_mms_set_stream_selection(URLContext *h, AVFormatContext *format);
+void ff_mms_set_stream_selection(URLContext *h, AVFormatContext *format);
 
 #undef NDEBUG
 #include <assert.h>
@@ -49,7 +49,7 @@ static const GUID stream_bitrate_guid = { /* (http://get.to/sdp) */
 #ifdef DEBUG
 #define PRINT_IF_GUID(g,cmp) \
 if (!memcmp(g, &cmp, sizeof(GUID))) \
-    printf("(GUID: %s) ", #cmp)
+    dprintf(NULL, "(GUID: %s) ", #cmp)
 
 static void print_guid(const GUID *g)
 {
@@ -77,12 +77,14 @@ static void print_guid(const GUID *g)
     else PRINT_IF_GUID(g, metadata_header);
     else PRINT_IF_GUID(g, stream_bitrate_guid);
     else
-        printf("(GUID: unknown) ");
+        dprintf(NULL, "(GUID: unknown) ");
     for(i=0;i<16;i++)
-        printf(" 0x%02x,", (*g)[i]);
-    printf("}\n");
+        dprintf(NULL, " 0x%02x,", (*g)[i]);
+    dprintf(NULL, "}\n");
 }
 #undef PRINT_IF_GUID
+#else
+#define print_guid(g)
 #endif
 
 static void get_guid(ByteIOContext *s, GUID *g)
@@ -139,6 +141,23 @@ static int get_value(ByteIOContext *pb, int type){
     }
 }
 
+static void get_tag(AVFormatContext *s, const char *key, int type, int len)
+{
+    char value[1024];
+    if (type <= 1) {         // unicode or byte
+        get_str16_nolen(s->pb, len, value, sizeof(value));
+    } 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);
+    } else {
+        url_fskip(s->pb, len);
+        return;
+    }
+    if (strncmp(key, "WM/", 3))
+        key += 3;
+    av_metadata_set(&s->metadata, key, value);
+}
+
 static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
 {
     ASFContext *asf = s->priv_data;
@@ -165,11 +184,9 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
     for(;;) {
         get_guid(pb, &g);
         gsize = get_le64(pb);
-#ifdef DEBUG
-        printf("%08"PRIx64": ", url_ftell(pb) - 24);
+        dprintf(s, "%08"PRIx64": ", url_ftell(pb) - 24);
         print_guid(&g);
-        printf("  size=0x%"PRIx64"\n", gsize);
-#endif
+        dprintf(s, "  size=0x%"PRIx64"\n", gsize);
         if (!memcmp(&g, &data_header, sizeof(GUID))) {
             asf->data_object_offset = url_ftell(pb);
             // if not streaming, gsize is not unlimited (how?), and there is enough space in the file..
@@ -197,7 +214,8 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
             asf->hdr.max_bitrate        = get_le32(pb);
             asf->packet_size = asf->hdr.max_pktsize;
         } else if (!memcmp(&g, &stream_header, sizeof(GUID))) {
-            int type, type_specific_size, sizeX;
+            enum CodecType type;
+            int type_specific_size, sizeX;
             uint64_t total_size;
             unsigned int tag1;
             int64_t pos1, pos2, start_time;
@@ -227,7 +245,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
             } else if (!memcmp(&g, &video_stream, sizeof(GUID))) {
                 type = CODEC_TYPE_VIDEO;
             } else if (!memcmp(&g, &command_stream, sizeof(GUID))) {
-                type = CODEC_TYPE_UNKNOWN;
+                type = CODEC_TYPE_DATA;
             } else if (!memcmp(&g, &ext_stream_embed_stream_header, sizeof(GUID))) {
                 test_for_ext_stream_audio = 1;
                 type = CODEC_TYPE_UNKNOWN;
@@ -264,10 +282,14 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
                 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_NONE;
+                    st->codec->codec_id = CODEC_ID_PROBE;
                     st->codec->codec_tag = 0;
                 }
-                st->need_parsing = AVSTREAM_PARSE_FULL;
+                if (st->codec->codec_id == CODEC_ID_AAC) {
+                    st->need_parsing = AVSTREAM_PARSE_NONE;
+                } else {
+                    st->need_parsing = AVSTREAM_PARSE_FULL;
+                }
                 /* We have to init the frame size at some point .... */
                 pos2 = url_ftell(pb);
                 if (gsize >= (pos2 + 8 - pos1 + 24)) {
@@ -315,10 +337,10 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
                 st->codec->height = get_le32(pb);
                 /* not available for asf */
                 get_le16(pb); /* panes */
-                st->codec->bits_per_sample = get_le16(pb); /* depth */
+                st->codec->bits_per_coded_sample = get_le16(pb); /* depth */
                 tag1 = get_le32(pb);
                 url_fskip(pb, 20);
-//                av_log(NULL, AV_LOG_DEBUG, "size:%d tsize:%d sizeX:%d\n", size, total_size, sizeX);
+//                av_log(s, AV_LOG_DEBUG, "size:%d tsize:%d sizeX:%d\n", size, total_size, sizeX);
                 size= sizeX;
                 if (size > 40) {
                     st->codec->extradata_size = size - 40;
@@ -329,7 +351,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
         /* Extract palette from extradata if bpp <= 8 */
         /* This code assumes that extradata contains only palette */
         /* This is true for all paletted codecs implemented in ffmpeg */
-        if (st->codec->extradata_size && (st->codec->bits_per_sample <= 8)) {
+        if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
             st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl));
 #ifdef WORDS_BIGENDIAN
             for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++)
@@ -356,24 +378,24 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
             len3 = get_le16(pb);
             len4 = get_le16(pb);
             len5 = get_le16(pb);
-            get_str16_nolen(pb, len1, s->title    , sizeof(s->title));
-            get_str16_nolen(pb, len2, s->author   , sizeof(s->author));
-            get_str16_nolen(pb, len3, s->copyright, sizeof(s->copyright));
-            get_str16_nolen(pb, len4, s->comment  , sizeof(s->comment));
+            get_tag(s, "title"    , 0, len1);
+            get_tag(s, "author"   , 0, len2);
+            get_tag(s, "copyright", 0, len3);
+            get_tag(s, "comment"  , 0, len4);
             url_fskip(pb, len5);
         } else if (!memcmp(&g, &stream_bitrate_guid, sizeof(GUID))) {
             int stream_count = get_le16(pb);
             int j;
 
-//            av_log(NULL, AV_LOG_ERROR, "stream bitrate properties\n");
-//            av_log(NULL, AV_LOG_ERROR, "streams %d\n", streams);
+//            av_log(s, AV_LOG_ERROR, "stream bitrate properties\n");
+//            av_log(s, AV_LOG_ERROR, "streams %d\n", streams);
             for(j = 0; j < stream_count; j++) {
                 int flags, bitrate, stream_id;
 
                 flags= get_le16(pb);
                 bitrate= get_le32(pb);
                 stream_id= (flags & 0x7f);
-//                av_log(NULL, AV_LOG_ERROR, "flags: 0x%x stream id %d, bitrate %d\n", flags, stream_id, bitrate);
+//                av_log(s, AV_LOG_ERROR, "flags: 0x%x stream id %d, bitrate %d\n", flags, stream_id, bitrate);
                 asf->stream_bitrates[stream_id]= bitrate;
             }
        } else if (!memcmp(&g, &extended_content_header, sizeof(GUID))) {
@@ -383,41 +405,13 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
                 for(i=0;i<desc_count;i++)
                 {
                         int name_len,value_type,value_len;
-                        uint64_t value_num = 0;
                         char name[1024];
 
                         name_len = get_le16(pb);
                         get_str16_nolen(pb, name_len, name, sizeof(name));
                         value_type = get_le16(pb);
                         value_len = get_le16(pb);
-                        if (value_type <= 1) // unicode or byte
-                        {
-                                if     (!strcmp(name,"WM/AlbumTitle")) get_str16_nolen(pb, value_len, s->album, sizeof(s->album));
-                                else if(!strcmp(name,"WM/Genre"     )) get_str16_nolen(pb, value_len, s->genre, sizeof(s->genre));
-                                else if(!strcmp(name,"WM/Year"      )) {
-                                    char year[8];
-                                    get_str16_nolen(pb, value_len, year, sizeof(year));
-                                    s->year = atoi(year);
-                                }
-                                else if(!strcmp(name,"WM/Track") && s->track == 0) {
-                                    char track[8];
-                                    get_str16_nolen(pb, value_len, track, sizeof(track));
-                                    s->track = strtol(track, NULL, 10) + 1;
-                                }
-                                else if(!strcmp(name,"WM/TrackNumber")) {
-                                    char track[8];
-                                    get_str16_nolen(pb, value_len, track, sizeof(track));
-                                    s->track = strtol(track, NULL, 10);
-                                }
-                                else url_fskip(pb, value_len);
-                        }
-                        else if (value_type <= 5) // boolean or DWORD or QWORD or WORD
-                        {
-                                value_num= get_value(pb, value_type);
-                                if (!strcmp(name,"WM/Track"      ) && s->track == 0) s->track = value_num + 1;
-                                if (!strcmp(name,"WM/TrackNumber")) s->track = value_num;
-                        }else
-                            url_fskip(pb, value_len);
+                        get_tag(s, name, value_type, value_len);
                 }
         } else if (!memcmp(&g, &metadata_header, sizeof(GUID))) {
             int n, stream_num, name_len, value_len, value_type, value_num;
@@ -433,7 +427,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
                 value_len=  get_le32(pb);
 
                 get_str16_nolen(pb, name_len, name, sizeof(name));
-//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d <%s>\n", i, stream_num, name_len, value_type, value_len, name);
+//av_log(s, AV_LOG_ERROR, "%d %d %d %d %d <%s>\n", i, stream_num, name_len, value_type, value_len, name);
                 value_num= get_le16(pb);//we should use get_value() here but it does not work 2 is le16 here but le32 elsewhere
                 url_fskip(pb, value_len - 2);
 
@@ -531,14 +525,14 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
     for(i=0; i<128; i++){
         int stream_num= asf->asfid2avid[i];
         if(stream_num>=0){
-            AVCodecContext *codec= s->streams[stream_num]->codec;
-            if (!codec->bit_rate)
-                codec->bit_rate = bitrate[i];
+            AVStream *st = s->streams[stream_num];
+            if (!st->codec->bit_rate)
+                st->codec->bit_rate = bitrate[i];
             if (dar[i].num > 0 && dar[i].den > 0)
-                av_reduce(&codec->sample_aspect_ratio.num,
-                          &codec->sample_aspect_ratio.den,
+                av_reduce(&st->sample_aspect_ratio.num,
+                          &st->sample_aspect_ratio.den,
                           dar[i].num, dar[i].den, INT_MAX);
-//av_log(NULL, AV_LOG_ERROR, "dar %d:%d sar=%d:%d\n", dar[i].num, dar[i].den, codec->sample_aspect_ratio.num, codec->sample_aspect_ratio.den);
+//av_log(s, AV_LOG_ERROR, "dar %d:%d sar=%d:%d\n", dar[i].num, dar[i].den, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
         }
     }
 
@@ -554,19 +548,14 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
     default: var = defval; break; \
     }
 
-/**
- *
- * @return <0 in case of an error
- */
-static int asf_get_packet(AVFormatContext *s)
+int ff_asf_get_packet(AVFormatContext *s, ByteIOContext *pb)
 {
     ASFContext *asf = s->priv_data;
-    ByteIOContext *pb = s->pb;
     uint32_t packet_length, padsize;
     int rsize = 8;
     int c, d, e, off;
 
-    off= (url_ftell(s->pb) - s->data_offset) % asf->packet_size + 3;
+    off= (url_ftell(pb) - s->data_offset) % asf->packet_size + 3;
 
     c=d=e=-1;
     while(off-- > 0){
@@ -625,9 +614,7 @@ static int asf_get_packet(AVFormatContext *s)
     if (packet_length < asf->hdr.min_pktsize)
         padsize += asf->hdr.min_pktsize - packet_length;
     asf->packet_padsize = padsize;
-#ifdef DEBUG
-    printf("packet: size=%d padsize=%d  left=%d\n", asf->packet_size, asf->packet_padsize, asf->packet_size_left);
-#endif
+    dprintf(s, "packet: size=%d padsize=%d  left=%d\n", asf->packet_size, asf->packet_padsize, asf->packet_size_left);
     return 0;
 }
 
@@ -635,9 +622,8 @@ static int asf_get_packet(AVFormatContext *s)
  *
  * @return <0 if error
  */
-static int asf_read_frame_header(AVFormatContext *s){
+static int asf_read_frame_header(AVFormatContext *s, ByteIOContext *pb){
     ASFContext *asf = s->priv_data;
-    ByteIOContext *pb = s->pb;
     int rsize = 1;
     int num = get_byte(pb);
     int64_t ts0, ts1;
@@ -706,12 +692,10 @@ static int asf_read_frame_header(AVFormatContext *s){
     return 0;
 }
 
-static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
+int ff_asf_parse_packet(AVFormatContext *s, ByteIOContext *pb, AVPacket *pkt)
 {
     ASFContext *asf = s->priv_data;
     ASFStream *asf_st = 0;
-    ByteIOContext *pb = s->pb;
-    //static int pc = 0;
     for (;;) {
         if(url_feof(pb))
             return AVERROR(EIO);
@@ -724,19 +708,14 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
             /* fail safe */
             url_fskip(pb, ret);
 
-            asf->packet_pos= url_ftell(s->pb);
+            asf->packet_pos= url_ftell(pb);
             if (asf->data_object_size != (uint64_t)-1 &&
                 (asf->packet_pos - asf->data_object_offset >= asf->data_object_size))
                 return AVERROR(EIO); /* Do not exceed the size of the data object */
-            ret = asf_get_packet(s);
-            //printf("READ ASF PACKET  %d   r:%d   c:%d\n", ret, asf->packet_size_left, pc++);
-            if (ret < 0)
-                assert(asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1);
-            asf->packet_time_start = 0;
-            continue;
+            return 1;
         }
         if (asf->packet_time_start == 0) {
-            if(asf_read_frame_header(s) < 0){
+            if(asf_read_frame_header(s, pb) < 0){
                 asf->packet_segments= 0;
                 continue;
             }
@@ -792,7 +771,7 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
             /* new packet */
             av_new_packet(&asf_st->pkt, asf->packet_obj_size);
             asf_st->seq = asf->packet_seq;
-            asf_st->pkt.pts = asf->packet_frag_timestamp;
+            asf_st->pkt.dts = asf->packet_frag_timestamp;
             asf_st->pkt.stream_index = asf->stream_index;
             asf_st->pkt.pos =
             asf_st->packet_pos= asf->packet_pos;
@@ -880,6 +859,24 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
     return 0;
 }
 
+static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    ASFContext *asf = s->priv_data;
+
+    for (;;) {
+        int ret;
+
+        /* parse cached packets, if any */
+        if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0)
+            return ret;
+        if ((ret = ff_asf_get_packet(s, s->pb)) < 0)
+            assert(asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1);
+        asf->packet_time_start = 0;
+    }
+
+    return 0;
+}
+
 // Added to support seeking after packets have been read
 // If information is not reset, read_packet fails due to
 // leftover information from previous reads
@@ -1000,12 +997,12 @@ static void asf_build_simple_index(AVFormatContext *s, int stream_index)
         itime=get_le64(s->pb);
         pct=get_le32(s->pb);
         ict=get_le32(s->pb);
-        av_log(NULL, AV_LOG_DEBUG, "itime:0x%"PRIx64", pct:%d, ict:%d\n",itime,pct,ict);
+        av_log(s, AV_LOG_DEBUG, "itime:0x%"PRIx64", pct:%d, ict:%d\n",itime,pct,ict);
 
         for (i=0;i<ict;i++){
             int pktnum=get_le32(s->pb);
             int pktct =get_le16(s->pb);
-            av_log(NULL, AV_LOG_DEBUG, "pktnum:%d, pktct:%d\n", pktnum, pktct);
+            av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d\n", pktnum, pktct);
 
             pos=s->data_offset + asf->packet_size*(int64_t)pktnum;
             index_pts=av_rescale(itime, i, 10000);
@@ -1073,7 +1070,7 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int
     //     }
 
         /* do the seek */
-        av_log(NULL, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos);
+        av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos);
         url_fseek(s->pb, pos, SEEK_SET);
     }
     asf_reset_header(s);