~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to libmpdemux/demux_asf.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:47:54 UTC
  • Revision ID: siretart@tauware.de-20060708084754-c3ff228cc9c2d8de
upgrade to pre8

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
 
15
15
#include "libvo/fastmemcpy.h"
16
16
 
 
17
#define ASFMIN(a,b) ((a) > (b) ? (b) : (a))
 
18
#define SLICE_MIN_START_CODE    0x00000101
 
19
#define SLICE_MAX_START_CODE    0x000001af
 
20
#define END_NOT_FOUND -100
 
21
 
17
22
/*
18
23
 * Load 16/32-bit values in little endian byte order
19
24
 * from an unaligned address
21
26
#ifdef ARCH_X86
22
27
#define LOAD_LE32(p)    (*(unsigned int*)(p))
23
28
#define LOAD_LE16(p)    (*(unsigned short*)(p))
 
29
#define LOAD_BE32(p)    (((unsigned char*)(p))[3]     | \
 
30
                         ((unsigned char*)(p))[2]<< 8 | \
 
31
                         ((unsigned char*)(p))[1]<<16 | \
 
32
                         ((unsigned char*)(p))[0]<<24 )
24
33
#else
25
34
#define LOAD_LE32(p)    (((unsigned char*)(p))[0]     | \
26
35
                         ((unsigned char*)(p))[1]<< 8 | \
28
37
                         ((unsigned char*)(p))[3]<<24 )
29
38
#define LOAD_LE16(p)    (((unsigned char*)(p))[0]     | \
30
39
                         ((unsigned char*)(p))[1]<<8)
 
40
#define LOAD_BE32(p)    (*(unsigned int*)(p))
31
41
#endif
32
42
 
33
43
// defined at asfheader.c:
34
 
extern unsigned char* asf_packet;
35
 
extern int asf_scrambling_h;
36
 
extern int asf_scrambling_w;
37
 
extern int asf_scrambling_b;
38
 
extern int asf_packetsize;
39
 
extern double asf_packetrate;
40
 
extern int asf_movielength;
 
44
 
41
45
extern int asf_check_header(demuxer_t *demuxer);
42
 
extern int read_asf_header(demuxer_t *demuxer);
 
46
extern int read_asf_header(demuxer_t *demuxer,struct asf_priv* asf);
43
47
 
44
48
// based on asf file-format doc by Eugene [http://divx.euro.ru]
45
49
 
46
 
static void asf_descrambling(unsigned char **src,int len){
 
50
static void asf_descrambling(unsigned char **src,unsigned len, struct asf_priv* asf){
47
51
  unsigned char *dst=malloc(len);
48
52
  unsigned char *s2=*src;
49
 
  int i=0,x,y;
50
 
  while(len-i>=asf_scrambling_h*asf_scrambling_w*asf_scrambling_b){
 
53
  unsigned i=0,x,y;
 
54
  while(len>=asf->scrambling_h*asf->scrambling_w*asf->scrambling_b+i){
51
55
//    mp_msg(MSGT_DEMUX,MSGL_DBG4,"descrambling! (w=%d  b=%d)\n",w,asf_scrambling_b);
52
56
        //i+=asf_scrambling_h*asf_scrambling_w;
53
 
        for(x=0;x<asf_scrambling_w;x++)
54
 
          for(y=0;y<asf_scrambling_h;y++){
55
 
            memcpy(dst+i,s2+(y*asf_scrambling_w+x)*asf_scrambling_b,asf_scrambling_b);
56
 
                i+=asf_scrambling_b;
 
57
        for(x=0;x<asf->scrambling_w;x++)
 
58
          for(y=0;y<asf->scrambling_h;y++){
 
59
            memcpy(dst+i,s2+(y*asf->scrambling_w+x)*asf->scrambling_b,asf->scrambling_b);
 
60
                i+=asf->scrambling_b;
57
61
          }
58
 
        s2+=asf_scrambling_h*asf_scrambling_w*asf_scrambling_b;
 
62
        s2+=asf->scrambling_h*asf->scrambling_w*asf->scrambling_b;
59
63
  }
60
64
  //if(i<len) memcpy(dst+i,src+i,len-i);
61
65
  free(*src);
70
74
#define FF_INPUT_BUFFER_PADDING_SIZE 8
71
75
#endif
72
76
 
 
77
static const uint8_t *find_start_code(const uint8_t * restrict p, const uint8_t *end, uint32_t * restrict state){
 
78
  int i;
 
79
  if(p>=end)
 
80
    return end;
 
81
 
 
82
  for(i=0; i<3; i++){
 
83
    uint32_t tmp= *state << 8;
 
84
    *state= tmp + *(p++);
 
85
    if(tmp == 0x100 || p==end)
 
86
      return p;
 
87
  }
 
88
 
 
89
  while(p<end){
 
90
    if     (p[-1] > 1      ) p+= 3;
 
91
    else if(p[-2]          ) p+= 2;
 
92
    else if(p[-3]|(p[-1]-1)) p++;
 
93
    else{
 
94
      p++;
 
95
      break;
 
96
    }
 
97
  }
 
98
 
 
99
  p= ASFMIN(p, end)-4;
 
100
  *state=  LOAD_BE32(p);
 
101
 
 
102
  return p+4;
 
103
}
 
104
 
 
105
static int mpeg1_find_frame_end(demuxer_t *demux, const uint8_t *buf, int buf_size)
 
106
{
 
107
  int i;
 
108
  struct asf_priv* asf = demux->priv;
 
109
 
 
110
  i=0;
 
111
   if(!asf->asf_frame_start_found){
 
112
    for(i=0; i<buf_size; i++){
 
113
      i= find_start_code(buf+i, buf+buf_size, &asf->asf_frame_state) - buf - 1;
 
114
      if(asf->asf_frame_state >= SLICE_MIN_START_CODE && asf->asf_frame_state <= SLICE_MAX_START_CODE){
 
115
        i++;
 
116
        asf->asf_frame_start_found=1;
 
117
        break;
 
118
      }
 
119
    }
 
120
  }
 
121
 
 
122
  if(asf->asf_frame_start_found){
 
123
    /* EOF considered as end of frame */
 
