~gma500/+junk/emgd160

« back to all changes in this revision

Viewing changes to mplayer-vaapi/libmpdemux/demux_asf.c

  • Committer: Luca Forina
  • Date: 2011-05-03 09:34:53 UTC
  • Revision ID: luca.forina@gmail.com-20110503093453-p1l4o1ck3g67vrha
added mplayer-vaapi

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ASF file parser for DEMUXER v0.3
 
3
 * copyright (c) 2001 A'rpi/ESP-team
 
4
 *
 
5
 * This file is part of MPlayer.
 
6
 *
 
7
 * MPlayer is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * MPlayer is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License along
 
18
 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
 
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
20
 */
 
21
 
 
22
#include <stdio.h>
 
23
#include <stdlib.h>
 
24
#include <unistd.h>
 
25
#include <limits.h>
 
26
 
 
27
#include "config.h"
 
28
#include "mp_msg.h"
 
29
#include "help_mp.h"
 
30
 
 
31
#include "stream/stream.h"
 
32
#include "asf.h"
 
33
#include "asfheader.h"
 
34
#include "demuxer.h"
 
35
#include "libmpcodecs/dec_audio.h"
 
36
#include "libvo/fastmemcpy.h"
 
37
#include "libavutil/intreadwrite.h"
 
38
 
 
39
// based on asf file-format doc by Eugene [http://divx.euro.ru]
 
40
 
 
41
/**
 
42
 * \brief reads int stored in number of bytes given by len
 
43
 * \param ptr pointer to read from, is incremented appropriately
 
44
 * \param len lowest 2 bits indicate number of bytes to read
 
45
 * \param def default value to return if len is invalid
 
46
 */
 
47
static inline unsigned read_varlen(uint8_t **ptr, int len, int def) {
 
48
    const uint8_t *p = *ptr;
 
49
    len &= 3;
 
50
    switch (len) {
 
51
      case 1: *ptr += 1; return *p;
 
52
      case 2: *ptr += 2; return AV_RL16(p);
 
53
      case 3: *ptr += 4; return AV_RL32(p);
 
54
    }
 
55
    return def;
 
56
}
 
57
 
 
58
/**
 
59
 * \brief checks if there is enough data to read the bytes given by len
 
60
 * \param ptr pointer to read from
 
61
 * \param endptr pointer to the end of the buffer
 
62
 * \param len lowest 2 bits indicate number of bytes to read
 
63
 */
 
64
static inline int check_varlen(uint8_t *ptr, uint8_t *endptr, int len) {
 
65
    return len&3 ? ptr + (1<<((len&3) - 1)) <= endptr : 1;
 
66
}
 
67
 
 
68
static void asf_descrambling(unsigned char **src,unsigned len, struct asf_priv* asf){
 
69
  unsigned char *dst;
 
70
  unsigned char *s2=*src;
 
71
  unsigned i=0,x,y;
 
72
  if (len > UINT_MAX - MP_INPUT_BUFFER_PADDING_SIZE)
 
73
        return;
 
74
  dst = malloc(len + MP_INPUT_BUFFER_PADDING_SIZE);
 
75
  while(len>=asf->scrambling_h*asf->scrambling_w*asf->scrambling_b+i){
 
76
//    mp_msg(MSGT_DEMUX,MSGL_DBG4,"descrambling! (w=%d  b=%d)\n",w,asf_scrambling_b);
 
77
        //i+=asf_scrambling_h*asf_scrambling_w;
 
78
        for(x=0;x<asf->scrambling_w;x++)
 
79
          for(y=0;y<asf->scrambling_h;y++){
 
80
            fast_memcpy(dst+i,s2+(y*asf->scrambling_w+x)*asf->scrambling_b,asf->scrambling_b);
 
81
                i+=asf->scrambling_b;
 
82
          }
 
83
        s2+=asf->scrambling_h*asf->scrambling_w*asf->scrambling_b;
 
84
  }
 
85
  //if(i<len) fast_memcpy(dst+i,src+i,len-i);
 
86
  free(*src);
 
87
  *src = dst;
 
88
}
 
89
 
 
90
/*****************************************************************
 
91
 * \brief initializes asf private data
 
92
 *
 
93
 */
 
