1 /** *************************************************************************
2     \file ADM_asf.cpp
3     \brief ASF/WMV demuxer
4     copyright            : (C) 2006/2009 by mean
5     email                : fixounet@free.fr
6  ***************************************************************************/
7 
8 /***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  ***************************************************************************/
16 
17 #include "ADM_default.h"
18 #include "ADM_Video.h"
19 #include "ADM_assert.h"
20 
21 #include "fourcc.h"
22 #include "DIA_coreToolkit.h"
23 #include "ADM_asf.h"
24 #include "ADM_asfPacket.h"
25 
26 #if 0
27 #define aprintf printf
28 #else
29 #define aprintf(...) {}
30 #endif
31 
32 /**
33     \fn getAudioInfo
34 */
getAudioInfo(uint32_t i)35 WAVHeader *asfHeader::getAudioInfo(uint32_t i )
36 {
37   if(!_nbAudioTrack) return NULL;
38 
39   ADM_assert(i<_nbAudioTrack);
40   if(NULL==_audioAccess) return NULL;
41   return &(_allAudioTracks[i].wavHeader);
42 }
43 /**
44     \fn getAudioStream
45 */
getAudioStream(uint32_t i,ADM_audioStream ** audio)46 uint8_t    asfHeader::getAudioStream(uint32_t i,ADM_audioStream  **audio)
47 {
48  *audio=NULL;
49   if(!_nbAudioTrack) return true;
50   ADM_assert(i<_nbAudioTrack);
51   *audio=_audioStreams[i];
52  return 1;
53 }
54 /**
55     \fn getNbAudioStreams
56 */
getNbAudioStreams(void)57 uint8_t                 asfHeader::getNbAudioStreams(void)
58 {
59     return _nbAudioTrack;
60 }
61 
62 /**
63     \fn Dump
64 */
65 
Dump(void)66 void asfHeader::Dump(void)
67 {
68 
69   printf("*********** ASF INFO***********\n");
70 }
71 
72 /**
73     \fn close
74 */
75 
close(void)76 uint8_t asfHeader::close(void)
77 {
78 	if (_fd)
79 		fclose(_fd);
80 
81 	_fd=NULL;
82 
83   if(_videoExtraData)
84   {
85     delete [] _videoExtraData;
86     _videoExtraData=NULL;
87   }
88   if(myName)
89   {
90     ADM_dealloc(myName);
91     myName=NULL;
92   }
93   if(_videoExtraData)
94   {
95     delete [] _videoExtraData;
96     _videoExtraData=NULL;
97   }
98 
99   if(_packet)
100     delete _packet;
101   _packet=NULL;
102 
103   for(int i=0;i<_nbAudioTrack;i++)
104   {
105     asfAudioTrak *trk=&(_allAudioTracks[i]);
106     if(trk->extraData) delete [] trk->extraData;
107     trk->extraData=NULL;
108     delete    _audioAccess[i];
109     _audioAccess[i]=NULL;
110     delete _audioStreams[i];
111     _audioStreams[i]=NULL;
112   }
113   freeQueue(&readQueue);
114   freeQueue(&storageQueue);
115   return 1;
116 }
117 /**
118     \fn asfHeader
119 */
120 
121 
asfHeader(void)122  asfHeader::asfHeader( void ) : vidHeader()
123 {
124   _fd=NULL;
125   _videoIndex=-1;
126   myName=NULL;
127   _packetSize=0;
128   _videoStreamId=0;
129   nbImage=0;
130 
131   _packet=NULL;
132   _nbPackets=0;
133   memset(&(_allAudioTracks[0]),0,sizeof(_allAudioTracks));
134   memset(&(_audioAccess[0]),0,sizeof(_audioAccess));
135   memset(&(_audioStreams[0]),0,sizeof(_audioStreams));
136   _nbAudioTrack=0;
137   _videostream.dwRate=0;
138   _shiftUs=0;
139 
140 }
141 /**
142     \fn ~ asfHeader
143 */
144 
~asfHeader()145  asfHeader::~asfHeader(  )
146 {
147   close();
148 }
149 /**
150     \fn open
151 */
152 
open(const char * name)153 uint8_t asfHeader::open(const char *name)
154 {
155   _fd=ADM_fopen(name,"rb");
156   if(!_fd)
157   {
158     GUI_Error_HIG(QT_TRANSLATE_NOOP("asfdemuxer","File Error."),QT_TRANSLATE_NOOP("asfdemuxer","Cannot open file\n"));
159     return 0;
160   }
161   myName=ADM_strdup(name);
162   if(!getHeaders())
163   {
164     return 0;
165   }
166   ADM_info("Stream Video: index=%d, sid=%d\n",(int)_videoIndex,(int)_videoStreamId);
167   for(int i=0;i<_nbAudioTrack;i++)
168     ADM_info("Stream Audio: index=%d, sid=%d\n",
169                 (int)_allAudioTracks[i].streamIndex,(int)_allAudioTracks[i].streamIndex);
170   uint8_t r=buildIndex();
171   switch(r)
172   {
173       case 0:
174           ADM_error("No images found \n");
175           return r;
176       case ADM_IGN:
177           ADM_warning("Indexing cancelled by user after %" PRIu32" images\n",nbImage);
178           return r;
179       default:
180           break;
181   }
182   fseeko(_fd,_dataStartOffset,SEEK_SET);
183   _packet=new asfPacket(_fd,_nbPackets,_packetSize,&readQueue,&storageQueue,_dataStartOffset);
184   curSeq=1;
185   for(int i=0;i<_nbAudioTrack;i++)
186   {
187         _audioAccess[i]=new asfAudioAccess(this,i);
188         _audioStreams[i]=ADM_audioCreateStream(&(_allAudioTracks[i].wavHeader), _audioAccess[i]);
189   }
190   return 1;
191 }
192 /**
193     \fn setFlag
194 */
195 
setFlag(uint32_t frame,uint32_t flags)196   uint8_t  asfHeader::setFlag(uint32_t frame,uint32_t flags)
197 {
198   ADM_assert(frame<nbImage);
199   _index[frame].flags=flags;
200   return 1;
201 }
202 /**
203     \fn getFlags
204 */
205 
getFlags(uint32_t frame,uint32_t * flags)206 uint32_t asfHeader::getFlags(uint32_t frame,uint32_t *flags)
207 {
208   if(frame>=nbImage) return 0;
209   if(!frame) *flags=AVI_KEY_FRAME;
210   else
211       *flags=_index[frame].flags;
212   return 1;
213 }
214 /**
215     \fn getFrameSize
216 */
getFrameSize(uint32_t frame,uint32_t * size)217 uint8_t     asfHeader::getFrameSize(uint32_t frame,uint32_t *size)
218 {
219     *size=0;
220     if(frame>=nbImage) return 0;
221     *size=_index[frame].frameLen;
222     return true;
223 }
224 /**
225     \fn getTime
226 */
getTime(uint32_t frameNum)227 uint64_t                   asfHeader::getTime(uint32_t frameNum)
228 {
229      if(frameNum>=nbImage) return ADM_NO_PTS;
230      return _index[frameNum].pts; // ??PTS??
231 }
232 /**
233     \fn getTime
234 */
235 
getVideoDuration(void)236 uint64_t                   asfHeader::getVideoDuration(void)
237 {
238     return _duration;
239 }
240 /**
241     \fn getTime
242 */
243 
getPtsDts(uint32_t frame,uint64_t * pts,uint64_t * dts)244 bool                       asfHeader::getPtsDts(uint32_t frame,uint64_t *pts,uint64_t *dts)
245 {
246     if(frame>=nbImage) return false;
247     *pts=_index[frame].pts;
248     *dts=_index[frame].dts;
249     return true;
250 }
251 /**
252     \fn getTime
253 */
254 
setPtsDts(uint32_t frame,uint64_t pts,uint64_t dts)255 bool                       asfHeader::setPtsDts(uint32_t frame,uint64_t pts,uint64_t dts)
256 {
257      if(frame>=nbImage) return false;
258     _index[frame].pts=pts;
259     _index[frame].dts=dts;;
260     return true;
261 }
262 /**
263     \fn getFrame
264 */
getFrame(uint32_t framenum,ADMCompressedImage * img)265 uint8_t  asfHeader::getFrame(uint32_t framenum,ADMCompressedImage *img)
266 {
267   img->dataLength=0;
268   img->flags=AVI_KEY_FRAME;
269   uint32_t len=0;
270   if(framenum>=nbImage)
271   {
272     printf("[ASF] Going out of bound %u %u\n",framenum, nbImage);
273     return 0;
274   }
275   if(!_index[framenum].frameLen)
276   {
277     goto gotcha;
278   }
279   // In case curSeq is stored as one byte..
280   curSeq&=0xff;
281   //
282 
283   aprintf("Framenum %u len: %u curSeq %u frameSeq=%u packetnb=%u \n",
284          framenum,_index[framenum].frameLen,curSeq,
285          _index[framenum].segNb,_index[framenum].packetNb);
286   // Seeking ?
287   if(_index[framenum].segNb!=curSeq || _index[framenum].segNb==1)
288   {
289     aprintf("Seeking.. curseq:%u wanted seq:%u packet=%" PRIu64"\n",curSeq,_index[framenum].segNb,_index[framenum].packetNb);
290     if(!_packet->goToPacket(_index[framenum].packetNb))
291     {
292       printf("[ASF] Cannot seek to frame %u\n",framenum);
293       return 0;
294     }
295     _packet->purge();
296     curSeq=_index[framenum].segNb;
297     printf("Seeking done, starting at seq=%u\n",curSeq);
298   }
299 
300 
301   len=0;
302   uint32_t delta;
303   while(1)
304   {
305     while(readQueue.size())
306     {
307       asfBit *bit;
308       bit=readQueue.front();
309       readQueue.pop_front();
310       aprintf(">found packet of size %d seq %d, while curseq =%d wanted seg=%u current offset=%u, packet=%u\n",
311                     bit->len,bit->sequence,curSeq,_index[framenum].segNb,len,bit->packet);
312       // Here it is tricky
313       // if len==0 we are reading the first part of our frame
314       // The packet may starts with segments from the previous frame
315       // discard them
316       // Delta is just a security as it should be slightly >10
317       delta=256+bit->sequence-_index[framenum].segNb;
318       delta &=0xff;
319       if(!len) // Starting a new frame
320       {
321           if(_index[framenum].segNb != bit->sequence )
322           {
323             aprintf("Dropping seq=%u too old for %u delta %d\n",
324                   bit->sequence,_index[framenum].segNb,delta);
325             storageQueue.push_back(bit);
326             bit=NULL;
327             if(delta<230)
328             {
329               printf("[ASF] Very suspicious delta :%" PRIu32"\n",delta);
330             }
331             continue;
332           }
333           // We have found our first chunk
334           curSeq=bit->sequence;
335           memcpy(img->data,bit->data,bit->len);
336           len=bit->len;
337           delete[] bit->data;
338           delete bit;
339           continue;
340       }
341       // Continuing a frame
342       // If the seq number is different it is the beginning of a new frame
343       if(bit->sequence!=curSeq )
344       {
345         aprintf("New sequence %u->%u while loading %u frame\n",curSeq,bit->sequence,framenum);
346         img->dataLength=len;
347         readQueue.push_front(bit);
348         curSeq=bit->sequence;
349         goto gotcha;
350       }
351       // still same sequence ...add
352       memcpy(img->data+len,bit->data,bit->len);
353       len+=bit->len;
354       storageQueue.push_back(bit);
355       bit=NULL;
356     }
357     if(!_packet->nextPacket(_videoStreamId))
358     {
359       printf("[ASF] Packet Error\n");
360       return 0;
361     }
362     _packet->skipPacket();
363   }
364 gotcha:
365 
366   img->dataLength=len;
367   img->demuxerDts=_index[framenum].dts;
368   img->demuxerPts=_index[framenum].pts;
369   img->flags=_index[framenum].flags;
370   if(len!=_index[framenum].frameLen)
371   {
372     ADM_error("[ASF] Frame=%u :-> Mismatch found len : %u expected %u\n",framenum,len, _index[framenum].frameLen);
373   }
374   aprintf(">>Len %d seq %d\n",len,curSeq);
375   return 1;
376 }
377 //EOF
378