124
      if (buf_size == 0)
 
125
          return 0;
 
126
            
 
127
    for(; i<buf_size; i++){
 
128
      i= find_start_code(buf+i, buf+buf_size, &asf->asf_frame_state) - buf - 1;
 
129
      if((asf->asf_frame_state&0xFFFFFF00) == 0x100){
 
130
        //if NOT in range 257 - 431
 
131
        if(asf->asf_frame_state < SLICE_MIN_START_CODE || asf->asf_frame_state > SLICE_MAX_START_CODE){
 
132
          asf->asf_frame_start_found=0;
 
133
          asf->asf_frame_state=-1;
 
134
          return i-3;
 
135
        }
 
136
      }
 
137
    }
 
138
  }
 
139
  return END_NOT_FOUND;
 
140
}
 
141
 
 
142
static void demux_asf_append_to_packet(demux_packet_t* dp,unsigned char *data,int len,int offs)
 
143
{
 
144
  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);
 
145
  dp->buffer=realloc(dp->buffer,dp->len+len+FF_INPUT_BUFFER_PADDING_SIZE);
 
146
  memcpy(dp->buffer+dp->len,data,len);
 
147
  memset(dp->buffer+dp->len+len, 0, FF_INPUT_BUFFER_PADDING_SIZE);
 
148
  mp_dbg(MSGT_DEMUX,MSGL_DBG4,"data appended! %d+%d\n",dp->len,len);
 
149
  dp->len+=len;
 
150
}
 
151
 