94
static void init_priv (struct asf_priv* asf){
 
95
  asf->last_vid_seq=-1;
 
96
  asf->vid_ext_timing_index=-1;
 
97
  asf->aud_ext_timing_index=-1;
 
98
  asf->vid_ext_frame_index=-1;
 
99
}
 
100
 
 
101
static void demux_asf_append_to_packet(demux_packet_t* dp,unsigned char *data,int len,int offs)
 
102
{
 
103
  if(dp->len!=offs && offs!=-1) mp_msg(MSGT_DEMUX,MSGL_V,"warning! fragment.len=%d BUT next fragment offset=%d  \n",dp->len,offs);
 
104
  dp->buffer=realloc(dp->buffer,dp->len+len+MP_INPUT_BUFFER_PADDING_SIZE);
 
105
  fast_memcpy(dp->buffer+dp->len,data,len);
 
106
  memset(dp->buffer+dp->len+len, 0, MP_INPUT_BUFFER_PADDING_SIZE);
 
107
  mp_dbg(MSGT_DEMUX,MSGL_DBG4,"data appended! %d+%d\n",dp->len,len);
 
108
  dp->len+=len;
 
109
}
 
110
 
 
111
static int demux_asf_read_packet(demuxer_t *demux,unsigned char *data,int len,int id,int seq,uint64_t time,unsigned short dur,int offs,int keyframe){
 
112
  struct asf_priv* asf = demux->priv;
 
113
  demux_stream_t *ds=NULL;
 
114
  int close_seg=0;
 
115
 
 
116
  mp_dbg(MSGT_DEMUX,MSGL_DBG4,"demux_asf.read_packet: id=%d seq=%d len=%d\n",id,seq,len);
 
117
 
 
118
  if(demux->video->id==-1)
 
119
    if(demux->v_streams[id])
 
120
        demux->video->id=id;
 
121
 
 
122
  if(demux->audio->id==-1)
 
123
    if(demux->a_streams[id])
 
124
        demux->audio->id=id;
 
125
 
 
126
  if(id==demux->audio->id){
 
127
      // audio
 
128
      ds=demux->audio;
 
129
      if(!ds->sh){
 
130
        ds->sh=demux->a_streams[id];
 
131
        mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected ASF audio ID = %d\n",ds->id);
 
132
      }
 
133
  } else
 
134
  if(id==demux->video->id){
 
135
      // video
 
136
      ds=demux->video;
 
137
      if(!ds->sh){
 
138
        ds->sh=demux->v_streams[id];
 
139
        mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected ASF video ID = %d\n",ds->id);
 
140
      }
 
141
  }
 
142
 
 
143
  if(ds){
 
144
    if(ds->asf_packet){
 
145
      demux_packet_t* dp=ds->asf_packet;
 
146
 
 
147
      if (ds==demux->video && asf->asf_is_dvr_ms) {
 
148
        if (asf->new_vid_frame_seg) {
 
149
          dp->pos=demux->filepos;
 
150
          close_seg = 1;
 
151
        } else seq = ds->asf_seq;
 
152
      } else close_seg = ds->asf_seq!=seq;
 
153
 
 
154
      if(close_seg){
 
155
        // closed segment, finalize packet:
 
156
                if(ds==demux->audio)
 
157
                  if(asf->scrambling_h>1 && asf->scrambling_w>1 && asf->scrambling_b>0)
 
158
                    asf_descrambling(&ds->asf_packet->buffer,ds->asf_packet->len,asf);
 
159
        ds_add_packet(ds,ds->asf_packet);
 
160
        ds->asf_packet=NULL;
 
161
      } else {
 
162
        // append data to it!
 
163
        demux_asf_append_to_packet(dp,data,len,offs);
 
164
        // we are ready now.
 
165
        return 1;
 
166
      }
 
167
    }
 
168
    // create new packet:
 
169
    { demux_packet_t* dp;
 
170
      if(offs>0){
 
171
        mp_msg(MSGT_DEMUX,MSGL_V,"warning!  broken fragment, %d bytes missing  \n",offs);
 
172
        return 0;
 
173
      }
 
174
      dp=new_demux_packet(len);
 
175
      fast_memcpy(dp->buffer,data,len);
 
176
      if (asf->asf_is_dvr_ms)
 
177
        dp->pts=time*0.0000001;
 
178
      else
 
179
        dp->pts=time*0.001;
 
180
      dp->flags=keyframe;
 
181
//      if(ds==demux->video) printf("ASF time: %8d  dur: %5d  \n",time,dur);
 
182
      dp->pos=demux->filepos;
 
183
      ds->asf_packet=dp;
 
184
      ds->asf_seq=seq;
 
185
      // we are ready now.
 
186
      return 1;
 
187
    }
 
188
  }
 
189
 
 
190
  return 0;
 
191
}
 