73
152
static int demux_asf_read_packet(demuxer_t *demux,unsigned char *data,int len,int id,int seq,unsigned long time,unsigned short dur,int offs,int keyframe){
 
153
  struct asf_priv* asf = demux->priv;
74
154
  demux_stream_t *ds=NULL;
 
155
  int close_seg=0;
 
156
  int frame_end_pos=END_NOT_FOUND;
75
157
  
76
158
  mp_dbg(MSGT_DEMUX,MSGL_DBG4,"demux_asf.read_packet: id=%d seq=%d len=%d\n",id,seq,len);
77
159
  
102
184
  
103
185
  if(ds){
104
186
    if(ds->asf_packet){
105
 
      if(ds->asf_seq!=seq){
 
187
      demux_packet_t* dp=ds->asf_packet;
 
188
 
 
189
      if (ds==demux->video && asf->asf_is_dvr_ms) {
 
190
        frame_end_pos=mpeg1_find_frame_end(demux, data, len);
 
191
 
 
192
        if (frame_end_pos != END_NOT_FOUND) {
 
193
          dp->pos=demux->filepos;
 
194
          if (frame_end_pos > 0) {
 
195
            demux_asf_append_to_packet(dp,data,frame_end_pos,offs);
 
196
            data += frame_end_pos;
 
197
            len -= frame_end_pos;
 
198
          }
 
199
          close_seg = 1;
 
200
        } else seq = ds->asf_seq;
 
201
      } else close_seg = ds->asf_seq!=seq;
 
202
 
 
203
      if(close_seg){
106
204
        // closed segment, finalize packet:
107
205
                if(ds==demux->audio)
108
 
                  if(asf_scrambling_h>1 && asf_scrambling_w>1)
109
 
                    asf_descrambling(&ds->asf_packet->buffer,ds->asf_packet->len);
 
206
                  if(asf->scrambling_h>1 && asf->scrambling_w>1 && asf->scrambling_b>0)
 
207
                    asf_descrambling(&ds->asf_packet->buffer,ds->asf_packet->len,asf);
110
208
        ds_add_packet(ds,ds->asf_packet);
111
209
        ds->asf_packet=NULL;
112
210
      } else {
113
211
        // append data to it!
114
 
        demux_packet_t* dp=ds->asf_packet;
115
 
        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);
116
 
        dp->buffer=realloc(dp->buffer,dp->len+len+FF_INPUT_BUFFER_PADDING_SIZE);
117
 
        memcpy(dp->buffer+dp->len,data,len);
118
 
        memset(dp->buffer+dp->len+len, 0, FF_INPUT_BUFFER_PADDING_SIZE);
119
 
        mp_dbg(MSGT_DEMUX,MSGL_DBG4,"data appended! %d+%d\n",dp->len,len);
120
 
        dp->len+=len;
 
212
        demux_asf_append_to_packet(dp,data,len,offs);
121
213
        // we are ready now.
122
214
        return 1;
123
215
      }
151
243
//     0 = EOF or no stream found
152
244
//     1 = successfully read a packet
153
245
static int demux_asf_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
 
246
  struct asf_priv* asf = demux->priv;
154
247
 
155
248
  demux->filepos=stream_tell(demux->stream);
156
249
  // Brodcast stream have movi_start==movi_end
160
253
          return 0;
161
254
  }
162
255
 
163
 
    stream_read(demux->stream,asf_packet,asf_packetsize);
 
256
    stream_read(demux->stream,asf->packet,asf->packetsize);
164
257
    if(demux->stream->eof) return 0; // EOF
165
258
    
166
259
    {
167
 
            unsigned char* p=asf_packet;
168
 
            unsigned char* p_end=asf_packet+asf_packetsize;
 
260
            unsigned char* p=asf->packet;
 
261
            unsigned char* p_end=asf->packet+asf->packetsize;
169
262
            unsigned char flags=p[0];
170
263
            unsigned char segtype=p[1];
171
 
            int padding;
172
 
            int plen;
173
 
            int sequence;
 
264
            unsigned padding;
 
265
            unsigned plen;
 
266
            unsigned sequence;
174
267
            unsigned long time=0;
175
268
            unsigned short duration=0;
176
269
 
178
271
            unsigned char segsizetype=0x80;
179
272
            int seg=-1;
180
273
            
181
 
            if(verbose>1){
 
274
            if( mp_msg_test(MSGT_DEMUX,MSGL_DBG2) ){
182
275
                int i;
183
 
                for(i=0;i<16;i++) printf(" %02X",asf_packet[i]);
 
276
                for(i=0;i<16;i++) printf(" %02X",asf->packet[i]);
184
277
                printf("\n");
185
278
            }
186
279
            
227
320
            if(((flags>>5)&3)!=0){
228
321
              // Explicit (absoulte) packet size
229
322
              mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Explicit packet size specified: %d  \n",plen);
230
 
              if(plen>asf_packetsize) mp_msg(MSGT_DEMUX,MSGL_V,"Warning! plen>packetsize! (%d>%d)  \n",plen,asf_packetsize);
 
323
              if(plen>asf->packetsize) mp_msg(MSGT_DEMUX,MSGL_V,"Warning! plen>packetsize! (%d>%d)  \n",plen,asf->packetsize);
231
324
            } else {
232
325
              // Padding (relative) size
233
 
              plen=asf_packetsize-padding;
 
326
              plen=asf->packetsize-padding;
234
327
            }
235
328
 
236
329
            // Read time & duration:
244
337
              segs=p[0] & 0x3F;
245
338
              ++p;
246
339
            }
247
 
            mp_dbg(MSGT_DEMUX,MSGL_DBG4,"%08X:  flag=%02X  segs=%d  seq=%d  plen=%d  pad=%d  time=%ld  dur=%d\n",
248
 
              demux->filepos,flags,segs,sequence,plen,padding,time,duration);
 
340
            mp_dbg(MSGT_DEMUX,MSGL_DBG4,"%08"PRIu64":  flag=%02X  segs=%d  seq=%u  plen=%u  pad=%u  time=%ld  dur=%d\n",
 
341
              (uint64_t)demux->filepos,flags,segs,sequence,plen,padding,time,duration);
249
342
 
250
343
            for(seg=0;seg<segs;seg++){
251
344
              //ASF_segmhdr_t* sh;
260
353
 
261
354
              if(p>=p_end) mp_msg(MSGT_DEMUX,MSGL_V,"Warning! invalid packet 1, sig11 coming soon...\n");
262
355
 
263
 
              if(verbose>1){
 
356
              if( mp_msg_test(MSGT_DEMUX,MSGL_DBG2) ){
264
357
                int i;
265
358
                printf("seg %d:",seg);
266
359
                for(i=0;i<16;i++) printf(" %02X",p[i]);
320
413
                  case 3: len=LOAD_LE32(p);p+=4;break;  // dword
321
414
                  case 2: len=LOAD_LE16(p);p+=2;break;  // word
322
415
                  case 1: len=p[0];p++;break;           // byte
323
 
                  default: len=plen-(p-asf_packet); // ???
 
416
                  default: len=plen-(p-asf->packet); // ???
324
417
                }
325
418
              } else {
326
419
                // single segment
327
 
                len=plen-(p-asf_packet);
 
420
                len=plen-(p-asf->packet);
328
421
              }
329
422
              if(len<0 || (p+len)>p_end){
330
423
                mp_msg(MSGT_DEMUX,MSGL_V,"ASF_parser: warning! segment len=%d\n",len);
361
454
            return 1; // success
362
455
    }
363
456
    
364
 
    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]);
 
457
    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]);