192
 
 
193
/*****************************************************************
 
194
 * \brief read the replicated data associated with each segment
 
195
 * \parameter pp reference to replicated data
 
196
 * \parameter id stream number
 
197
 * \parameter seq media object number
 
198
 * \parameter keyframe key frame indicator - set to zero if keyframe, non-zero otherwise
 
199
 * \parameter seg_time set to payload time when valid, if audio or new video frame payload, zero otherwise
 
200
 *
 
201
 */
 
202
static void get_payload_extension_data(demuxer_t *demux, unsigned char** pp, unsigned char id, unsigned int seq, int *keyframe, uint64_t *seg_time){
 
203
    struct asf_priv* asf = demux->priv;
 
204
    uint64_t payload_time; //100ns units
 
205
    int i, ext_max, ext_timing_index;
 
206
    uint8_t *pi = *pp+4;
 
207
 
 
208
    if(demux->video->id==-1)
 
209
        if(demux->v_streams[id])
 
210
            demux->video->id=id;
 
211
 
 
212
    if(demux->audio->id==-1)
 
213
        if(demux->a_streams[id])
 
214
            demux->audio->id=id;
 
215
 
 
216
    if (id!=demux->video->id && id!=demux->audio->id) return;
 
217
 
 
218
    if (id==demux->video->id) {
 
219
      ext_max = asf->vid_repdata_count;
 
220
      ext_timing_index = asf->vid_ext_timing_index;
 
221
    } else {
 
222
      ext_max = asf->aud_repdata_count;
 
223
      ext_timing_index = asf->aud_ext_timing_index;
 
224
    }
 
225
 
 
226
    *seg_time=0.0;
 
227
    asf->new_vid_frame_seg = 0;
 
228
 
 
229
    for (i=0; i<ext_max; i++) {
 
230
        uint16_t payextsize;
 
231
        uint8_t segment_marker;
 
232
 
 
233
        if (id==demux->video->id)
 
234
            payextsize = asf->vid_repdata_sizes[i];
 
235
        else
 
236
            payextsize = asf->aud_repdata_sizes[i];
 
237
 
 
238
        if (payextsize == 65535) {
 
239
            payextsize = AV_RL16(pi);
 
240
            pi+=2;
 
241
        }
 
242
 
 
243
        // if this is the timing info extension then read the payload time
 
244
        if (i == ext_timing_index)
 
245
            payload_time = AV_RL64(pi+8);
 
246
 
 
247
        // if this is the video frame info extension then
 
248
        // set the keyframe indicator, the 'new frame segment' indicator
 
249
        // and (initially) the 'frame time'
 
250
        if (i == asf->vid_ext_frame_index && id==demux->video->id) {
 
251
            segment_marker = pi[0];
 
252
            // Known video stream segment_marker values that
 
253
            // contain useful information:
 
254
            //
 
255
            // NTSC/ATSC (29.97fps):        0X4A 01001010
 
256
            //                              0X4B 01001011
 
257
            //                              0X49 01001001
 
258
            //
 
259
            // PAL/ATSC (25fps):            0X3A 00111010
 
260
            //                              0X3B 00111011
 
261
            //                              0X39 00111001
 
262
            //
 
263
            // ATSC progressive (29.97fps): 0X7A 01111010
 
264
            //                              0X7B 01111011
 
265
            //                              0X79 01111001
 
266
            //   11111111
 
267
            //       ^    this is new video frame marker
 
268
            //
 
269
            //   ^^^^     these bits indicate the framerate
 
270
            //            0X4 is 29.97i, 0X3 is 25i, 0X7 is 29.97p, ???=25p
 
271
            //
 
272
            //        ^^^ these bits indicate the frame type:
 
273
            //              001 means I-frame
 
274
            //              010 and 011 probably mean P and B
 
275
 
 
276
            asf->new_vid_frame_seg = (0X08 & segment_marker) && seq != asf->last_vid_seq;
 
277
 
 
278
            if (asf->new_vid_frame_seg) asf->last_vid_seq = seq;
 
279
 
 
280
            if (asf->avg_vid_frame_time == 0) {
 
281
                // set the average frame time initially (in 100ns units).
 
282
                // This is based on what works for known samples.
 
283
                // It can be extended if more samples of different types can be obtained.
 
284
                if (((segment_marker & 0XF0) >> 4) == 4) {
 
285
                    asf->avg_vid_frame_time = (uint64_t)((1.001 / 30.0) * 10000000.0);
 
286
                    asf->know_frame_time=1;
 
287
                } else if (((segment_marker & 0XF0) >> 4) == 3) {
 
288
                    asf->avg_vid_frame_time = (uint64_t)(0.04 * 10000000.0);
 
289
                    asf->know_frame_time=1;
 
290
                } else if (((segment_marker & 0XF0) >> 4) == 6) {
 
291
                    asf->avg_vid_frame_time = (uint64_t)(0.02 * 10000000.0);
 
292
                    asf->know_frame_time=1;
 
293
                } else if (((segment_marker & 0XF0) >> 4) == 7) {
 
294
                    asf->avg_vid_frame_time = (uint64_t)((1.001 / 60.0) * 10000000.0);
 
295
                    asf->know_frame_time=1;
 
296
                } else {
 
297
                    // we dont know the frame time initially so
 
298
                    // make a guess and then recalculate as we go.
 
299
                    asf->avg_vid_frame_time = (uint64_t)((1.001 / 60.0) * 10000000.0);
 
300
                    asf->know_frame_time=0;
 
301
                }
 
302
            }
 
303
            *keyframe = (asf->new_vid_frame_seg && (segment_marker & 0X07) == 1);
 
304
        }
 
305
        pi +=payextsize;
 
306
    }
 
307
 
 
308
    if (id==demux->video->id && asf->new_vid_frame_seg) {
 
309
        asf->vid_frame_ct++;
 
310
        // Some samples only have timings on key frames and
 
311
        // the rest contain non-cronological timestamps. Interpolating
 
312
        // the values between key frames works for all samples.
 
313
        if (*keyframe) {
 
314
            asf->found_first_key_frame=1;
 
315
            if (!asf->know_frame_time && asf->last_key_payload_time > 0) {
 
316
                // We dont know average frametime so recalculate.
 
317
                // Giving precedence to the 'weight' of the existing
 
318
                // average limits damage done to new value when there is
 
319
                // a sudden time jump which happens occasionally.
 
320
                asf->avg_vid_frame_time =
 
321
                   (0.9 * asf->avg_vid_frame_time) +
 
322
                   (0.1 * ((payload_time - asf->last_key_payload_time) / asf->vid_frame_ct));
 
323
            }
 
324
            asf->last_key_payload_time = payload_time;
 
325
            asf->vid_frame_ct = 1;
 
326
            *seg_time = payload_time;
 
327
        } else
 
328
            *seg_time = (asf->last_key_payload_time  + (asf->avg_vid_frame_time * (asf->vid_frame_ct-1)));
 
329
    }
 
330
 
 
331
    if (id==demux->audio->id) {
 
332
        if (payload_time != -1)
 
333
            asf->last_aud_diff = payload_time - asf->last_aud_pts;
 
334
        asf->last_aud_pts += asf->last_aud_diff;
 
335
        *seg_time = asf->last_aud_pts;
 
336
   }
 
337
}
 
338
//static int num_elementary_packets100=0;
 
339
//static int num_elementary_packets101=0;
 
340
 
 
341
// return value:
 
342
//     0 = EOF or no stream found
 
343
//     1 = successfully read a packet
 
344
static int demux_asf_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
 
345
  struct asf_priv* asf = demux->priv;
 
346
 
 
347
  demux->filepos=stream_tell(demux->stream);
 
348
  // Brodcast stream have movi_start==movi_end
 
349
  // Better test ?
 
350
  if((demux->movi_start < demux->movi_end) && (demux->filepos>=demux->movi_end)){
 
351
          demux->stream->eof=1;
 
352
          return 0;
 
353
  }
 
354
 
 
355
    stream_read(demux->stream,asf->packet,asf->packetsize);
 
356
    if(demux->stream->eof) return 0; // EOF
 
357
    if(asf->packetsize < 2) return 0; // Packet too short
 
358
 
 
359
    {
 
360
            unsigned char* p=asf->packet;
 
361
            unsigned char* p_end=asf->packet+asf->packetsize;
 
362
            unsigned char flags=p[0];
 
363
            unsigned char segtype=p[1];
 
364
            unsigned padding;
 
365
            unsigned plen;
 
366
            unsigned sequence;
 
367
            unsigned long time=0;
 
368
            unsigned short duration=0;
 
369
 
 
370
            int segs=1;
 
371
            unsigned char segsizetype=0x80;
 
372
            int seg=-1;
 
373
 
 
374
            if( mp_msg_test(MSGT_DEMUX,MSGL_DBG2) ){
 
375
                int i;
 
376
                for(i=0;i<FFMIN(16, asf->packetsize);i++) printf(" %02X",asf->packet[i]);
 
377
                printf("\n");
 
378
            }
 
379
 
 
380
            // skip ECC data if present by testing bit 7 of flags
 
381
            // 1xxxbbbb -> ecc data present, skip bbbb byte(s)
 
382
            // 0xxxxxxx -> payload parsing info starts
 
383
            if (flags & 0x80)
 
384
            {
 
385
                p += (flags & 0x0f)+1;
 
386
                if (p+1 >= p_end) return 0; // Packet too short
 
387
                flags = p[0];
 
388
                segtype = p[1];
 
389
            }
 
390
 
 
391
            //if(segtype!=0x5d) printf("Warning! packet[4] != 0x5d  \n");
 
392
 
 
393
            p+=2; // skip flags & segtype
 
394
 
 
395
            // Read packet size (plen):
 
396
            if(!check_varlen(p, p_end, flags>> 5)) return 0; // Not enough data
 
397
            plen = read_varlen(&p, flags >> 5, 0);
 
398
 
 
399
            // Read sequence:
 
400
            if(!check_varlen(p, p_end, flags>> 1)) return 0; // Not enough data
 
401
            sequence = read_varlen(&p, flags >> 1, 0);
 
402
 
 
403
            // Read padding size (padding):
 
404
            if(!check_varlen(p, p_end, flags>> 3)) return 0; // Not enough data
 
405
            padding = read_varlen(&p, flags >> 3, 0);
 
406
 
 
407
            if(((flags>>5)&3)!=0){
 
408
              // Explicit (absoulte) packet size
 
409
              mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Explicit packet size specified: %d  \n",plen);
 
410
              if(plen>asf->packetsize) mp_msg(MSGT_DEMUX,MSGL_V,"Warning! plen>packetsize! (%d>%d)  \n",plen,asf->packetsize);
 
411
            } else {
 
412
              // Padding (relative) size
 
413
              plen=asf->packetsize-padding;
 
414
            }
 
415
 
 
416
            // Read time & duration:
 
417
            if (p+5 >= p_end) return 0; // Packet too short
 
418
            time = AV_RL32(p); p+=4;
 
419
            duration = AV_RL16(p); p+=2;
 
420
 
 
421
            // Read payload flags:
 
422
            if(flags&1){
 
423
              // multiple sub-packets
 
424
              if (p >= p_end) return 0; // Packet too short
 
425
              segsizetype=p[0]>>6;
 
426
              segs=p[0] & 0x3F;
 
427
              ++p;
 
428
            }
 
429
            mp_dbg(MSGT_DEMUX,MSGL_DBG4,"%08"PRIu64":  flag=%02X  segs=%d  seq=%u  plen=%u  pad=%u  time=%ld  dur=%d\n",
 
430
              (uint64_t)demux->filepos,flags,segs,sequence,plen,padding,time,duration);
 
431
 
 
432
            for(seg=0;seg<segs;seg++){
 
433
              //ASF_segmhdr_t* sh;
 
434
              unsigned char streamno;
 
435
              unsigned int seq;
 
436
              unsigned int x;   // offset or timestamp
 
437
              unsigned int rlen;
 
438
              //
 
439
              int len;
 
440
              uint64_t time2=0;
 
441
              int keyframe=0;
 
442
 
 
443
              if(p>=p_end) {
 
444
                mp_msg(MSGT_DEMUX,MSGL_V,"Warning! invalid packet 1, aborting parsing...\n");
 
445
                break;
 
446
              }
 
447
 
 
448
              if( mp_msg_test(MSGT_DEMUX,MSGL_DBG2) ){
 
449
                int i;
 
450
                printf("seg %d:",seg);
 
451
                for(i=0;i<FFMIN(16, p_end - p);i++) printf(" %02X",p[i]);
 
452
                printf("\n");
 
453
              }
 
454
 
 
455
              streamno=p[0]&0x7F;
 
456
              if(p[0]&0x80) keyframe=1;
 
457
              p++;
 
458
 
 
459
              // Read media object number (seq):
 
460
              if(!check_varlen(p, p_end, segtype >> 4)) break; // Not enough data
 
461
              seq = read_varlen(&p, segtype >> 4, 0);
 
462
 
 
463
              // Read offset or timestamp:
 
464
              if(!check_varlen(p, p_end, segtype >> 2)) break; // Not enough data
 
465
              x = read_varlen(&p, segtype >> 2, 0);
 
466
 
 
467
              // Read replic.data len:
 
468
              if(!check_varlen(p, p_end, segtype)) break; // Not enough data
 
469
              rlen = read_varlen(&p, segtype, 0);
 
470
 
 
471
//            printf("### rlen=%d   \n",rlen);
 
472
 
 
473
              switch(rlen){
 
474
              case 0x01: // 1 = special, means grouping
 
475
                //printf("grouping: %02X  \n",p[0]);
 
476
                ++p; // skip PTS delta
 
477
                break;
 
478
              default:
 
479
                if(rlen>=8){
 
480
                    p+=4;       // skip object size
 
481
                    if (p+3 >= p_end) break; // Packet too short
 
482
                    time2=AV_RL32(p); // read PTS
 
483
                    if (asf->asf_is_dvr_ms)
 
484
                        get_payload_extension_data(demux, &p, streamno, seq, &keyframe, &time2);
 
485
                    p+=rlen-4;
 
486
                } else {
 
487
                    mp_msg(MSGT_DEMUX,MSGL_V,"unknown segment type (rlen): 0x%02X  \n",rlen);
 
488
                    time2=0; // unknown
 
489
                    p+=rlen;
 
490
                }
 
491
              }
 
492
 
 
493
              if(flags&1){
 
494
                // multiple segments
 
495
                if(!check_varlen(p, p_end, segsizetype)) break; // Not enough data
 
496
                len = read_varlen(&p, segsizetype, plen-(p-asf->packet));
 
497
              } else {
 
498
                // single segment
 
499
                len=plen-(p-asf->packet);
 
500
              }
 
501
              if(len<0 || (p+len)>p_end){
 
502
                mp_msg(MSGT_DEMUX,MSGL_V,"ASF_parser: warning! segment len=%d\n",len);
 
503
                len = p_end - p;
 
504
              }
 
505
              mp_dbg(MSGT_DEMUX,MSGL_DBG4,"  seg #%d: streamno=%d  seq=%d  type=%02X  len=%d\n",seg,streamno,seq,rlen,len);
 
506
 
 
507
              switch(rlen){
 
508
              case 0x01:
 
509
                // GROUPING:
 
510
                //printf("ASF_parser: warning! grouping (flag=1) not yet supported!\n",len);
 
511
                //printf("  total: %d  \n",len);
 
512
                while(len>0){
 
513
                  int len2=p[0];
 
514
                  p++;
 
515
                  //printf("  group part: %d bytes\n",len2);
 
516
                  if(len2 > len - 1 || len2 < 0) break; // Not enough data
 
517
                  len2 = FFMIN(len2, asf->packetsize);
 
518
                  demux_asf_read_packet(demux,p,len2,streamno,seq,x,duration,-1,keyframe);
 
519
                  p+=len2;
 
520
                  len-=len2+1;
 
521
                  ++seq;
 
522
                }
 
523
                if(len!=0){
 
524
                  mp_msg(MSGT_DEMUX,MSGL_V,"ASF_parser: warning! groups total != len\n");
 
525
                }
 
526
                break;
 
527
              default:
 
528
                // NO GROUPING:
 
529
                //printf("fragment offset: %d  \n",sh->x);
 
530
                if (len <= 0) break;
 
531
                if (!asf->asf_is_dvr_ms || asf->found_first_key_frame) {
 
532
                    len = FFMIN(len, asf->packetsize);
 
533
                    demux_asf_read_packet(demux,p,len,streamno,seq,time2,duration,x,keyframe);
 
534
                }
 
535
                p+=len;
 
536
                break;
 
537
              }
 
538
 
 
539
            } // for segs
 
540
            return 1; // success
 
541
    }
 