365
458
    return 0;
366
459
}
367
460
 
369
462
 
370
463
extern void skip_audio_frame(sh_audio_t *sh_audio);
371
464
 
372
 
static void demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,int flags){
 
465
static void demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
 
466
    struct asf_priv* asf = demuxer->priv;
373
467
    demux_stream_t *d_audio=demuxer->audio;
374
468
    demux_stream_t *d_video=demuxer->video;
375
469
    sh_audio_t *sh_audio=d_audio->sh;
379
473
  //FIXME: reports good or bad to steve@daviesfam.org please
380
474
 
381
475
  //================= seek in ASF ==========================
382
 
    float p_rate=asf_packetrate; // packets / sec
 
476
    float p_rate=asf->packetrate; // packets / sec
383
477
    off_t rel_seek_packs=(flags&2)?      // FIXME: int may be enough?
384
 
        (rel_seek_secs*(demuxer->movi_end-demuxer->movi_start)/asf_packetsize):
 
478
        (rel_seek_secs*(demuxer->movi_end-demuxer->movi_start)/asf->packetsize):
385
479
        (rel_seek_secs*p_rate);
386
 
    off_t rel_seek_bytes=rel_seek_packs*asf_packetsize;
 
480
    off_t rel_seek_bytes=rel_seek_packs*asf->packetsize;
387
481
    off_t newpos;
388
482
    //printf("ASF: packs: %d  duration: %d  \n",(int)fileh.packets,*((int*)&fileh.duration));
389
483
//    printf("ASF_seek: %d secs -> %d packs -> %d bytes  \n",
421
515
}
422
516
 
423
517
static int demux_asf_control(demuxer_t *demuxer,int cmd, void *arg){
 
518
    struct asf_priv* asf = demuxer->priv;
424
519
/*  demux_stream_t *d_audio=demuxer->audio;
425
520
    demux_stream_t *d_video=demuxer->video;
426
521
    sh_audio_t *sh_audio=d_audio->sh;
428
523
*/
429
524
    switch(cmd) {
430
525
        case DEMUXER_CTRL_GET_TIME_LENGTH:
431
 
            *((double *)arg)=(double)(asf_movielength);
 
526
            *((double *)arg)=(double)(asf->movielength);
432
527
            return DEMUXER_CTRL_OK;
433
528
 
434
529
        case DEMUXER_CTRL_GET_PERCENT_POS:
442
537
 
443
538
static demuxer_t* demux_open_asf(demuxer_t* demuxer)
444
539
{
 
540
    struct asf_priv* asf = demuxer->priv;
445
541
    sh_audio_t *sh_audio=NULL;
446
542
    sh_video_t *sh_video=NULL;
447
543
 
448
544
    //---- ASF header:
449
 
    read_asf_header(demuxer);
 
545
    if(!asf) return NULL;
 
546
    if (!read_asf_header(demuxer,asf)) {
 
547
        free(asf);
 
548
        return NULL;
 
549
    }
450
550
    stream_reset(demuxer->stream);
451
551
    stream_seek(demuxer->stream,demuxer->movi_start);
452
552
//    demuxer->idx_pos=0;
459
559
        } else {
460
560
            sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
461
561
            sh_video->fps=1000.0f; sh_video->frametime=0.001f; // 1ms
462
 
            //sh_video->i_bps=10*asf_packetsize; // FIXME!
 
562
            //sh_video->i_bps=10*asf->packetsize; // FIXME!
463
563
        }
464
564
    }
465
565