542
 
 
543
    mp_msg(MSGT_DEMUX,MSGL_V,"%08"PRIX64":  UNKNOWN TYPE  %02X %02X %02X %02X %02X...\n",(int64_t)demux->filepos,asf->packet[0],asf->packet[1],asf->packet[2],asf->packet[3],asf->packet[4]);
 
544
    return 0;
 
545
}
 
546
 
 
547
#include "stheader.h"
 
548
 
 
549
static void demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
 
550
    struct asf_priv* asf = demuxer->priv;
 
551
    demux_stream_t *d_audio=demuxer->audio;
 
552
    demux_stream_t *d_video=demuxer->video;
 
553
    sh_audio_t *sh_audio=d_audio->sh;
 
554
//    sh_video_t *sh_video=d_video->sh;
 
555
 
 
556
  //FIXME: OFF_T - didn't test ASF case yet (don't have a large asf...)
 
557
  //FIXME: reports good or bad to steve@daviesfam.org please
 
558
 
 
559
  //================= seek in ASF ==========================
 
560
    float p_rate=asf->packetrate; // packets / sec
 
561
    off_t rel_seek_packs=(flags&SEEK_FACTOR)?    // FIXME: int may be enough?
 
562
        (rel_seek_secs*(demuxer->movi_end-demuxer->movi_start)/asf->packetsize):
 
563
        (rel_seek_secs*p_rate);
 
564
    off_t rel_seek_bytes=rel_seek_packs*asf->packetsize;
 
565
    off_t newpos;
 
566
    //printf("ASF: packs: %d  duration: %d  \n",(int)fileh.packets,*((int*)&fileh.duration));
 
567
//    printf("ASF_seek: %d secs -> %d packs -> %d bytes  \n",
 
568
//       rel_seek_secs,rel_seek_packs,rel_seek_bytes);
 
569
    newpos=((flags&SEEK_ABSOLUTE)?demuxer->movi_start:demuxer->filepos)+rel_seek_bytes;
 
570
    if(newpos<0 || newpos<demuxer->movi_start) newpos=demuxer->movi_start;
 
571
//    printf("\r -- asf: newpos=%d -- \n",newpos);
 
572
    stream_seek(demuxer->stream,newpos);
 
573
 
 
574
    if (asf->asf_is_dvr_ms) asf->dvr_last_vid_pts = 0.0f;
 
575
 
 
576
    if (d_video->id >= 0)
 
577
    ds_fill_buffer(d_video);
 
578
    if(sh_audio){
 
579
      ds_fill_buffer(d_audio);
 
580
    }
 
581
 
 
582
    if (d_video->id >= 0)
 
583
    while(1){
 
584
        if(sh_audio && !d_audio->eof){
 
585
          float a_pts=d_audio->pts;
 
586
          a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
 
587
          // sync audio:
 
588
          if (d_video->pts > a_pts){
 
589
              skip_audio_frame(sh_audio);
 
590
//            if(!ds_fill_buffer(d_audio)) sh_audio=NULL; // skip audio. EOF?
 
591
              continue;
 
592
          }
 
593
        }
 
594
        if(d_video->flags&1) break; // found a keyframe!
 
595
        if(!ds_fill_buffer(d_video)) break; // skip frame.  EOF?
 
596
    }
 
597
 
 
598
 
 
599
}
 
600
 
 
601
static int demux_asf_control(demuxer_t *demuxer,int cmd, void *arg){
 
602
    struct asf_priv* asf = demuxer->priv;
 
603
/*  demux_stream_t *d_audio=demuxer->audio;
 
604
    demux_stream_t *d_video=demuxer->video;
 
605
    sh_audio_t *sh_audio=d_audio->sh;
 
606
    sh_video_t *sh_video=d_video->sh;
 
607
*/
 
608
    switch(cmd) {
 
609
        case DEMUXER_CTRL_GET_TIME_LENGTH:
 
610
            *((double *)arg)=asf->movielength;
 
611
            return DEMUXER_CTRL_OK;
 
612
 
 
613
        case DEMUXER_CTRL_GET_PERCENT_POS:
 
614
                return DEMUXER_CTRL_DONTKNOW;
 
615
 
 
616
        default:
 
617
            return DEMUXER_CTRL_NOTIMPL;
 
618
    }
 
619
}
 
620
 
 
621
 
 
622
static demuxer_t* demux_open_asf(demuxer_t* demuxer)
 
623
{
 
624
    struct asf_priv* asf = demuxer->priv;
 
625
    sh_video_t *sh_video=NULL;
 
626
 
 
627
    //---- ASF header:
 
628
    if(!asf) return NULL;
 
629
    init_priv(asf);
 
630
    if (!read_asf_header(demuxer,asf))
 
631
        return NULL;
 
632
    stream_reset(demuxer->stream);
 
633
    stream_seek(demuxer->stream,demuxer->movi_start);
 
634
//    demuxer->idx_pos=0;
 
635
//    demuxer->endpos=avi_header.movi_end;
 
636
    if(demuxer->video->id != -2) {
 
637
        if(!ds_fill_buffer(demuxer->video)){
 
638
            mp_msg(MSGT_DEMUXER,MSGL_WARN,"ASF: " MSGTR_MissingVideoStream);
 
639
            demuxer->video->sh=NULL;
 
640
            //printf("ASF: missing video stream!? contact the author, it may be a bug :(\n");
 
641
        } else {
 
642
            sh_video=demuxer->video->sh;
 
643
            sh_video->fps=1000.0f; sh_video->frametime=0.001f;
 
644
 
 
645
            if (asf->asf_is_dvr_ms) {
 
646
                sh_video->bih->biWidth = 0;
 
647
                sh_video->bih->biHeight = 0;
 
648
            }
 
649
        }
 
650
    }
 
651
 
 
652
    if(demuxer->audio->id!=-2){
 
653
        mp_msg(MSGT_DEMUXER,MSGL_V,MSGTR_ASFSearchingForAudioStream,demuxer->audio->id);
 
654
        if(!ds_fill_buffer(demuxer->audio)){
 
655
            mp_msg(MSGT_DEMUXER,MSGL_INFO,"ASF: " MSGTR_MissingAudioStream);
 
656
            demuxer->audio->sh=NULL;
 
657
        }
 
658
    }
 
659
    if(!demuxer->stream->seek)
 
660
        demuxer->seekable=0;
 
661
 
 
662
    return demuxer;
 
663
}
 
664
 
 
665
 
 
666
static void demux_close_asf(demuxer_t *demuxer) {
 
667
    struct asf_priv* asf = demuxer->priv;
 
668
 
 
669
    if (!asf) return;
 
670
 
 
671
    free(asf->aud_repdata_sizes);
 
672
    free(asf->vid_repdata_sizes);
 
673
    free(asf->packet);
 
674
    free(asf);
 
675
}
 
676
 
 
677
const demuxer_desc_t demuxer_desc_asf = {
 
678
  "ASF demuxer",
 
679
  "asf",
 
680
  "ASF",
 
681
  "A'rpi",
 
682
  "ASF, WMV, WMA",
 
683
  DEMUXER_TYPE_ASF,
 
684
  1, // safe autodetect
 
685
  asf_check_header,
 
686
  demux_asf_fill_buffer,
 
687
  demux_open_asf,
 
688
  demux_close_asf,
 
689
  demux_seek_asf,
 
690
  demux_asf_control
 
691
};